From e0b7bfe78736f4ba917f6111c3a86e7a8f6e281d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juho=20V=C3=A4h=C3=A4-Herttua?= Date: Fri, 2 Dec 2011 23:50:13 +0200 Subject: [PATCH] Backport commit 4314 from nginx to http-parser for IP-literal support. --- http_parser.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/http_parser.c b/http_parser.c index bbeceb0a..19c49528 100644 --- a/http_parser.c +++ b/http_parser.c @@ -231,7 +231,10 @@ enum state , s_req_schema , s_req_schema_slash , s_req_schema_slash_slash + , s_req_host_start , s_req_host + , s_req_host_end + , s_req_host_ip_literal , s_req_port , s_req_path , s_req_query_string_start @@ -315,6 +318,7 @@ enum header_states #define IS_ALPHA(c) (LOWER(c) >= 'a' && LOWER(c) <= 'z') #define IS_NUM(c) ((c) >= '0' && (c) <= '9') #define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c)) +#define IS_LITERAL_CHAR(c) (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f') || (c) == '.' || (c) == ':') #if HTTP_PARSER_STRICT #define IS_URL_CHAR(c) (normal_url_char[(unsigned char) (c)]) @@ -411,7 +415,8 @@ size_t http_parser_execute (http_parser *parser, if (state == s_req_path || state == s_req_schema || state == s_req_schema_slash || state == s_req_schema_slash_slash || state == s_req_port || state == s_req_query_string_start || state == s_req_query_string - || state == s_req_host + || state == s_req_host_start || state == s_req_host || state == s_req_host_end + || state == s_req_host_ip_literal || state == s_req_fragment_start || state == s_req_fragment) url_mark = data; @@ -760,7 +765,7 @@ size_t http_parser_execute (http_parser *parser, */ if (IS_ALPHA(ch) || (parser->method == HTTP_CONNECT && IS_NUM(ch))) { MARK(url); - state = (parser->method == HTTP_CONNECT) ? s_req_host : s_req_schema; + state = (parser->method == HTTP_CONNECT) ? s_req_host_start : s_req_schema; break; } @@ -788,12 +793,23 @@ size_t http_parser_execute (http_parser *parser, case s_req_schema_slash_slash: STRICT_CHECK(ch != '/'); - state = s_req_host; + state = s_req_host_start; break; + case s_req_host_start: + if (ch == '[') { + state = s_req_host_ip_literal; + break; + } + state = s_req_host; + /* fall through */ + case s_req_host: - { if (IS_HOST_CHAR(ch)) break; + /* fall through */ + + case s_req_host_end: + { switch (ch) { case ':': state = s_req_port; @@ -819,6 +835,17 @@ size_t http_parser_execute (http_parser *parser, break; } + case s_req_host_ip_literal: + { + if (IS_LITERAL_CHAR(ch)) break; + if (ch == ']') { + state = s_req_host_end; + break; + } else { + SET_ERRNO(HPE_INVALID_HOST); + } + } + case s_req_port: { if (IS_NUM(ch)) break;