aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2020-11-01 22:05:35 -0800
committerGarrett D'Amore <garrett@damore.org>2020-11-08 17:50:24 -0800
commitfc6882305f0b5e06e58a0a25740f422d133015b5 (patch)
tree714b1fa4656253c8731a8f3f0861c24715440f95 /tests
parent4bf06d03f6ebead7f4e0603a2da3b1b891887878 (diff)
downloadnng-fc6882305f0b5e06e58a0a25740f422d133015b5.tar.gz
nng-fc6882305f0b5e06e58a0a25740f422d133015b5.tar.bz2
nng-fc6882305f0b5e06e58a0a25740f422d133015b5.zip
fixes #1041 Abstract socket address for IPC
fixes #1326 Linux IPC could use fchmod fixes #1327 getsockname on ipc may not work This introduces an abstract:// style transport, which on Linux results in using the abstract socket with the given name (not including the leading NULL byte). A new NNG_AF_ABSTRACT is provided. Auto bind abstract sockets are also supported. While here we have inlined the aios for the POSIX ipc pipe objects, eliminating at least one set of failure paths, and have also performed various other cleanups. A unix:// alias is available on POSIX systems, which acts just like ipc:// (and is fact just an alias). This is supplied so that in the future we can add support for AF_UNIX on Windows. We've also absorbed the ipcperms test into the new ipc_test suite. Finally we are now enforcing that IPC path names on Windows are not over the maximum size, rather than just silently truncating them.
Diffstat (limited to 'tests')
-rw-r--r--tests/CMakeLists.txt3
-rw-r--r--tests/ipcperms.c120
-rw-r--r--tests/testutil.c14
-rw-r--r--tests/testutil.h14
-rw-r--r--tests/url.c777
5 files changed, 483 insertions, 445 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 737aa4d7..a7835826 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -132,6 +132,7 @@ nng_test(platform)
nng_test(reconnect)
nng_test(resolv)
nng_test(sock)
+nng_test(url)
add_nng_test(device 5)
@@ -141,7 +142,6 @@ add_nng_test1(httpclient 60 NNG_SUPP_HTTP)
add_nng_test1(httpserver 30 NNG_SUPP_HTTP)
add_nng_test(inproc 5)
add_nng_test(ipc 5)
-add_nng_test(ipcperms 5)
add_nng_test(ipcsupp 10)
add_nng_test(ipcwinsec 5)
add_nng_test(list 5)
@@ -161,7 +161,6 @@ add_nng_test(tcp 180)
add_nng_test(tcp6 60)
add_nng_test(transport 5)
add_nng_test(udp 5)
-add_nng_test(url 5)
add_nng_test(ws 30)
add_nng_test(wss 30)
add_nng_test1(zt 60 NNG_TRANSPORT_ZEROTIER)
diff --git a/tests/ipcperms.c b/tests/ipcperms.c
deleted file mode 100644
index 5f4a847c..00000000
--- a/tests/ipcperms.c
+++ /dev/null
@@ -1,120 +0,0 @@
-//
-// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
-// Copyright 2018 Capitar IT Group BV <info@capitar.com>
-//
-// This software is supplied under the terms of the MIT License, a
-// copy of which should be located in the distribution where this
-// file was obtained (LICENSE.txt). A copy of the license may also be
-// found online at https://opensource.org/licenses/MIT.
-//
-
-#ifndef _WIN32
-#include <errno.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/un.h>
-#include <unistd.h>
-#endif
-
-#include <nng/nng.h>
-#include <nng/protocol/reqrep0/rep.h>
-#include <nng/protocol/reqrep0/req.h>
-#include <nng/transport/ipc/ipc.h>
-
-#include "convey.h"
-#include "stubs.h"
-#include "trantest.h"
-
-#define ADDR "/tmp/ipc_perms_test"
-
-#if defined(__sun)
-#define honor_chmod() false
-#else
-#define honor_chmod() true
-#endif
-
-// Inproc tests.
-
-#ifdef _WIN32
-TestMain("IPC Permissions", {
- atexit(nng_fini);
- Convey("Given a socket and an IPC listener", {
- nng_socket s;
- nng_listener l;
-
- So(nng_rep0_open(&s) == 0);
- Reset({ nng_close(s); });
- So(nng_listener_create(&l, s, "ipc://" ADDR) == 0);
- Convey("We cannot set perms on Windows", {
- So(nng_listener_setopt_int(l, NNG_OPT_IPC_PERMISSIONS,
- 0444) == NNG_ENOTSUP);
- });
- });
-})
-#else
-TestMain("IPC Permissions", {
- atexit(nng_fini);
-
- Convey("Given a socket and an IPC listener", {
- nng_socket s;
- nng_listener l;
-
- So(nng_rep0_open(&s) == 0);
- Reset({
- nng_close(s);
- unlink(ADDR);
- });
- So(nng_listener_create(&l, s, "ipc://" ADDR) == 0);
- Convey("We can set perms on POSIX", {
- struct stat st;
- So(nng_listener_setopt_int(
- l, NNG_OPT_IPC_PERMISSIONS, 0444) == 0);
- So(nng_listener_start(l, 0) == 0);
- So(stat(ADDR, &st) == 0);
- So((st.st_mode & 0777) == 0444);
-
- Convey("And permissions are honored", {
- struct sockaddr_un sa;
- int cfd;
-
- if (geteuid() == 0) {
- Skip("Running as root");
- }
- if (!honor_chmod()) {
- Skip("System does not honor chmod");
- }
- strcpy(sa.sun_path, ADDR);
- sa.sun_family = AF_UNIX;
- So((cfd = socket(AF_UNIX, SOCK_STREAM, 0)) >=
- 0);
- Reset({ close(cfd); });
- So(connect(cfd, (void *) &sa, sizeof(sa)) < 0);
- So(errno == EACCES);
- });
- });
-
- Convey("We cannot set perms after it is started", {
- So(nng_listener_start(l, 0) == 0);
- So(nng_listener_setopt_int(
- l, NNG_OPT_IPC_PERMISSIONS, 0444) == NNG_EBUSY);
- });
-
- Convey("We cannot set bogus permissions", {
- So(nng_listener_setopt_int(l, NNG_OPT_IPC_PERMISSIONS,
- S_IFREG) == NNG_EINVAL);
- });
- });
-
- Convey("We cannot set perms on an IPC dialer", {
- nng_socket s;
- nng_dialer d;
-
- So(nng_rep0_open(&s) == 0);
- Reset({ nng_close(s); });
- So(nng_dialer_create(&d, s, "ipc://" ADDR) == 0);
- So(nng_dialer_setopt_int(d, NNG_OPT_IPC_PERMISSIONS, 0444) ==
- NNG_ENOTSUP);
- });
-})
-#endif
diff --git a/tests/testutil.c b/tests/testutil.c
index 58de1524..7068e394 100644
--- a/tests/testutil.c
+++ b/tests/testutil.c
@@ -136,7 +136,8 @@ testutil_htonl(uint32_t in)
void
testutil_scratch_addr(const char *scheme, size_t sz, char *addr)
{
- if (strcmp(scheme, "inproc") == 0) {
+ if ((strcmp(scheme, "inproc") == 0) ||
+ (strcmp(scheme, "abstract") == 0)) {
(void) snprintf(addr, sz, "%s://testutil%04x%04x%04x%04x",
scheme, nng_random(), nng_random(), nng_random(),
nng_random());
@@ -158,7 +159,8 @@ testutil_scratch_addr(const char *scheme, size_t sz, char *addr)
return;
}
- if (strncmp(scheme, "ipc", 3) == 0) {
+ if ((strncmp(scheme, "ipc", 3) == 0) ||
+ (strncmp(scheme, "unix", 4) == 0)) {
#ifdef _WIN32
// Windows doesn't place IPC names in the filesystem.
(void) snprintf(addr, sz, "%s://testutil%04x%04x%04x%04x",
@@ -476,10 +478,10 @@ stream_xfr_alloc(nng_stream *s, void (*submit)(nng_stream *, nng_aio *),
nng_aio_begin(x->upper_aio);
- x->s = s;
- x->rem = size;
- x->base = buf;
- x->submit = submit;
+ x->s = s;
+ x->rem = size;
+ x->base = buf;
+ x->submit = submit;
return (x);
}
diff --git a/tests/testutil.h b/tests/testutil.h
index 15028106..eb7ab7d1 100644
--- a/tests/testutil.h
+++ b/tests/testutil.h
@@ -63,8 +63,8 @@ extern int testutil_marry_ex(
// success, an NNG error number otherwise.)
extern void *testutil_stream_send_start(nng_stream *, void *, size_t);
extern void *testutil_stream_recv_start(nng_stream *, void *, size_t);
-extern int testutil_stream_send_wait(void *);
-extern int testutil_stream_recv_wait(void *);
+extern int testutil_stream_send_wait(void *);
+extern int testutil_stream_recv_wait(void *);
// These are TLS certificates. The client and server are signed with the
// root. The server uses CN 127.0.0.1. Other details are bogus, but
@@ -111,6 +111,16 @@ extern const char *testutil_client_crt;
strcmp(string, buf_) == 0, "%s == %s", string, buf_); \
} while (0)
+#define TEST_STREQUAL(s1, s2) \
+ do { \
+ TEST_CHECK_(strcmp(s1, s2) == 0, "%s == %s", s1, s2); \
+ } while (0)
+
+#define TEST_NULL(x) \
+ do { \
+ TEST_CHECK_((x) == NULL, "%p == NULL", x); \
+ } while (0)
+
#ifdef __cplusplus
};
#endif
diff --git a/tests/url.c b/tests/url.c
index 9b44dda4..847b7df3 100644
--- a/tests/url.c
+++ b/tests/url.c
@@ -8,325 +8,472 @@
// found online at https://opensource.org/licenses/MIT.
//
+
+#include "acutest.h"
+
#include <string.h>
#include <nng/nng.h>
-#include "convey.h"
+#include "core/url.h"
+
+#include "testutil.h"
+
+void
+test_url_host(void)
+{
+ nng_url *url;
+
+ TEST_NNG_PASS(nng_url_parse(&url, "http://www.google.com"));
+ TEST_ASSERT(url != NULL);
+ TEST_CHECK(strcmp(url->u_scheme, "http") == 0);
+ TEST_CHECK(strcmp(url->u_host, "www.google.com") == 0);
+ TEST_CHECK(strcmp(url->u_hostname, "www.google.com") == 0);
+ TEST_CHECK(strcmp(url->u_port, "80") == 0);
+ TEST_CHECK(strcmp(url->u_path, "") == 0);
+ TEST_CHECK(strcmp(url->u_requri, "") == 0);
+ TEST_CHECK(url->u_query == NULL);
+ TEST_CHECK(url->u_fragment == NULL);
+ TEST_CHECK(url->u_userinfo == NULL);
+ nng_url_free(url);
+}
+
+void
+test_url_host_port(void)
+{
+ nng_url *url;
+ TEST_NNG_PASS(nng_url_parse(&url, "http://www.google.com:1234"));
+ TEST_ASSERT(url != NULL);
+ TEST_CHECK(strcmp(url->u_scheme, "http") == 0);
+ TEST_CHECK(strcmp(url->u_host, "www.google.com:1234") == 0);
+ TEST_CHECK(strcmp(url->u_hostname, "www.google.com") == 0);
+ TEST_CHECK(strcmp(url->u_port, "1234") == 0);
+ TEST_CHECK(strcmp(url->u_path, "") == 0);
+ TEST_CHECK(strcmp(url->u_requri, "") == 0);
+ TEST_CHECK(url->u_query == NULL);
+ TEST_CHECK(url->u_fragment == NULL);
+ TEST_CHECK(url->u_userinfo == NULL);
+ nng_url_free(url);
+}
+
+void
+test_url_host_port_path(void)
+{
+ nng_url *url;
+
+ TEST_NNG_PASS(
+ nng_url_parse(&url, "http://www.google.com:1234/somewhere"));
+ TEST_ASSERT(url != NULL);
+ TEST_CHECK(strcmp(url->u_scheme, "http") == 0);
+ TEST_CHECK(strcmp(url->u_host, "www.google.com:1234") == 0);
+ TEST_CHECK(strcmp(url->u_hostname, "www.google.com") == 0);
+ TEST_CHECK(strcmp(url->u_port, "1234") == 0);
+ TEST_CHECK(strcmp(url->u_path, "/somewhere") == 0);
+ TEST_CHECK(strcmp(url->u_requri, "/somewhere") == 0);
+ TEST_CHECK(url->u_userinfo == NULL);
+ TEST_CHECK(url->u_query == NULL);
+ TEST_CHECK(url->u_fragment == NULL);
+ nng_url_free(url);
+}
+
+void
+test_url_user_info(void)
+{
+ nng_url *url;
+ TEST_NNG_PASS(nng_url_parse(
+ &url, "http://garrett@www.google.com:1234/somewhere"));
+ TEST_ASSERT(url != NULL);
+ TEST_STREQUAL(url->u_scheme, "http");
+ TEST_STREQUAL(url->u_userinfo, "garrett");
+ TEST_STREQUAL(url->u_host, "www.google.com:1234");
+ TEST_STREQUAL(url->u_hostname, "www.google.com");
+ TEST_STREQUAL(url->u_port, "1234");
+ TEST_STREQUAL(url->u_path, "/somewhere");
+ TEST_STREQUAL(url->u_requri, "/somewhere");
+ TEST_NULL(url->u_query);
+ TEST_NULL(url->u_fragment);
+ nng_url_free(url);
+}
+
+void
+test_url_path_query_param(void)
+{
+ nng_url *url;
+ TEST_NNG_PASS(
+ nng_url_parse(&url, "http://www.google.com/somewhere?result=yes"));
+ TEST_ASSERT(url != NULL);
+ TEST_STREQUAL(url->u_scheme, "http");
+ TEST_STREQUAL(url->u_host, "www.google.com");
+ TEST_STREQUAL(url->u_hostname, "www.google.com");
+ TEST_STREQUAL(url->u_port, "80");
+ TEST_STREQUAL(url->u_path, "/somewhere");
+ TEST_STREQUAL(url->u_query, "result=yes");
+ TEST_STREQUAL(url->u_requri, "/somewhere?result=yes");
+ TEST_NULL(url->u_userinfo);
+ TEST_NULL(url->u_fragment);
+ nng_url_free(url);
+}
+
+void
+test_url_query_param_anchor(void)
+{
+ nng_url *url;
+ TEST_NNG_PASS(nng_url_parse(&url,
+ "http://www.google.com/"
+ "somewhere?result=yes#chapter1"));
+ TEST_ASSERT(url != NULL);
+ TEST_STREQUAL(url->u_scheme, "http");
+ TEST_STREQUAL(url->u_host, "www.google.com");
+ TEST_STREQUAL(url->u_hostname, "www.google.com");
+ TEST_STREQUAL(url->u_port, "80");
+ TEST_STREQUAL(url->u_path, "/somewhere");
+ TEST_STREQUAL(url->u_query, "result=yes");
+ TEST_STREQUAL(url->u_fragment, "chapter1");
+ TEST_STREQUAL(url->u_requri, "/somewhere?result=yes#chapter1");
+ TEST_NULL(url->u_userinfo);
+ nng_url_free(url);
+}
+
+void
+test_url_path_anchor(void)
+{
+ nng_url *url;
+ TEST_NNG_PASS(
+ nng_url_parse(&url, "http://www.google.com/somewhere#chapter2"));
+ TEST_ASSERT(url != NULL);
+ TEST_STREQUAL(url->u_scheme, "http");
+ TEST_STREQUAL(url->u_host, "www.google.com");
+ TEST_STREQUAL(url->u_hostname, "www.google.com");
+ TEST_STREQUAL(url->u_port, "80");
+ TEST_STREQUAL(url->u_path, "/somewhere");
+ TEST_STREQUAL(url->u_fragment, "chapter2");
+ TEST_STREQUAL(url->u_requri, "/somewhere#chapter2");
+ TEST_NULL(url->u_query);
+ TEST_NULL(url->u_userinfo);
+ nng_url_free(url);
+}
+
+void
+test_url_anchor(void)
+{
+ nng_url *url;
+ TEST_NNG_PASS(nng_url_parse(&url, "http://www.google.com#chapter3"));
+ TEST_ASSERT(url != NULL);
+ TEST_STREQUAL(url->u_scheme, "http");
+ TEST_STREQUAL(url->u_host, "www.google.com");
+ TEST_STREQUAL(url->u_hostname, "www.google.com");
+ TEST_STREQUAL(url->u_path, "");
+ TEST_STREQUAL(url->u_port, "80");
+ TEST_STREQUAL(url->u_fragment, "chapter3");
+ TEST_STREQUAL(url->u_requri, "#chapter3");
+ TEST_NULL(url->u_query);
+ TEST_NULL(url->u_userinfo);
+ nng_url_free(url);
+}
+
+void
+test_url_query_param(void)
+{
+ nng_url *url;
+ TEST_NNG_PASS(nng_url_parse(&url, "http://www.google.com?color=red"));
+ TEST_ASSERT(url != NULL);
+ TEST_STREQUAL(url->u_scheme, "http");
+ TEST_STREQUAL(url->u_host, "www.google.com");
+ TEST_STREQUAL(url->u_hostname, "www.google.com");
+ TEST_STREQUAL(url->u_path, "");
+ TEST_STREQUAL(url->u_port, "80");
+ TEST_STREQUAL(url->u_query, "color=red");
+ TEST_STREQUAL(url->u_requri, "?color=red");
+ TEST_ASSERT(url != NULL);
+ TEST_NULL(url->u_userinfo);
+ nng_url_free(url);
+}
+
+void
+test_url_v6_host(void)
+{
+ nng_url *url;
+ TEST_NNG_PASS(nng_url_parse(&url, "http://[::1]"));
+ TEST_ASSERT(url != NULL);
+ TEST_STREQUAL(url->u_scheme, "http");
+ TEST_STREQUAL(url->u_host, "[::1]");
+ TEST_STREQUAL(url->u_hostname, "::1");
+ TEST_STREQUAL(url->u_path, "");
+ TEST_STREQUAL(url->u_port, "80");
+ TEST_NULL(url->u_query);
+ TEST_NULL(url->u_fragment);
+ TEST_NULL(url->u_userinfo);
+ nng_url_free(url);
+}
+
+void
+test_url_v6_host_port(void)
+{
+ nng_url *url;
+ TEST_NNG_PASS(nng_url_parse(&url, "http://[::1]:29"));
+ TEST_ASSERT(url != NULL);
+ TEST_STREQUAL(url->u_scheme, "http");
+ TEST_STREQUAL(url->u_host, "[::1]:29");
+ TEST_STREQUAL(url->u_hostname, "::1");
+ TEST_STREQUAL(url->u_path, "");
+ TEST_STREQUAL(url->u_port, "29");
+ TEST_NULL(url->u_query);
+ TEST_NULL(url->u_fragment);
+ TEST_NULL(url->u_userinfo);
+ nng_url_free(url);
+}
+
+void
+test_url_v6_host_port_path(void)
+{
+ nng_url *url;
+ TEST_NNG_PASS(nng_url_parse(&url, "http://[::1]:29/bottles"));
+ TEST_ASSERT(url != NULL);
+ TEST_STREQUAL(url->u_scheme, "http");
+ TEST_STREQUAL(url->u_host, "[::1]:29");
+ TEST_STREQUAL(url->u_hostname, "::1");
+ TEST_STREQUAL(url->u_path, "/bottles");
+ TEST_STREQUAL(url->u_port, "29");
+ TEST_NULL(url->u_query);
+ TEST_NULL(url->u_fragment);
+ TEST_NULL(url->u_userinfo);
+ nng_url_free(url);
+}
+
+void
+test_url_tcp_port(void)
+{
+ nng_url *url;
+ TEST_NNG_PASS(nng_url_parse(&url, "tcp://:9876/"));
+ TEST_ASSERT(url != NULL);
+ TEST_STREQUAL(url->u_scheme, "tcp");
+ TEST_STREQUAL(url->u_host, ":9876");
+ TEST_STREQUAL(url->u_hostname, "");
+ TEST_STREQUAL(url->u_path, "/");
+ TEST_STREQUAL(url->u_port, "9876");
+ TEST_NULL(url->u_query);
+ TEST_NULL(url->u_fragment);
+ TEST_NULL(url->u_userinfo);
+ nng_url_free(url);
+}
+
+void
+test_url_bare_ws(void)
+{
+ nng_url *url;
+
+ TEST_NNG_PASS(nng_url_parse(&url, "ws://"));
+ TEST_ASSERT(url != NULL);
+ TEST_STREQUAL(url->u_scheme, "ws");
+ TEST_STREQUAL(url->u_host, "");
+ TEST_STREQUAL(url->u_hostname, "");
+ TEST_STREQUAL(url->u_path, "");
+ TEST_STREQUAL(url->u_port, "80");
+ TEST_NULL(url->u_query);
+ TEST_NULL(url->u_fragment);
+ TEST_NULL(url->u_userinfo);
+ nng_url_free(url);
+}
+
+void
+test_url_ws_wildcard(void)
+{
+ nng_url *url;
+ TEST_NNG_PASS(nng_url_parse(&url, "ws://*:12345/foobar"));
+ TEST_ASSERT(url != NULL);
+ TEST_STREQUAL(url->u_scheme, "ws");
+ TEST_STREQUAL(url->u_host, ":12345");
+ TEST_STREQUAL(url->u_hostname, "");
+ TEST_STREQUAL(url->u_path, "/foobar");
+ TEST_STREQUAL(url->u_port, "12345");
+ TEST_NULL(url->u_query);
+ TEST_NULL(url->u_fragment);
+ TEST_NULL(url->u_userinfo);
+ nng_url_free(url);
+}
-TestMain("URLs", {
+void
+test_url_ssh(void)
+{
nng_url *url;
+ TEST_NNG_PASS(nng_url_parse(&url, "ssh://user@host.example.com"));
+ TEST_ASSERT(url != NULL);
+ TEST_STREQUAL(url->u_scheme, "ssh");
+ TEST_STREQUAL(url->u_host, "host.example.com");
+ TEST_STREQUAL(url->u_hostname, "host.example.com");
+ TEST_STREQUAL(url->u_path, "");
+ TEST_STREQUAL(url->u_port, "22");
+ TEST_NULL(url->u_query);
+ TEST_NULL(url->u_fragment);
+ TEST_STREQUAL(url->u_userinfo, "user");
+ nng_url_free(url);
+}
+
+void
+test_url_bad_scheme(void)
+{
+ nng_url *url = NULL;
+ TEST_NNG_FAIL(nng_url_parse(&url, "www.google.com"), NNG_EINVAL);
+ TEST_NULL(url);
+ TEST_NNG_FAIL(nng_url_parse(&url, "http:www.google.com"), NNG_EINVAL);
+ TEST_NULL(url);
+}
+
+void
+test_url_bad_ipv6(void)
+{
+ nng_url *url = NULL;
+ TEST_NNG_FAIL(nng_url_parse(&url, "http://[::1"), NNG_EINVAL);
+ TEST_NULL(url);
+ TEST_NNG_FAIL(nng_url_parse(&url, "http://[::1]bogus"), NNG_EINVAL);
+ TEST_NULL(url);
+}
+
+void
+test_url_canonify(void)
+{
+ nng_url *url = NULL;
+ TEST_NNG_PASS(nng_url_parse(
+ &url, "hTTp://www.EXAMPLE.com/bogus/.%2e/%7egarrett"));
+ TEST_ASSERT(url != NULL);
+ TEST_STREQUAL(url->u_scheme, "http");
+ TEST_STREQUAL(url->u_hostname, "www.example.com");
+ TEST_STREQUAL(url->u_port, "80");
+ TEST_STREQUAL(url->u_path, "/~garrett");
+ nng_url_free(url);
+}
+
+void
+test_url_path_resolve(void)
+{
+ nng_url *url = NULL;
+ TEST_NNG_PASS(
+ nng_url_parse(&url, "http://www.x.com//abc/def/./x/..///./../y"));
+ TEST_STREQUAL(url->u_scheme, "http");
+ TEST_STREQUAL(url->u_hostname, "www.x.com");
+ TEST_STREQUAL(url->u_port, "80");
+ TEST_STREQUAL(url->u_path, "/abc/y");
+ nng_url_free(url);
+}
+
+void
+test_url_query_info_pass(void)
+{
+ nng_url *url = NULL;
+ TEST_NNG_PASS(
+ nng_url_parse(&url, "http://www.x.com/?/abc/def/./x/.././../y"));
+ TEST_ASSERT(url != NULL);
+ TEST_STREQUAL(url->u_scheme, "http");
+ TEST_STREQUAL(url->u_hostname, "www.x.com");
+ TEST_STREQUAL(url->u_port, "80");
+ TEST_STREQUAL(url->u_path, "/");
+ TEST_STREQUAL(url->u_query, "/abc/def/./x/.././../y");
+ nng_url_free(url);
+}
+
+void
+test_url_bad_utf8(void)
+{
+ nng_url *url = NULL;
+ TEST_NNG_FAIL(nng_url_parse(&url, "http://x.com/x%80x"), NNG_EINVAL);
+ TEST_NULL(url);
+ TEST_NNG_FAIL(nng_url_parse(&url, "http://x.com/x%c0%81"), NNG_EINVAL);
+ TEST_NULL(url);
+}
+
+void
+test_url_good_utf8(void)
+{
+ nng_url *url = NULL;
+ TEST_NNG_PASS(nng_url_parse(&url, "http://www.x.com/%c2%a2_cents"));
+ TEST_ASSERT(url != NULL);
+ TEST_STREQUAL(url->u_scheme, "http");
+ TEST_STREQUAL(url->u_hostname, "www.x.com");
+ TEST_STREQUAL(url->u_port, "80");
+ TEST_STREQUAL(url->u_path, "/\xc2\xa2_cents");
+ nng_url_free(url);
+}
+
+void
+test_url_decode(void)
+{
+ uint8_t out[16];
+ size_t len;
+
+ out[3] = 'x';
+ len = nni_url_decode(out, "abc", 3);
+ TEST_CHECK(len == 3);
+ TEST_CHECK(memcmp(out, "abc", 3) == 0);
+ TEST_CHECK(out[3] == 'x');
+
+ len = nni_url_decode(out, "x%00y", 3); // embedded NULL
+ TEST_CHECK(len == 3);
+ TEST_CHECK(memcmp(out, "x\x00y", 3) == 0);
+ TEST_CHECK(out[3] == 'x');
+
+ len = nni_url_decode(out, "%3987", 3);
+ TEST_CHECK(len == 3);
+ TEST_CHECK(memcmp(out, "987", 3) == 0);
+ TEST_CHECK(out[3] == 'x');
+
+ len = nni_url_decode(out, "78%39", 3);
+ TEST_CHECK(len == 3);
+ TEST_CHECK(memcmp(out, "789", 3) == 0);
+ TEST_CHECK(out[3] == 'x');
+
+ len = nni_url_decode(out, "", 5);
+ TEST_CHECK(len == 0);
+ TEST_CHECK(memcmp(out, "789", 3) == 0);
+ TEST_CHECK(out[3] == 'x');
+
+ len = nni_url_decode(out, "be", 2);
+ TEST_CHECK(len == 2);
+ TEST_CHECK(memcmp(out, "be9", 3) == 0);
+ TEST_CHECK(out[3] == 'x');
+
+ len = nni_url_decode(out, "78%39", 2);
+ TEST_CHECK(len == (size_t) -1);
+
+ len = nni_url_decode(out, "", 2);
+ TEST_CHECK(len == 0);
+
+ len = nni_url_decode(out, "78%", 5);
+ TEST_CHECK(len == (size_t) -1);
+
+ len = nni_url_decode(out, "78%xy", 5);
+ TEST_CHECK(len == (size_t) -1);
+
+ len = nni_url_decode(out, "78%1$", 5);
+ TEST_CHECK(len == (size_t) -1);
+
+ len = nni_url_decode(out, "%%20", 5);
+ TEST_CHECK(len == (size_t) -1);
+}
- Convey("http://www.google.com", {
- So(nng_url_parse(&url, "http://www.google.com") == 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "http") == 0);
- So(strcmp(url->u_host, "www.google.com") == 0);
- So(strcmp(url->u_hostname, "www.google.com") == 0);
- So(strcmp(url->u_port, "80") == 0);
- So(strcmp(url->u_path, "") == 0);
- So(strcmp(url->u_requri, "") == 0);
- So(url->u_query == NULL);
- So(url->u_fragment == NULL);
- So(url->u_userinfo == NULL);
- nng_url_free(url);
- });
-
- Convey("http://www.google.com:1234", {
- So(nng_url_parse(&url, "http://www.google.com:1234") == 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "http") == 0);
- So(strcmp(url->u_host, "www.google.com:1234") == 0);
- So(strcmp(url->u_hostname, "www.google.com") == 0);
- So(strcmp(url->u_port, "1234") == 0);
- So(strcmp(url->u_path, "") == 0);
- So(strcmp(url->u_requri, "") == 0);
- So(url->u_query == NULL);
- So(url->u_fragment == NULL);
- So(url->u_userinfo == NULL);
- nng_url_free(url);
- });
-
- Convey("http://www.google.com:1234/somewhere", {
- So(nng_url_parse(
- &url, "http://www.google.com:1234/somewhere") == 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "http") == 0);
- So(strcmp(url->u_host, "www.google.com:1234") == 0);
- So(strcmp(url->u_hostname, "www.google.com") == 0);
- So(strcmp(url->u_port, "1234") == 0);
- So(strcmp(url->u_path, "/somewhere") == 0);
- So(strcmp(url->u_requri, "/somewhere") == 0);
- So(url->u_userinfo == NULL);
- So(url->u_query == NULL);
- So(url->u_fragment == NULL);
- nng_url_free(url);
- });
- Convey("http://garrett@www.google.com:1234/somewhere", {
- So(nng_url_parse(&url,
- "http://garrett@www.google.com:1234/somewhere") == 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "http") == 0);
- So(strcmp(url->u_userinfo, "garrett") == 0);
- So(strcmp(url->u_host, "www.google.com:1234") == 0);
- So(strcmp(url->u_hostname, "www.google.com") == 0);
- So(strcmp(url->u_port, "1234") == 0);
- So(strcmp(url->u_path, "/somewhere") == 0);
- So(strcmp(url->u_requri, "/somewhere") == 0);
- So(url->u_query == NULL);
- So(url->u_fragment == NULL);
- nng_url_free(url);
- });
- Convey("http://www.google.com/somewhere?result=yes", {
- So(nng_url_parse(&url,
- "http://www.google.com/somewhere?result=yes") == 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "http") == 0);
- So(strcmp(url->u_host, "www.google.com") == 0);
- So(strcmp(url->u_hostname, "www.google.com") == 0);
- So(strcmp(url->u_port, "80") == 0);
- So(strcmp(url->u_path, "/somewhere") == 0);
- So(strcmp(url->u_query, "result=yes") == 0);
- So(strcmp(url->u_requri, "/somewhere?result=yes") == 0);
- So(url->u_userinfo == NULL);
- So(url->u_fragment == NULL);
- nng_url_free(url);
- });
- Convey("http://www.google.com/somewhere?result=yes#chapter1", {
- So(nng_url_parse(&url,
- "http://www.google.com/"
- "somewhere?result=yes#chapter1") == 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "http") == 0);
- So(strcmp(url->u_host, "www.google.com") == 0);
- So(strcmp(url->u_hostname, "www.google.com") == 0);
- So(strcmp(url->u_port, "80") == 0);
- So(strcmp(url->u_path, "/somewhere") == 0);
- So(strcmp(url->u_query, "result=yes") == 0);
- So(strcmp(url->u_fragment, "chapter1") == 0);
- So(strcmp(url->u_requri, "/somewhere?result=yes#chapter1") ==
- 0);
- So(url->u_userinfo == NULL);
- nng_url_free(url);
- });
- Convey("http://www.google.com/somewhere#chapter2", {
- So(nng_url_parse(
- &url, "http://www.google.com/somewhere#chapter2") == 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "http") == 0);
- So(strcmp(url->u_host, "www.google.com") == 0);
- So(strcmp(url->u_hostname, "www.google.com") == 0);
- So(strcmp(url->u_port, "80") == 0);
- So(strcmp(url->u_path, "/somewhere") == 0);
- So(strcmp(url->u_fragment, "chapter2") == 0);
- So(strcmp(url->u_requri, "/somewhere#chapter2") == 0);
- So(url->u_query == NULL);
- So(url->u_userinfo == NULL);
- nng_url_free(url);
- });
- Convey("http://www.google.com#chapter3", {
- So(nng_url_parse(&url, "http://www.google.com#chapter3") == 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "http") == 0);
- So(strcmp(url->u_host, "www.google.com") == 0);
- So(strcmp(url->u_hostname, "www.google.com") == 0);
- So(strcmp(url->u_path, "") == 0);
- So(strcmp(url->u_port, "80") == 0);
- So(strcmp(url->u_fragment, "chapter3") == 0);
- So(strcmp(url->u_requri, "#chapter3") == 0);
- So(url->u_query == NULL);
- So(url->u_userinfo == NULL);
- nng_url_free(url);
- });
- Convey("http://www.google.com?color=red", {
- So(nng_url_parse(&url, "http://www.google.com?color=red") ==
- 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "http") == 0);
- So(strcmp(url->u_host, "www.google.com") == 0);
- So(strcmp(url->u_hostname, "www.google.com") == 0);
- So(strcmp(url->u_path, "") == 0);
- So(strcmp(url->u_port, "80") == 0);
- So(strcmp(url->u_query, "color=red") == 0);
- So(strcmp(url->u_requri, "?color=red") == 0);
- So(url->u_fragment == NULL);
- So(url->u_userinfo == NULL);
- nng_url_free(url);
- });
-
- Convey("http://[::1]", {
- So(nng_url_parse(&url, "http://[::1]") == 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "http") == 0);
- So(strcmp(url->u_host, "[::1]") == 0);
- So(strcmp(url->u_hostname, "::1") == 0);
- So(strcmp(url->u_path, "") == 0);
- So(strcmp(url->u_port, "80") == 0);
- So(url->u_query == NULL);
- So(url->u_fragment == NULL);
- So(url->u_userinfo == NULL);
- nng_url_free(url);
- });
-
- Convey("http://[::1]:29", {
- So(nng_url_parse(&url, "http://[::1]:29") == 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "http") == 0);
- So(strcmp(url->u_host, "[::1]:29") == 0);
- So(strcmp(url->u_hostname, "::1") == 0);
- So(strcmp(url->u_path, "") == 0);
- So(strcmp(url->u_port, "29") == 0);
- So(url->u_query == NULL);
- So(url->u_fragment == NULL);
- So(url->u_userinfo == NULL);
- nng_url_free(url);
- });
- Convey("http://[::1]:29/bottles", {
- So(nng_url_parse(&url, "http://[::1]:29/bottles") == 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "http") == 0);
- So(strcmp(url->u_host, "[::1]:29") == 0);
- So(strcmp(url->u_hostname, "::1") == 0);
- So(strcmp(url->u_path, "/bottles") == 0);
- So(strcmp(url->u_port, "29") == 0);
- So(url->u_query == NULL);
- So(url->u_fragment == NULL);
- So(url->u_userinfo == NULL);
- nng_url_free(url);
- });
-
- Convey("tcp://:9876/", {
- So(nng_url_parse(&url, "tcp://:9876/") == 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "tcp") == 0);
- So(strcmp(url->u_host, ":9876") == 0);
- So(strcmp(url->u_hostname, "") == 0);
- So(strcmp(url->u_path, "/") == 0);
- So(strcmp(url->u_port, "9876") == 0);
- So(url->u_query == NULL);
- So(url->u_fragment == NULL);
- So(url->u_userinfo == NULL);
- nng_url_free(url);
- });
-
- Convey("ws://", {
- So(nng_url_parse(&url, "ws://") == 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "ws") == 0);
- So(strcmp(url->u_host, "") == 0);
- So(strcmp(url->u_hostname, "") == 0);
- So(strcmp(url->u_path, "") == 0);
- So(strcmp(url->u_port, "80") == 0);
- So(url->u_query == NULL);
- So(url->u_fragment == NULL);
- So(url->u_userinfo == NULL);
- nng_url_free(url);
- });
-
- Convey("ws://*:12345/foobar", {
- So(nng_url_parse(&url, "ws://*:12345/foobar") == 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "ws") == 0);
- So(strcmp(url->u_host, ":12345") == 0);
- So(strcmp(url->u_hostname, "") == 0);
- So(strcmp(url->u_path, "/foobar") == 0);
- So(strcmp(url->u_port, "12345") == 0);
- So(url->u_query == NULL);
- So(url->u_fragment == NULL);
- So(url->u_userinfo == NULL);
- nng_url_free(url);
- });
-
- Convey("ssh://user@host.example.com", {
- So(nng_url_parse(&url, "ssh://user@host.example.com") == 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "ssh") == 0);
- So(strcmp(url->u_host, "host.example.com") == 0);
- So(strcmp(url->u_hostname, "host.example.com") == 0);
- So(strcmp(url->u_path, "") == 0);
- So(strcmp(url->u_port, "22") == 0);
- So(url->u_query == NULL);
- So(url->u_fragment == NULL);
- So(strcmp(url->u_userinfo, "user") == 0);
- nng_url_free(url);
- });
-
- Convey("Negative www.google.com", {
- url = NULL;
- So(nng_url_parse(&url, "www.google.com") == NNG_EINVAL);
- So(url == NULL);
- });
-
- Convey("Negative http:www.google.com", {
- url = NULL;
- So(nng_url_parse(&url, "http:www.google.com") == NNG_EINVAL);
- So(url == NULL);
- });
-
- Convey("Negative http://[::1", {
- url = NULL;
- So(nng_url_parse(&url, "http://[::1") == NNG_EINVAL);
- So(url == NULL);
- });
-
- Convey("Negative http://[::1]bogus", {
- url = NULL;
- So(nng_url_parse(&url, "http://[::1]bogus") == NNG_EINVAL);
- So(url == NULL);
- });
-
- Convey("Canonicalization works", {
- url = NULL;
- So(nng_url_parse(&url,
- "hTTp://www.EXAMPLE.com/bogus/.%2e/%7egarrett") == 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "http") == 0);
- So(strcmp(url->u_hostname, "www.example.com") == 0);
- So(strcmp(url->u_port, "80") == 0);
- So(strcmp(url->u_path, "/~garrett") == 0);
- nng_url_free(url);
- });
-
- Convey("Path resolution works", {
- url = NULL;
- So(nng_url_parse(&url,
- "http://www.x.com//abc/def/./x/..///./../y") == 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "http") == 0);
- So(strcmp(url->u_hostname, "www.x.com") == 0);
- So(strcmp(url->u_port, "80") == 0);
- So(strcmp(url->u_path, "/abc/y") == 0);
- nng_url_free(url);
- });
-
- Convey("Query info unmolested", {
- url = NULL;
- So(nng_url_parse(
- &url, "http://www.x.com/?/abc/def/./x/.././../y") == 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "http") == 0);
- So(strcmp(url->u_hostname, "www.x.com") == 0);
- So(strcmp(url->u_port, "80") == 0);
- So(strcmp(url->u_path, "/") == 0);
- So(strcmp(url->u_query, "/abc/def/./x/.././../y") == 0);
- nng_url_free(url);
- });
-
- Convey("Bad UTF-8 fails", {
- url = NULL;
- So(nng_url_parse(&url, "http://x.com/x%80x") == NNG_EINVAL);
- So(nng_url_parse(&url, "http://x.com/x%c0%81") == NNG_EINVAL);
- });
-
- Convey("Valid UTF-8 works", {
- url = NULL;
- So(nng_url_parse(&url, "http://www.x.com/%c2%a2_centsign") ==
- 0);
- So(url != NULL);
- So(strcmp(url->u_scheme, "http") == 0);
- So(strcmp(url->u_hostname, "www.x.com") == 0);
- So(strcmp(url->u_port, "80") == 0);
- So(strcmp(url->u_path, "/\xc2\xa2_centsign") == 0);
- nng_url_free(url);
- });
-})
+TEST_LIST = {
+ { "url host", test_url_host },
+ { "url host port", test_url_host_port },
+ { "url host port path", test_url_host_port_path },
+ { "url user info", test_url_user_info },
+ { "url path query param", test_url_path_query_param },
+ { "url query param anchor", test_url_query_param_anchor },
+ { "url path anchor", test_url_path_anchor },
+ { "url anchor", test_url_anchor },
+ { "url query param", test_url_query_param },
+ { "url v6 host", test_url_v6_host },
+ { "url v6 host port", test_url_v6_host_port },
+ { "url v6 host port path", test_url_v6_host_port_path },
+ { "url tcp port", test_url_tcp_port },
+ { "url bare ws", test_url_bare_ws },
+ { "url ws wildcard", test_url_ws_wildcard },
+ { "url ssh", test_url_ssh },
+ { "url bad scheme", test_url_bad_scheme },
+ { "url bad v6", test_url_bad_ipv6 },
+ { "url canonify", test_url_canonify },
+ { "url path resolve", test_url_path_resolve },
+ { "url query info pass", test_url_query_info_pass },
+ { "url bad utf8", test_url_bad_utf8 },
+ { "url good utf8", test_url_good_utf8 },
+ { "url decode", test_url_decode },
+ { NULL, NULL },
+}; \ No newline at end of file