client: support pipelining / h2 multi for POST

https://github.com/warmcat/libwebsockets/issues/1256
This commit is contained in:
Andy Green 2018-04-27 07:25:45 +08:00
parent 5d06f610a9
commit 800cd40f88
4 changed files with 50 additions and 19 deletions

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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