HTTP Server, Content type: application/json

Find and share HowTos to various installations / configurations!
7 posts • Page 1 of 1
eraytufan
Posts:9
Joined: Tue Sep 03, 2019 9:19 am

HTTP Server, Content type: application/json

Post by eraytufan »

Hello all,

I have to create HTTP Server with POST requests that uses content type application/json. Request body consists of JSON body and there aren't request query parameters.

Request body contains the following json:

Code: Select all

{
    "attribute1": 11,
    "attribute2": 22
}
When I used httpConnect for my callback function, I am able to get request parameters inside my callback function, however I cannot access JSON body.

Example:

If I send a request with query parameters additionally with the JSON body I put before, my callback function only returns 2 items `queryAttribute1=33` and `queryAttribute2=44`. 'attribute1' and 'attribute2' values are not returned in the callback function.

http://127.0.0.1:3300/myMethod?queryAtt ... ribute2=44

Code: Select all

cbFunction(dyn_string dsParameter, dyn_string dsValue, const string sUser, const string sIP){

  DebugTN(dsParameter);
  DebugTN(dsValue);
}
Log File:

Code: Select all

WCCOActrl2:2021.05.03 17:10:10.048[dyn_string 2 items
WCCOActrl2:     1: "queryAttribute1"
WCCOActrl2:     2: "queryAttribute2"
WCCOActrl2:]
WCCOActrl2:2021.05.03 17:10:10.048[dyn_string 2 items
WCCOActrl2:     1: "33"
WCCOActrl2:     2: "44"
WCCOActrl2:]

So my question is how can I write a httpConnect with Content type: application/json. Additionally, how can I access body of the request?

p.s.: Code snippet or an example CB function would be a huge help.

Thank you,
Eray

gschijndel
Posts:376
Joined: Tue Jan 15, 2019 3:12 pm

Re: HTTP Server, Content type: application/json

Post by gschijndel »

To retrieve the body in the callback function, you need to specify the content type as 3rd parameter of the httpConnect function.
The content is then the value of the first parameter instead of the names and values dyn_strings.
In case you also need the query attributes they could be retrieved with the function httpGetQuery with as parameter the connection index, which is passed to the callback function after the header dyn_strings.

EER
Posts:17
Joined: Fri Jun 12, 2015 1:31 pm

Re: HTTP Server, Content type: application/json

Post by EER »

I'm having the same problem, without solution so far.

If I send the following JSON data (application/json):

Code: Select all

{
    "test": 1
}
It following WinCCOA server:

Code: Select all

#uses "CtrlHTTP"

main()
{
  httpServer(false, 8440);
  httpConnect("cbFunction", "/", "application/json");
}

string cbFunction(anytype content)
{
  DebugTN(content);
}
It yields me:

Code: Select all

WCCOActrl2:2022.03.04 10:16:41.089[Blob encountered with 19 items, dump follows
WCCOActrl2:7b d a 20 20 20 20 22 74 65 73 74 22 3a 20 31 d a 7d 
WCCOActrl2:]
It returns a blob.
The hex values can manually be converted to UTF-8 text which matches the input data. But I can't find a way to convert the blob to an (UTF-8) string using CTRL script.

Does anyone know a solution? Can HttpConnect or cbFunction be 'configured' to automagically convert it to a string or mapping?

kilianvp
Posts:443
Joined: Fri Jan 16, 2015 10:29 am

Re: HTTP Server, Content type: application/json

Post by kilianvp »

you looking for blobGetValue. Here my example.

Code: Select all

#uses "json"
#uses "CtrlHTTP"

main()
{
  httpServer(false, 8440);
  httpConnect("cbFunction", "/", "application/json");
}

string cbFunction(const anytype &content)
{
  string sjson;
  blobGetValue(content, 0, sjson, bloblen(content));
  DebugTN(jsonDecode(sjson));
}

gschijndel
Posts:376
Joined: Tue Jan 15, 2019 3:12 pm

Re: HTTP Server, Content type: application/json

Post by gschijndel »

Here are 2 'automagically' changes. Either should do the trick:

Code: Select all

httpConnect("cbFunction", "/", "text/json");

Code: Select all

string cbFunction(const string &content)

weirdal
Posts:34
Joined: Thu Mar 12, 2015 11:37 am

Re: HTTP Server, Content type: application/json

Post by weirdal »

I'll just jump right into this thread since I am having similar issues.

We have changed the http-Method for our web application from GET to POST. When using GET we would get the request parameters in the callback function in the following form, as specified in the WinCC OA help:

workCB(dyn_string keys, dyn_string values, string user, string ip, dyn_string httpKeys, dyn_string httpValues, int connectionIndex)

However, this doesn't work anymore when changing to POST since POST uses a different callback function definition depending on the content type used. If keeping application/json - as it was before with GET -, the data is received in binary form (BLOB). POST combined with application/json leads to the following callback function definition being used:

workCB(blob content, string user, string ip, dyn_string httpKeys, dyn_string httpValues, int connectionIndex)

Here, the content variable of type BLOB contains the json data in binary form, which can be retrieved using blobGetValue() as described by Kilian.

In the help it is described that changing the content type from application/json to application/x-www-form-urlencoded will lead to the same result as when using GET, so that you receive data in two dyn_string variables. Apparently, that is not the case:
I have changed the content type as described, but the data received is as follows:

first parameter (string): raw JSON
second parameter (string): empty
other parameters as before

That result doesn't match one of the function definitions that are in the help - or I am missing out on something.


Help states:
When using POST with

- application/x-www-form-urlencoded --> workCB(dyn_string keys, dyn_string values, string user, string ip, dyn_string httpKeys, dyn_string httpValues, int connectionIndex)
- text/* --> workCB(string content, string user, string ip, dyn_string httpKeys, dyn_string httpValues, int connectionIndex)
- any other content type --> workCB(blob content, string user, string ip, dyn_string httpKeys, dyn_string httpValues, int connectionIndex)

It is of course manageable to work with the raw JSON and parse it myself, but the nicer solution would be if the correct function definition was called.

Any hints on how I can force the application to use the workCB(dyn_string keys, dyn_string values, ...) definition?

gschijndel
Posts:376
Joined: Tue Jan 15, 2019 3:12 pm

Re: HTTP Server, Content type: application/json

Post by gschijndel »

I do not know how you have tested it, but the documentation mentions this:
If a client sends data in the content type "application/x-www-form-urlencoded" to the HTTP server, the CTRL callback functions get field names and field values in the same form as the GET method

Do not think it is possible to force that definition if the client uses another content type. But I do not see any problem to use the 'jsonDecode' function to parse a json string. Otherwise it is also possible use the 'httpGetQuery' function.

7 posts • Page 1 of 1