[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lwip-devel] [RFC] Extend httpd.c to support REST services more easily
From: |
tinic-lwip-devel |
Subject: |
[lwip-devel] [RFC] Extend httpd.c to support REST services more easily |
Date: |
Thu, 29 Oct 2020 15:13:13 -0700 |
User-agent: |
Roundcube Webmail |
I present a patch which adds support for REST services over HTTP in a
relatively user
friendly manner.
Rationale: REST is the standard for most interesting Javascript
frameworks.
My use case was a vue.js based configuration UI built into a STM32
microcontroller.
This is primarily a variation of the existing LWIP_HTTPD_SUPPORT_POST
code
but different enough to where extending or mashing it together was not
pratical. The two
new #ifdefs are LWIP_HTTPD_SUPPORT_REST and LWIP_HTTPD_REST_MANUAL_WND.
You either enable LWIP_HTTPD_SUPPORT_POST or LWIP_HTTPD_SUPPORT_REST but
not both.
My question is: Is there any interest in merging such functionality into
upstream LwIP?
If so I'd be willing to clean up and explain the code; add
documentation, examples and a
few test cases. On the other hand I am also happy to just move on :-)
My fork is here: https://github.com/tinic/lwip-ajax
A patch is attached to this email.
From a user perspective a minimal REST service can be implemented as
such:
----
#define SERVICE_GET_STATUS 1
#define SERVICE_POST_SETTINGS 2
static int method = 0;
err_t httpd_rest_begin(void *handle, rest_method_t method, const char
*url, const char *, u16_t, int, u8_t *) {
switch(method) {
case REST_METHOD_GET: {
if (strcmp(url, "/status") == 0) {
method = SERVICE_GET_STATUS;
return ERR_OK;
}
} break;
case REST_METHOD_POST: {
if (strcmp(url, "/settings") == 0) {
method = SERVICE_POST_SETTINGS;
return ERR_OK;
}
} break;
case REST_METHOD_PUT:
case REST_METHOD_PATCH:
case REST_METHOD_DELETE:
case REST_METHOD_OPTIONS: {
} break;
}
method = 0;
return ERR_ARG;
}
err_t httpd_rest_receive_data(void *handle, struct pbuf *p) {
if (method == SERVICE_POST_SETTINGS) {
// user: send data to json parser
return ERR_OK;
}
}
err_t httpd_rest_finished(void *handle, const char **data, u16_t
*dataLen) {
if (method == SERVICE_POST_SETTINGS) {
// Minimal set of fields for most browsers to work correctly in
2020
// Response string is user controlled as it is security
sensitive
const char *okResponse =
"HTTP/1.0 200 OK" CRLF
"Access-Control-Allow-Origin: *" CRLF; // Wildcard is a
potential security risk
*data = okResponse;
*dataLen = strlen(okResponse);
return ERR_OK;
}
if (method == SERVICE_GET_STATUS) {
static char response[1024];
memset(response, 0, sizeof(response))
// Minimal set of fields for most browsers to work correctly in
2020
// Response string is user controlled as it is security
sensitive
const char *responsePrototype =
"HTTP/1.0 200 OK" CRLF
"Access-Control-Allow-Origin: *" CRLF // Wildcard is a
potential security risk
"Content-Type: application/json; charset=utf-8" CRLF
"X-Content-Type-Options: nosniff" CRLF
"Vary: Origin, Accept-Encoding" CRLF
"Content-Length: @@@@@@@@@@@" CRLF // Needs to be patched
after JSON data is added
"Cache-Control: no-cache" CRLF
CRLF;
strncpy(response, responsePrototype, sizeof(response) - 1);
// user: safely add json to response
// user: safely patch content length field in response
*data = response;
*dataLen = strlen(response);
return ERR_OK;
}
return ERR_ARG;
}
---
REST.patch
Description: Text Data
- [lwip-devel] [RFC] Extend httpd.c to support REST services more easily,
tinic-lwip-devel <=