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; } --- _______________________________________________ lwip-devel mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/lwip-devel |
Am 29.10.2020 um 23:13 schrieb [hidden email]:
> 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 :-) Being able to easily support REST would be nice, but I'm not sure if there's enough man-power available for lwIP at the moment to integrate this. A clean patch would of course help. > > 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; This won't work: you cannot use a global variable. REST calls may come interleaved, depending on segment size. You have to pass everything as arguments, not using globals. > > err_t httpd_rest_begin(void *handle, rest_method_t method, const char > *url, const char *, u16_t, int, u8_t *) { This won't work either: you have 2 variables named 'method' here. Regards, Simon > 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; > } > --- _______________________________________________ lwip-devel mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/lwip-devel |
On 2020-10-30 00:14, [hidden email] wrote:
> > Being able to easily support REST would be nice, but I'm not sure if > there's enough man-power available for lwIP at the moment to integrate > this. A clean patch would of course help. > No problem, I'll move on then. Thanks for the clarification. --tinic _______________________________________________ lwip-devel mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/lwip-devel |
Free forum by Nabble | Edit this page |