Sending large xml as body in request module in nodejs - node.js

I have a very large xml which gets generated using wsjs node module. it looks like
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:diag="http://diagnostic.ws.fcrewards.test.com/" xmlns:ws="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><soapenv:Header><ws:Action>http://diagnostic.ws.fcrewards.test.com/doEcho</ws:Action><ws:To>https://ws.mastercard.com/mtf/MRS/DiagnosticService</ws:To><ws:MessageID>35b479f1-5a54-e9a4-5551-0f15507f54b8</ws:MessageID><ws:ReplyTo><ws:Address>http://www.w3.org/2005/08/addressing/role/anonymous</ws:Address></ws:ReplyTo><o:Security><u:Timestamp wsu:Id="_0" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><u:Created>2017-02-24T17:13:13Z</u:Created><u:Expires>2017-02-24T17:18:13Z</u:Expires></u:Timestamp><o:BinarySecurityToken ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" u:Id="sec_0">MIID1zCCAr+gAwIBAgIRAIVAIPeDa+CgeYorExNgwDQYJKoZIhvcNAQELBQAwgYUxCzAJBgNVBAYTAkJFMRwwGgYDVQQKExNNYXN0ZUNhcmQgV29ybGR3aWRlMSQwIgYDVQQLExtHbG9iYWwgSW5mb3JtYXRpb24gU2VjdXJpdHkxMjAwBgNVBAjdjdjjdjdjjdjjdQgUFJEIE1lc3NhZ2VzIFNpssssssssssssssssssssssssIxNjIxMzcwN1owZjEbMBkGA1UEAxMSbXRmLkNIUy5wYXlGb3J3jdjjdjdjdjjdjjndkwlklwlwlwww25pbmcgU1cxDjAMBgNVBAsTBUNIUyAxMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM675qti1N/aMP+YsPe9UIaJasISYzIpEoysKhClmWfBTqJTrcw0UWnraSOGqdPvEpgcLdW2BwnZ+T2gmcLa/BY69hW+CYm0pR0px9MPNuP77YcJCS5d6ffuHvTlkVpBq2hWVhOck0X0uhu+m2I6G8Dshi8yiBJohs+jpuf63OxVtBTemFNM5pVDdB5z7sYhkrdcNzlSoPTKNcTFfZgnj0G6iwkb4XK1mSlXbQL8jYEPPZWDdxPFl1SrSnwUoyl3r84SZrV13JstZ4YrolAm8mmKB7pU+bJ46+zpeYDRDo/YH4cxSpkyPUuwB27PtLk1J/9FgBNLfY0XQnlk/b3Mm3MCAwEAAaNgMF4wHwYDVR0jBBgwFoAU66ASd4JT9FhYrwHp4f9kBT5H2aowDAYDVR0TBAUwAwIBADAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFJ1obzmA1M2PIL8GumtHSIdwUrZMMA0GCSqGSIb3DQEBCwUAA4IBAQASqfFjdTt74OHwmEJVlO3pYnnHcxvDU0v7+2xTTMpWSAKmfDGf5j71UDsa6E/ymclcz/mdbsHSvyYii8TsrYK8Nyq6o2nTAQ0mhRhSpip7kjv5eQ0PtJZhl0Je7W9b3GIS1M5IbNN7xusKNHaJSg7ZIf/gUwWuBOq1CxABE0xRGY5b5e6giglP2iJwgeOHukmeGiLck3HGqZjei+T/Fnvsyy7hQ6qzGTDZg6B6yd1ojMZddmjDV8QsQfUQWM0//rvORZup98VP7I9LmrDBQuu7cPPy0Vg8VRWZC9wrM82e6IHl1uMovU12PCth1vAcSyTjuorNn5NoQg8FIoLCdgLk</o:BinarySecurityToken><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><Reference URI="#_0"><Transforms><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><DigestValue>qNgtbxFDtGr1QCRG4ZnGSzfWqQ+GZJkuQAHgTxcI4B8=</DigestValue></Reference></SignedInfo><SignatureValue>ZqHJTwD91tcddddddddd3uZkuChVE0BHEx55YF3kGNw1D55VbunmbNZkmxxkuBvyAMjns/DJ8/duThXhlAmyPLYhRgj4djz8smJbksago1Tb+DFT8RQ4tOVPD2TPSaC5wrwA9g9zCCpPDHHv5FmZ4TIxwkPjG37MBqOIgUF8cUkL9kXU0sIJrUQddddddddddddddddddddddddddddddddddddddddddddddddddddddwsRtcjKDksvWpMBj0oSysWi+8/ce2HnO4nOuhrvX66BDOAyPL+avL2+JNTlA==</SignatureValue><KeyInfo><o:SecurityTokenReference><o:Reference URI="#sec_0" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/></o:SecurityTokenReference></KeyInfo></Signature></o:Security></soapenv:Header><soapenv:Body><diag:doEcho>Cieran</diag:doEcho></soapenv:Body></soapenv:Envelope>
when I send this request using request module of node.js
request.post({
url: ctx.url,
body: ctx.request,
headers: {
"SOAPAction": ctx.action,
"Content-Type": ctx.contentType,
"ContentLength": Buffer.byteLength(ctx.request),
"MIME-Version": "1.0",
"Connection": "Keep-Alive",
"AcceptEncoding": "gzip"
},
encoding: null,
rejectUnauthorized: true,
agentOptions: ctx.agentOptions
},
function(error, response, body) {
ctx.response = body
if (response) {
ctx.resp_headers = response.headers
ctx.resp_contentType = response.headers["content-type"]
}
if (error) ctx.error = error
else ctx.statusCode = response.statusCode
callback(ctx)
})
ctx.request has the whole xml in it as 1 big string
I always get Authorization failed error because endpoint is out rightly rejecting my request.
But if I take the xml and put it in SOAPUI and do format xml then I get the right result.
So I concluded that since i'm sending the body as 1 big xml the endpoint doesn't like my request.
What's the workaround for this?
Is there any other node module available which can format the xml or break it up in small strings?

