@@ -428,19 +428,6 @@ namespace http
428428
429429// ----------------------------------------------------------------------------------------------------------------
430430
431- constexpr char fast_ascii_tolower (const char c)
432- {
433- // The following is a tad faster than std::tolower(c)
434- return (c >= ' A' && c <= ' Z' ) ? (c | 0x20 ) : c;
435- }
436-
437- constexpr bool case_insenstive_equals (std::string_view a, std::string_view b)
438- {
439- return a.size () == b.size () && std::equal (begin (a), end (a), begin (b), [](char ac, char bc) {
440- return fast_ascii_tolower (ac) == fast_ascii_tolower (bc);
441- });
442- }
443-
444431 std::string_view field_label (field f)
445432 {
446433 return FIELDS[f];
@@ -449,7 +436,7 @@ namespace http
449436 field field_enum (std::string_view f)
450437 {
451438 for (unsigned int i = 0 ; i < std::size (FIELDS) ; ++i)
452- if (case_insenstive_equals ( FIELDS[i], f) )
439+ if (FIELDS[i] == f )
453440 return (field)i;
454441 return unknown_field;
455442 }
@@ -979,6 +966,14 @@ namespace http
979966 return is_websocket_message (headers);
980967 }
981968
969+ // ----------------------------------------------------------------------------------------------------------------
970+
971+ constexpr char fast_ascii_tolower (const char c)
972+ {
973+ // The following is a tad faster than std::tolower(c)
974+ return (c >= ' A' && c <= ' Z' ) ? (c | 0x20 ) : c;
975+ }
976+
982977// ----------------------------------------------------------------------------------------------------------------
983978
984979 template <class Message >
@@ -1017,7 +1012,7 @@ namespace http
10171012 if (buf.size () >= max_method_size)
10181013 {
10191014 std::string_view method_str (&buf[0 ], max_method_size);
1020- const auto end = method_str.find (" " );
1015+ const auto end = method_str.find (' ' );
10211016 const verb_type method = verb_enum (method_str.substr (0 , end));
10221017
10231018 // Found
@@ -1043,16 +1038,17 @@ namespace http
10431038 // URI (Request only)
10441039 else if (state == uri)
10451040 {
1046- const auto end = buf. find ( " " );
1041+ auto * end = strchr (&buf[ 0 ], ' ' );
10471042
10481043 // Found
1049- if (end != std::string_view::npos )
1044+ if (end != nullptr )
10501045 {
1046+ const size_t len = std::distance (&buf[0 ], end);
10511047 if constexpr (std::is_same_v<Message, request>)
1052- parse_url (buf. substr ( 0 , end ), msg.uri , msg.params , ec);
1048+ parse_url (std::string_view (&buf[ 0 ],len ), msg.uri , msg.params , ec);
10531049
10541050 state = version;
1055- buf.erase (begin (buf), begin (buf) + end + 1 );
1051+ buf.erase (begin (buf), begin (buf) + len + 1 );
10561052 }
10571053
10581054 // Not found
@@ -1104,12 +1100,13 @@ namespace http
11041100 // Status code (response only)
11051101 else if (state == status_code)
11061102 {
1107- const auto end = buf. find ( " " );
1103+ auto * end = strchr (&buf[ 0 ], ' ' );
11081104
11091105 // Sufficient
1110- if (end != std::string::npos )
1106+ if (end != nullptr )
11111107 {
1112- buf[end] = ' \0 ' ;
1108+ const size_t len = std::distance (&buf[0 ], end);
1109+ *end = ' \0 ' ;
11131110 int status{-1 };
11141111 const int ret = sscanf (&buf[0 ], " %i" , &status);
11151112
@@ -1119,7 +1116,7 @@ namespace http
11191116 if constexpr (std::is_same_v<Message, response>)
11201117 msg.status = (status_type)status;
11211118 state = status_msg;
1122- buf.erase (begin (buf), begin (buf) + end + 1 );
1119+ buf.erase (begin (buf), begin (buf) + len + 1 );
11231120 }
11241121
11251122 // Not found
@@ -1135,13 +1132,13 @@ namespace http
11351132 // Status label
11361133 else if (state == status_msg)
11371134 {
1138- const auto end = buf. find ( " \r\n " );
1135+ auto * end = strstr (&buf[ 0 ], " \r\n " );
11391136
11401137 // Sufficient
1141- if (end != std::string::npos )
1138+ if (end != nullptr )
11421139 {
11431140 state = header_line;
1144- buf.erase (begin (buf), begin (buf) + end + 2 );
1141+ buf.erase (begin (buf), begin (buf) + std::distance (&buf[ 0 ], end) + 2 );
11451142 }
11461143
11471144 // Insufficient
@@ -1152,24 +1149,28 @@ namespace http
11521149 // Header line
11531150 else if (state == header_line)
11541151 {
1155- const auto end = buf. find ( " \r\n " );
1152+ auto * end = strstr (&buf[ 0 ], " \r\n " );
11561153
11571154 // Sufficient
1158- if (end != std::string::npos )
1155+ if (end != nullptr )
11591156 {
1157+ const size_t line_length = std::distance (&buf[0 ], end);
1158+
11601159 // Found header
1161- if (end > 0 )
1160+ if (line_length > 0 )
11621161 {
1163- std::string_view line (&buf[0 ], end);
1164- const auto kend = line.find (" : " );
1162+ auto * kend = strstr (&buf[0 ], " : " );
11651163
1166- if (kend == std::string_view::npos )
1164+ if (kend == nullptr )
11671165 ec = make_error_code (http_read_header_kv_delimiter_not_found);
11681166
11691167 else
11701168 {
1171- auto field = field_enum (line.substr (0 , kend));
1172- auto value = line.substr (kend+2 );
1169+ for (auto * ptr = &buf[0 ] ; ptr != kend ; ++ptr)
1170+ *ptr = fast_ascii_tolower (*ptr);
1171+
1172+ auto field = field_enum (std::string_view (&buf[0 ], std::distance (&buf[0 ], kend)));
1173+ auto value = std::string_view (kend+2 , std::distance (kend+2 , end));
11731174
11741175 if (field == unknown_field)
11751176 ec = make_error_code (http_read_header_unsupported_field);
@@ -1196,7 +1197,7 @@ namespace http
11961197 state = done;
11971198 }
11981199
1199- buf.erase (begin (buf), begin (buf) + end + 2 );
1200+ buf.erase (begin (buf), begin (buf) + line_length + 2 );
12001201 }
12011202
12021203 // Insufficient
0 commit comments