Why doesn't XML-to-JSON policy set the Content-Length header?

Not applicable

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 Solved
0 3 1,015
2 ACCEPTED SOLUTIONS

Not applicable

Work around Javascript policy:

var body = context.targetRequest.body.asJSON;
var len = body.byteLength;
context.proxyRequest.headers['Content-Length']=len;

View solution in original post

Not applicable

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;

@Mike Dunker, @Birute Awasthi

View solution in original post

3 REPLIES 3

Not applicable

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?

Not applicable

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;

@Mike Dunker, @Birute Awasthi