From: Andy Green Date: Mon, 25 Apr 2016 02:04:49 +0000 (+0800) Subject: post example in test server X-Git-Tag: upstream/2.0.3~77 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f79534e0a4ae526c934cea3f6a580a9e085e6d03;p=platform%2Fupstream%2Flibwebsockets.git post example in test server https://github.com/warmcat/libwebsockets/issues/501 This demonstrates how to do a 303 redirect on POST and provide the results there, in both libwebsockets-test-server and the plugin version. Signed-off-by: Andy Green --- diff --git a/lib/header.c b/lib/header.c index 9bc4b7d..bacbe97 100644 --- a/lib/header.c +++ b/lib/header.c @@ -255,13 +255,13 @@ lws_return_http_status(struct lws *wsi, unsigned int code, } LWS_VISIBLE int -lws_http_redirect(struct lws *wsi, const unsigned char *loc, int len, +lws_http_redirect(struct lws *wsi, int code, const unsigned char *loc, int len, unsigned char **p, unsigned char *end) { unsigned char *start = *p; int n; - if (lws_add_http_header_status(wsi, 301, p, end)) + if (lws_add_http_header_status(wsi, code, p, end)) return -1; if (lws_add_http_header_by_token(wsi, diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index e4dcaae..7e8eb37 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -816,6 +816,10 @@ enum http_status { HTTP_STATUS_OK = 200, HTTP_STATUS_NO_CONTENT = 204, + HTTP_STATUS_MOVED_PERMANENTLY = 301, + HTTP_STATUS_FOUND = 302, + HTTP_STATUS_SEE_OTHER = 303, + HTTP_STATUS_BAD_REQUEST = 400, HTTP_STATUS_UNAUTHORIZED, HTTP_STATUS_PAYMENT_REQUIRED, @@ -1667,7 +1671,7 @@ lws_add_http_header_status(struct lws *wsi, unsigned char *end); LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_http_redirect(struct lws *wsi, const unsigned char *loc, int len, +lws_http_redirect(struct lws *wsi, int code, const unsigned char *loc, int len, unsigned char **p, unsigned char *end); LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT diff --git a/lib/server.c b/lib/server.c index 24392af..5fd1517 100644 --- a/lib/server.c +++ b/lib/server.c @@ -242,7 +242,7 @@ int lws_http_serve(struct lws *wsi, char *uri, const char *origin) spin++; if (stat(path, &st)) { - lwsl_err("unable to stat %s\n", path); + lwsl_info("unable to stat %s\n", path); goto bail; } @@ -321,7 +321,6 @@ int lws_http_serve(struct lws *wsi, char *uri, const char *origin) return 0; bail: - lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL); return -1; } @@ -480,7 +479,8 @@ lws_http_action(struct lws *wsi) n = sprintf((char *)end, "https://%s/", lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST)); - n = lws_http_redirect(wsi, end, n, &p, end); + n = lws_http_redirect(wsi, HTTP_STATUS_MOVED_PERMANENTLY, + end, n, &p, end); if ((int)n < 0) goto bail_nuke_ah; @@ -613,7 +613,8 @@ lws_http_action(struct lws *wsi) lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST), uri_ptr); - n = lws_http_redirect(wsi, end, n, &p, end); + n = lws_http_redirect(wsi, HTTP_STATUS_MOVED_PERMANENTLY, + end, n, &p, end); if ((int)n < 0) goto bail_nuke_ah; @@ -670,6 +671,13 @@ lws_http_action(struct lws *wsi) wsi->cache_intermediaries = hit->cache_intermediaries; n = lws_http_serve(wsi, s, hit->origin); + if (n) { + /* + * lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL); + */ + n = wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP, + wsi->user_space, uri_ptr, uri_len); + } } else n = wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP, wsi->user_space, uri_ptr, uri_len); diff --git a/lwsws/http.c b/lwsws/http.c index 000b90c..4ae8ccf 100644 --- a/lwsws/http.c +++ b/lwsws/http.c @@ -74,7 +74,7 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, char leaf_path[1024]; const char *mimetype; char *other_headers; - unsigned char *end; + unsigned char *end, *start; struct timeval tv; unsigned char *p; #ifndef LWS_NO_CLIENT @@ -140,7 +140,7 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, } #endif -#if 1 +#if 0 /* this example server has no concept of directories */ if (strchr((const char *)in + 1, '/')) { lws_return_http_status(wsi, HTTP_STATUS_FORBIDDEN, NULL); @@ -148,6 +148,40 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, } #endif + if (strlen(in) >= 12 && + !strncmp(in + strlen(in) - 12, "/postresults", 12)) { + m = sprintf(buf, "Form results: '%s'
" + "", pss->post_string); + + p = buffer + LWS_PRE; + start = p; + end = p + sizeof(buffer) - LWS_PRE; + + if (lws_add_http_header_status(wsi, 200, &p, end)) + return 1; + if (lws_add_http_header_by_token(wsi, + WSI_TOKEN_HTTP_CONTENT_TYPE, + (unsigned char *)"text/html", + 9, &p, end)) + return 1; + if (lws_add_http_header_content_length(wsi, m, &p, + end)) + return 1; + if (lws_finalize_http_header(wsi, &p, end)) + return 1; + + n = lws_write(wsi, start, p - start, + LWS_WRITE_HTTP_HEADERS); + if (n < 0) + return 1; + + n = lws_write(wsi, (unsigned char *)buf, m, LWS_WRITE_HTTP); + if (n < 0) + return 1; + + goto try_to_reuse; + } + /* if a legal POST URL, let it continue and accept data */ if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) return 0; @@ -212,20 +246,25 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, break; case LWS_CALLBACK_HTTP_BODY: - strncpy(buf, in, 20); - buf[20] = '\0'; - if (len < 20) - buf[len] = '\0'; - - lwsl_notice("LWS_CALLBACK_HTTP_BODY: %s... len %d\n", - (const char *)buf, (int)len); - + lwsl_notice("LWS_CALLBACK_HTTP_BODY: len %d\n", (int)len); + strncpy(pss->post_string, in, sizeof (pss->post_string) -1); + pss->post_string[sizeof(pss->post_string) - 1] = '\0'; break; case LWS_CALLBACK_HTTP_BODY_COMPLETION: lwsl_notice("LWS_CALLBACK_HTTP_BODY_COMPLETION\n"); - /* the whole of the sent body arrived, close or reuse the connection */ - lws_return_http_status(wsi, HTTP_STATUS_OK, NULL); + /* + * the whole of the sent body arrived, + * respond to the client with a redirect to show the + * results + */ + p = (unsigned char *)buf + LWS_PRE; + n = lws_http_redirect(wsi, + HTTP_STATUS_SEE_OTHER, /* 303 */ + (unsigned char *)"postresults", 12, /* location + len */ + &p, /* temp buffer to use */ + p + sizeof(buf) - 1 - LWS_PRE /* buffer len */ + ); goto try_to_reuse; case LWS_CALLBACK_HTTP_FILE_COMPLETION: diff --git a/lwsws/lwsws.h b/lwsws/lwsws.h index a1936c9..bd18d7a 100644 --- a/lwsws/lwsws.h +++ b/lwsws/lwsws.h @@ -45,6 +45,7 @@ struct per_session_data__http { #if defined(LWS_WITH_CGI) || !defined(LWS_NO_CLIENT) int reason_bf; #endif + char post_string[256]; unsigned int client_finished:1; }; diff --git a/test-server/test-server-http.c b/test-server/test-server-http.c index 4904e45..32b36ba 100644 --- a/test-server/test-server-http.c +++ b/test-server/test-server-http.c @@ -137,7 +137,7 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, char leaf_path[1024]; const char *mimetype; char *other_headers; - unsigned char *end; + unsigned char *end, *start; struct timeval tv; unsigned char *p; #ifndef LWS_NO_CLIENT @@ -226,6 +226,39 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, } #endif + if (!strncmp(in, "/postresults", 12)) { + m = sprintf(buf, "Form results: '%s'
" + "", pss->post_string); + + p = buffer + LWS_PRE; + start = p; + end = p + sizeof(buffer) - LWS_PRE; + + if (lws_add_http_header_status(wsi, 200, &p, end)) + return 1; + if (lws_add_http_header_by_token(wsi, + WSI_TOKEN_HTTP_CONTENT_TYPE, + (unsigned char *)"text/html", + 9, &p, end)) + return 1; + if (lws_add_http_header_content_length(wsi, m, &p, + end)) + return 1; + if (lws_finalize_http_header(wsi, &p, end)) + return 1; + + n = lws_write(wsi, start, p - start, + LWS_WRITE_HTTP_HEADERS); + if (n < 0) + return 1; + + n = lws_write(wsi, (unsigned char *)buf, m, LWS_WRITE_HTTP); + if (n < 0) + return 1; + + goto try_to_reuse; + } + /* if a legal POST URL, let it continue and accept data */ if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) return 0; @@ -371,20 +404,25 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, break; case LWS_CALLBACK_HTTP_BODY: - strncpy(buf, in, 20); - buf[20] = '\0'; - if (len < 20) - buf[len] = '\0'; - - lwsl_notice("LWS_CALLBACK_HTTP_BODY: %s... len %d\n", - (const char *)buf, (int)len); - + lwsl_notice("LWS_CALLBACK_HTTP_BODY: len %d\n", (int)len); + strncpy(pss->post_string, in, sizeof (pss->post_string) -1); + pss->post_string[sizeof(pss->post_string) - 1] = '\0'; break; case LWS_CALLBACK_HTTP_BODY_COMPLETION: lwsl_notice("LWS_CALLBACK_HTTP_BODY_COMPLETION\n"); - /* the whole of the sent body arrived, close or reuse the connection */ - lws_return_http_status(wsi, HTTP_STATUS_OK, NULL); + /* + * the whole of the sent body arrived, + * respond to the client with a redirect to show the + * results + */ + p = (unsigned char *)buf + LWS_PRE; + n = lws_http_redirect(wsi, + HTTP_STATUS_SEE_OTHER, /* 303 */ + (unsigned char *)"/postresults", 12, /* location + len */ + &p, /* temp buffer to use */ + p + sizeof(buf) - 1 - LWS_PRE /* buffer len */ + ); goto try_to_reuse; case LWS_CALLBACK_HTTP_FILE_COMPLETION: diff --git a/test-server/test-server.h b/test-server/test-server.h index 41602ae..1118a02 100644 --- a/test-server/test-server.h +++ b/test-server/test-server.h @@ -70,6 +70,7 @@ extern void test_server_unlock(int care); struct per_session_data__http { lws_filefd_type fd; + char post_string[256]; #ifdef LWS_WITH_CGI struct lws_cgi_args args; #endif diff --git a/test-server/test.html b/test-server/test.html index fa493cd..ebf01de 100644 --- a/test-server/test.html +++ b/test-server/test.html @@ -242,7 +242,7 @@ This information is sent by the server over a ws[s] link and updated live whenever the information changes server-side. -
+
@@ -252,6 +252,35 @@ whenever the information changes server-side.
+
+ + + +
+
+ + + + + + + + +
+POST Form testing +
+This tests POST handling in lws. +
+
+ Some text:
+
+ +
+
+
+
+
+