nodejs requestify.request() crashes when the method is given in the options - node.js

Why does requestify.request() crash because it doesn't think it was given the method POST
var postBody = querystring.stringify(dat);
var postOptions = {
host: 'https://www.example.com'
, path: '/admin'
, method: 'post' // POST, 'POST', post
, headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postBody) }
};
var postReq = requestify.request(postOptions, function (err, resp, respBody) {
resp.setEncoding('utf8');
resp.on('data', function (chunk) {
console.log('Response: ' + chunk);
});
});

It looks like you are using an old version of the documentation for the newer version of requestify
Read the API reference section of https://github.com/ranm8/requestify
And read just a little lower down it see a requestify.request() example.
Options doesn't have host, path, ...

Related

Core https library vs. npm 'request' library

I am running into a very strange issue when trying to use the built-in node https library.
Request Headers:
let requestDetails = {
hostname: 'api.domain.com',
method: 'POST',
path: '/endpointIWant/goHere
headers: {
'Client-ID': clientId,
'Content-Type': 'application/json',
Authorization: bearerToken
},
};
Request body:
let body = JSON.stringify({
"content_type": "application/json",
"message" : message
});
This is my standard call using the default https library of node:
let req = https.request(requestDetails, function (res){
let responseBody = undefined;
res.on('body', function(res) {
responseBody = '';
});
res.on('data', function(chunk) {
responseBody += chunk;
});
res.on('end', function() {
console.log(responseBody);
});
});
req.write(body);
req.on('error', function(e) {
console.log(e);
});
req.end();
Now whenever I send this request to the relevant server I get a:
Your browser sent a request that this server could not understand.
Reference #7.24507368.1554749705.3185b29b
However when I use the popular 'request' library on NPM it works fine and I get the response I expect.
This leads be to believe there is something different in maybe the 'encoding' or 'chunking' of the requests between these two libraries, but I cannot figure out what.
Does anyone have experience with the Node https library and understand any gotcha's there?
I prefer to use built-in libraries as much as possible to keep my package size low.
When using native http or https modules, you need to use the querystring module to stringify your body.
const querystring = require('querystring');
let body = querystring.stringify({
"content_type": "application/json",
"message" : message
});
//also include the content length of your body as a header
let requestDetails = {
hostname: 'api.domain.com',
method: 'POST',
path: '/endpointIWant/goHere
headers: {
'Client-ID': clientId,
'Content-Type': 'application/json',
'Content-Length' : body.length
Authorization: bearerToken
},
};
'request' is built on top of the native modules and does this internally when you pass it a json body

Node HTTPS Request – MalformedJsonException

I'm trying to make a POST request using node/HTTPS, but I keep getting this error:
BODY: {"message":"MalformedJsonException:
com.google.gson.stream.MalformedJsonException: Use
JsonReader.setLenient(true) to accept malformed JSON at line 1 column
11 path $","mdcKey":""}
Here's the code that initiates the request:
const https = require('https');
const querystring = require('querystring');
const POSTData = querystring.stringify({
'addressTo': 'myemail#address.com',
'subject': 'testing your email template',
'templateName': 'genericTemplate',
'bodyText': 'this is a test'
});
console.log(POSTData);
const HTTPOptions = {
hostname: 'url.com',
port: 00000,
path: '/path',
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
};
const HTTPSrequest = https.request(HTTPOptions, (response) => {
console.log(`STATUS: ${res.statusCode}`);
console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
response.setEncoding('utf8');
response.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
response.on('end', () => {
console.log('No more data in response.');
});
});
HTTPSrequest.on('error', (error) => {
console.log(`problem with request: ${error}`);
});
// write data to request body
HTTPSrequest.write(POSTData);
HTTPSrequest.end();
I'm assuming it's the POSTData that is the "malformed JSON", here's what it looks like stringified:
addressTo=name%40companyname.com&subject=testing%20your%20email%20template&templateName=genericTemplate&bodyText=this%20is%20a%20test
I'm not sure what I'm doing that is causing the malformed JSON. What am I missing?
You're sending an application/x-www-form-urlencoded payload but telling the server it's application/json. The server is complaining because of this mismatch.
The simple solution should be to just change querystring.stringify to JSON.stringify.
You may also need to specify a Content-Length header since some servers may not support chunked requests (which is the default in node). If you do add this, make sure you use Buffer.byteLength(POSTData) as the header value instead of just POSTData.length since the former works for multi-byte characters and the latter returns the number of characters (not bytes).
Help more with explication from #mscdex
Your options object after querystring.stringify has returned. Otherwise you won't know the length of the stringified body data.
It is important to note that you need two extra headers in your options object in order to make a successful post request. These are :
'Content-Type': 'application/json',
'Content-Length': POSTData.length
Check example:
const HTTPOptions = {
hostname: 'url.com',
port: 00000,
path: '/path',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': POSTData.length
}
};
You can see this examples too: 1st post.
JsonReader.setLenient(true) to accept malformed JSON at line 1 column 11 path $","mdcKey":""}

Asana POST Task

