Posting JSON in URL body


#1

Hey,

I’m having some issues posting JSON in the body of a URL. It seems when I convert the JSON var to a String, it is sticking a delimiting null at the end. When the URL body is created this null remains and is throwing the JSON parser on the backend.

Here is the code that constructs a simple JSON string.

String AnalyticsEventRequest::httpJSONBody()
{

DynamicObject* properties = new DynamicObject();

StringArray keys = mAnalyticsEvent.getEventProperties().getAllKeys();
StringArray values = mAnalyticsEvent.getEventProperties().getAllValues();

for(int i=0; i<mAnalyticsEvent.getEventProperties().size(); i++)
{
    properties->setProperty(keys[i], values[i]);
}

DynamicObject* event = new DynamicObject();

event->setProperty("user_id", mAnalyticsEvent.getUserID());
event->setProperty("session_uuid", mAnalyticsEvent.getSessionUUID());
event->setProperty("title", mAnalyticsEvent.getTitle());
event->setProperty("funnel_uuid", mAnalyticsEvent.getFunnelUUID());
event->setProperty("type", mAnalyticsEvent.getType());

event->setProperty("properties", properties);

DynamicObject* root = new DynamicObject();

root->setProperty("event", event);
root->setProperty("time_stamp",  mAnalyticsEvent.getTimeStamp());

var json (root);

return JSON::toString(json);

}

I then attach the JSON string to the body of the URL…

String JSONBody = httpJSONBody();

if(!JSONBody.isEmpty()) url = url.withPOSTData(JSONBody);

So far so good, however when it hits the backend, the Rails JSON parser is failing due to what seems a delimiting nil

{“{\“event\“: {\“user_id\“: \“\”, \“session_uuid\“: \“3d1691e1ffac41fc86e9845a5fbb1fc6\“, \“title\“: \“Session.Start\“, \“funnel_uuid\“: \“\”, \“type\“: \“client_1234\“, \“properties\“: {}}, \“time_stamp\“: \“21 Nov 2017 14:48:30\“}”=>nil}


#2

Can you debug a bit more and see where the trailing nil is inserted? Look at JSONBody in your debugger, for example. Does it include any nil characters?


#3

@fabian

So I managed to figure it out, but there is a small bit of funkiness on the JUCE side.

The main issue was that the headers were getting malformed.

If I formed the headers as a single string, with each line delimited by a ‘\n’ as per the header comments it would fail. The only way I could get it to work correctly was to add each header individually as below. The funky bit is that if after adding the headers I then make a call to getRequestHeaders(), the JUCE framework skips the first entry in the parsed string array (says in the comments “ignore the first line as this is the status line” ). Maybe I’m missing something here?

mStream->withExtraHeaders(“Authorization: Bearer 715c2538-c607-4748-96a2-622w85ds4cd3”);
mStream->withExtraHeaders(“Content-Type: application/json; charset=utf-8”);


#4

Hey Gav.

The implementation of withExtraHeaders adds \r\n after each header, rather than just \n, so probably that’s why it was not working for you when you were adding all headers at once.

As for getRequestHeaders(), this looks like a bug indeed, which we probably missed because you rarely (if ever) need to call this function at all - you just set the headers and internally JUCE does the job for you. The reason why it is skipping the first line, is because the response headers start with a status line, for instance:

HTTP/1.x 200 OK
Transfer-Encoding: chunked
Date: Sat, 28 Nov 2009 04:36:25 GMT
Server: LiteSpeed
Connection: close
X-Powered-By: W3 Total Cache/0.8

so we skip it on purpose. We should not skip it for own headers though in getRequestHeaders() However this will not fix your issue I think, because it seems unrelated and it only affects getRequestHeaders() result which we don’t use internally. Does it change anything for you if you add all the headers in one string, delimited by \r\n ?


#5

@lukasz.k all makes sense, thanks for the reply.

I switched to using a full string with ‘\r\n’ delimiter and it works fine.