I am converting an inbound request from XML to JSON before passing to my backend Node.js App and I noticed some strange behavior, like not being able to parse the body or even just echo it back. Then I noticed the error: "request size did not match content length" from the Node.js App.
After further experimenting I noticed that XML-to-JSON policy does not set the Content-Length header. If I manually set it to the correct value, the Node.js App is happy.
I guess I could write a Javascript callout to fix it, but it makes sense for the policy to set it.
@Mike Dunker needs to know this 🙂
Solved! Go to Solution.
Work around Javascript policy:
var body = context.targetRequest.body.asJSON; var len = body.byteLength; context.proxyRequest.headers['Content-Length']=len;
OK, found another workaround to correctly set the Content-Length even with special characters. One that doesn't rely on Buffer.
Here's my JS policy script that runs after the XML-to-JSON policy:
var obj = context.targetRequest.body.asJSON; var str = JSON.stringify(obj); // Attribution: http://stackoverflow.com/questions/23318037/size-of-json-object-in-kbs-mbs# // Matches only the 10.. bytes that are non-initial characters in a multi-byte sequence. var m = encodeURIComponent(str).match(/%[89ABab]/g); var len = str.length + (m ? m.length : 0); context.targetRequest.headers['Content-Length']=len;
Work around Javascript policy:
var body = context.targetRequest.body.asJSON; var len = body.byteLength; context.proxyRequest.headers['Content-Length']=len;
Oops, this stopped working today as of Version 160120 which was just released today.
After a bit of research, it appears I need to use the Buffer class and byteLength() to correctly calculate the length of the output of the XML-to-JSON policy in a subsequent JS policy.
Here's what I'm doing now, but it doesn't work given the special characters in the example.
var body = context.targetRequest.body; var obj = context.targetRequest.body.asJSON; var str = JSON.stringify(obj); // ISSUE: Need to use Buffer to get correct length for example below, but Buffer isnt available to the JS policy. // NOTE: Special character in lastName // EXAMPLE: <persons><person><firstName>Accent</firstName><lastName>Gravé</lastName></person></persons> // EXAMPLE JSON: { persons: { person: { firstName: 'Accent', lastName: 'Gravé' } } } // var len = Buffer.byteLength(str); var len = str.length;print( 'body '+ body); print( 'obj '+ obj); print( 'str '+ str); // print( 'buf '+ buf); print( 'len '+ len); context.targetRequest.headers['Content-Length']=len;
Maybe, the question is how do I access the Buffer class in the JS policy?
OK, found another workaround to correctly set the Content-Length even with special characters. One that doesn't rely on Buffer.
Here's my JS policy script that runs after the XML-to-JSON policy:
var obj = context.targetRequest.body.asJSON; var str = JSON.stringify(obj); // Attribution: http://stackoverflow.com/questions/23318037/size-of-json-object-in-kbs-mbs# // Matches only the 10.. bytes that are non-initial characters in a multi-byte sequence. var m = encodeURIComponent(str).match(/%[89ABab]/g); var len = str.length + (m ? m.length : 0); context.targetRequest.headers['Content-Length']=len;
User | Count |
---|---|
2 | |
1 | |
1 | |
1 | |
1 |