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 | |
| 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')
| -rw-r--r-- | src/supplemental/http/http_api.h | 18 | ||||
| -rw-r--r-- | src/supplemental/http/http_client.c | 181 | ||||
| -rw-r--r-- | src/supplemental/http/http_conn.c | 125 | ||||
| -rw-r--r-- | src/supplemental/http/http_server.c | 192 |
4 files changed, 170 insertions, 346 deletions
diff --git a/src/supplemental/http/http_api.h b/src/supplemental/http/http_api.h index 569e8532..45738318 100644 --- a/src/supplemental/http/http_api.h +++ b/src/supplemental/http/http_api.h @@ -1,7 +1,7 @@ // -// 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 Devolutions <info@devolutions.net> +// 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 @@ -96,9 +96,7 @@ extern void *nni_http_conn_get_ctx(nni_http_conn *); // These initialization functions create stream for HTTP transactions. // They should only be used by the server or client HTTP implementations, // and are not for use by other code. -extern int nni_http_conn_init_tcp(nni_http_conn **, nni_tcp_conn *); -extern int nni_http_conn_init_tls( - nni_http_conn **, struct nng_tls_config *, nni_tcp_conn *); +extern int nni_http_conn_init(nni_http_conn **, nng_stream *); extern void nni_http_conn_close(nni_http_conn *); extern void nni_http_conn_fini(nni_http_conn *); @@ -207,6 +205,11 @@ extern int nni_http_server_set_tls(nni_http_server *, struct nng_tls_config *); extern int nni_http_server_get_tls( nni_http_server *, struct nng_tls_config **); +extern int nni_http_server_setx( + nni_http_server *, const char *, const void *, size_t, nni_type); +extern int nni_http_server_getx( + nni_http_server *, const char *, void *, size_t *, nni_type); + // nni_http_server_start starts listening on the supplied port. extern int nni_http_server_start(nni_http_server *); @@ -350,6 +353,11 @@ extern int nni_http_client_set_tls(nni_http_client *, struct nng_tls_config *); extern int nni_http_client_get_tls( nni_http_client *, struct nng_tls_config **); +extern int nni_http_client_setx( + nni_http_client *, const char *, const void *, size_t, nni_type); +extern int nni_http_client_getx( + nni_http_client *, const char *, void *, size_t *, nni_type); + extern void nni_http_client_connect(nni_http_client *, nni_aio *); // nni_http_transact_conn is used to perform a round-trip exchange (i.e. a diff --git a/src/supplemental/http/http_client.c b/src/supplemental/http/http_client.c index 798cbe14..c35dcaa8 100644 --- a/src/supplemental/http/http_client.c +++ b/src/supplemental/http/http_client.c @@ -1,6 +1,7 @@ // -// 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 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 @@ -14,25 +15,20 @@ #include <string.h> #include "core/nng_impl.h" -#include "nng/supplemental/tls/tls.h" #include "supplemental/tls/tls_api.h" +#include <nng/supplemental/tls/tls.h> + #include "http_api.h" static nni_mtx http_txn_lk; struct nng_http_client { - nni_list aios; - nni_mtx mtx; - bool closed; - bool resolving; - nng_tls_config *tls; - nni_aio * aio; - nng_sockaddr sa; - nni_tcp_dialer *dialer; - char * host; - char * port; - nni_url * url; + nni_list aios; + nni_mtx mtx; + bool closed; + nni_aio * aio; + nng_stream_dialer *dialer; }; static void @@ -43,9 +39,7 @@ http_dial_start(nni_http_client *c) if ((aio = nni_list_first(&c->aios)) == NULL) { return; } - c->resolving = true; - nni_aio_set_input(c->aio, 0, &c->sa); - nni_tcp_resolv(c->host, c->port, NNG_AF_UNSPEC, 0, c->aio); + nng_stream_dialer_dial(c->dialer, c->aio); } static void @@ -54,7 +48,7 @@ http_dial_cb(void *arg) nni_http_client *c = arg; nni_aio * aio; int rv; - nni_tcp_conn * tcp; + nng_stream * stream; nni_http_conn * conn; nni_mtx_lock(&c->mtx); @@ -63,9 +57,9 @@ http_dial_cb(void *arg) if ((aio = nni_list_first(&c->aios)) == NULL) { // User abandoned request, and no residuals left. nni_mtx_unlock(&c->mtx); - if ((rv == 0) && !c->resolving) { - tcp = nni_aio_get_output(c->aio, 0); - nni_tcp_conn_fini(tcp); + if (rv == 0) { + stream = nni_aio_get_output(c->aio, 0); + nng_stream_free(stream); } return; } @@ -78,28 +72,16 @@ http_dial_cb(void *arg) return; } - if (c->resolving) { - // This was a DNS lookup -- advance to normal TCP connect. - c->resolving = false; - nni_tcp_dialer_dial(c->dialer, &c->sa, c->aio); - nni_mtx_unlock(&c->mtx); - return; - } - nni_aio_list_remove(aio); - tcp = nni_aio_get_output(c->aio, 0); - NNI_ASSERT(tcp != NULL); + stream = nni_aio_get_output(c->aio, 0); + NNI_ASSERT(stream != NULL); - if (c->tls != NULL) { - rv = nni_http_conn_init_tls(&conn, c->tls, tcp); - } else { - rv = nni_http_conn_init_tcp(&conn, tcp); - } + rv = nni_http_conn_init(&conn, stream); http_dial_start(c); nni_mtx_unlock(&c->mtx); if (rv != 0) { - // the conn_init function will have already discard tcp. + // the conn_init function will have already discard stream. nni_aio_finish_error(aio, rv); return; } @@ -112,16 +94,8 @@ void nni_http_client_fini(nni_http_client *c) { nni_aio_fini(c->aio); - nni_tcp_dialer_fini(c->dialer); + nng_stream_dialer_free(c->dialer); nni_mtx_fini(&c->mtx); -#ifdef NNG_SUPP_TLS - if (c->tls != NULL) { - nni_tls_config_fini(c->tls); - } -#endif - nni_strfree(c->host); - nni_strfree(c->port); - NNI_FREE_STRUCT(c); } @@ -130,59 +104,37 @@ nni_http_client_init(nni_http_client **cp, const nni_url *url) { int rv; nni_http_client *c; + 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 (strlen(url->u_hostname) == 0) { // We require a valid hostname. return (NNG_EADDRINVAL); } - 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)) { - return (NNG_EADDRINVAL); - } if ((c = NNI_ALLOC_STRUCT(c)) == NULL) { return (NNG_ENOMEM); } nni_mtx_init(&c->mtx); nni_aio_list_init(&c->aios); - if (((c->host = nni_strdup(url->u_hostname)) == NULL) || - ((strlen(url->u_port) != 0) && - ((c->port = nni_strdup(url->u_port)) == NULL))) { - nni_http_client_fini(c); - 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(&c->tls, NNG_TLS_MODE_CLIENT); - if (rv != 0) { - nni_http_client_fini(c); - return (rv); - } - // Take the server name right from the client URL. We only - // consider the name, as the port is never part of the - // certificate. - rv = nng_tls_config_server_name(c->tls, url->u_hostname); - if (rv != 0) { - nni_http_client_fini(c); - return (rv); - } - // Note that the application has to supply the location of - // certificates. We could probably use a default based - // on environment or common locations used by OpenSSL, but - // as there is no way to *unload* the cert file, lets not - // do that. (We might want to consider a mode to reset.) + if ((rv = nng_stream_dialer_alloc_url(&c->dialer, &myurl)) != 0) { + nni_http_client_fini(c); + return (rv); } -#endif - if (((rv = nni_tcp_dialer_init(&c->dialer)) != 0) || - ((rv = nni_aio_init(&c->aio, http_dial_cb, c)) != 0)) { + if ((rv = nni_aio_init(&c->aio, http_dial_cb, c)) != 0) { nni_http_client_fini(c); return (rv); } @@ -192,46 +144,37 @@ nni_http_client_init(nni_http_client **cp, const nni_url *url) } int -nni_http_client_set_tls(nni_http_client *c, struct nng_tls_config *tls) +nni_http_client_set_tls(nni_http_client *c, nng_tls_config *tls) { -#ifdef NNG_SUPP_TLS - struct nng_tls_config *old; - nni_mtx_lock(&c->mtx); - old = c->tls; - c->tls = tls; - if (tls != NULL) { - nni_tls_config_hold(tls); - } - nni_mtx_unlock(&c->mtx); - if (old != NULL) { - nni_tls_config_fini(old); - } - return (0); -#else - NNI_ARG_UNUSED(c); - NNI_ARG_UNUSED(tls); - return (NNG_EINVAL); -#endif + int rv; + rv = nni_stream_dialer_setx(c->dialer, NNG_OPT_TLS_CONFIG, &tls, + sizeof(tls), NNI_TYPE_POINTER); + return (rv); } int -nni_http_client_get_tls(nni_http_client *c, struct nng_tls_config **tlsp) +nni_http_client_get_tls(nni_http_client *c, nng_tls_config **tlsp) { -#ifdef NNG_SUPP_TLS - nni_mtx_lock(&c->mtx); - if (c->tls == NULL) { - nni_mtx_unlock(&c->mtx); - return (NNG_EINVAL); - } - nni_tls_config_hold(c->tls); - *tlsp = c->tls; - nni_mtx_unlock(&c->mtx); - return (0); -#else - NNI_ARG_UNUSED(c); - NNI_ARG_UNUSED(tlsp); - return (NNG_ENOTSUP); -#endif + size_t sz = sizeof(*tlsp); + int rv; + rv = nni_stream_dialer_getx( + c->dialer, NNG_OPT_TLS_CONFIG, tlsp, &sz, NNI_TYPE_POINTER); + return (rv); +} + +int +nni_http_client_setx(nni_http_client *c, 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_dialer_setx(c->dialer, name, buf, sz, t)); +} + +int +nni_http_client_getx( + nni_http_client *c, const char *name, void *buf, size_t *szp, nni_type t) +{ + return (nni_stream_dialer_getx(c->dialer, name, buf, szp, t)); } static void diff --git a/src/supplemental/http/http_conn.c b/src/supplemental/http/http_conn.c index 7c6159cd..1fc2c34e 100644 --- a/src/supplemental/http/http_conn.c +++ b/src/supplemental/http/http_conn.c @@ -1,7 +1,7 @@ // -// 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 Devolutions <info@devolutions.net> +// 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 @@ -40,25 +40,6 @@ enum write_flavor { HTTP_WR_RES, }; -typedef void (*http_read_fn)(void *, nni_aio *); -typedef void (*http_write_fn)(void *, nni_aio *); -typedef void (*http_close_fn)(void *); -typedef void (*http_fini_fn)(void *); -typedef int (*http_addr_fn)(void *, nni_sockaddr *); -typedef int (*http_getopt_fn)( - void *, const char *, void *, size_t *, nni_type); -typedef int (*http_setopt_fn)( - void *, const char *, const void *, size_t, nni_type); - -typedef struct { - http_read_fn h_read; - http_write_fn h_write; - http_getopt_fn h_getopt; - http_setopt_fn h_setopt; - http_close_fn h_close; - http_fini_fn h_fini; -} http_tran; - #define SET_RD_FLAVOR(aio, f) \ nni_aio_set_prov_extra(aio, 0, ((void *) (intptr_t)(f))) #define GET_RD_FLAVOR(aio) (int) ((intptr_t) nni_aio_get_prov_extra(aio, 0)) @@ -67,17 +48,11 @@ typedef struct { #define GET_WR_FLAVOR(aio) (int) ((intptr_t) nni_aio_get_prov_extra(aio, 0)) struct nng_http_conn { - void * sock; - http_read_fn rd; - http_write_fn wr; - http_setopt_fn setopt; - http_getopt_fn getopt; - http_close_fn close; - http_fini_fn fini; - void * ctx; - bool closed; - nni_list rdq; // high level http read requests - nni_list wrq; // high level http write requests + nng_stream *sock; + void * ctx; + bool closed; + nni_list rdq; // high level http read requests + nni_list wrq; // high level http write requests nni_aio *rd_uaio; // user aio for read nni_aio *wr_uaio; // user aio for write @@ -138,7 +113,7 @@ http_close(nni_http_conn *conn) } if (conn->sock != NULL) { - conn->close(conn->sock); + nng_stream_close(conn->sock); } } @@ -204,7 +179,7 @@ http_rd_buf(nni_http_conn *conn, nni_aio *aio) // to get *any* data for a partial RAW read.) nni_aio_set_data(conn->rd_aio, 1, NULL); nni_aio_set_iov(conn->rd_aio, niov, iov); - conn->rd(conn->sock, conn->rd_aio); + nng_stream_recv(conn->sock, conn->rd_aio); return (NNG_EAGAIN); case HTTP_RD_REQ: @@ -220,7 +195,7 @@ http_rd_buf(nni_http_conn *conn, nni_aio *aio) iov1.iov_len = conn->rd_bufsz - conn->rd_put; nni_aio_set_iov(conn->rd_aio, 1, &iov1); nni_aio_set_data(conn->rd_aio, 1, aio); - conn->rd(conn->sock, conn->rd_aio); + nng_stream_recv(conn->sock, conn->rd_aio); } return (rv); @@ -237,7 +212,7 @@ http_rd_buf(nni_http_conn *conn, nni_aio *aio) iov1.iov_len = conn->rd_bufsz - conn->rd_put; nni_aio_set_iov(conn->rd_aio, 1, &iov1); nni_aio_set_data(conn->rd_aio, 1, aio); - conn->rd(conn->sock, conn->rd_aio); + nng_stream_recv(conn->sock, conn->rd_aio); } return (rv); @@ -254,7 +229,7 @@ http_rd_buf(nni_http_conn *conn, nni_aio *aio) iov1.iov_len = conn->rd_bufsz - conn->rd_put; nni_aio_set_iov(conn->rd_aio, 1, &iov1); nni_aio_set_data(conn->rd_aio, 1, aio); - conn->rd(conn->sock, conn->rd_aio); + nng_stream_recv(conn->sock, conn->rd_aio); } return (rv); } @@ -428,7 +403,7 @@ http_wr_start(nni_http_conn *conn) nni_aio_get_iov(aio, &niov, &iov); nni_aio_set_iov(conn->wr_aio, niov, iov); - conn->wr(conn->sock, conn->wr_aio); + nng_stream_send(conn->sock, conn->wr_aio); } static void @@ -475,7 +450,7 @@ http_wr_cb(void *arg) if (nni_aio_iov_count(aio) > 0) { // We have more to transmit - start another and leave // (we will get called again when it is done). - conn->wr(conn->sock, aio); + nng_stream_send(conn->sock, aio); nni_mtx_unlock(&conn->mtx); return; } @@ -680,7 +655,7 @@ nni_http_conn_getopt( if (conn->closed) { rv = NNG_ECLOSED; } else { - rv = conn->getopt(conn->sock, name, buf, szp, t); + rv = nni_stream_getx(conn->sock, name, buf, szp, t); } nni_mtx_unlock(&conn->mtx); return (rv); @@ -695,7 +670,7 @@ nni_http_conn_setopt(nni_http_conn *conn, const char *name, const void *buf, if (conn->closed) { rv = NNG_ECLOSED; } else { - rv = conn->setopt(conn->sock, name, buf, sz, t); + rv = nni_stream_setx(conn->sock, name, buf, sz, t); } nni_mtx_unlock(&conn->mtx); return (rv); @@ -709,8 +684,8 @@ nni_http_conn_fini(nni_http_conn *conn) nni_mtx_lock(&conn->mtx); http_close(conn); - if ((conn->sock != NULL) && (conn->fini != NULL)) { - conn->fini(conn->sock); + if (conn->sock != NULL) { + nng_stream_free(conn->sock); conn->sock = NULL; } nni_mtx_unlock(&conn->mtx); @@ -723,7 +698,7 @@ nni_http_conn_fini(nni_http_conn *conn) } static int -http_init(nni_http_conn **connp, http_tran *tran, void *data) +http_init(nni_http_conn **connp, nng_stream *data) { nni_http_conn *conn; int rv; @@ -747,73 +722,19 @@ http_init(nni_http_conn **connp, http_tran *tran, void *data) return (rv); } - conn->sock = data; - conn->rd = tran->h_read; - conn->wr = tran->h_write; - conn->close = tran->h_close; - conn->fini = tran->h_fini; - conn->getopt = tran->h_getopt; - conn->setopt = tran->h_setopt; + conn->sock = data; *connp = conn; return (0); } -static http_tran http_tcp_ops = { - .h_read = (http_read_fn) nni_tcp_conn_recv, - .h_write = (http_write_fn) nni_tcp_conn_send, - .h_close = (http_close_fn) nni_tcp_conn_close, - .h_fini = (http_fini_fn) nni_tcp_conn_fini, - .h_getopt = (http_getopt_fn) nni_tcp_conn_getopt, - .h_setopt = (http_setopt_fn) nni_tcp_conn_setopt, -}; - int -nni_http_conn_init_tcp(nni_http_conn **connp, nni_tcp_conn *tcp) +nni_http_conn_init(nni_http_conn **connp, nng_stream *stream) { int rv; - if ((rv = http_init(connp, &http_tcp_ops, tcp)) != 0) { - nni_tcp_conn_fini(tcp); - } - return (rv); -} - -#ifdef NNG_SUPP_TLS -static http_tran http_tls_ops = { - .h_read = (http_read_fn) nni_tls_recv, - .h_write = (http_write_fn) nni_tls_send, - .h_close = (http_close_fn) nni_tls_close, - .h_fini = (http_fini_fn) nni_tls_fini, - .h_getopt = (http_getopt_fn) nni_tls_getopt, - .h_setopt = (http_setopt_fn) nni_tls_setopt, -}; - -int -nni_http_conn_init_tls( - nni_http_conn **connp, struct nng_tls_config *cfg, nni_tcp_conn *tcp) -{ - nni_tls *tls; - int rv; - - if ((rv = nni_tls_init(&tls, cfg, tcp)) != 0) { - nni_tcp_conn_fini(tcp); - return (rv); - } - - if ((rv = http_init(connp, &http_tls_ops, tls)) != 0) { - nni_tls_fini(tls); + if ((rv = http_init(connp, stream)) != 0) { + nng_stream_free(stream); } return (rv); } -#else -int -nni_http_conn_init_tls( - nni_http_conn **connp, struct nng_tls_config *cfg, nni_tcp_conn *tcp) -{ - NNI_ARG_UNUSED(connp); - NNI_ARG_UNUSED(cfg); - nni_tcp_conn_fini(tcp); - return (NNG_ENOTSUP); -} -#endif // NNG_SUPP_TLS 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 |
