the http.request return a wrong statusCode? - node.js

I use this code:
var options = {
hostname: 'torcache.net',
path: '/torrent/4C1E01E1E7AE19082F4BAC9C3C82B5B2CD0EEA23.torrent',
port: 80,
method: 'GET'
};
http.request(options, function (res) {
var chunks = [];
res.on('data', function (chunk) {
chunks.push(chunk);
});
res.on('end', function () {
if (res.statusCode !== 200) {
callback(res.statusCode);
return;
}
//...
});
}).on('error', function (err) {
callback(err);
}).end();
the statusCode is 200, but open the url(http://torcache.net/torrent/4C1E01E1E7AE19082F4BAC9C3C82B5B2CD0EEA23.torrent) is Chrome, the statusCode is 404. what's wrong with the code?
update:
I find if I use this options:
{
hostname: 'torcache.net',
path: '/torrent/4C1E01E1E7AE19082F4BAC9C3C82B5B2CD0EEA23.torrent',
port: 80,
method: 'GET',
secureProtocol: 'SSLv3_method',
headers: {
'accept-charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
'accept-language': 'en-US,en;q=0.8',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13+ (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2',
'accept-encoding': 'gzip,deflate',
'referer': 'http://torcache.net' // !!!
}
}
when the headers['referer'] is not null, the res.statusCode is wrong. but I don't know why?

The request does indeed return with a 200. It is later redirect with JavaScript to a 404 page, which Node doesn't follow.

Related

Can't PUT to source_blob.put_url using in Axios

Having made a successful request to https://api.heroku.com/sources, I'm now attempting to upload a file to the put_url returned.
In postman this is working a treat. However, when I attempt to do the same in Axios no good. I've attached a screenshot of the postman with the 200 status.
So far I've the following....
const data = fs.readFileSync(zipPath, 'utf-8');
var config = {
method: 'put',
url: put_url,
headers: {
'Accept-Encoding': 'gzip, deflate, br',
'Content-Type': 'text/plain; charset=utf-8',
'Content-Length': Buffer.byteLength(data),
},
data,
};
await axios(config);
Which results in the following error SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method
I've played around with the encoding, and content types (pretty much stabbing in the dark tbh)
Annoyingly, I've got it working with this:
const post_data = fs.readFileSync(path.join(__dirname, 'compare-api.tar.gz'));
const options = {
method: 'PUT',
hostname: host,
path: put_url.substring(httpHost.length),
headers: {
Host: host,
'Accept-Encoding': 'gzip, deflate, br',
'Content-Length': Buffer.byteLength(post_data),
},
};
const req = https.request(options, function (res) {
res.on('data', function () {
// Can't remove this even though it's doing nothing :(
});
res.on('end', function () {
cb(null, source_blob);
});
res.on('error', function (error) {
console.log('error', error);
cb(error);
});
});
req.write(post_data, 'utf-8');
req.end();
But I'd much rather it worked in Axios.
After what seemed like forever....
'Content-Type': ''
...did the trick!

AWS Lambda return "Internal Server Error"

My version Node.js 14.x
When using https.request return "Internal Server Error" :
const https = require('https');
exports.handler = async(event) => {
console.log(event);
let dataString = ''
const response = await new Promise((resolve, reject) => {
const { pathParameters } = event;
if (!pathParameters || !pathParameters.id) {
resolve({
statusCode: 400,
body: 'Please provide a id!'
})
}
const options = {
hostname: 'pokeapi.co',
path: `/api/v2/pokemon/${pathParameters.id}`,
port: 443,
method: 'GET',
headers: { 'Content-Type': 'application/json' }
};
const req = https.request(options, function(res) {
res.on('data', chunk => {
console.log(chunk);
dataString += chunk;
});
res.on('end', () => {
resolve({
statusCode: 200,
body: JSON.stringify(JSON.parse(dataString), null, 4)
});
});
});
req.on('error', (e) => {
reject({
statusCode: 500,
body: 'Something went wrong!'
});
});
});
return response
;};
https.get works well :
const https = require('https');
exports.handler = async(event) => {
console.log(event);
let dataString = ''
const response = await new Promise((resolve, reject) => {
const { pathParameters } = event;
if (!pathParameters || !pathParameters.id) {
resolve({
statusCode: 400,
body: 'Please provide a id!'
})
}
const req = https.get(`https://pokeapi.co/api/v2/pokemon/${pathParameters.id}`, function(res) {
res.on('data', chunk => {
console.log(chunk);
dataString += chunk;
});
res.on('end', () => {
resolve({
statusCode: 200,
body: JSON.stringify(JSON.parse(dataString), null, 4)
});
});
});
req.on('error', (e) => {
reject({
statusCode: 500,
body: 'Something went wrong!'
});
});
});
return response;
};
{pathParameters.id} this is the id that I get from the gateway and I need to handle it in a function. I must say right away that this is not because of the quotes in the path and not in the port. There are no errors in the CloudWatch logs. I am connecting lambda function to AWS gateway http.
START RequestId: 86503ade-fd54-400a-bd39-d58cd9d5cc45 Version: $LATEST
2021-07-28T19:21:37.826Z 86503ade-fd54-400a-bd39-d58cd9d5cc45 INFO {
version: '2.0',
routeKey: 'GET /api/schedule/quest/{id}',
rawPath: '/dev/api/schedule/quest/1',
rawQueryString: '',
headers: {
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'en-US,en;q=0.5',
'cache-control': 'max-age=0',
'content-length': '0',
host: 'hkh9lnprbf.execute-api.eu-central-1.amazonaws.com',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0',
'x-amzn-trace-id': 'Root=1-6101ae41-697bf7894a7c98d73f84bf31',
'x-forwarded-for': '78.85.49.90',
'x-forwarded-port': '443',
'x-forwarded-proto': 'https'
},
requestContext: {
accountId: '617260961257',
apiId: 'hkh9lnprbf',
domainName: 'hkh9lnprbf.execute-api.eu-central-1.amazonaws.com',
domainPrefix: 'hkh9lnprbf',
http: {
method: 'GET',
path: '/dev/api/schedule/quest/1',
protocol: 'HTTP/1.1',
sourceIp: '78.85.49.90',
userAgent: 'Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0'
},
requestId: 'DMgqTgDpliAEQzg=',
routeKey: 'GET /api/schedule/quest/{id}',
stage: 'dev',
time: '28/Jul/2021:19:21:37 +0000',
timeEpoch: 1627500097792
},
pathParameters: { id: '1' },
isBase64Encoded: false
}
END RequestId: 86503ade-fd54-400a-bd39-d58cd9d5cc45
REPORT RequestId: 86503ade-fd54-400a-bd39-d58cd9d5cc45 Duration: 3004.50 ms Billed Duration: 3000 ms Memory Size: 128 MB Max Memory Used: 17 MB
2021-07-28T19:21:40.823Z 86503ade-fd54-400a-bd39-d58cd9d5cc45 Task timed out after 3.00 seconds
This is not a solution, but now I see an error in the logs after listening to the answer about increasing the timeout.
2021-07-29T04:59:26.187Z 8536861f-b6e8-46fd-8c9b-93a060be47bb ERROR Invoke Error
{
"errorType": "Error",
"errorMessage": "[object Object]",
"stack": [
"Error: [object Object]",
" at _homogeneousError (/var/runtime/CallbackContext.js:12:12)",
" at postError (/var/runtime/CallbackContext.js:29:54)",
" at done (/var/runtime/CallbackContext.js:58:7)",
" at fail (/var/runtime/CallbackContext.js:70:7)",
" at /var/runtime/CallbackContext.js:106:16",
" at processTicksAndRejections (internal/process/task_queues.js:95:5)"
]
}
I also found a workaround using
http.get(option, function (res) {.....
instead of
http.reguest(option, function (res) {.....
Your Lambda is timing out after the default 3 seconds:
2021-07-28T19:21:40.823Z 86503ade-fd54-400a-bd39-d58cd9d5cc45 Task timed out after 3.00 seconds
You'll need to increase this in either the AWS console (AWS Lambda -> Functions -> function_name -> General configuration -> Edit and set timeout) or via your method of deployment.

Gibrish when fetching an image and sending to client

In my server i read an image - jpg - from a url with :
let _uri = "https.....xxxxxxxxxxx.jpg";
let _headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Encoding': '*',
'Accept-Language': 'en-US,en',
'Cache-Control': 'max-age=0',
'Connection': 'keep-alive',
'Referer': 'http://www.google.com/',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}
var options = {
uri: _uri,
headers: _headers
};
rp(options)
.then(parsedBody => {
//response.setHeader('Content-Type', 'image/jpg');
// return response.status(200).send(parsedBody); //** don't work also
return response.json(parsedBody);
})
.catch(err => {
response.status(400).send(err)
});
});
No matter what i try, this will get a huge chunk of garbage when i check the response.
I can't find out what type of data is it.
On client i receive it - again - a lot of jibrish :
fetch('https://...my server')
.then(res => res.blob())
.then(blob => {
console.log(blob);
How do i get this photo on server and send to client ?
Add an option encoding: null to have the response returned as Buffer
var options = {
uri: _uri,
headers: _headers,
encoding: null // add this line
}
Then you can just send the buffer as response
rp(options)
.then(buffer => {
response.setHeader('Content-Type', 'image/jpg');
return response.status(200).send(buffer);
})

Unknown protocol error while using request api ( node.js )

Here is my code. I am running 0.10.24 version. Can someone look into this? An error, "Error: 6304:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:openssl\ssl\s23_clnt.c:766:" is displayed.
var url = require('url'),
request = require('request'),
loginLink = "https://foo";
var params = {
maxRedirects: 10,
followRedirect: true,
followAllRedirects: true,
timeout: 10000,
url: url.parse(loginLink),
method: "POST",
jar: true,
strictSSL: false,
form: {
'userid': 'userid',
'pwd': 'pass',
'timezoneOffset': -330
},
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1753.0 Safari/537.36',
'Connection': 'keep-alive',
'Origin': 'https://foo'
}
}
request(params,function(error,response,body){
if(!error && response.statusCode == 200){
console.log(body);
}else{
console.log(response);
console.log(error);
}
});
change SSL version (?)
options = {
....
strictSSL: false,
secureProtocol: 'SSLv3_client_method',
....
}

Node.js: How to send headers with form data using request module?

I have code like the following:
var req = require('request');
req.post('someUrl',
{ form: { username: 'user', password: '', opaque: 'someValue', logintype: '1'}, },
function (e, r, body) {
console.log(body);
});
How can I set headers for this?
I need user-agent, content-type and probably something else to be in the headers:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36',
'Content-Type' : 'application/x-www-form-urlencoded'
};
I've tried in multiple ways but I can either send header or form-data, failed to send both.
I've finally managed to do it.
Answer in code snippet below:
var querystring = require('querystring');
var request = require('request');
var form = {
username: 'usr',
password: 'pwd',
opaque: 'opaque',
logintype: '1'
};
var formData = querystring.stringify(form);
var contentLength = formData.length;
request({
headers: {
'Content-Length': contentLength,
'Content-Type': 'application/x-www-form-urlencoded'
},
uri: 'http://myUrl',
body: formData,
method: 'POST'
}, function (err, res, body) {
//it works!
});
This should work.
var url = 'http://<your_url_here>';
var headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0',
'Content-Type' : 'application/x-www-form-urlencoded'
};
var form = { username: 'user', password: '', opaque: 'someValue', logintype: '1'};
request.post({ url: url, form: form, headers: headers }, function (e, r, body) {
// your callback body
});
I think it's just because you have forgot HTTP METHOD. The default HTTP method of request is GET.
You should add method: 'POST' and your code will work if your backend receive the post method.
var req = require('request');
req.post({
url: 'someUrl',
form: { username: 'user', password: '', opaque: 'someValue', logintype: '1'},
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36',
'Content-Type' : 'application/x-www-form-urlencoded'
},
method: 'POST'
},
function (e, r, body) {
console.log(body);
});
I found the solution to this problem and It should work. I'm sure about this because I also faced the same problem
here is my solution----->
var request = require('request');
//set url
var url = 'http://localhost:8088/example';
//set header
var headers = {
'Authorization': 'Your authorization'
};
//set form data
var form = {first_name: first_name, last_name: last_name};
//set request parameter
request.post({headers: headers, url: url, form: form, method: 'POST'}, function (e, r, body) {
var bodyValues = JSON.parse(body);
res.send(bodyValues);
});
Just remember set method to POST in options. Here is my code
var options = {
url: 'http://www.example.com',
method: 'POST', // Don't forget this line
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-MicrosoftAjax': 'Delta=true', // blah, blah, blah...
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36',
},
form: {
'key-1':'value-1',
'key-2':'value-2',
...
}
};
//console.log('options:', options);
// Create request to get data
request(options, (err, response, body) => {
if (err) {
//console.log(err);
} else {
console.log('body:', body);
}
});

Resources