Intercept sending request to change a header with request library - node.js

I am using the infamous request library to send requests.
One of those requests requires me to send the header multipart/mixed; boundary={myboundary}.
Request is using the form-data library for such requests but it does not set the Content-Type header properly. Therefore I would need to set it like this:
let req = request.post({url: "https://..."}, formData: formData)
req.setHeader('Content-Type', `multipart/mixed; boundary=${req.form().getBoundary()}`)
Sadly I can't add/alter any headers after firing the request. Therefore I want to know whether there is a way to intercept the sending so I can change the header?

You will need to use the multipart option instead of formData to use other, arbitrary multipart/* content types. Each object in the multipart array contains the headers to send in that part. The one exception is the body property which is used as the actual body of that part.
request.post({
url: 'https://...',
multipart: [
{ 'X-Foo-Header': 'bar', body: 'baz' },
// ...
],
headers: { 'Content-Type': 'multipart/mixed' }
});
The boundary should be automatically appended for an existing, explicit Content-Type header. This request test explicitly tests for this behavior.

Related

Send Post request with Headers in Nestjs

I am trying to use Nestjs to send a Post request to a 3rd party API which requires authorization (client-key and secret). Would anyone know how to attach headers in a request. I want to use axio's HttpService.
give the HttpService post request a custom headers object
this.httpService.post('http://www.stackoverflow.com', { my: 'data' }, { headers: { 'x-custom-header': "this a header" }})
would result in a POST request with { my: 'data' } as payload and a custom header x-custom-header: this is header
underlying the nest HttpService there is an axios instance so you will find more information in the axios doc

NetSuite: How to make http request sending cookies?

I need to call an external API to get some data from a SuiteScript file and I'm getting an issue. The GET call needs to go with credentials (basically, it has to go with the cookies in the Request Header).
If I make the API call from the chrome console setting withCredentials = true, but when I make that API call with NetSuite N/https module -through https.get()- the cookies don't go on the request header.
So in summary, I'm looking for a way to set withCredentials = true on the http.get() call or to be able to somehow get the cookies from my SuiteScript so that I can manually set it in the header option of the call.
Thanks in advance for your time!
Within the get, pass the headers option and populate your header values. I believe these are KVP.
If your external app is expecting information about the logged in user then what you probably want to do is an XHR request (jQuery's $.getJSON would be your best bet). If you need to pass information to a server side script then you'd call your Suitelet with the returned data.
A post example would be as follows. Note the withCredentials :
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: url,
dataType: "json",
data: jsonData,
xhrFields: {
withCredentials: true
},
success: function(response){
console.log(response);
},
error: function(response){
console.log('error: ' + JSON.stringify(response));
}
});

Sending URL encoded string in POST request using node.js

I am having difficulty sending a url encoded string to the Stormpath /oauth/token API endpoint. The string is meant to look like this:
grant_type=password&username=<username>&password=<password>
Using Postman I was successful in hitting the endpoint and retrieving the data I want by providing a string similar to the one above in the request body by selecting the raw / text option. But when I generate the code snippet it looks like this:
var request = require("request");
var options = { method: 'POST',
url: 'https://<My DNS label>.apps.stormpath.io/oauth/token',
headers:
{ 'postman-token': '<token>',
'cache-control': 'no-cache',
'content-type': 'application/x-www-form-urlencoded',
host: '<My DNS label>.apps.stormpath.io',
accept: 'application/json' },
form: false };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Where did that string go? I would like some help in understanding the disconnect between knowing I sent a url encoded string to the API endpoint using Postman and not seeing it in the code generated by Postman. Because now I don't know how to reproduce a successful call to the endpoint in my actual app.
To me it seems like I should simply provide a body to the request, but the response comes out to be {"error":"invalid_request","message":"invalid_request"}. I have also tried appending the url encoded string to the url but that returns a 404 error.
I'm just now getting back into using an API and am not very experienced doing so.
The form data needs to be posted as an object, here is an example:
request.post('http://service.com/upload', {form:{key:'value'}})
Taken from this documentation:
https://github.com/request/request#forms
Hope this helps!

Servicestack accessing json

My Servicestack service is beeing posted Json (by jquery).
sendData = function(dataToSend) {
var request;
return request = $.ajax({
url: "/api/test",
type: "post",
data: JSON.stringify(dataToSend),
dataType: "json",
accept: "application/json",
contentType: "application/json"
});
The Json data is correctly deserialized if it corresponds to the root properties of my DTO (eg: userId:'foo' -> UserId=foo in the DTO).
I want to access the raw json posted data before it gets deserialized for adding custom deserialization.
Till now I had no problems accessing the querystrings with custom filters (RequestFilterAttribute) or if data vas posted like form.
Now I see the data that gets posted with Chrome Developer Tools is in the headers with "Request Payload" so it is nor in FormData and nor QueryString I can access when debugging my IHttpRequest.
How can I get my raw json data in the filter?
If you want to replace the default deserialization behavior with custom behavior for a specific request DTO, you can do this in your AppHost setup code:
JsConfig<MyRequestDtoClass>.DeSerializeFn = DeserializeMyRequestDto;
Where DeserializeMyRequestDto is a function or lambda taking a single string param - the raw request body - and returning the deserialized instance of your DTO:
MyRequestDtoClass DeserializeMyRequestDto(string rawBody) { ... }
RequestFilterAttribute subclasses purpotedly have access to the raw request body using request.GetRawBody(), where request is the IHttpRequest object passed into the filter's Execute method. But in my experience, GetRawBody returns an empty string, because the request input stream seems to be consumed by that time due to the deserialization. I worked around this once by creating an HTTP module (registered in AppHost via DynamicModuleUtility.RegisterModule) that would "peek" at the request input stream in a BeginRequest event handler. (The "peek" function would read the request input stream and then reset the Position of the stream to where it initially was.)

IronMQ empty message body from push queue when read from Node.JS / Express.JS

I'm playing with node + express + IronMQ and I'm encountering a little problem.
In my express.js POST callback I'm getting {} as request body but I'm sure that the message content is being pushed from my IronMQ message queue.
Any hint ?
Ok I've found both the reason of my problem and its solution. So to answer my own question:
Problem:
1) I'm receiving POST messages from an IronMQ push queue (http://dev.iron.io/mq/reference/push_queues/), their content type is text/plain.
2) I'm using connect.js middleware (express.connect) and it parses only application/json,application/x-www-form-urlencoded, and multipart/form-data.
http://www.senchalabs.org/connect/bodyParser.html
So the body gets parsed and as its content type is not supported the result is {}
Solution:
In order to get the body of my text/plain request I had to parse it by myself as in https://stackoverflow.com/a/9920700
IronMQ have now updated their push queues to send custom headers. If you set the headers to 'Content-Type': 'application/json' in the list of subscribers when creating the queue, then the body gets parsed correctly. eg
# update groups queue
payload =
subscribers: [
{
url: "#{process.env.ROOT_URL}/groups/update"
headers:
'Content-Type': 'application/json' # this fixes request parsing issue
}
]
push_type: 'multicast'
retries: 3
retries_delay: 10
error_queue: 'groups_errors'
url = "https://mq-aws-us-east-1.iron.io/1/projects/#{process.env.IRON_MQ_PROJECT_ID}/queues/groups"
headers =
'Authorization': "OAuth #{process.env.IRON_MQ_TOKEN}"
'Content-Type': 'application/json'
result = HTTP.post url, {headers: headers, content: JSON.stringify(payload)}
Here's the relevant change on github

Resources