Browse Source

Fix check for URI length to prevent incorrect HTTP 414 errors (#2046)

Brett Profitt 10 months ago
parent
commit
a268d65c4f
2 changed files with 20 additions and 9 deletions
  1. 8 8
      httplib.h
  2. 12 1
      test/test.cc

+ 8 - 8
httplib.h

@@ -7234,14 +7234,6 @@ Server::process_request(Stream &strm, const std::string &remote_addr,
 #endif
 #endif
 
-  // Check if the request URI doesn't exceed the limit
-  if (line_reader.size() > CPPHTTPLIB_REQUEST_URI_MAX_LENGTH) {
-    Headers dummy;
-    detail::read_headers(strm, dummy);
-    res.status = StatusCode::UriTooLong_414;
-    return write_response(strm, close_connection, req, res);
-  }
-
   // Request line and headers
   if (!parse_request_line(line_reader.ptr(), req) ||
       !detail::read_headers(strm, req.headers)) {
@@ -7249,6 +7241,14 @@ Server::process_request(Stream &strm, const std::string &remote_addr,
     return write_response(strm, close_connection, req, res);
   }
 
+  // Check if the request URI doesn't exceed the limit
+  if (req.target.size() > CPPHTTPLIB_REQUEST_URI_MAX_LENGTH) {
+    Headers dummy;
+    detail::read_headers(strm, dummy);
+    res.status = StatusCode::UriTooLong_414;
+    return write_response(strm, close_connection, req, res);
+  }
+
   if (req.get_header_value("Connection") == "close") {
     connection_closed = true;
   }

+ 12 - 1
test/test.cc

@@ -3541,7 +3541,7 @@ TEST_F(ServerTest, LongRequest) {
 
 TEST_F(ServerTest, TooLongRequest) {
   std::string request;
-  for (size_t i = 0; i < 545; i++) {
+  for (size_t i = 0; i < 546; i++) {
     request += "/TooLongRequest";
   }
   request += "_NG";
@@ -3552,6 +3552,17 @@ TEST_F(ServerTest, TooLongRequest) {
   EXPECT_EQ(StatusCode::UriTooLong_414, res->status);
 }
 
+TEST_F(ServerTest, AlmostTooLongRequest) {
+  // test for #2046 - URI length check shouldn't include other content on req line
+  // URI is max URI length, minus 14 other chars in req line (GET, space, leading /, space, HTTP/1.1)
+  std::string request = "/" + string(CPPHTTPLIB_REQUEST_URI_MAX_LENGTH - 14, 'A');
+
+  auto res = cli_.Get(request.c_str());
+
+  ASSERT_TRUE(res);
+  EXPECT_EQ(StatusCode::NotFound_404, res->status);
+}
+
 TEST_F(ServerTest, LongHeader) {
   Request req;
   req.method = "GET";