From f65f819f7fb3bbe9e24bc73342b4f335f5034fe0 Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Tue, 12 Mar 2019 23:53:50 -0700 Subject: fixes #907 WebSocket ephemeral port cannot be reused --- src/supplemental/http/http_server.c | 18 +++++++++++------- tests/ws.c | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/supplemental/http/http_server.c b/src/supplemental/http/http_server.c index 624ba1e4..b927d8f3 100644 --- a/src/supplemental/http/http_server.c +++ b/src/supplemental/http/http_server.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "core/nng_impl.h" @@ -79,7 +80,7 @@ struct nng_http_server { bool closed; nni_aio * accaio; nng_stream_listener *listener; - char * port; + int port; // native order char * hostname; nni_list errors; nni_mtx errors_mtx; @@ -830,7 +831,6 @@ http_server_fini(nni_http_server *s) nni_aio_fini(s->accaio); nni_mtx_fini(&s->mtx); nni_strfree(s->hostname); - nni_strfree(s->port); NNI_FREE_STRUCT(s); } @@ -869,10 +869,10 @@ http_server_init(nni_http_server **serverp, const nni_url *url) return (rv); } - if ((s->port = nni_strdup(url->u_port)) == NULL) { - http_server_fini(s); - return (NNG_ENOMEM); - } + // NB: We only support number port numbers, and the URL framework + // expands empty port numbers to 80 or 443 as appropriate. + s->port = atoi(url->u_port); + if ((s->hostname = nni_strdup(url->u_hostname)) == NULL) { http_server_fini(s); return (NNG_ENOMEM); @@ -898,7 +898,7 @@ nni_http_server_init(nni_http_server **serverp, const nni_url *url) nni_mtx_lock(&http_servers_lk); NNI_LIST_FOREACH (&http_servers, s) { - if ((!s->closed) && (strcmp(url->u_port, s->port) == 0) && + if ((!s->closed) && (atoi(url->u_port) == s->port) && (strcmp(url->u_hostname, s->hostname) == 0)) { *serverp = s; s->refcnt++; @@ -924,6 +924,10 @@ http_server_start(nni_http_server *s) if ((rv = nng_stream_listener_listen(s->listener)) != 0) { return (rv); } + if (s->port == 0) { + nng_stream_listener_get_int( + s->listener, NNG_OPT_TCP_BOUND_PORT, &s->port); + } nng_stream_listener_accept(s->listener, s->accaio); return (0); } diff --git a/tests/ws.c b/tests/ws.c index e5cc8ba5..59d4d52d 100644 --- a/tests/ws.c +++ b/tests/ws.c @@ -155,5 +155,25 @@ TestMain("WebSocket Transport", { So(nng_dial(s2, "ws://127.0.0.1:5599/one", NULL, 0) == 0); }); + Convey("Wild card port works and can be used again", { + nng_socket s1; + nng_socket s2; + nng_listener l1; + int port; + char ws_url[128]; + So(nng_pair_open(&s1) == 0); + So(nng_pair_open(&s2) == 0); + Reset({ + nng_close(s1); + nng_close(s2); + }); + So(nng_listen(s1, "ws://*:0/one", &l1, 0) == 0); + So(nng_listener_getopt_int( + l1, NNG_OPT_TCP_BOUND_PORT, &port) == 0); + So(port != 0); + snprintf(ws_url, 1023, "ws://*:%d/two", port); + So(nng_listen(s2, ws_url, NULL, 0) == 0); + }); + nng_fini(); }) -- cgit v1.2.3-70-g09d2