From 224dae56a379aa309fca261d61e7e356b14a536f Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Thu, 4 Jan 2018 20:11:38 -0800 Subject: Fix some more leaks, add a generic URL parser. --- tests/CMakeLists.txt | 1 + tests/tls.c | 52 ++++++------ tests/trantest.h | 4 +- tests/url.c | 230 +++++++++++++++++++++++++++++++++++++++++++++++++++ tests/ws.c | 101 ++++++++++------------ tests/wss.c | 101 ++++++++++------------ 6 files changed, 349 insertions(+), 140 deletions(-) create mode 100644 tests/url.c (limited to 'tests') diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7e855f23..f6c9a62d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -158,6 +158,7 @@ add_nng_test(tcp 5 NNG_TRANSPORT_TCP) add_nng_test(tcp6 5 NNG_TRANSPORT_TCP) add_nng_test(transport 5 ON) add_nng_test(udp 5 ON) +add_nng_test(url 5 ON) add_nng_test(ws 30 NNG_TRANSPORT_WS) add_nng_test(wss 30 NNG_TRANSPORT_WSS) add_nng_test(zt 60 NNG_TRANSPORT_ZEROTIER) diff --git a/tests/tls.c b/tests/tls.c index fe8aea1e..4ce70a28 100644 --- a/tests/tls.c +++ b/tests/tls.c @@ -1,7 +1,6 @@ // -// Copyright 2017 Garrett D'Amore -// Copyright 2017 Capitar IT Group BV -// Copyright 2017 Staysail Systems, Inc. +// Copyright 2018 Capitar IT Group BV +// Copyright 2018 Staysail Systems, Inc. // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -79,27 +78,23 @@ check_props_v4(nng_msg *msg, nng_listener l, nng_dialer d) size_t z; p = nng_msg_get_pipe(msg); So(p > 0); - - Convey("Local address property works", { - nng_sockaddr la; - z = sizeof(nng_sockaddr); - So(nng_pipe_getopt(p, NNG_OPT_LOCADDR, &la, &z) == 0); - So(z == sizeof(la)); - So(la.s_un.s_family == NNG_AF_INET); - So(la.s_un.s_in.sa_port == htons(trantest_port - 1)); - So(la.s_un.s_in.sa_port != 0); - So(la.s_un.s_in.sa_addr == htonl(0x7f000001)); - }); - - Convey("Remote address property works", { - nng_sockaddr ra; - z = sizeof(nng_sockaddr); - So(nng_pipe_getopt(p, NNG_OPT_REMADDR, &ra, &z) == 0); - So(z == sizeof(ra)); - So(ra.s_un.s_family == NNG_AF_INET); - So(ra.s_un.s_in.sa_port != 0); - So(ra.s_un.s_in.sa_addr == htonl(0x7f000001)); - }); + nng_sockaddr la; + nng_sockaddr ra; + + z = sizeof(nng_sockaddr); + So(nng_pipe_getopt(p, NNG_OPT_LOCADDR, &la, &z) == 0); + So(z == sizeof(la)); + So(la.s_un.s_family == NNG_AF_INET); + So(la.s_un.s_in.sa_port == htons(trantest_port - 1)); + So(la.s_un.s_in.sa_port != 0); + So(la.s_un.s_in.sa_addr == htonl(0x7f000001)); + + z = sizeof(nng_sockaddr); + So(nng_pipe_getopt(p, NNG_OPT_REMADDR, &ra, &z) == 0); + So(z == sizeof(ra)); + So(ra.s_un.s_family == NNG_AF_INET); + So(ra.s_un.s_in.sa_port != 0); + So(ra.s_un.s_in.sa_addr == htonl(0x7f000001)); return (0); } @@ -205,18 +200,21 @@ TestMain("TLS Transport", { So(nng_tls_register() == 0); So(nng_pair_open(&s1) == 0); Reset({ nng_close(s1); }); + + // Note that if we listen to an unspecified port, then we + // get a random port. So we don't look at that. This allows + // a user to obtain a port at random and then query to see + // which one was chosen. + So(nng_dial(s1, "tls+tcp://127.0.0.1", NULL, 0) == NNG_EADDRINVAL); So(nng_dial(s1, "tls+tcp://127.0.0.1.32", NULL, 0) == NNG_EADDRINVAL); So(nng_dial(s1, "tls+tcp://127.0.x.1.32", NULL, 0) == NNG_EADDRINVAL); - So(nng_listen(s1, "tls+tcp://127.0.0.1", NULL, 0) == - NNG_EADDRINVAL); So(nng_listen(s1, "tls+tcp://127.0.0.1.32", NULL, 0) == NNG_EADDRINVAL); So(nng_listen(s1, "tls+tcp://127.0.x.1.32", NULL, 0) == NNG_EADDRINVAL); }); - }) diff --git a/tests/trantest.h b/tests/trantest.h index 0346e3ff..46eaa7b1 100644 --- a/tests/trantest.h +++ b/tests/trantest.h @@ -248,10 +248,11 @@ trantest_listen_accept(trantest *tt) So(trantest_listen(tt, &l) == 0); So(l != 0); + nng_msleep(200); d = 0; So(trantest_dial(tt, &d) == 0); So(d != 0); - }) + }); } void @@ -384,6 +385,7 @@ trantest_check_properties(trantest *tt, trantest_proptest_t f) So(nng_msg_append(send, "props", 5) == 0); So(nng_sendmsg(tt->reqsock, send, 0) == 0); + recv = NULL; So(nng_recvmsg(tt->repsock, &recv, 0) == 0); So(recv != NULL); diff --git a/tests/url.c b/tests/url.c new file mode 100644 index 00000000..019a1519 --- /dev/null +++ b/tests/url.c @@ -0,0 +1,230 @@ +// +// Copyright 2018 Staysail Systems, Inc. +// Copyright 2018 Capitar IT Group BV +// +// 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. +// + +#include + +#include "convey.h" + +#include "core/nng_impl.h" +#include "core/url.h" + +//#include "stubs.h" + +TestMain("URLs", { + + nni_url *url; + + Convey("http://www.google.com", { + So(nni_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, "") == 0); + So(strcmp(url->u_path, "") == 0); + So(url->u_query == NULL); + So(url->u_fragment == NULL); + So(url->u_userinfo == NULL); + nni_url_free(url); + }); + + Convey("http://www.google.com:1234", { + So(nni_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(url->u_query == NULL); + So(url->u_fragment == NULL); + So(url->u_userinfo == NULL); + nni_url_free(url); + }); + + Convey("http://www.google.com:1234/somewhere", { + So(nni_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(url->u_userinfo == NULL); + So(url->u_query == NULL); + So(url->u_fragment == NULL); + nni_url_free(url); + }); + Convey("http://garrett@www.google.com:1234/somewhere", { + So(nni_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(url->u_query == NULL); + So(url->u_fragment == NULL); + nni_url_free(url); + }); + Convey("http://www.google.com/somewhere?result=yes", { + So(nni_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, "") == 0); + So(strcmp(url->u_path, "/somewhere") == 0); + So(strcmp(url->u_query, "result=yes") == 0); + So(url->u_userinfo == NULL); + So(url->u_fragment == NULL); + nni_url_free(url); + }); + Convey("http://www.google.com/somewhere?result=yes#chapter1", { + So(nni_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, "") == 0); + So(strcmp(url->u_path, "/somewhere") == 0); + So(strcmp(url->u_query, "result=yes") == 0); + So(strcmp(url->u_fragment, "chapter1") == 0); + So(url->u_userinfo == NULL); + nni_url_free(url); + }); + Convey("http://www.google.com/somewhere#chapter2", { + So(nni_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, "") == 0); + So(strcmp(url->u_path, "/somewhere") == 0); + So(strcmp(url->u_fragment, "chapter2") == 0); + So(url->u_query == NULL); + So(url->u_userinfo == NULL); + nni_url_free(url); + }); + Convey("http://www.google.com#chapter3", { + So(nni_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, "") == 0); + So(strcmp(url->u_fragment, "chapter3") == 0); + So(url->u_query == NULL); + So(url->u_userinfo == NULL); + nni_url_free(url); + }); + Convey("http://www.google.com?color=red", { + So(nni_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, "") == 0); + So(strcmp(url->u_query, "color=red") == 0); + So(url->u_fragment == NULL); + So(url->u_userinfo == NULL); + nni_url_free(url); + }); + + Convey("http://[::1]", { + So(nni_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, "") == 0); + So(url->u_query == NULL); + So(url->u_fragment == NULL); + So(url->u_userinfo == NULL); + nni_url_free(url); + }); + + Convey("http://[::1]:29", { + So(nni_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); + nni_url_free(url); + }); + Convey("http://[::1]:29/bottles", { + So(nni_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); + nni_url_free(url); + }); + + Convey("tcp://:9876/", { + So(nni_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); + nni_url_free(url); + }); + + Convey("Negative www.google.com", { + url = NULL; + So(nni_url_parse(&url, "www.google.com") == NNG_EINVAL); + So(url == NULL); + }); + + Convey("Negative http:www.google.com", { + url = NULL; + So(nni_url_parse(&url, "http:www.google.com") == NNG_EINVAL); + So(url == NULL); + }); + + Convey("Negative http://[::1", { + url = NULL; + So(nni_url_parse(&url, "http://[::1") == NNG_EINVAL); + So(url == NULL); + }); + + Convey("Negative http://[::1]bogus", { + url = NULL; + So(nni_url_parse(&url, "http://[::1]bogus") == NNG_EINVAL); + So(url == NULL); + }); + +}) diff --git a/tests/ws.c b/tests/ws.c index aa2ba56e..386c0690 100644 --- a/tests/ws.c +++ b/tests/ws.c @@ -24,65 +24,54 @@ static int check_props_v4(nng_msg *msg, nng_listener l, nng_dialer d) { - nng_pipe p; - size_t z; + nng_pipe p; + size_t z; + nng_sockaddr la; + nng_sockaddr ra; + char * buf; + size_t len; + p = nng_msg_get_pipe(msg); So(p > 0); - Convey("Local address property works", { - nng_sockaddr la; - z = sizeof(nng_sockaddr); - So(nng_pipe_getopt(p, NNG_OPT_LOCADDR, &la, &z) == 0); - So(z == sizeof(la)); - So(la.s_un.s_family == NNG_AF_INET); - So(la.s_un.s_in.sa_port == htons(trantest_port - 1)); - So(la.s_un.s_in.sa_port != 0); - So(la.s_un.s_in.sa_addr == htonl(0x7f000001)); - }); - - Convey("Remote address property works", { - nng_sockaddr ra; - z = sizeof(nng_sockaddr); - So(nng_pipe_getopt(p, NNG_OPT_REMADDR, &ra, &z) == 0); - So(z == sizeof(ra)); - So(ra.s_un.s_family == NNG_AF_INET); - So(ra.s_un.s_in.sa_port != 0); - So(ra.s_un.s_in.sa_addr == htonl(0x7f000001)); - }); - - Convey("Request header property works", { - char * buf; - size_t len; - z = 0; - buf = NULL; - So(nng_pipe_getopt(p, NNG_OPT_WS_REQUEST_HEADERS, buf, &z) == - 0); - So(z > 0); - len = z; - So((buf = nni_alloc(len)) != NULL); - So(nng_pipe_getopt(p, NNG_OPT_WS_REQUEST_HEADERS, buf, &z) == - 0); - So(strstr(buf, "Sec-WebSocket-Key") != NULL); - So(z == len); - nni_free(buf, len); - }); - - Convey("Response header property works", { - char * buf; - size_t len; - z = 0; - buf = NULL; - So(nng_pipe_getopt(p, NNG_OPT_WS_RESPONSE_HEADERS, buf, &z) == - 0); - So(z > 0); - len = z; - So((buf = nni_alloc(len)) != NULL); - So(nng_pipe_getopt(p, NNG_OPT_WS_RESPONSE_HEADERS, buf, &z) == - 0); - So(strstr(buf, "Sec-WebSocket-Accept") != NULL); - So(z == len); - nni_free(buf, len); - }); + z = sizeof(nng_sockaddr); + So(nng_pipe_getopt(p, NNG_OPT_LOCADDR, &la, &z) == 0); + So(z == sizeof(la)); + So(la.s_un.s_family == NNG_AF_INET); + So(la.s_un.s_in.sa_port == htons(trantest_port - 1)); + So(la.s_un.s_in.sa_port != 0); + So(la.s_un.s_in.sa_addr == htonl(0x7f000001)); + + z = sizeof(nng_sockaddr); + So(nng_pipe_getopt(p, NNG_OPT_REMADDR, &ra, &z) == 0); + So(z == sizeof(ra)); + So(ra.s_un.s_family == NNG_AF_INET); + So(ra.s_un.s_in.sa_port != 0); + So(ra.s_un.s_in.sa_addr == htonl(0x7f000001)); + + // Request Header + z = 0; + buf = NULL; + So(nng_pipe_getopt(p, NNG_OPT_WS_REQUEST_HEADERS, buf, &z) == 0); + So(z > 0); + len = z; + So((buf = nni_alloc(len)) != NULL); + So(nng_pipe_getopt(p, NNG_OPT_WS_REQUEST_HEADERS, buf, &z) == 0); + So(strstr(buf, "Sec-WebSocket-Key") != NULL); + So(z == len); + nni_free(buf, len); + + // Response Header + z = 0; + buf = NULL; + So(nng_pipe_getopt(p, NNG_OPT_WS_RESPONSE_HEADERS, buf, &z) == 0); + So(z > 0); + len = z; + So((buf = nni_alloc(len)) != NULL); + So(nng_pipe_getopt(p, NNG_OPT_WS_RESPONSE_HEADERS, buf, &z) == 0); + So(strstr(buf, "Sec-WebSocket-Accept") != NULL); + So(z == len); + nni_free(buf, len); return (0); } diff --git a/tests/wss.c b/tests/wss.c index 151b4287..38b333b9 100644 --- a/tests/wss.c +++ b/tests/wss.c @@ -72,65 +72,54 @@ static const char server_key[] = static int check_props_v4(nng_msg *msg, nng_listener l, nng_dialer d) { - nng_pipe p; - size_t z; + nng_pipe p; + size_t z; + nng_sockaddr la; + nng_sockaddr ra; + char * buf; + size_t len; + p = nng_msg_get_pipe(msg); So(p > 0); - Convey("Local address property works", { - nng_sockaddr la; - z = sizeof(nng_sockaddr); - So(nng_pipe_getopt(p, NNG_OPT_LOCADDR, &la, &z) == 0); - So(z == sizeof(la)); - So(la.s_un.s_family == NNG_AF_INET); - So(la.s_un.s_in.sa_port == htons(trantest_port - 1)); - So(la.s_un.s_in.sa_port != 0); - So(la.s_un.s_in.sa_addr == htonl(0x7f000001)); - }); - - Convey("Remote address property works", { - nng_sockaddr ra; - z = sizeof(nng_sockaddr); - So(nng_pipe_getopt(p, NNG_OPT_REMADDR, &ra, &z) == 0); - So(z == sizeof(ra)); - So(ra.s_un.s_family == NNG_AF_INET); - So(ra.s_un.s_in.sa_port != 0); - So(ra.s_un.s_in.sa_addr == htonl(0x7f000001)); - }); - - Convey("Request header property works", { - char * buf; - size_t len; - z = 0; - buf = NULL; - So(nng_pipe_getopt(p, NNG_OPT_WS_REQUEST_HEADERS, buf, &z) == - 0); - So(z > 0); - len = z; - So((buf = nni_alloc(len)) != NULL); - So(nng_pipe_getopt(p, NNG_OPT_WS_REQUEST_HEADERS, buf, &z) == - 0); - So(strstr(buf, "Sec-WebSocket-Key") != NULL); - So(z == len); - nni_free(buf, len); - }); - - Convey("Response header property works", { - char * buf; - size_t len; - z = 0; - buf = NULL; - So(nng_pipe_getopt(p, NNG_OPT_WS_RESPONSE_HEADERS, buf, &z) == - 0); - So(z > 0); - len = z; - So((buf = nni_alloc(len)) != NULL); - So(nng_pipe_getopt(p, NNG_OPT_WS_RESPONSE_HEADERS, buf, &z) == - 0); - So(strstr(buf, "Sec-WebSocket-Accept") != NULL); - So(z == len); - nni_free(buf, len); - }); + z = sizeof(nng_sockaddr); + So(nng_pipe_getopt(p, NNG_OPT_LOCADDR, &la, &z) == 0); + So(z == sizeof(la)); + So(la.s_un.s_family == NNG_AF_INET); + So(la.s_un.s_in.sa_port == htons(trantest_port - 1)); + So(la.s_un.s_in.sa_port != 0); + So(la.s_un.s_in.sa_addr == htonl(0x7f000001)); + + z = sizeof(nng_sockaddr); + So(nng_pipe_getopt(p, NNG_OPT_REMADDR, &ra, &z) == 0); + So(z == sizeof(ra)); + So(ra.s_un.s_family == NNG_AF_INET); + So(ra.s_un.s_in.sa_port != 0); + So(ra.s_un.s_in.sa_addr == htonl(0x7f000001)); + + // Request header + z = 0; + buf = NULL; + So(nng_pipe_getopt(p, NNG_OPT_WS_REQUEST_HEADERS, buf, &z) == 0); + So(z > 0); + len = z; + So((buf = nni_alloc(len)) != NULL); + So(nng_pipe_getopt(p, NNG_OPT_WS_REQUEST_HEADERS, buf, &z) == 0); + So(strstr(buf, "Sec-WebSocket-Key") != NULL); + So(z == len); + nni_free(buf, len); + + // Response header + z = 0; + buf = NULL; + So(nng_pipe_getopt(p, NNG_OPT_WS_RESPONSE_HEADERS, buf, &z) == 0); + So(z > 0); + len = z; + So((buf = nni_alloc(len)) != NULL); + So(nng_pipe_getopt(p, NNG_OPT_WS_RESPONSE_HEADERS, buf, &z) == 0); + So(strstr(buf, "Sec-WebSocket-Accept") != NULL); + So(z == len); + nni_free(buf, len); return (0); } -- cgit v1.2.3-70-g09d2