diff --git a/README.md b/README.md index aa476a840f3d2fdee3189b22260af2e2394ea83d..2305fbb61aac7afca277aade9c5d2173bc9f0bda 100644 --- a/README.md +++ b/README.md @@ -13,16 +13,16 @@ The Travis build of lws done on every commit now runs Tests|Count|Explanation ---|---|--- -Build / Linux / gcc|13|-Wall -Werror -Build / Mac / Clang|13|-Wall -Werror +Build / Linux / gcc|13|-Wall -Werror cmake config variants +Build / Mac / Clang|13|-Wall -Werror cmake config variants Build / Windows / MSVC|7|default -Selftests|29|minimal examples built and run against each other and remote server +Selftests|33|minimal examples built and run against each other and remote server attack.sh|225|Correctness, robustness and security tests for http parser Autobahn Server|480|Testing lws ws client, including permessage-deflate Autobahn Client|480|Testing lws ws server, including permaessage-deflate h2spec|146|Http/2 server compliance suite (in strict mode) -The nearly 1,400 tests run on every commit take most of an hour to complete. +The over 1,400 tests run on every commit take most of an hour to complete. If any problems are found, it breaks the travis build, generating an email. Current master passes all the tests and these new CI arrangements will help diff --git a/lib/roles/http/client/client-handshake.c b/lib/roles/http/client/client-handshake.c index 197b28b5cec9172753265aabd7abb3462f1f3adc..ab940a3f1a198a8f11639e14f9b91d57fd5d06a1 100644 --- a/lib/roles/http/client/client-handshake.c +++ b/lib/roles/http/client/client-handshake.c @@ -59,7 +59,7 @@ lws_client_connect_2(struct lws *wsi) /* we can only piggyback GET */ meth = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD); - if (meth && strcmp(meth, "GET")) + if (meth && strcmp(meth, "GET") && strcmp(meth, "POST")) goto create_new_conn; /* we only pipeline connections that said it was okay */ @@ -79,7 +79,8 @@ lws_client_connect_2(struct lws *wsi) struct lws *w = lws_container_of(d, struct lws, dll_active_client_conns); - lwsl_debug("%s: check %s %s %d %d\n", __func__, adsin, w->client_hostname_copy, wsi->c_port, w->c_port); + lwsl_debug("%s: check %s %s %d %d\n", __func__, adsin, + w->client_hostname_copy, wsi->c_port, w->c_port); if (w != wsi && w->client_hostname_copy && !strcmp(adsin, w->client_hostname_copy) && @@ -161,7 +162,7 @@ create_new_conn: * piggyback on our transaction queue */ - if (meth && !strcmp(meth, "GET") && + if (meth && (!strcmp(meth, "GET") || !strcmp(meth, "POST")) && lws_dll_is_null(&wsi->dll_client_transaction_queue) && lws_dll_is_null(&wsi->dll_active_client_conns)) { lws_vhost_lock(wsi->vhost); diff --git a/minimal-examples/http-client/minimal-http-client-post/minimal-http-client-post.c b/minimal-examples/http-client/minimal-http-client-post/minimal-http-client-post.c index 0d7aedfaf579cad41e49b528fdd543f9c67ff8a6..a5f3ed2bdc3e272a25989f67b19fe7f311e1a6bd 100644 --- a/minimal-examples/http-client/minimal-http-client-post/minimal-http-client-post.c +++ b/minimal-examples/http-client/minimal-http-client-post/minimal-http-client-post.c @@ -17,8 +17,8 @@ #include <string.h> #include <signal.h> -static int interrupted, bad = 1, status; -static struct lws *client_wsi; +static int interrupted, bad = 0, status, count_clients = 1, completed; +static struct lws *client_wsi[4]; struct pss { char boundary[32]; @@ -42,13 +42,20 @@ callback_http(struct lws *wsi, enum lws_callback_reasons reason, case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: lwsl_err("CLIENT_CONNECTION_ERROR: %s\n", in ? (char *)in : "(null)"); - client_wsi = NULL; + bad = 1; + if (++completed == count_clients) + lws_cancel_service(lws_get_context(wsi)); break; case LWS_CALLBACK_CLOSED_CLIENT_HTTP: - client_wsi = NULL; - bad = status != 200; - lws_cancel_service(lws_get_context(wsi)); /* abort poll wait */ + for (n = 0; n < count_clients; n++) + if (client_wsi[n] == wsi) { + client_wsi[n] = NULL; + bad |= status != 200; + if (++completed == count_clients) + /* abort poll wait */ + lws_cancel_service(lws_get_context(wsi)); + } break; /* ...callbacks related to receiving the result... */ @@ -72,8 +79,18 @@ callback_http(struct lws *wsi, enum lws_callback_reasons reason, case LWS_CALLBACK_COMPLETED_CLIENT_HTTP: lwsl_user("LWS_CALLBACK_COMPLETED_CLIENT_HTTP\n"); - client_wsi = NULL; - bad = status != 200; + bad |= status != 200; + /* + * Do this to mark us as having processed the completion + * so close doesn't duplicate (with pipelining, completion != + * connection close + */ + for (n = 0; n < count_clients; n++) + if (client_wsi[n] == wsi) + client_wsi[n] = NULL; + if (++completed == count_clients) + /* abort poll wait */ + lws_cancel_service(lws_get_context(wsi)); break; /* ...callbacks related to generating the POST... */ @@ -232,6 +249,9 @@ int main(int argc, const char **argv) return 1; } + if (lws_cmdline_option(argc, argv, "-m")) + count_clients = LWS_ARRAY_SIZE(client_wsi); + memset(&i, 0, sizeof i); /* otherwise uninitialized garbage */ i.context = context; i.ssl_connection = LCCSCF_USE_SSL; @@ -256,10 +276,14 @@ int main(int argc, const char **argv) i.alpn = "http/1.1"; i.protocol = protocols[0].name; - i.pwsi = &client_wsi; - lws_client_connect_via_info(&i); - while (n >= 0 && client_wsi && !interrupted) + for (n = 0; n < count_clients; n++) { + i.pwsi = &client_wsi[n]; + if (!lws_client_connect_via_info(&i)) + completed++; + } + + while (n >= 0 && completed != count_clients && !interrupted) n = lws_service(context, 1000); lws_context_destroy(context); diff --git a/minimal-examples/http-client/minimal-http-client-post/selftest.sh b/minimal-examples/http-client/minimal-http-client-post/selftest.sh index eeabeea143e57ac526f17e0ec149c897bee4421d..2f887f2a07134bf32aefa4e44e54f84c6c83a744 100755 --- a/minimal-examples/http-client/minimal-http-client-post/selftest.sh +++ b/minimal-examples/http-client/minimal-http-client-post/selftest.sh @@ -18,15 +18,21 @@ . $5/selftests-library.sh -COUNT_TESTS=4 +COUNT_TESTS=8 dotest $1 $2 warmcat dotest $1 $2 warmcat-h1 --h1 +dotest $1 $2 warmcat-m -m +dotest $1 $2 warmcat-m-h1 -m --h1 spawn "" $5 $1/libwebsockets-test-server -s dotest $1 $2 localhost -l spawn $SPID $5 $1/libwebsockets-test-server -s dotest $1 $2 localhost-h1 -l --h1 +spawn $SPID $5 $1/libwebsockets-test-server -s +dotest $1 $2 localhost-m -l -m +spawn $SPID $5 $1/libwebsockets-test-server -s +dotest $1 $2 localhost-m-h1 -l -m --h1 kill $SPID 2>/dev/null wait $SPID 2>/dev/null