From f41cd6a9edf4b9a680194b3fb4378f39d1ed1f34 Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Thu, 9 Oct 2025 07:54:52 -0700 Subject: fixes #1868 Add nng_http_[remote,local]_address APIs. --- src/supplemental/http/http_api.h | 3 ++ src/supplemental/http/http_conn.c | 10 ++++ src/supplemental/http/http_public.c | 12 +++++ src/supplemental/http/http_server_test.c | 82 ++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+) (limited to 'src') 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 @@ -306,6 +306,18 @@ nng_http_read_response(nng_http *conn, nng_aio *aio) #endif } +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 #include #include +#ifndef _WIN32 +#include // for endianness functions +#endif #include "../../testing/nuts.h" @@ -134,6 +137,56 @@ httpecho(nng_http *conn, void *arg, nng_aio *aio) nng_aio_finish(aio, 0); } +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) { @@ -662,6 +715,34 @@ test_server_post_handler(void) server_free(&st); } +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) { @@ -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 }, -- cgit v1.2.3-70-g09d2