diff options
| -rw-r--r-- | include/nng/nng.h | 20 | ||||
| -rw-r--r-- | src/core/url.c | 53 | ||||
| -rw-r--r-- | src/core/url_test.c | 11 |
3 files changed, 60 insertions, 24 deletions
diff --git a/include/nng/nng.h b/include/nng/nng.h index a6f5dc9a..a41deeb4 100644 --- a/include/nng/nng.h +++ b/include/nng/nng.h @@ -1083,16 +1083,16 @@ enum nng_errno_enum { // give us a convenient way of doing so. typedef struct nng_url { - char *u_rawurl; // never NULL - char *u_scheme; // never NULL - char *u_userinfo; // will be NULL if not specified - char *u_host; // including colon and port - char *u_hostname; // name only, will be "" if not specified - char *u_port; // port, will be "" if not specified - char *u_path; // path, will be "" if not specified - char *u_query; // without '?', will be NULL if not specified - char *u_fragment; // without '#', will be NULL if not specified - char *u_requri; // includes query and fragment, "" if not specified + char *u_rawurl; // never NULL + const char *u_scheme; // never NULL + char *u_userinfo; // will be NULL if not specified + char *u_host; // including colon and port + char *u_hostname; // name only, will be "" if not specified + char *u_port; // port, will be "" if not specified + char *u_path; // path, will be "" if not specified + char *u_query; // without '?', will be NULL if not specified + char *u_fragment; // without '#', will be NULL if not specified + char *u_requri; // includes query and fragment, "" if not specified } nng_url; // nng_url_parse parses a URL string into a structured form. diff --git a/src/core/url.c b/src/core/url.c index 074be145..c1318719 100644 --- a/src/core/url.c +++ b/src/core/url.c @@ -253,6 +253,40 @@ static struct { // clang-format on }; +// List of schemes that we recognize. We don't support them all. +static const char *nni_schemes[] = { + "http", + "https", + "tcp", + "tcp4", + "tcp6", + "tls+tcp", + "tls+tcp4", + "tls+tcp6", + "socket", + "inproc", + "ipc", + "unix", + "abstract", + "ws", + "ws4", + "ws6", + "wss", + "wss4", + "wss6", + // we don't support these + "file", + "mailto", + "gopher", + "ftp", + "ssh", + "git", + "telnet", + "irc", + "imap", + NULL, +}; + const char * nni_url_default_port(const char *scheme) { @@ -321,14 +355,16 @@ nni_url_parse(nni_url **urlp, const char *raw) goto error; } - if ((url->u_scheme = nni_alloc(len + 1)) == NULL) { - rv = NNG_ENOMEM; - goto error; + for (int i = 0; nni_schemes[i] != NULL; i++) { + if (strncmp(s, nni_schemes[i], len) == 0) { + url->u_scheme = nni_schemes[i]; + break; + } } - for (size_t i = 0; i < len; i++) { - url->u_scheme[i] = (char) tolower(s[i]); + if (url->u_scheme == NULL) { + rv = NNG_ENOTSUP; + goto error; } - url->u_scheme[len] = '\0'; s += len + 3; // strlen("://") // For compatibility reasons, we treat ipc:// and inproc:// paths @@ -507,7 +543,6 @@ nni_url_free(nni_url *url) { if (url != NULL) { nni_strfree(url->u_rawurl); - nni_strfree(url->u_scheme); nni_strfree(url->u_userinfo); nni_strfree(url->u_host); nni_strfree(url->u_hostname); @@ -580,7 +615,6 @@ nni_url_clone(nni_url **dstp, const nni_url *src) return (NNG_ENOMEM); } if (URL_COPYSTR(dst->u_rawurl, src->u_rawurl) || - URL_COPYSTR(dst->u_scheme, src->u_scheme) || URL_COPYSTR(dst->u_userinfo, src->u_userinfo) || URL_COPYSTR(dst->u_host, src->u_host) || URL_COPYSTR(dst->u_hostname, src->u_hostname) || @@ -592,7 +626,8 @@ nni_url_clone(nni_url **dstp, const nni_url *src) nni_url_free(dst); return (NNG_ENOMEM); } - *dstp = dst; + dst->u_scheme = src->u_scheme; + *dstp = dst; return (0); } diff --git a/src/core/url_test.c b/src/core/url_test.c index 6504ff6c..232cabc8 100644 --- a/src/core/url_test.c +++ b/src/core/url_test.c @@ -1,5 +1,5 @@ // -// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech> +// Copyright 2024 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 @@ -54,8 +54,7 @@ test_url_host_port_path(void) { nng_url *url; - NUTS_PASS( - nng_url_parse(&url, "http://www.google.com:1234/somewhere")); + NUTS_PASS(nng_url_parse(&url, "http://www.google.com:1234/somewhere")); NUTS_ASSERT(url != NULL); NUTS_TRUE(strcmp(url->u_scheme, "http") == 0); NUTS_TRUE(strcmp(url->u_host, "www.google.com:1234") == 0); @@ -310,6 +309,8 @@ test_url_bad_scheme(void) NUTS_NULL(url); NUTS_FAIL(nng_url_parse(&url, "http:www.google.com"), NNG_EINVAL); NUTS_NULL(url); + NUTS_FAIL(nng_url_parse(&url, "nosuch://bogus"), NNG_ENOTSUP); + NUTS_NULL(url); } void @@ -327,7 +328,7 @@ test_url_canonify(void) { nng_url *url = NULL; NUTS_PASS(nng_url_parse( - &url, "hTTp://www.EXAMPLE.com/bogus/.%2e/%7egarrett")); + &url, "http://www.EXAMPLE.com/bogus/.%2e/%7egarrett")); NUTS_ASSERT(url != NULL); NUTS_MATCH(url->u_scheme, "http"); NUTS_MATCH(url->u_hostname, "www.example.com"); @@ -469,4 +470,4 @@ NUTS_TESTS = { { "url good utf8", test_url_good_utf8 }, { "url decode", test_url_decode }, { NULL, NULL }, -};
\ No newline at end of file +}; |
