aboutsummaryrefslogtreecommitdiff
path: root/src/supplemental/http
diff options
context:
space:
mode:
Diffstat (limited to 'src/supplemental/http')
-rw-r--r--src/supplemental/http/http_api.h3
-rw-r--r--src/supplemental/http/http_conn.c10
-rw-r--r--src/supplemental/http/http_public.c12
-rw-r--r--src/supplemental/http/http_server_test.c82
4 files changed, 107 insertions, 0 deletions
diff --git a/src/supplemental/http/http_api.h b/src/supplemental/http/http_api.h
index 6acc1ba5..74472f50 100644
--- a/src/supplemental/http/http_api.h
+++ b/src/supplemental/http/http_api.h
@@ -72,6 +72,9 @@ extern void nni_http_read_chunks(
extern nni_http_req *nni_http_conn_req(nni_http_conn *);
extern nni_http_res *nni_http_conn_res(nni_http_conn *);
+extern nng_err nni_http_get_addr(
+ nni_http_conn *, const char *, nng_sockaddr *);
+
// Private to the server. (Used to support session hijacking.)
extern void nni_http_conn_set_ctx(nni_http_conn *, void *);
extern void *nni_http_conn_get_ctx(nni_http_conn *);
diff --git a/src/supplemental/http/http_conn.c b/src/supplemental/http/http_conn.c
index 6f2ecef6..ac549649 100644
--- a/src/supplemental/http/http_conn.c
+++ b/src/supplemental/http/http_conn.c
@@ -159,6 +159,16 @@ nni_http_conn_close(nni_http_conn *conn)
nni_mtx_unlock(&conn->mtx);
}
+nng_err
+nni_http_get_addr(nni_http_conn *conn, const char *opt, nng_sockaddr *addrp)
+{
+ nng_err rv;
+ nni_mtx_lock(&conn->mtx);
+ rv = nng_stream_get_addr(conn->sock, opt, addrp);
+ nni_mtx_unlock(&conn->mtx);
+ return (rv);
+}
+
// http_buf_pull_up pulls the content of the read buffer back to the
// beginning, so that the next read can go at the end. This avoids the problem
// of dealing with a read that might wrap.
diff --git a/src/supplemental/http/http_public.c b/src/supplemental/http/http_public.c
index e63c5f96..8c225e5e 100644
--- a/src/supplemental/http/http_public.c
+++ b/src/supplemental/http/http_public.c
@@ -307,6 +307,18 @@ nng_http_read_response(nng_http *conn, nng_aio *aio)
}
nng_err
+nng_http_remote_address(nng_http *conn, nng_sockaddr *addrp)
+{
+ return (nni_http_get_addr(conn, NNG_OPT_REMADDR, addrp));
+}
+
+nng_err
+nng_http_local_address(nng_http *conn, nng_sockaddr *addrp)
+{
+ return (nni_http_get_addr(conn, NNG_OPT_LOCADDR, addrp));
+}
+
+nng_err
nng_http_handler_alloc(
nng_http_handler **hp, const char *uri, nng_http_handler_func cb)
{
diff --git a/src/supplemental/http/http_server_test.c b/src/supplemental/http/http_server_test.c
index ed63e136..d299cb97 100644
--- a/src/supplemental/http/http_server_test.c
+++ b/src/supplemental/http/http_server_test.c
@@ -14,6 +14,9 @@
#include <complex.h>
#include <nng/http.h>
#include <nng/nng.h>
+#ifndef _WIN32
+#include <arpa/inet.h> // for endianness functions
+#endif
#include "../../testing/nuts.h"
@@ -135,6 +138,56 @@ httpecho(nng_http *conn, void *arg, nng_aio *aio)
}
static void
+httpaddrcheck(nng_http *conn, void *arg, nng_aio *aio)
+{
+ nng_err rv;
+ void *body;
+ size_t len;
+ nng_sockaddr loc;
+ nng_sockaddr rem;
+
+ NNI_ARG_UNUSED(arg);
+
+ if (((rv = nng_http_local_address(conn, &loc)) != NNG_OK) ||
+ ((rv = nng_http_remote_address(conn, &rem)) != NNG_OK)) {
+ nng_aio_finish(aio, rv);
+ return;
+ }
+ if ((loc.s_family != NNG_AF_INET) || (rem.s_family != NNG_AF_INET)) {
+ nng_http_set_status(conn, NNG_HTTP_STATUS_BAD_REQUEST,
+ "Adddresses were not INET");
+ nng_aio_finish(aio, 0);
+ return;
+ }
+ if ((loc.s_in.sa_addr != htonl(0x7F000001)) ||
+ (rem.s_in.sa_addr != htonl(0x7F000001))) {
+ nng_http_set_status(conn, NNG_HTTP_STATUS_BAD_REQUEST,
+ "Adddresses were not localhost");
+ nng_aio_finish(aio, 0);
+ return;
+ }
+ if ((loc.s_in.sa_port == 0) || (rem.s_in.sa_port == 0) ||
+ (loc.s_in.sa_port == rem.s_in.sa_port)) {
+ nng_http_set_status(
+ conn, NNG_HTTP_STATUS_BAD_REQUEST, "Port checks failed");
+ nng_aio_finish(aio, 0);
+ return;
+ }
+
+ nng_http_get_body(conn, &body, &len);
+
+ if (((rv = nng_http_copy_body(conn, body, len)) != 0) ||
+ ((rv = nng_http_set_header(conn, "Content-type", "text/plain")) !=
+ 0)) {
+ nng_aio_finish(aio, rv);
+ return;
+ }
+
+ nng_http_set_status(conn, NNG_HTTP_STATUS_OK, NULL);
+ nng_aio_finish(aio, 0);
+}
+
+static void
server_setup(struct server_test *st, nng_http_handler *h)
{
nng_sockaddr sa;
@@ -663,6 +716,34 @@ test_server_post_handler(void)
}
static void
+test_server_addrs_handler(void)
+{
+ struct server_test st;
+ nng_http_handler *h;
+ char txdata[5];
+ char *rxdata;
+ size_t size;
+
+ NUTS_PASS(nng_http_handler_alloc(&h, "/addrs", httpaddrcheck));
+ nng_http_handler_set_method(h, "POST");
+
+ server_setup(&st, h);
+
+ snprintf(txdata, sizeof(txdata), "1234");
+
+ NUTS_PASS(nng_http_set_uri(st.conn, "/addrs", NULL));
+ nng_http_set_body(st.conn, txdata, strlen(txdata));
+ nng_http_set_method(st.conn, "POST");
+ NUTS_PASS(httpdo(&st, (void **) &rxdata, &size));
+ NUTS_HTTP_STATUS(st.conn, NNG_HTTP_STATUS_OK);
+ NUTS_TRUE(size == strlen(txdata));
+ NUTS_TRUE(strncmp(txdata, rxdata, size) == 0);
+ nng_free(rxdata, size);
+
+ server_free(&st);
+}
+
+static void
test_server_get_redirect(void)
{
const char *dest;
@@ -1170,6 +1251,7 @@ NUTS_TESTS = {
{ "server tree redirect", test_server_tree_redirect },
{ "server post redirect", test_server_post_redirect },
{ "server post echo tree", test_server_post_echo_tree },
+ { "server address checks", test_server_addrs_handler },
{ "server error page", test_server_error_page },
{ "server multiple trees", test_server_multiple_trees },
{ "server serve directory", test_serve_directory },