From ed8d1ebaaa4e50058bb1c5a4b2871b66cbbedcc3 Mon Sep 17 00:00:00 2001 From: The-EDev Date: Mon, 1 Nov 2021 12:02:25 +0300 Subject: [PATCH 1/2] Added checks for GET on HTTP/0.9 and any other errors Earlier behavior only checked whether every byte was parsed, which isn't ideal Signed-off-by: The-EDev --- include/crow/http_parser_merged.h | 10 ++++++--- include/crow/parser.h | 4 ++++ tests/unittest.cpp | 34 ++++++++++++++++++++++++++++--- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/include/crow/http_parser_merged.h b/include/crow/http_parser_merged.h index d0ee6cebf..2d2dfaa65 100644 --- a/include/crow/http_parser_merged.h +++ b/include/crow/http_parser_merged.h @@ -1245,9 +1245,7 @@ static const int8_t unhex[256] = case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH, MKCALENDAR */ break; case 'N': parser->method = HTTP_NOTIFY; break; case 'O': parser->method = HTTP_OPTIONS; break; - case 'P': parser->method = HTTP_POST; - /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */ - break; + case 'P': parser->method = HTTP_POST; /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */ break; case 'R': parser->method = HTTP_REPORT; break; case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH */ break; case 'T': parser->method = HTTP_TRACE; break; @@ -1404,6 +1402,12 @@ static const int8_t unhex[256] = break; case CROW_CR: case CROW_LF: + if (parser->method != HTTP_GET) + { + parser->state = s_dead; + CROW_SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } parser->http_major = 0; parser->http_minor = 9; parser->state = (ch == CROW_CR) ? diff --git a/include/crow/parser.h b/include/crow/parser.h index dd96ac7bb..f333451df 100644 --- a/include/crow/parser.h +++ b/include/crow/parser.h @@ -112,6 +112,10 @@ namespace crow }; int nparsed = http_parser_execute(this, &settings_, buffer, length); + if (http_errno != HPE_OK) + { + return false; + } return nparsed == length; } diff --git a/tests/unittest.cpp b/tests/unittest.cpp index 4805239cf..a8c090a21 100644 --- a/tests/unittest.cpp +++ b/tests/unittest.cpp @@ -460,7 +460,34 @@ TEST_CASE("server_handling_error_request") c.receive(asio::buffer(buf, 2048)); FAIL_CHECK(); } catch (std::exception& e) { - // std::cerr << e.what() << std::endl; + CROW_LOG_DEBUG << e.what(); + } + } + app.stop(); +} + +TEST_CASE("server_handling_error_request_http_version") +{ + static char buf[2048]; + SimpleApp app; + CROW_ROUTE(app, "/")([] { return "A"; }); + auto _ = async(launch::async, + [&] { app.bindaddr(LOCALHOST_ADDRESS).port(45451).run(); }); + app.wait_for_server_start(); + std::string sendmsg = "POST /\r\nContent-Length:3\r\nX-HeaderTest: 123\r\n\r\nA=B\r\n"; + asio::io_service is; + { + asio::ip::tcp::socket c(is); + c.connect(asio::ip::tcp::endpoint( + asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); + + c.send(asio::buffer(sendmsg)); + + try { + c.receive(asio::buffer(buf, 2048)); + FAIL_CHECK(); + } catch (std::exception& e) { + CROW_LOG_DEBUG << e.what(); } } app.stop(); @@ -483,9 +510,9 @@ TEST_CASE("multi_server") app2.wait_for_server_start(); std::string sendmsg = - "POST /\r\nContent-Length:3\r\nX-HeaderTest: 123\r\n\r\nA=B\r\n"; - asio::io_service is; + "POST HTTP/1.1 /\r\nContent-Length:3\r\nX-HeaderTest: 123\r\n\r\nA=B\r\n"; { + asio::io_service is; asio::ip::tcp::socket c(is); c.connect(asio::ip::tcp::endpoint( asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); @@ -497,6 +524,7 @@ TEST_CASE("multi_server") } { + asio::io_service is; asio::ip::tcp::socket c(is); c.connect(asio::ip::tcp::endpoint( asio::ip::address::from_string(LOCALHOST_ADDRESS), 45452)); From 9b3f83a06f0147344a6c8392633bd5daab531aa5 Mon Sep 17 00:00:00 2001 From: The-EDev Date: Mon, 1 Nov 2021 21:10:45 +0300 Subject: [PATCH 2/2] Fixed issue in Test message formulation --- tests/unittest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unittest.cpp b/tests/unittest.cpp index a8c090a21..323eac1e3 100644 --- a/tests/unittest.cpp +++ b/tests/unittest.cpp @@ -510,7 +510,7 @@ TEST_CASE("multi_server") app2.wait_for_server_start(); std::string sendmsg = - "POST HTTP/1.1 /\r\nContent-Length:3\r\nX-HeaderTest: 123\r\n\r\nA=B\r\n"; + "POST / HTTP/1.0\r\nContent-Length:3\r\nX-HeaderTest: 123\r\n\r\nA=B\r\n"; { asio::io_service is; asio::ip::tcp::socket c(is);