diff options
| author | Garrett D'Amore <garrett@damore.org> | 2018-01-02 13:20:53 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2018-01-02 15:34:44 -0800 |
| commit | ce681752c44f792feab122cbd846b2407a42da72 (patch) | |
| tree | 842fc38b7589463d3e07d30f7dadaf5bb3b0064d /src/supplemental/websocket | |
| parent | 68f9a47cb836b72e69a69c60938c3728d3a94fe2 (diff) | |
| download | nng-ce681752c44f792feab122cbd846b2407a42da72.tar.gz nng-ce681752c44f792feab122cbd846b2407a42da72.tar.bz2 nng-ce681752c44f792feab122cbd846b2407a42da72.zip | |
fixes #191 Several HTTP problems found
First, httpbin.org was having some high latency (load) earlier today,
so we needed to bump the timeout up.
Next, this also uncovered a bug where our cancellation of http channels
was a bit dodgy. This is changed to be a bit more robust, separating the
"current" active http streams (for read or write) into separate tracking
variables variables. Also, now cancellation immediately calls the aio
finish for those -- there were assumptions elsewhere (expire timeouts)
that cancellation caused nni_aio_finish() to be called.
Finally there was a use after free bug in the websocket listener code
where the listener could be freed while still having outstanding streams
waiting to send the websocket reply.
Diffstat (limited to 'src/supplemental/websocket')
| -rw-r--r-- | src/supplemental/websocket/websocket.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/src/supplemental/websocket/websocket.c b/src/supplemental/websocket/websocket.c index a8699663..bb16cf3c 100644 --- a/src/supplemental/websocket/websocket.c +++ b/src/supplemental/websocket/websocket.c @@ -62,6 +62,7 @@ struct nni_ws_listener { char * serv; char * path; nni_mtx mtx; + nni_cv cv; nni_list pend; nni_list reply; nni_list aios; @@ -417,6 +418,7 @@ ws_close_cb(void *arg) nni_http_close(ws->http); nni_aio_cancel(ws->txaio, NNG_ECLOSED); nni_aio_cancel(ws->rxaio, NNG_ECLOSED); + nni_aio_cancel(ws->httpaio, NNG_ECLOSED); // This list (receive) should be empty. while ((wm = nni_list_first(&ws->rxmsgs)) != NULL) { @@ -1122,7 +1124,6 @@ nni_ws_fini(nni_ws *ws) static void ws_http_cb_listener(nni_ws *ws, nni_aio *aio) { - // This is only nni_ws_listener *l; l = nni_aio_get_data(aio, 0); @@ -1140,6 +1141,9 @@ ws_http_cb_listener(nni_ws *ws, nni_aio *aio) } else { nni_list_append(&l->pend, ws); } + if (nni_list_empty(&l->reply)) { + nni_cv_wake(&l->cv); + } nni_mtx_unlock(&l->mtx); } @@ -1240,7 +1244,6 @@ err: static void ws_http_cb(void *arg) { - // This is only done on the server/listener side. nni_ws * ws = arg; nni_aio *aio = ws->httpaio; @@ -1294,11 +1297,18 @@ nni_ws_listener_fini(nni_ws_listener *l) nni_ws_listener_close(l); + nni_mtx_lock(&l->mtx); + while (!nni_list_empty(&l->reply)) { + nni_cv_wait(&l->cv); + } + nni_mtx_unlock(&l->mtx); + if (l->server != NULL) { nni_http_server_fini(l->server); l->server = NULL; } + nni_cv_fini(&l->cv); nni_mtx_fini(&l->mtx); nni_strfree(l->url); nni_strfree(l->proto); @@ -1468,6 +1478,7 @@ err: nni_aio_finish(aio, 0, 0); } } + static int ws_parse_url(const char *url, char **schemep, char **hostp, char **servp, char **pathp, char **queryp) @@ -1570,6 +1581,7 @@ nni_ws_listener_init(nni_ws_listener **wslp, const char *url) return (NNG_ENOMEM); } nni_mtx_init(&l->mtx); + nni_cv_init(&l->cv, &l->mtx); nni_aio_list_init(&l->aios); NNI_LIST_INIT(&l->pend, nni_ws, node); |
