summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2018-01-12 10:55:44 -0800
committerGarrett D'Amore <garrett@damore.org>2018-01-16 08:45:11 -0800
commit18229bbb69423d64d0a1b98bcf4bf3e24fba3aa4 (patch)
tree7fa71622a83c5429d4e4e09a9f051f0c79d9e6a5
parent7e52d0b37a0b1c87071f3bc5d528caef8e400156 (diff)
downloadnng-18229bbb69423d64d0a1b98bcf4bf3e24fba3aa4.tar.gz
nng-18229bbb69423d64d0a1b98bcf4bf3e24fba3aa4.tar.bz2
nng-18229bbb69423d64d0a1b98bcf4bf3e24fba3aa4.zip
Supply default ports for some well-known schemes.
-rw-r--r--src/core/url.c44
-rw-r--r--tests/url.c42
2 files changed, 74 insertions, 12 deletions
diff --git a/src/core/url.c b/src/core/url.c
index aa4cd2e1..7e1b61b5 100644
--- a/src/core/url.c
+++ b/src/core/url.c
@@ -175,6 +175,40 @@ nni_url_encode(char **out, const char *in)
return (nni_url_encode_ext(out, in, ""));
}
+static struct {
+ const char *scheme;
+ const char *port;
+} nni_url_default_ports[] = {
+ // This list is not exhaustive, but likely covers the main ones we
+ // care about. Feel free to add additional ones as use cases arise.
+ // Note also that we don't use "default" ports for SP protocols
+ // that have no "default" port, like tcp:// or tls+tcp://.
+ // clang-format off
+ { "git", "9418" },
+ { "gopher", "70" },
+ { "http", "80" },
+ { "https", "443" },
+ { "ssh", "22" },
+ { "telnet", "23" },
+ { "ws", "80" },
+ { "wss", "443" },
+ { NULL, NULL },
+ // clang-format on
+};
+
+static const char *
+nni_url_default_port(const char *scheme)
+{
+ const char *s;
+
+ for (int i = 0; (s = nni_url_default_ports[i].scheme) != NULL; i++) {
+ if (strcmp(s, scheme) == 0) {
+ return (nni_url_default_ports[i].port);
+ }
+ }
+ return ("");
+}
+
// URLs usually follow the following format:
//
// scheme:[//[userinfo@]host][/]path[?query][#fragment]
@@ -338,11 +372,11 @@ nni_url_parse(nni_url **urlp, const char *raw)
s++; // skip over ']', only used with IPv6 addresses
}
if (s[0] == ':') {
- if ((url->u_port = nni_strdup(s + 1)) == NULL) {
- rv = NNG_ENOMEM;
- goto error;
- }
- } else if ((url->u_port = nni_strdup("")) == NULL) {
+ url->u_port = nni_strdup(s + 1);
+ } else {
+ url->u_port = nni_strdup(nni_url_default_port(url->u_scheme));
+ }
+ if (url->u_port == NULL) {
rv = NNG_ENOMEM;
goto error;
}
diff --git a/tests/url.c b/tests/url.c
index 6fb35596..5348d470 100644
--- a/tests/url.c
+++ b/tests/url.c
@@ -27,7 +27,7 @@ TestMain("URLs", {
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_port, "80") == 0);
So(strcmp(url->u_path, "") == 0);
So(strcmp(url->u_rawpath, "") == 0);
So(url->u_query == NULL);
@@ -88,7 +88,7 @@ TestMain("URLs", {
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_port, "80") == 0);
So(strcmp(url->u_path, "/somewhere") == 0);
So(strcmp(url->u_query, "result=yes") == 0);
So(strcmp(url->u_rawpath, "/somewhere?result=yes") == 0);
@@ -104,7 +104,7 @@ TestMain("URLs", {
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_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);
@@ -120,7 +120,7 @@ TestMain("URLs", {
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_port, "80") == 0);
So(strcmp(url->u_path, "/somewhere") == 0);
So(strcmp(url->u_fragment, "chapter2") == 0);
So(strcmp(url->u_rawpath, "/somewhere#chapter2") == 0);
@@ -135,7 +135,7 @@ TestMain("URLs", {
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_port, "80") == 0);
So(strcmp(url->u_fragment, "chapter3") == 0);
So(strcmp(url->u_rawpath, "#chapter3") == 0);
So(url->u_query == NULL);
@@ -150,7 +150,7 @@ TestMain("URLs", {
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_port, "80") == 0);
So(strcmp(url->u_query, "color=red") == 0);
So(strcmp(url->u_rawpath, "?color=red") == 0);
So(url->u_fragment == NULL);
@@ -165,7 +165,7 @@ TestMain("URLs", {
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(strcmp(url->u_port, "80") == 0);
So(url->u_query == NULL);
So(url->u_fragment == NULL);
So(url->u_userinfo == NULL);
@@ -213,6 +213,34 @@ TestMain("URLs", {
nni_url_free(url);
});
+ Convey("ws://", {
+ So(nni_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);
+ nni_url_free(url);
+ });
+
+ Convey("ssh://user@host.example.com", {
+ So(nni_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);
+ nni_url_free(url);
+ });
+
Convey("Negative www.google.com", {
url = NULL;
So(nni_url_parse(&url, "www.google.com") == NNG_EINVAL);