aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2024-11-17 15:27:02 -0800
committerGarrett D'Amore <garrett@damore.org>2024-11-17 15:29:41 -0800
commitef82d4792bf59b1fe8053d9bb5ac924b443d8a78 (patch)
treedb865bea3afc153b27ccef35335919d98723507f
parent9ea51a5bd5828648c68dbfbc43b2edcde65e5262 (diff)
downloadnng-ef82d4792bf59b1fe8053d9bb5ac924b443d8a78.tar.gz
nng-ef82d4792bf59b1fe8053d9bb5ac924b443d8a78.tar.bz2
nng-ef82d4792bf59b1fe8053d9bb5ac924b443d8a78.zip
intern URL scheme
-rw-r--r--include/nng/nng.h20
-rw-r--r--src/core/url.c53
-rw-r--r--src/core/url_test.c11
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
+};