Axios Proxy Configuration causing Bad Request - node.js

I am trying to send a request to the particle cloud from a NodeJS application.
I am using Axios to make the PUT request. The application sends the request through a proxy server which is configured as well.
// axios proxy - not working
axios.default.put("https://api.particle.io/v1/devices/<deviceId>/ping", {}, {
proxy: {host: <proxy_ip>, protocol:'http', port:<port_no>},
headers: {
authorization: "Bearer <access_token>"
}
}).then((response) => {
console.log("Success", response.data);
}).catch((error) => {
console.log("Failed", error);
});
Error Message: Request failed with status code 400
When I send this request I get a 400 Bad Request response from the particle cloud.
But when I send the same request using the request module of NodeJS, the request is successful.
var options = {
method: 'PUT',
url: 'https://api.particle.io/v1/devices/<device_id>/ping',
proxy: {hostname: <proxy_ip>, protocol:'http', port:<port_no>},
headers:
{
authorization: 'Bearer <access_token>'
},
form: false
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(response);
});
Response: body: '{"online":false,"ok":true}'
The request also works when the application was deployed on the open network and axios was used without the proxy configuration.
// axios without proxy - working
axios.default.put("https://api.particle.io/v1/devices/<deviceId>/ping", {}, {
headers: {
authorization: "Bearer <access_token>"
}
}).then((response) => {
console.log("Success", response.data);
}).catch((error) => {
console.log("Failed", error);
});
Questions:
Why is the request from Axios failing with proxy configuration?
Is this an inherent issue with Axios?
Regards.

Axios itself has a bug which isnt fixed yet.
To overcome this issue, https-proxy-agent can be used instead of axios proxy.
const HttpsProxyAgent = require('https-proxy-agent')
axios.default.put("https://api.particle.io/v1/devices/<deviceId>/ping", {}, {
headers: {
authorization: "Bearer <access_token>"
},
proxy: false,
httpsAgent: new HttpsProxyAgent('http://proxy_domain:port')
}).then((response) => {
console.log("Success", response.data);
}).catch((error) => {
console.log("Failed", error);
});

Related

'Axios' show Error: Network Error on server returning with 200 http status

I am using axios: "^0.19.0" to create get and post requests in react-native 0.60.4, but even after backend returning HTTP status code 200 axois showing Error: Network Error. Working perfectly on iOS but not on Android.
My request:
export default function uploadImageWithData(formData, url = "createGroup") {
return new Promise((resolve, reject) => {
axios({
method: "post",
url: BASEURL + "api/webservice/" + url,
data: formData,
headers: {
"Content-Type": "multipart/form-data",
Authorization: `Bearer ${global.authToken}`
}
})
.then(response => {
resolve(response);
})
.catch(err => {
console.log("error: ", err);
reject(err);
});
});
}
Kindly help.
The issue with formData, in formData empty array appending in formData causing the issue(For Android).

Proxy API request through Express return pending Promise instead of response

I am currently trying to work with the Atlassian Jira rest API. In order to not get a CORS error I go through the recommended route of not sending the request from the browser but proxy it through my express server.
Now as I am doing this, all I receive back in the app is a pending promise. I assume that I have not correctly resolved it at one point but I cant figure out where.
API Handler sending the request to the proxy:
const baseURL = `${apiConfig}/jiraproxy`;
export const testConnection = integration => {
return fetch(`${baseURL}/get`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify(integration)
})
.then(handleResponse)
.catch(handleError);
};
Jira Proxy Endpoint on the Express Server
const baseURL = `rest/api/3/dashboard`;
router.post("/get", (req, res) => {
fetch(req.body.link + baseURL, {
method: "GET",
headers: { Accept: "application/json" },
auth: {
username: req.body.credentials.username,
password: req.body.credentials.token
}
})
.then(handleResponse)
.catch(handleError);
});
handleResponse & handle Error Methods:
async function handleResponse(response) {
if (response.ok) {
return response.json();
}
if (response.status === 400) {
const error = await response.text();
throw new Error(error);
}
throw new Error("Network response was not ok.");
}
function handleError(error) {
// eslint-disable-next-line no-console
console.error(`API call failed. ${error}`);
throw error;
}
Goal:
Send the request of sending a request to the proxy and return the resonse of the proxy as the return of the initial "testConction" method.
Error:
No errors thrown, but the response received in the Browser is a pending promise.
Change to the Jira Proxy router fixed it. Thanks to #jfriend00.
router.post("/get", (req, res) => {
return fetch(req.body.link + baseURL, {
method: "GET",
headers: { Accept: "application/json" },
auth: {
username: req.body.credentials.username,
password: req.body.credentials.token
}
})
// This is the part that changed
.then(response => handleResponse(response))
.then(jiraResponse => res.status(200).json(jiraResponse))
.catch(handleError);
});

nodejs request post large json fail

