Closed elockman closed 2 years ago
Hello @elockman ,
In fact, Ulfius' Jansson integration is just with those 4 functions, and in the ulfius_set_{request,response}_properties
functions with the U_OPT_JSON_BODY
.
If you check ulfius_get_json_body_request
and ulfius_set_json_body_response
(the most used in my case), you'll see the code is pretty simple: converting a char *
from and to a json_t *
:
https://github.com/babelouest/ulfius/blob/master/src/u_request.c#L843 https://github.com/babelouest/ulfius/blob/master/src/u_response.c#L676
At first sight I'm not very willing to support another JSON library in ulfius, but I can definitely help you write the functions like ulfius_get_cjson_body_request
and ulfius_set_cjson_body_response
that you can keep in your own code base.
How about that?
Sounds good. I've done a little digging and found those 2 files as the majority of the work to move forward. There would potentially be significant work with integrating cJSON build arg flags. Your help would be greatly appreciated to understand the required changes.
Your help would be greatly appreciated to understand the required changes.
I invite you to send a link to your code or a PR to review then
@babelouest I have an example function I am using here:
int callback_write_config_param (const struct _u_request * request, struct _u_response * response, void * user_data) {
char group[24];
char param[24];
char value[24];
sprintf(group, "%s", u_map_get(request->map_url, "group"));
sprintf(param, "%s", u_map_get(request->map_url, "param"));
sprintf(value, "%s", u_map_get(request->map_url, "value"));
write_config_param(group, param, value);
json_t * json_body = NULL;
json_body = json_object();
json_object_set_new(json_body, param, json_string(value));
ulfius_set_json_body_response(response, 200, json_body);
json_decref(json_body);
return U_CALLBACK_CONTINUE;
}
As you can see, this uses jansson functions in the application code as well. Could I simply replace the the json block with a manually (or cjson) assembled string to pass to a ulfius_set_cjson_body_response() function?
char * resp_body = NULL;
sprintf(resp_body, "{\"%s\":\"%s\"}", param, value);
ulfius_set_cjson_body_response(response, 200, resp_body);
The ulfius_set_cjson_body_response() function would then just assign the binary_body string, binary_body_length, and status. Then it would u_map_put the json header with ULFIUS_HTTP_ENCODING_JSON.
Does that make sense?
This would be a proposed ulfiussetcjson_body_response() function with some of the safeguards removed for the time being.
int ulfius_set_cjson_body_response(struct _u_response * response, const unsigned int status, const char * j_body) {
if (response != NULL && j_body != NULL) {
response->binary_body = j_body;
response->binary_body_length = o_strlen((char*)response->binary_body);
response->status = status;
u_map_put(response->map_header, ULFIUS_HTTP_HEADER_CONTENT, ULFIUS_HTTP_ENCODING_JSON);
return U_OK;
} else {
return U_ERROR_PARAMS;
}
}
I'll fork and make proposed changes for you to review.
According to cJSON's documentation, you should use cJSON_Parse
and cJSON_Print
, something like this:
int ulfius_set_cjson_body_response(struct _u_response * response, const unsigned int status, cJSON *json) {
if (response != NULL && json != NULL) {
o_free(response->binary_body);
response->binary_body = cJSON_Print(json);
response->binary_body_length = o_strlen((char*)response->binary_body);
response->status = status;
u_map_put(response->map_header, ULFIUS_HTTP_HEADER_CONTENT, ULFIUS_HTTP_ENCODING_JSON);
return U_OK;
} else {
return U_ERROR_PARAMS;
}
}
Thanks. You can view my code here: https://github.com/elockman/ulfius/tree/dev_cjson It contains a rough webui_example project. It breaks on the /info page where it grabs data from a JSON file.
[user@pc webui_example]$ ./webui_example 8080
2021-09-24T23:50:54Z - webui_example INFO: Starting WebUI code
Start WebUI at http://localhost:8080/info
read_config_param: config/wifi/name = None
./webui_example: symbol lookup error: ./webui_example: undefined symbol: ulfius_set_cjson_body_response
[user@pc webui_example]$
I'm not sure where the undefined symbol error is coming from.
Like I said above, I suggest to write the cjson functions in your own code base, rather than forking ulfius. With a fork, it will be more difficult to keep your fork up-to-date with my repo, since your code changes core functions.
Instead, I suggest you create a single project webui
that has ulfius and cJSON as dependency.
In that project you can implement the functions ulfius_set_cjson_body_response
and others.
Thanks, that makes sense. It was also much easier.
I am running into issues installing jansson on my embedded system.
Would it be possible to provide cjson support to create a simple json REST API on embedded systems?
cjson is just comprised of a single c and a single h file.