Related

Pipe gzipped content without decompression to response in NodeJS

I am using the node-fetch library and it by-default decompresses the response. I want to make a POST request which returns gzipped content and I want to pipe the POST request response to the response.
The code I am currently using is here:
router.post('/getData', async(request, response) => {
fetch(`http://url:port/path`, { method: 'POST', headers: {'Accept-Encoding': 'gzip'}, body: ''})
.then(data=> {
return data.body.pipe(response);
}
}
}
I understand that the node-fetch library decompresses the data by default. I do not need this. I want to pass the compressed data directly using streams. (Like a proxy)
What worked for me was setting compress=false but then adding the header to accept gzip encoding:
fetch(url, {
compress: false,
headers: { "accept-encoding": "gzip" },
});

Node JS send empty JSON body

I have the code below which is supposed to send a POST request but with an empty JSON body:
request.post({
url: url,
headers: {
"data_digest": 'muZ7EcapQZVb77RF',
"partner_code": "ebfebc241db9b9c1a",
"msg_type": "GET_BASEDATA_TRANSPORT",
"msg_id": '1590464383047',
"Accept-Language": "zh-cn"
},
json: true,
body: {}
}, function(error, response, body) {
console.log(body);
});
However this keeps returning
'System Exception:\r\ntype org.springframework.web.HttpMediaTypeNotAcceptableException\r\nmessage:Could not find acceptable representation'
But using Postman I'm able to correctly send POST request with the exact same headers but just an empty {} in the Body parameter with Raw format.
How can I send a POST request with an empty JSON body in Node JS?
Your way of sending the body is fine. If you'd look at the actual request sent (for example using Fiddler or Wireshark) you'd see the body is sent correctly. The problem is something else - instead you'd see that the headers are not the exact same.
Using json (either with json: true and body, or as you do it, with json as object) also automatically sets the Accept header to application/json and attempts to parse the response as JSON.
It seems that this server chiguotest.ytoglobal.com has a bug, where it returns JSON but does not handle the Accept header correctly (I tested it and it seems the server "thinks" it is returning text/plain). So request is (correctly) telling the server "I expect you to return JSON", but the server says "What, JSON? No I don't know how to return JSON, only text, sorry.". Yet, it in fact does return JSON.
You can circumvent this server bug by explicitely sending an Accept: */* header:
request.post({
url: url,
headers: {
"data_digest": 'muZ7EcapQZV',
"partner_code": "ebfebc241db9b9c",
"msg_type": "GET_BASEDATA_TRANSPORT",
"msg_id": '1590464383047',
"Accept-Language": "zh-cn",
"Accept": "*/*"
},
json: true,
body: {}
}, function(error, response, body) {
console.log(body);
});
My output:
{
"data": {
"productKinds": [
{
"productCnname": "(美国)测试用-不拉G单号",
"productCode": "1",
"productEnname": "1",
"productServerhawbcodeNeed": "Y"
},
{
"productCnname": "散客可见产品",
"productCode": "111",
"productEnname": "内部产品",
"productServerhawbcodeNeed": "N"
},
... many more entries ...
]
},
"errorCode": "SUCCESS",
"errorMsg": "成功",
"status": true
}

Sending JSON through API as a Post request in Node and displaying BLOB data in console

