diff options
| author | Garrett D'Amore <garrett@damore.org> | 2019-01-21 22:40:10 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2019-02-16 19:22:27 -0800 |
| commit | 5cf750697624d4fd63cfe26921209d7c30e1a2d2 (patch) | |
| tree | bf11695e5f1ec5e400c87da0cc6ff23935a2eeff /src/supplemental/http/http_server.c | |
| parent | ca655b9db689ee0e655248b1a9f166b8db6cc984 (diff) | |
| download | nng-5cf750697624d4fd63cfe26921209d7c30e1a2d2.tar.gz nng-5cf750697624d4fd63cfe26921209d7c30e1a2d2.tar.bz2 nng-5cf750697624d4fd63cfe26921209d7c30e1a2d2.zip | |
fixes #872 create unified nng_stream API
This is a major change, and includes changes to use a polymorphic
stream API for all transports. There have been related bugs fixed
along the way. Additionally the man pages have changed.
The old non-polymorphic APIs are removed now. This is a breaking
change, but the old APIs were never part of any released public API.
Diffstat (limited to 'src/supplemental/http/http_server.c')
| -rw-r--r-- | src/supplemental/http/http_server.c | 192 |
1 files changed, 72 insertions, 120 deletions
diff --git a/src/supplemental/http/http_server.c b/src/supplemental/http/http_server.c index a6343d87..939273b7 100644 --- a/src/supplemental/http/http_server.c +++ b/src/supplemental/http/http_server.c @@ -1,7 +1,8 @@ // -// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> +// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech> // Copyright 2018 Capitar IT Group BV <info@capitar.com> // Copyright 2018 QXSoftware <lh563566994@126.com> +// Copyright 2019 Devolutions <info@devolutions.net> // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -68,22 +69,21 @@ typedef struct http_error { } http_error; struct nng_http_server { - nng_sockaddr addr; - nni_list_node node; - int refcnt; - int starts; - nni_list handlers; - nni_list conns; - nni_mtx mtx; - bool closed; - nng_tls_config * tls; - nni_aio * accaio; - nni_tcp_listener *listener; - char * port; - char * hostname; - nni_list errors; - nni_mtx errors_mtx; - nni_reap_item reap; + nng_sockaddr addr; + nni_list_node node; + int refcnt; + int starts; + nni_list handlers; + nni_list conns; + nni_mtx mtx; + bool closed; + nni_aio * accaio; + nng_stream_listener *listener; + char * port; + char * hostname; + nni_list errors; + nni_mtx errors_mtx; + nni_reap_item reap; }; int @@ -720,13 +720,13 @@ http_sconn_cbdone(void *arg) } static int -http_sconn_init(http_sconn **scp, nni_http_server *s, nni_tcp_conn *tcp) +http_sconn_init(http_sconn **scp, nng_stream *stream) { http_sconn *sc; int rv; if ((sc = NNI_ALLOC_STRUCT(sc)) == NULL) { - nni_tcp_conn_fini(tcp); + nng_stream_free(stream); return (NNG_ENOMEM); } @@ -741,11 +741,7 @@ http_sconn_init(http_sconn **scp, nni_http_server *s, nni_tcp_conn *tcp) return (rv); } - if (s->tls != NULL) { - rv = nni_http_conn_init_tls(&sc->conn, s->tls, tcp); - } else { - rv = nni_http_conn_init_tcp(&sc->conn, tcp); - } + rv = nni_http_conn_init(&sc->conn, stream); if (rv != 0) { http_sconn_close(sc); return (rv); @@ -760,7 +756,7 @@ http_server_acccb(void *arg) { nni_http_server *s = arg; nni_aio * aio = s->accaio; - nni_tcp_conn * tcp; + nng_stream * stream; http_sconn * sc; int rv; @@ -768,22 +764,22 @@ http_server_acccb(void *arg) if ((rv = nni_aio_result(aio)) != 0) { if (!s->closed) { // try again? - nni_tcp_listener_accept(s->listener, s->accaio); + nng_stream_listener_accept(s->listener, s->accaio); } nni_mtx_unlock(&s->mtx); return; } - tcp = nni_aio_get_output(aio, 0); + stream = nni_aio_get_output(aio, 0); if (s->closed) { // If we're closing, then reject this one. - nni_tcp_conn_fini(tcp); + nng_stream_free(stream); nni_mtx_unlock(&s->mtx); return; } - if (http_sconn_init(&sc, s, tcp) != 0) { - // The TCP structure is already cleaned up. + if (http_sconn_init(&sc, stream) != 0) { + // The stream structure is already cleaned up. // Start another accept attempt. - nni_tcp_listener_accept(s->listener, s->accaio); + nng_stream_listener_accept(s->listener, s->accaio); nni_mtx_unlock(&s->mtx); return; } @@ -792,7 +788,7 @@ http_server_acccb(void *arg) sc->handler = NULL; nni_http_read_req(sc->conn, sc->req, sc->rxaio); - nni_tcp_listener_accept(s->listener, s->accaio); + nng_stream_listener_accept(s->listener, s->accaio); nni_mtx_unlock(&s->mtx); } @@ -812,20 +808,13 @@ http_server_fini(nni_http_server *s) nni_mtx_unlock(&s->mtx); return; } - if (s->listener != NULL) { - nni_tcp_listener_fini(s->listener); - } + nng_stream_listener_free(s->listener); while ((h = nni_list_first(&s->handlers)) != NULL) { nni_list_remove(&s->handlers, h); h->refcnt--; nni_http_handler_fini(h); } nni_mtx_unlock(&s->mtx); -#ifdef NNG_SUPP_TLS - if (s->tls != NULL) { - nni_tls_config_fini(s->tls); - } -#endif nni_mtx_lock(&s->errors_mtx); while ((epage = nni_list_first(&s->errors)) != NULL) { nni_list_remove(&s->errors, epage); @@ -847,16 +836,20 @@ http_server_init(nni_http_server **serverp, const nni_url *url) { nni_http_server *s; int rv; - nni_aio * aio; - - if ((strcmp(url->u_scheme, "http") != 0) && -#ifdef NNG_SUPP_TLS - (strcmp(url->u_scheme, "https") != 0) && - (strcmp(url->u_scheme, "wss") != 0) && -#endif - (strcmp(url->u_scheme, "ws") != 0)) { + nng_url myurl; + + // Rewrite URLs to either TLS or TCP. + memcpy(&myurl, url, sizeof(myurl)); + if ((strcmp(url->u_scheme, "http") == 0) || + (strcmp(url->u_scheme, "ws") == 0)) { + myurl.u_scheme = "tcp"; + } else if ((strcmp(url->u_scheme, "https") == 0) || + (strcmp(url->u_scheme, "wss") == 0)) { + myurl.u_scheme = "tls+tcp"; + } else { return (NNG_EADDRINVAL); } + if ((s = NNI_ALLOC_STRUCT(s)) == NULL) { return (NNG_ENOMEM); } @@ -884,34 +877,11 @@ http_server_init(nni_http_server **serverp, const nni_url *url) return (NNG_ENOMEM); } -#ifdef NNG_SUPP_TLS - if ((strcmp(url->u_scheme, "https") == 0) || - (strcmp(url->u_scheme, "wss") == 0)) { - rv = nni_tls_config_init(&s->tls, NNG_TLS_MODE_SERVER); - if (rv != 0) { - http_server_fini(s); - return (rv); - } - } -#endif - - // Do the DNS lookup *now*. This means that this is - // synchronous, but it should be fast, since it should either - // resolve as a number, or resolve locally, without having to - // hit up DNS. - if ((rv = nni_aio_init(&aio, NULL, NULL)) != 0) { - http_server_fini(s); - return (rv); - } - nni_aio_set_input(aio, 0, &s->addr); - nni_tcp_resolv(s->hostname, s->port, NNG_AF_UNSPEC, true, aio); - nni_aio_wait(aio); - rv = nni_aio_result(aio); - nni_aio_fini(aio); - if (rv != 0) { + if ((rv = nng_stream_listener_alloc_url(&s->listener, &myurl)) != 0) { http_server_fini(s); return (rv); } + s->refcnt = 1; *serverp = s; return (0); @@ -950,15 +920,10 @@ static int http_server_start(nni_http_server *s) { int rv; - if ((rv = nni_tcp_listener_init(&s->listener)) != 0) { - return (rv); - } - if ((rv = nni_tcp_listener_listen(s->listener, &s->addr)) != 0) { - nni_tcp_listener_fini(s->listener); - s->listener = NULL; + if ((rv = nng_stream_listener_listen(s->listener)) != 0) { return (rv); } - nni_tcp_listener_accept(s->listener, s->accaio); + nng_stream_listener_accept(s->listener, s->accaio); return (0); } @@ -992,7 +957,7 @@ http_server_stop(nni_http_server *s) // Close the TCP endpoint that is listening. if (s->listener) { - nni_tcp_listener_close(s->listener); + nng_stream_listener_close(s->listener); } // Stopping the server is a hard stop -- it aborts any work @@ -1764,50 +1729,37 @@ nni_http_handler_init_static(nni_http_handler **hpp, const char *uri, } int -nni_http_server_set_tls(nni_http_server *s, nng_tls_config *tcfg) +nni_http_server_set_tls(nni_http_server *s, nng_tls_config *tls) { -#ifdef NNG_SUPP_TLS - 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) { - nni_tls_config_fini(old); - } - return (0); -#else - NNI_ARG_UNUSED(s); - NNI_ARG_UNUSED(tcfg); - return (NNG_ENOTSUP); -#endif + int rv; + rv = nni_stream_listener_setx(s->listener, NNG_OPT_TLS_CONFIG, &tls, + sizeof(tls), NNI_TYPE_POINTER); + return (rv); } int -nni_http_server_get_tls(nni_http_server *s, nng_tls_config **tp) +nni_http_server_get_tls(nni_http_server *s, nng_tls_config **tlsp) { -#ifdef NNG_SUPP_TLS - nni_mtx_lock(&s->mtx); - if (s->tls == NULL) { - nni_mtx_unlock(&s->mtx); - return (NNG_EINVAL); - } - nni_tls_config_hold(s->tls); - *tp = s->tls; - nni_mtx_unlock(&s->mtx); - return (0); -#else - NNI_ARG_UNUSED(s); - NNI_ARG_UNUSED(tp); - return (NNG_ENOTSUP); -#endif + size_t sz = sizeof(*tlsp); + int rv; + rv = nni_stream_listener_getx( + s->listener, NNG_OPT_TLS_CONFIG, tlsp, &sz, NNI_TYPE_POINTER); + return (rv); +} + +int +nni_http_server_setx(nni_http_server *s, const char *name, const void *buf, + size_t sz, nni_type t) +{ + // We have no local options, but we just pass them straight through. + return (nni_stream_listener_setx(s->listener, name, buf, sz, t)); +} + +int +nni_http_server_getx( + nni_http_server *s, const char *name, void *buf, size_t *szp, nni_type t) +{ + return (nni_stream_listener_getx(s->listener, name, buf, szp, t)); } void |
