@@ -1114,6 +1114,11 @@ class stream_line_reader {
11141114 }
11151115 }
11161116
1117+ bool end_with_crlf () const {
1118+ auto end = ptr () + size ();
1119+ return size () >= 2 && end[-2 ] == ' \r ' && end[-1 ] == ' \n ' ;
1120+ }
1121+
11171122 bool getline () {
11181123 fixed_buffer_used_size_ = 0 ;
11191124 glowable_buffer_.clear ();
@@ -1562,34 +1567,33 @@ inline uint64_t get_header_value_uint64(const Headers &headers, const char *key,
15621567}
15631568
15641569inline bool read_headers (Stream &strm, Headers &headers) {
1565- // Horizontal tab and ' ' are considered whitespace and are ignored when on
1566- // the left or right side of the header value:
1567- // - https://stackoverflow.com/questions/50179659/
1568- // - https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html
1569- static std::regex re (R"( (.+?):[\t ]*(.+))" );
1570-
15711570 const auto bufsiz = 2048 ;
15721571 char buf[bufsiz];
1573-
15741572 stream_line_reader line_reader (strm, buf, bufsiz);
15751573
15761574 for (;;) {
15771575 if (!line_reader.getline ()) { return false ; }
1578- const char *end = line_reader.ptr () + line_reader.size ();
1579- auto erase_last_char = [&](char c) {
1580- if (line_reader.ptr () == end || end[-1 ] != c) {
1581- return false ;
1582- }
1576+
1577+ // Check if the line ends with CRLF.
1578+ if (line_reader.end_with_crlf ()) {
1579+ // Blank line indicates end of headers.
1580+ if (line_reader.size () == 2 ) { break ; }
1581+ } else {
1582+ continue ; // Skip invalid line.
1583+ }
1584+
1585+ // Skip trailing spaces and tabs.
1586+ auto end = line_reader.ptr () + line_reader.size () - 2 ;
1587+ while (line_reader.ptr () < end && (end[-1 ] == ' ' || end[-1 ] == ' \t ' )) {
15831588 end--;
1584- return true ;
1585- };
1586- if (!erase_last_char (' \n ' )) { continue ; }
1587- if (!erase_last_char (' \r ' )) { continue ; }
1589+ }
15881590
1589- // Blank line indicates end of headers.
1590- if (line_reader.ptr () == end) { break ; }
1591+ // Horizontal tab and ' ' are considered whitespace and are ignored when on
1592+ // the left or right side of the header value:
1593+ // - https://stackoverflow.com/questions/50179659/
1594+ // - https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html
1595+ static const std::regex re (R"( (.+?):[\t ]*(.+))" );
15911596
1592- while (erase_last_char (' ' ) || erase_last_char (' \t ' )) {}
15931597 std::cmatch m;
15941598 if (std::regex_match (line_reader.ptr (), end, m, re)) {
15951599 auto key = std::string (m[1 ]);
0 commit comments