I am trying to post a task in asana with the following node/express function
exports.addTask = function(req, res) {
var url ='/api/1.0/tasks?workspace=' + req.session.workspace_id
var postBase = "app.asana.com";
var options = {
host: postBase,
port: 443,
path: url,
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + JSON.parse(req.session.user).access_token,
}
};
var req2 = https.request(options, function(res2) {
res2.on('data', function(chunk) {
console.log(chunk + "");
});
res2.on('error', function(e){
console.log(e.message);
});
});
req2.end();
}
I get the correct response back from asana which is:
{"data":{"id":8253508011735,"created_at":"2013-10-20T16:17:53.140Z","modified_at":"2013-10-20T16:17:53.140Z","name":"","notes":"","completed":false,"assignee_status":"upcoming","completed_at":null,"due_on":null,"workspace":{"id":1361701377437,"name":"getspur.com"},"assignee":null,"parent":null,"followers":[{"id":1050147548705,"name":"Gorkem Yurtseven"}],"projects":[],"tags":[]}}
but nothing seems to be added in my asana tasks..
ps. I am currently at the Facebook Hackathon in New York,so bring it on!
It could be because the assignee is null, and it's not in any projects - that basically makes it impossible to find (except perhaps via Search?)
Without seeing the post body I'm not sure if that's intentional or just a formatting issue.

How to pipe POST requests

I'm a bit confused about how to pipe some data.
I've got some pipes working and chained such that I not have an output stream containing the data I want to input to a request POST
var options = {
host: 'localhost',
port: 8529,
path: '/_api/cursor',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': data.length
}
}
var req = http.request(options);
I would normally just action 'mystreams2.pipe(req)' but how do I set the 'data.length' value ?
(I'm using the streams2 interface not the old stream format)
By assumption that you don't have a massive amount of data in your buffer, you first need to collect the data in order to find its length.
var source = /* a readable stream */;
var data = '';
source.on('data', function(chunk) {
data += chunk;
});
source.on('end', function() {
var options = {
host: 'localhost',
port: 8529,
path: '/_api/cursor',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': data.length
}
};
var req = http.request(options);
req.end(data);
});

node.js paypal https request

first question here, so apologies if it turns out to be something very obvious
I am trying to call the paypal adaptive payments api via node.js and am getting a 580001 invalid request error. I can make a successfull call via curl with the below message and headers, but not through node.
any help would be much appreciated.
var API_endpoint = "svcs.sandbox.paypal.com";
var API_user = '';
var API_pass = '';
var API_sig = '';
message='requestEnvelope.errorLanguage=en_US&actionType=PAY&senderEmail=test_1320882990_per#gmail.com&receiverList.receiver(0).email=test2_1320887729_biz#gmail.com& receiverList.receiver(0).amount=100.00&currencyCode=USD&cancelUrl=http://your_cancel_url& returnUrl=http://your_return_url'
//var params = qs.parse(message);
//params = qs.stringify(params);
var req_options = {
host: API_endpoint,
method: 'POST',
path: '/AdaptivePayments/Pay',
headers: {
'Host': API_endpoint,
'Content-Type': 'application/x-www-form-urlencoded',
//'Content-Type': 'text/namevalue',
'Content-Length': message.length,
'X-PAYPAL-REQUEST-DATA-FORMAT:':'NV',
'X-PAYPAL-RESPONSE-DATA-FORMAT':'NV',
'X-PAYPAL-SECURITY-USERID':API_user,
'X-PAYPAL-SECURITY-PASSWORD':API_pass,
'X-PAYPAL-SECURITY-SIGNATURE':API_sig,
'X-PAYPAL-APPLICATION-ID':'APP-80W284485P519543T'
}
}
fs.readFile('/home/dev/.ssh/sandbox-paypal-private.pem', 'ascii', function(err, key){
fs.readFile('/home/dev/.ssh/sandbox-paypal-public.pem', 'ascii', function(err, cert){
req_options.key=key
req_options.cert=cert
var req = https.request(req_options, function(res){
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.on('data', function(d){
var response = d.toString();
console.log(response)
});
});
req.write(message);
req.end();
req.on('error', function request_error(e) {
console.log(e);
});
});
});
I'm not sure if it's only a copy paste problem, but your message variable does not seem to contain properly formatted string. It has white spaces and the special characters are not encoded.
requestEnvelope.errorLanguage=en_US&actionType=PAY&senderEmail=test_1320882990_per#gmail.com&receiverList.receiver(0).email=test2_1320887729_biz#gmail.com&receiverList.receiver(0).amount=100.00&currencyCode=USD&cancelUrl=http://your_cancel_url& returnUrl=http://your_return_url'.
It should look like this:
requestEnvelope.errorLanguage=en_US&actionType=PAY&senderEmail=test_1320882990_per%40gmail.com&receiverList.receiver(0).email=test2_1320887729_biz%40gmail.com& receiverList.receiver(0).amount=100.00&currencyCode=USD&cancelUrl=http%3A%2F%2Fyour_cancel_url&returnUrl=http%3A%2F%2Fyour_return_url
There's a trailing colon in one of your header fields; Rather than:
'X-PAYPAL-REQUEST-DATA-FORMAT:'
You should have:
'X-PAYPAL-REQUEST-DATA-FORMAT'

Resources