Skip to content

Commit

Permalink
intern URL scheme
Browse files Browse the repository at this point in the history
  • Loading branch information
gdamore committed Nov 17, 2024
1 parent 9ea51a5 commit ef82d47
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 24 deletions.
20 changes: 10 additions & 10 deletions include/nng/nng.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
53 changes: 44 additions & 9 deletions src/core/url.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) ||
Expand All @@ -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);
}

Expand Down
11 changes: 6 additions & 5 deletions src/core/url_test.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2020 Staysail Systems, Inc. <[email protected]>
// Copyright 2024 Staysail Systems, Inc. <[email protected]>
// Copyright 2018 Capitar IT Group BV <[email protected]>
//
// This software is supplied under the terms of the MIT License, a
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -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");
Expand Down Expand Up @@ -469,4 +470,4 @@ NUTS_TESTS = {
{ "url good utf8", test_url_good_utf8 },
{ "url decode", test_url_decode },
{ NULL, NULL },
};
};

0 comments on commit ef82d47

Please sign in to comment.