I have a python flask server running and its api is exposed. It is being used for converting json to excel file. I need to pass json through node code to that api and get back the response which would be a blob and save as a excel file locally. My first step is to display the blob object in console but I am getting a lot of data in console which is irrelevant. Here is my nodejs code
const request = require('request');
jsonobj={...} //a big json not displaying here
request(
{
method:'post',
url:'http://127.0.0.1:8095/excel/download',
form: jsonobj,
headers: {
"content-type": "application/json"
},
json: true,
}, function (error, response, body) {
//Print the Response
console.log(body);
});
The body is displaying a lot of data, I only need to display the excel blob
Ok, I changed form to body in request and it resolved. Here is the code but I still need to convert blob object and save as an excel file locally. -
method:'post',
url:'http://127.0.0.1:8095/excel/download',
body: jsonobj, //changed form to body here
headers: {
"content-type": "application/json"

Unsupported media type when uploading form data to spring server

I am trying to upload a file to a remote spring server via an API, and I keep getting an unsupported media type error (415) even though I have already made the data into form data.
Here is the express http post request:
var FormData = require('form-data');
var fs = require('fs');
var form = new FormData();
form.append('pid', params.pid);
form.append('deliveryAttachment', fs.createReadStream(params.deliveryAttachment.path));
var url = someDomain + '/proj/new/deliveryAttachment';
requestLib({
url: url,
method: "POST",
jar: getJar(),
form: form
},function (error, response, body){
console.log(body)
});
And here is the Java Spring controller for reference:
#RequestMapping(value = "proj/new/deliveryAttachment", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.TEXT_PLAIN_VALUE)
public String insertDeliveryAttachment(#RequestParam("pid") long pid,
#RequestParam("deliveryAttachment") MultipartFile file) {
try {
DeliveryAttachment a = new DeliveryAttachment(file.getOriginalFilename(), pid);
ps.insertDeliveryAttachment(a, file.getBytes());
return String.valueOf(a.id);
} catch (IOException e) {
return "-1";
}
}
This is the form data console log:
And the 415 response:
{
"timestamp": 1494671395688,
"status": 415,
"error": "Unsupported Media Type",
"exception": "org.springframework.web.HttpMediaTypeNotSupportedException",
"message": "Content type 'application/x-www-form-urlencoded' not supported",
"path": "/proj/new/deliveryAttachment"
}
--UPDATE--
Alright, I just found out after reading request's docs that if you use form as the holder for the data, it will treat the data as application/x-www-form-urlencoded
e.g.; request.post({url:'http://service.com/upload', form: {key:'value'}}, function(err,httpResponse,body){ ... });
Meanwhile the correct key for multipart/form-data is formData
e.g.; request.post({url:'http://service.com/upload', formData: formData}, function optionalCallback(err, httpResponse, body) { ... });
I tried it, and now it's giving me a new error:
TypeError: Cannot read property 'name' of null at FormData._getContentDisposition
It seems that you are sending a POST request with Content-Type: 'application/x-www-form-urlencoded', and your SpringController insertDeliveryAttachment() consumes multipart/form-data mime-type.
I would recommend you to change the consumes mime-type on your insertDeliveryAttachment() method to MediaType.APPLICATION_FORM_URLENCODED_VALUE
I've solved it. I did not use FormData and just went with inserting the values inside an object and it worked.
var data = {
pid: params.pid,
deliveryAttachment: fs.createReadStream(params.deliveryAttachment[0].path)
};
var url = wfDomain + '/proj/new/deliveryAttachment';
requestLib({
url: url,
method: "POST",
headers: {
'Content-Type': 'multipart/form-data'
},
jar: getJar(),
formData: data
},function (error, response, body){ ... });

How to set POST encoding with request module on node.js?

I'm using request module on node.js but there is something problem with encoding option. beneath codes are simple post request, but I don't know how to set up encoding of form field data. I already set headers to 'Content-Type': 'application/x-www-form-urlencoded; charset=euc-kr' But it doesn't works. field data is korean, like "안녕하세요", and I should post it with euc-kr encoding. (The site takes euc-kr, not utf8)
The same program on Java application, I coded like this :
PrintWriter wr = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "euc-kr"));
But I don't know how to in nodejs. Can anyone give some solution...?
Code Sample
//Load the request module
var request = require('request');
//Lets configure and request
request({
url: 'http://google.com', //URL to hit
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=euc-kr' },
method: 'POST',
form: {
field1: 'data',
field2: 'data'
}
}, function(error, response, body){
if(error) {
console.log(error);
} else {
console.log(response.statusCode, body);
}
});
Finally I got a soultion, and I solved this problem.
If you send a data as a form using request module, the module change your form encoding to utf-8 by force. So even you setted your form encoding to another charset, the module changes your charset to utf8 again. You can see that at request.js on line 1120-1130.
So, You'd better send a data by 'body' option, not 'form' option.
Node doesn't support EUC-KR so you can use iconv-lite to extend the native encodings available and set the encoding option in request.
List of Natively Supported Encodings
iconv.extendNodeEncodings(); only works for node pre v4+. See here to get this working for a newer version of node.
var iconv = require('iconv-lite');
var request = require('request');
// This will add to the native encodings available.
iconv.extendNodeEncodings();
request({
url: 'http://google.com', //URL to hit
method: 'POST',
form: {
field1: 'data',
field2: 'data'
},
encoding: 'EUC-KR'
}, function(error, response, body){
if(error) {
console.log(error);
} else {
console.log(response.statusCode, body);
}
});
iconv.undoExtendNodeEncodings();

Resources