aboutsummaryrefslogtreecommitdiff
path: root/src/supplemental/http
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2019-01-21 22:40:10 -0800
committerGarrett D'Amore <garrett@damore.org>2019-02-16 19:22:27 -0800
commit5cf750697624d4fd63cfe26921209d7c30e1a2d2 (patch)
treebf11695e5f1ec5e400c87da0cc6ff23935a2eeff /src/supplemental/http
parentca655b9db689ee0e655248b1a9f166b8db6cc984 (diff)
downloadnng-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.h18
-rw-r--r--src/supplemental/http/http_client.c181
-rw-r--r--src/supplemental/http/http_conn.c125
-rw-r--r--src/supplemental/http/http_server.c192
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