src: 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.

PR-URL: https://github.com/joyent/http-parser/pull/253
Reviewed-By: Fedor Indutny <fedor@indutny.com>
make-http-max-header-size-gyp-configurable
Tatsuhiro Tsujikawa 10 years ago committed by Fedor Indutny
parent ab0b162ef6
commit 7d75dd7325

@ -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
};
@ -2211,6 +2213,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:
@ -2261,6 +2280,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;
@ -2290,6 +2314,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:

@ -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<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PATH)
,.port=0
,.field_data=
{{ 0, 4 } /* UF_SCHEMA */
,{ 8, 14 } /* UF_HOST */
,{ 0, 0 } /* UF_PORT */
,{ 23, 1 } /* UF_PATH */
,{ 0, 0 } /* UF_QUERY */
,{ 0, 0 } /* UF_FRAGMENT */
,{ 0, 0 } /* UF_USERINFO */
}
}
,.rv=0
}
, {.name="ipv6 address with Zone ID, but '%' is not percent-encoded"
,.url="http://[fe80::a%eth0]/"
,.is_connect=0
,.u=
{.field_set= (1<<UF_SCHEMA) | (1<<UF_HOST) | (1<<UF_PATH)
,.port=0
,.field_data=
{{ 0, 4 } /* UF_SCHEMA */
,{ 8, 12 } /* UF_HOST */
,{ 0, 0 } /* UF_PORT */
,{ 21, 1 } /* UF_PATH */
,{ 0, 0 } /* UF_QUERY */
,{ 0, 0 } /* UF_FRAGMENT */
,{ 0, 0 } /* UF_USERINFO */
}
}
,.rv=0
}
, {.name="ipv6 address ending with '%'"
,.url="http://[fe80::a%]/"
,.rv=1 /* s_dead */
}
, {.name="ipv6 address with Zone ID including bad character"
,.url="http://[fe80::a%$HOME]/"
,.rv=1 /* s_dead */
}
, {.name="just ipv6 Zone ID"
,.url="http://[%eth0]/"
,.rv=1 /* s_dead */
}
#if HTTP_PARSER_STRICT
, {.name="tab in URL"

Loading…
Cancel
Save