aboutsummaryrefslogtreecommitdiff
path: root/src/supplemental
diff options
context:
space:
mode:
Diffstat (limited to 'src/supplemental')
-rw-r--r--src/supplemental/http/http_server.c35
-rw-r--r--src/supplemental/websocket/websocket.c46
-rw-r--r--src/supplemental/websocket/websocket.h6
3 files changed, 56 insertions, 31 deletions
diff --git a/src/supplemental/http/http_server.c b/src/supplemental/http/http_server.c
index c7738aee..5c6d1dcc 100644
--- a/src/supplemental/http/http_server.c
+++ b/src/supplemental/http/http_server.c
@@ -30,7 +30,7 @@ static nni_initializer http_server_initializer = {
struct nng_http_handler {
nni_list_node node;
- char * path;
+ char * uri;
char * method;
char * host;
bool tree;
@@ -75,14 +75,18 @@ struct nng_http_server {
int
nni_http_handler_init(
- nni_http_handler **hp, const char *path, void (*cb)(nni_aio *))
+ nni_http_handler **hp, const char *uri, void (*cb)(nni_aio *))
{
nni_http_handler *h;
if ((h = NNI_ALLOC_STRUCT(h)) == NULL) {
return (NNG_ENOMEM);
}
- if (((h->path = nni_strdup(path)) == NULL) ||
+ // Default for HTTP is /.
+ if ((uri == NULL) || (strlen(uri) == 0)) {
+ uri = "/";
+ }
+ if (((h->uri = nni_strdup(uri)) == NULL) ||
((h->method = nni_strdup("GET")) == NULL)) {
nni_http_handler_fini(h);
return (NNG_ENOMEM);
@@ -108,7 +112,7 @@ nni_http_handler_fini(nni_http_handler *h)
h->dtor(h->data);
}
nni_strfree(h->host);
- nni_strfree(h->path);
+ nni_strfree(h->uri);
nni_strfree(h->method);
NNI_FREE_STRUCT(h);
}
@@ -133,7 +137,7 @@ nni_http_handler_get_data(nni_http_handler *h)
const char *
nni_http_handler_get_uri(nni_http_handler *h)
{
- return (h->path);
+ return (h->uri);
}
int
@@ -383,8 +387,7 @@ http_uri_canonify(char *path)
}
*dst = '\0';
- // XXX: this is where we should also remove /./ and /../ references.
- return (path);
+ return ((strlen(path) != 0) ? path : "/");
}
static void
@@ -527,8 +530,8 @@ http_sconn_rxdone(void *arg)
}
}
- len = strlen(h->path);
- if (strncmp(path, h->path, len) != 0) {
+ len = strlen(h->uri);
+ if (strncmp(path, h->uri, len) != 0) {
continue;
}
switch (path[len]) {
@@ -957,11 +960,11 @@ nni_http_server_add_handler(nni_http_server *s, nni_http_handler *h)
// Must have a legal method (and not one that is HEAD), path,
// and handler. (The reason HEAD is verboten is that we supply
// it automatically as part of GET support.)
- if (((len = strlen(h->path)) == 0) || (h->path[0] != '/') ||
+ if (((len = strlen(h->uri)) == 0) || (h->uri[0] != '/') ||
(h->cb == NULL)) {
return (NNG_EINVAL);
}
- while ((len > 0) && (h->path[len - 1] == '/')) {
+ while ((len > 0) && (h->uri[len - 1] == '/')) {
len--; // ignore trailing '/' (this collapses them)
}
@@ -992,22 +995,22 @@ nni_http_server_add_handler(nni_http_server *s, nni_http_handler *h)
continue;
}
- len2 = strlen(h2->path);
+ len2 = strlen(h2->uri);
- while ((len2 > 0) && (h2->path[len2 - 1] == '/')) {
+ while ((len2 > 0) && (h2->uri[len2 - 1] == '/')) {
len2--; // ignore trailing '/'
}
- if (strncmp(h->path, h2->path, len > len2 ? len2 : len) != 0) {
+ if (strncmp(h->uri, h2->uri, len > len2 ? len2 : len) != 0) {
continue; // prefixes don't match.
}
if (len2 > len) {
- if ((h2->path[len] == '/') && (h->tree)) {
+ if ((h2->uri[len] == '/') && (h->tree)) {
nni_mtx_unlock(&s->mtx);
return (NNG_EADDRINUSE);
}
} else if (len > len2) {
- if ((h->path[len2] == '/') && (h2->tree)) {
+ if ((h->uri[len2] == '/') && (h2->tree)) {
nni_mtx_unlock(&s->mtx);
return (NNG_EADDRINUSE);
}
diff --git a/src/supplemental/websocket/websocket.c b/src/supplemental/websocket/websocket.c
index 6d4d3c13..18491190 100644
--- a/src/supplemental/websocket/websocket.c
+++ b/src/supplemental/websocket/websocket.c
@@ -75,6 +75,7 @@ struct nni_ws_listener {
nni_ws_listen_hook hookfn;
void * hookarg;
nni_list headers; // response headers
+ size_t maxframe;
};
// The dialer tracks user aios in two lists. The first list is for aios
@@ -94,6 +95,7 @@ struct nni_ws_dialer {
bool closed;
nng_sockaddr sa;
nni_list headers; // request headers
+ size_t maxframe;
};
typedef enum ws_type {
@@ -945,7 +947,7 @@ ws_read_cb(void *arg)
break;
}
- if (frame->len > ws->maxframe) {
+ if ((frame->len > ws->maxframe) && (ws->maxframe > 0)) {
ws_close(ws, WS_CLOSE_TOO_BIG);
nni_mtx_unlock(&ws->mtx);
return;
@@ -1380,7 +1382,6 @@ ws_init(nni_ws **wsp)
nni_aio_set_timeout(ws->httpaio, 2000);
ws->fragsize = 1 << 20; // we won't send a frame larger than this
- ws->maxframe = (1 << 20) * 10; // default limit on incoming frame size
*wsp = ws;
return (0);
}
@@ -1557,12 +1558,13 @@ ws_handler(nni_aio *aio)
status = NNG_HTTP_STATUS_INTERNAL_SERVER_ERROR;
goto err;
}
- ws->http = conn;
- ws->req = req;
- ws->res = res;
- ws->mode = NNI_EP_MODE_LISTEN;
+ ws->http = conn;
+ ws->req = req;
+ ws->res = res;
+ ws->mode = NNI_EP_MODE_LISTEN;
+ ws->maxframe = l->maxframe;
- // XXX: Inherit fragmentation and message size limits!
+ // XXX: Inherit fragmentation? (Frag is limited for now).
nni_list_append(&l->reply, ws);
nni_aio_set_data(ws->httpaio, 0, l);
@@ -1621,7 +1623,8 @@ nni_ws_listener_init(nni_ws_listener **wslp, nni_url *url)
return (rv);
}
- *wslp = l;
+ l->maxframe = 0;
+ *wslp = l;
return (0);
}
@@ -1785,6 +1788,14 @@ nni_ws_listener_get_tls(nni_ws_listener *l, nng_tls_config **tlsp)
}
void
+nni_ws_listener_set_maxframe(nni_ws_listener *l, size_t maxframe)
+{
+ nni_mtx_lock(&l->mtx);
+ l->maxframe = maxframe;
+ nni_mtx_unlock(&l->mtx);
+}
+
+void
ws_conn_cb(void *arg)
{
nni_ws_dialer *d;
@@ -1920,8 +1931,8 @@ nni_ws_dialer_init(nni_ws_dialer **dp, nni_url *url)
nni_ws_dialer_fini(d);
return (rv);
}
-
- *dp = d;
+ d->maxframe = 0;
+ *dp = d;
return (0);
}
@@ -2021,9 +2032,10 @@ nni_ws_dialer_dial(nni_ws_dialer *d, nni_aio *aio)
ws_fini(ws);
return;
}
- ws->dialer = d;
- ws->useraio = aio;
- ws->mode = NNI_EP_MODE_DIAL;
+ ws->dialer = d;
+ ws->useraio = aio;
+ ws->mode = NNI_EP_MODE_DIAL;
+ ws->maxframe = d->maxframe;
nni_list_append(&d->wspend, ws);
nni_http_client_connect(d->client, ws->connaio);
nni_mtx_unlock(&d->mtx);
@@ -2071,6 +2083,14 @@ nni_ws_dialer_header(nni_ws_dialer *d, const char *n, const char *v)
return (rv);
}
+void
+nni_ws_dialer_set_maxframe(nni_ws_dialer *d, size_t maxframe)
+{
+ nni_mtx_lock(&d->mtx);
+ d->maxframe = maxframe;
+ nni_mtx_unlock(&d->mtx);
+}
+
// Dialer does not get a hook chance, as it can examine the request
// and reply after dial is done; this is not a 3-way handshake, so
// the dialer does not confirm the server's response at the HTTP
diff --git a/src/supplemental/websocket/websocket.h b/src/supplemental/websocket/websocket.h
index 546f41a9..9936b10f 100644
--- a/src/supplemental/websocket/websocket.h
+++ b/src/supplemental/websocket/websocket.h
@@ -33,14 +33,16 @@ extern int nni_ws_listener_listen(nni_ws_listener *);
extern void nni_ws_listener_accept(nni_ws_listener *, nng_aio *);
extern void nni_ws_listener_hook(
nni_ws_listener *, nni_ws_listen_hook, void *);
-extern int nni_ws_listener_set_tls(nni_ws_listener *, nng_tls_config *);
-extern int nni_ws_listener_get_tls(nni_ws_listener *, nng_tls_config **s);
+extern int nni_ws_listener_set_tls(nni_ws_listener *, nng_tls_config *);
+extern int nni_ws_listener_get_tls(nni_ws_listener *, nng_tls_config **s);
+extern void nni_ws_listener_set_maxframe(nni_ws_listener *, size_t);
extern int nni_ws_dialer_init(nni_ws_dialer **, nni_url *);
extern void nni_ws_dialer_fini(nni_ws_dialer *);
extern void nni_ws_dialer_close(nni_ws_dialer *);
extern int nni_ws_dialer_proto(nni_ws_dialer *, const char *);
extern int nni_ws_dialer_header(nni_ws_dialer *, const char *, const char *);
+extern void nni_ws_dialer_set_maxframe(nni_ws_dialer *, size_t);
extern void nni_ws_dialer_dial(nni_ws_dialer *, nng_aio *);
extern int nni_ws_dialer_set_tls(nni_ws_dialer *, nng_tls_config *);
extern int nni_ws_dialer_get_tls(nni_ws_dialer *, nng_tls_config **);