aboutsummaryrefslogtreecommitdiff
path: root/src/supplemental/http/http_client.c
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/http_client.c
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/http_client.c')
-rw-r--r--src/supplemental/http/http_client.c181
1 files changed, 62 insertions, 119 deletions
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