diff --git a/http_parser.c b/http_parser.c index 9941b7ea..ba1374e9 100644 --- a/http_parser.c +++ b/http_parser.c @@ -314,6 +314,8 @@ enum state , s_req_http_HT , s_req_http_HTT , s_req_http_HTTP + , s_req_http_I + , s_req_http_IC , s_req_http_major , s_req_http_dot , s_req_http_minor @@ -1084,11 +1086,17 @@ size_t http_parser_execute (http_parser *parser, case s_req_http_start: switch (ch) { + case ' ': + break; case 'H': UPDATE_STATE(s_req_http_H); break; - case ' ': - break; + case 'I': + if (parser->method == HTTP_SOURCE) { + UPDATE_STATE(s_req_http_I); + break; + } + /* fall through */ default: SET_ERRNO(HPE_INVALID_CONSTANT); goto error; @@ -1110,6 +1118,16 @@ size_t http_parser_execute (http_parser *parser, UPDATE_STATE(s_req_http_HTTP); break; + case s_req_http_I: + STRICT_CHECK(ch != 'C'); + UPDATE_STATE(s_req_http_IC); + break; + + case s_req_http_IC: + STRICT_CHECK(ch != 'E'); + UPDATE_STATE(s_req_http_HTTP); /* Treat "ICE" as "HTTP". */ + break; + case s_req_http_HTTP: STRICT_CHECK(ch != '/'); UPDATE_STATE(s_req_http_major); diff --git a/test.c b/test.c index 681cc88a..115ddcac 100644 --- a/test.c +++ b/test.c @@ -1173,6 +1173,26 @@ const struct message requests[] = ,.headers= { { "Host", "example.com" } } ,.body= "" } + +#define SOURCE_ICE_REQUEST 42 +, {.name = "source request" + ,.type= HTTP_REQUEST + ,.raw= "SOURCE /music/sweet/music ICE/1.0\r\n" + "Host: example.com\r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.method= HTTP_SOURCE + ,.request_path= "/music/sweet/music" + ,.request_url= "/music/sweet/music" + ,.query_string= "" + ,.fragment= "" + ,.num_headers= 1 + ,.headers= { { "Host", "example.com" } } + ,.body= "" + } }; /* * R E S P O N S E S * */ @@ -4268,6 +4288,8 @@ main (void) /// REQUESTS + test_simple("GET / IHTTP/1.0\r\n\r\n", HPE_INVALID_CONSTANT); + test_simple("GET / ICE/1.0\r\n\r\n", HPE_INVALID_CONSTANT); test_simple("GET / HTP/1.1\r\n\r\n", HPE_INVALID_VERSION); test_simple("GET / HTTP/01.1\r\n\r\n", HPE_INVALID_VERSION); test_simple("GET / HTTP/11.1\r\n\r\n", HPE_INVALID_VERSION);