From 422d7707b4cd45511551f14422d54c685f9caf6e Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Thu, 18 Jun 2015 21:37:58 +0900 Subject: [PATCH] Support IPv6 Zone ID as per RFC 6874 IPv6 scoped address contains Zone ID, which is appended to IPv6 address after '%' separator. RFC 6874 says that Zone ID after '%' must consist of 1*(unreserved or pct-encoded). This commit adds this IPv6 Zone ID support. --- http_parser.c | 26 +++++++++++++++++++++++++ test.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/http_parser.c b/http_parser.c index cbe8a90b..3414896a 100644 --- a/http_parser.c +++ b/http_parser.c @@ -400,6 +400,8 @@ enum http_host_state , s_http_host , s_http_host_v6 , s_http_host_v6_end + , s_http_host_v6_zone_start + , s_http_host_v6_zone , s_http_host_port_start , s_http_host_port }; @@ -2213,6 +2215,23 @@ http_parse_host_char(enum http_host_state s, const char ch) { return s_http_host_v6; } + if (s == s_http_host_v6 && ch == '%') { + return s_http_host_v6_zone_start; + } + break; + + case s_http_host_v6_zone: + if (ch == ']') { + return s_http_host_v6_end; + } + + /* FALLTHROUGH */ + case s_http_host_v6_zone_start: + /* RFC 6874 Zone ID consists of 1*( unreserved / pct-encoded) */ + if (IS_ALPHANUM(ch) || ch == '%' || ch == '.' || ch == '-' || ch == '_' || + ch == '~') { + return s_http_host_v6_zone; + } break; case s_http_host_port: @@ -2263,6 +2282,11 @@ http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { u->field_data[UF_HOST].len++; break; + case s_http_host_v6_zone_start: + case s_http_host_v6_zone: + u->field_data[UF_HOST].len++; + break; + case s_http_host_port: if (s != s_http_host_port) { u->field_data[UF_PORT].off = p - buf; @@ -2292,6 +2316,8 @@ http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { case s_http_host_start: case s_http_host_v6_start: case s_http_host_v6: + case s_http_host_v6_zone_start: + case s_http_host_v6_zone: case s_http_host_port_start: case s_http_userinfo: case s_http_userinfo_start: diff --git a/test.c b/test.c index 4c00571e..a4789a46 100644 --- a/test.c +++ b/test.c @@ -2918,6 +2918,59 @@ const struct url_test url_tests[] = ,.rv=1 /* s_dead */ } +, {.name="ipv6 address with Zone ID" + ,.url="http://[fe80::a%25eth0]/" + ,.is_connect=0 + ,.u= + {.field_set= (1<