e89b4c4
From d1bb7a564e0f92ef2081d3af8b4b7f85a307c38f Mon Sep 17 00:00:00 2001
e89b4c4
From: Edward Thomson <ethomson@edwardthomson.com>
e89b4c4
Date: Fri, 14 Jun 2019 17:37:22 +0100
e89b4c4
Subject: [PATCH] url: treat empty port as default
e89b4c4
e89b4c4
When parsing URLs, treat an empty port (eg `http://hostname:/`) as if it
e89b4c4
were unspecified.  RFC 3986 says:
e89b4c4
e89b4c4
> URI producers and normalizers SHOULD omit the port component and its
e89b4c4
> ":" delimiter if port is empty or if its value would be the same as
e89b4c4
> that of the scheme's default.
e89b4c4
e89b4c4
(Emphasis on the "SHOULD" is mine.)  This indicates that URIs MAY be
e89b4c4
produced with an empty port and the `:` delimiter.
e89b4c4
e89b4c4
Thus, we stop failing if we end host parsing at the port delimiter.
e89b4c4
---
e89b4c4
 http_parser.c |  1 -
e89b4c4
 test.c        | 25 +++++++++++++++++++------
e89b4c4
 2 files changed, 19 insertions(+), 7 deletions(-)
e89b4c4
e89b4c4
diff --git a/http_parser.c b/http_parser.c
e89b4c4
index 4896385..7e268d8 100644
e89b4c4
--- a/http_parser.c
e89b4c4
+++ b/http_parser.c
e89b4c4
@@ -2326,7 +2326,6 @@ http_parse_host(const char * buf, struct http_parser_url *u, int found_at) {
e89b4c4
     case s_http_host_v6:
e89b4c4
     case s_http_host_v6_zone_start:
e89b4c4
     case s_http_host_v6_zone:
e89b4c4
-    case s_http_host_port_start:
e89b4c4
     case s_http_userinfo:
e89b4c4
     case s_http_userinfo_start:
e89b4c4
       return 1;
e89b4c4
diff --git a/test.c b/test.c
e89b4c4
index 0140a18..54eca61 100644
e89b4c4
--- a/test.c
e89b4c4
+++ b/test.c
e89b4c4
@@ -2825,6 +2825,25 @@ const struct url_test url_tests[] =
e89b4c4
   ,.rv=0
e89b4c4
   }
e89b4c4
 
e89b4c4
+, {.name="proxy empty port"
e89b4c4
+  ,.url="http://hostname:/"
e89b4c4
+  ,.is_connect=0
e89b4c4
+  ,.u=
e89b4c4
+    {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH)
e89b4c4
+    ,.port=0
e89b4c4
+    ,.field_data=
e89b4c4
+      {{  0,  4 } /* UF_SCHEMA */
e89b4c4
+      ,{  7,  8 } /* UF_HOST */
e89b4c4
+      ,{  0,  0 } /* UF_PORT */
e89b4c4
+      ,{ 16,  1 } /* UF_PATH */
e89b4c4
+      ,{  0,  0 } /* UF_QUERY */
e89b4c4
+      ,{  0,  0 } /* UF_FRAGMENT */
e89b4c4
+      ,{  0,  0 } /* UF_USERINFO */
e89b4c4
+      }
e89b4c4
+    }
e89b4c4
+  ,.rv=0
e89b4c4
+  }
e89b4c4
+
e89b4c4
 , {.name="CONNECT request"
e89b4c4
   ,.url="hostname:443"
e89b4c4
   ,.is_connect=1
e89b4c4
@@ -3059,12 +3078,6 @@ const struct url_test url_tests[] =
e89b4c4
   ,.rv=1
e89b4c4
   }
e89b4c4
 
e89b4c4
-, {.name="proxy empty port"
e89b4c4
-  ,.url="http://hostname:/"
e89b4c4
-  ,.is_connect=0
e89b4c4
-  ,.rv=1
e89b4c4
-  }
e89b4c4
-
e89b4c4
 , {.name="CONNECT with basic auth"
e89b4c4
   ,.url="a:b@hostname:443"
e89b4c4
   ,.is_connect=1
e89b4c4
-- 
e89b4c4
2.25.1
e89b4c4