I am trying to post large json to a http server(a grafana server actually):
here is my code:
const http = require('http')
const request = require('request')
const fs = require('fs')
const opts = {
hostname: 'myip',
port: 3000,
path: '/api/dashboards/uid/KPEiIQVWk',
method: 'GET',
timeout: 5000,
headers : {
'Authorization' : 'Bearer ********************************************',
'Accept' : 'application/json',
'Content-Type' : 'application/json'
}
}
const req = http.request(opts, res => {
console.log(`Fetch: statusCode: ${res.statusCode}`)
var origin = ''
res.on('data', d => {
origin += d
})
res.on('end', function(){
dash = JSON.parse(origin)
dash.dashboard.panels.forEach(p => {
if(p.id == 26){
fs.readFile(__dirname + '/grafana/pm/branch-graph.html','utf-8', function(err, newPanel){
if(err){
console.log(err)
}
p.content = newPanel
const fresh = JSON.stringify(dash)
const updateOptions = {
uri: 'http://myip:3000/api/dashboards/db',
method: 'post',
headers : {
'Authorization' : 'Bearer *************************',
'Accept' : 'application/json',
'Content-Type' : 'application/json',
'Content-length' : fresh.length
},
json: fresh
}
fs.writeFile('tmp.json', fresh, function(err){
if(err){
console.error(err)
}
})
request(updateOptions, function(error, response, body){
console.log(`update: statusCode=${response.statusCode}`)
console.log(`update: ${body}`)
})
})
}
})
})
})
req.on('error', error => {
console.error(error)
})
req.on('timeout', () => {
req.abort()
})
req.end()
as you can see, I first fetch a grafana dashboard's source, then make some udpate, then post it back to grafana server. but always get 400 error. The strange thing is that if I dump the json to a file and use curl to post, it will work.
curl -vH "Authorization: Bearer $TOKEN" -H "Expect:" -d #tmp.json -H "Content-Type:application/json" http://myip:3000/api/dashboards/db
the whole json is about 40000+ bytes. any hint on this? I am not very famillar with nodejs. I am just trying to write some CI scripts.
First, I don't think it's necessary to use both the http and request modules. http is a module built into nodejs, and request is an npm package.
I recommend you use the npm request package because it's easier. You can read its documentation here: https://www.npmjs.com/package/request#http-authentication
Second, the options you're passing to the request module is not formatted correctly, I think this is why it is not working. With your current code, I would console.log('POST error', error); to print out the error. The correct options for the request module is proposed below.
const options = {
url: 'https://myip:3000/api/dashboards/db',
body: fresh, // the json from the fs.read callback
auth: {
'bearer': 'bearerToken'
},
json: true // from docs: If json is true, then body must be a JSON-serializable object.
}
request.post(
options,
(err, httpResponse, body) => {
console.log(err, body);
});

HTTP call to send data to server using Axios/Axios-retry

I have a JSON object that I wish to send to a server using the server's API key. I wish to have a retry count of 3 so that I can retry sending data if previous calls fail.
I am not sure whether to use 'axios-retry' or 'retry-axios'.
How do I configure the Content-Type in the header, and where do I add the API key and the data to be sent. My present code looks like this:
const axiosRetry = require('axios-retry');
axiosRetry(axios, { retries: 3 });
var data = { /*----My JSON Object----*/ };
axios.post('my url', data, {
headers: {
'Authorization': 'API_Key',
'Content-Type': 'application/json'
}
})
.then(function(response){
console.log(response);
})
.catch(function(error){
console.log(error);
});
Use axios instead, it is a Promise based HTTP client for the browser and node.js
var axios = require('axios')
axios.post(url,data, {
headers: {
'authorization': your_token,
'Accept' : 'application/json',
'Content-Type': 'application/json'
}
}).then(response => {
// return response;
}).catch((error) => {
//return error;
});

Request API node js using bearer token

I tried doing the following:
request({
url: 'https://vdms-dev.clientsolve.com/evoDMDev/api_event.php',
headers: {
'Authorization': 'Bearer 71D50F9987529'
}
}, function(err, res) {
console.log(res);
});
The log is showing undefined but when I try it on Postman it seems to be working fine.
Any help would be appreciated!
Since your are calling https host (https://evodms-dev.clientsolve.com/evoDMSDev/api/api_event_all.php), request client will throws an error while doing SSL handshake,
thats why you got response as undefined. Inorder to check the exact error response log the error console.error("Error Response : ", err)
Checkout this working snippet with error handling.err
Note: Now you will get Invalid Bearer Token error, Enter valid Bearer token
const request = require('request');
request({
url: 'https://evodms-dev.clientsolve.com/evoDMSDev/api/api_event_all.php',
headers: {
'Authorization': 'Bearer 71D50F9987529'
},
rejectUnauthorized: false
}, function(err, res) {
if(err) {
console.error(err);
} else {
console.log(res.body);
}
});

Resources