diff options
| author | Garrett D'Amore <garrett@damore.org> | 2017-12-29 14:21:20 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2017-12-30 19:05:41 -0800 |
| commit | 6a50035b242b972c1d9b659ba63e037a0a8afe71 (patch) | |
| tree | fe2600235a01e72d1e7bd5fad1d5e2ea62aada2e /src/supplemental/http/server.c | |
| parent | a0364185784895c4bc748a6e6453a132d618c96c (diff) | |
| download | nng-6a50035b242b972c1d9b659ba63e037a0a8afe71.tar.gz nng-6a50035b242b972c1d9b659ba63e037a0a8afe71.tar.bz2 nng-6a50035b242b972c1d9b659ba63e037a0a8afe71.zip | |
fixes #166 Websocket TLS mapping
This introduces the wss:// scheme, which is available and works like
the ws:// scheme if TLS is enabled in the library.
The library modularization is refactored somewhat, to make it easier
to use. There is now a single NNG_ENABLE_TLS that enables TLS support
under the hood.
This also adds a new option for the TLS transport, NNG_OPT_TLS_CONFIG
(and a similar one for WSS, NNG_OPT_TLS_WSS_CONFIG) that offer access
to the underlying TLS configuration object, which now has a public API
to go with it as well.
Note that it is also possible to use pure HTTPS using the *private*
API, which will be exposed in a public form soon.
Diffstat (limited to 'src/supplemental/http/server.c')
| -rw-r--r-- | src/supplemental/http/server.c | 115 |
1 files changed, 78 insertions, 37 deletions
diff --git a/src/supplemental/http/server.c b/src/supplemental/http/server.c index ea7f15ce..ba74a138 100644 --- a/src/supplemental/http/server.c +++ b/src/supplemental/http/server.c @@ -14,6 +14,8 @@ #include <string.h> #include "core/nng_impl.h" +#include "supplemental/tls/tls.h" + #include "http.h" static int http_server_sys_init(void); @@ -50,7 +52,6 @@ typedef struct http_sconn { nni_aio * rxaio; nni_aio * txaio; nni_aio * txdataio; - nni_http_tran tran; nni_reap_item reap; } http_sconn; @@ -64,7 +65,7 @@ struct nni_http_server { nni_mtx mtx; nni_cv cv; bool closed; - bool tls; + nng_tls_config * tls; nni_aio * accaio; nni_plat_tcp_ep *tep; }; @@ -105,28 +106,48 @@ http_sconn_fini(http_sconn *sc) } static void -http_sconn_close(http_sconn *sc) +http_sconn_close_locked(http_sconn *sc) { nni_http_server *s; s = sc->server; + nni_http *h; + if (sc->closed) { + return; + } NNI_ASSERT(!sc->finished); - nni_mtx_lock(&s->mtx); - if (!sc->closed) { - nni_http *h; - sc->closed = true; - // Close the underlying transport. - if (nni_list_node_active(&sc->node)) { - nni_list_remove(&s->conns, sc); - if (nni_list_empty(&s->conns)) { - nni_cv_wake(&s->cv); - } - } - if ((h = sc->http) != NULL) { - nni_http_close(h); + + sc->closed = true; + // Close the underlying transport. + if (nni_list_node_active(&sc->node)) { + nni_list_remove(&s->conns, sc); + if (nni_list_empty(&s->conns)) { + nni_cv_wake(&s->cv); } - http_sconn_fini(sc); } + nni_aio_cancel(sc->rxaio, NNG_ECLOSED); + nni_aio_cancel(sc->txaio, NNG_ECLOSED); + nni_aio_cancel(sc->txdataio, NNG_ECLOSED); + nni_aio_cancel(sc->cbaio, NNG_ECLOSED); + + if ((h = sc->http) != NULL) { + nni_http_close(h); + } + http_sconn_fini(sc); +} + +static void +http_sconn_close(http_sconn *sc) +{ + nni_http_server *s; + s = sc->server; + + if (sc->closed) { + return; + } + + nni_mtx_lock(&s->mtx); + http_sconn_close_locked(sc); nni_mtx_unlock(&s->mtx); } @@ -484,14 +505,16 @@ http_sconn_cbdone(void *arg) } static int -http_sconn_init(http_sconn **scp, nni_plat_tcp_pipe *tcp) +http_sconn_init(http_sconn **scp, nni_http_server *s, nni_plat_tcp_pipe *tcp) { http_sconn *sc; int rv; if ((sc = NNI_ALLOC_STRUCT(sc)) == NULL) { + nni_plat_tcp_pipe_fini(tcp); return (NNG_ENOMEM); } + if (((rv = nni_http_req_init(&sc->req)) != 0) || ((rv = nni_aio_init(&sc->rxaio, http_sconn_rxdone, sc)) != 0) || ((rv = nni_aio_init(&sc->txaio, http_sconn_txdone, sc)) != 0) || @@ -502,18 +525,13 @@ http_sconn_init(http_sconn **scp, nni_plat_tcp_pipe *tcp) http_sconn_close(sc); return (rv); } - // XXX: for HTTPS we would then try to do the TLS negotiation here. - // That would use a different set of tran values. - sc->tran.h_data = tcp; - sc->tran.h_read = (void *) nni_plat_tcp_pipe_recv; - sc->tran.h_write = (void *) nni_plat_tcp_pipe_send; - sc->tran.h_close = (void *) nni_plat_tcp_pipe_close; // close implied - sc->tran.h_fini = (void *) nni_plat_tcp_pipe_fini; - sc->tran.h_sock_addr = (void *) nni_plat_tcp_pipe_sockname; - sc->tran.h_peer_addr = (void *) nni_plat_tcp_pipe_peername; - - if ((rv = nni_http_init(&sc->http, &sc->tran)) != 0) { + if (s->tls != NULL) { + rv = nni_http_init_tls(&sc->http, s->tls, tcp); + } else { + rv = nni_http_init_tcp(&sc->http, tcp); + } + if (rv != 0) { http_sconn_close(sc); return (rv); } @@ -539,9 +557,8 @@ http_server_acccb(void *arg) return; } tcp = nni_aio_get_pipe(aio); - if (http_sconn_init(&sc, tcp) != 0) { - nni_plat_tcp_pipe_close(tcp); - nni_plat_tcp_pipe_fini(tcp); + if (http_sconn_init(&sc, s, tcp) != 0) { + // The TCP structure is already cleaned up. nni_plat_tcp_ep_accept(s->tep, s->accaio); return; @@ -590,6 +607,11 @@ http_server_fini(nni_http_server *s) http_handler_fini(h); } nni_mtx_unlock(&s->mtx); +#ifdef NNG_SUPP_TLS + if (s->tls != NULL) { + nng_tls_config_fini(s->tls); + } +#endif nni_aio_fini(s->accaio); nni_cv_fini(&s->cv); nni_mtx_fini(&s->mtx); @@ -726,11 +748,7 @@ http_server_stop(nni_http_server *s) // Stopping the server is a hard stop -- it aborts any work being // done by clients. (No graceful shutdown). NNI_LIST_FOREACH (&s->conns, sc) { - nni_list_remove(&s->conns, sc); - if (sc->http != NULL) { - nni_http_close(sc->http); - } - http_sconn_fini(sc); + http_sconn_close_locked(sc); } nni_cv_wake(&s->cv); } @@ -1073,6 +1091,29 @@ nni_http_server_add_static(nni_http_server *s, const char *host, return (0); } +#ifdef NNG_SUPP_TLS +int +nni_http_server_set_tls(nni_http_server *s, nng_tls_config *tcfg) +{ + nng_tls_config *old; + nni_mtx_lock(&s->mtx); + if (s->starts) { + nni_mtx_unlock(&s->mtx); + return (NNG_EBUSY); + } + old = s->tls; + s->tls = tcfg; + if (tcfg) { + nni_tls_config_hold(tcfg); + } + nni_mtx_unlock(&s->mtx); + if (old) { + nng_tls_config_fini(old); + } + return (0); +} +#endif + static int http_server_sys_init(void) { |
