@@ -906,7 +906,7 @@ namespace http
906906 uri.clear ();
907907 headers.clear ();
908908 content.clear ();
909- http_version_minor = - 1 ;
909+ version = {} ;
910910 verb = UNKNOWN_VERB;
911911 }
912912
@@ -934,7 +934,7 @@ namespace http
934934 }
935935
936936 // HTTP 1.1 - default is to keep open otherwise default is to close
937- return http_version_minor == 1 ;
937+ return version == HTTP_1_1 ;
938938 }
939939
940940 bool request::is_websocket_req () const
@@ -946,8 +946,8 @@ namespace http
946946
947947 void response::clear ()
948948 {
949- status = unknown;
950- http_version_minor = - 1 ;
949+ status = unknown;
950+ version = {} ;
951951 headers.clear ();
952952 content_str.clear ();
953953 content_file.reset ();
@@ -987,7 +987,7 @@ namespace http
987987 if constexpr (std::is_same_v<Message, request>)
988988 state = method;
989989 else
990- state = http_version ;
990+ state = version ;
991991 body_read = 0 ;
992992 }
993993
@@ -1045,7 +1045,7 @@ namespace http
10451045 if constexpr (std::is_same_v<Message, request>)
10461046 parse_url (buf.substr (0 , end), msg.uri , msg.params , ec);
10471047
1048- state = http_version ;
1048+ state = version ;
10491049 buf.erase (begin (buf), begin (buf) + end + 1 );
10501050 }
10511051
@@ -1055,7 +1055,7 @@ namespace http
10551055 }
10561056
10571057 // HTTP version
1058- else if (state == http_version )
1058+ else if (state == version )
10591059 {
10601060 constexpr std::size_t http_size{8 };
10611061
@@ -1082,7 +1082,7 @@ namespace http
10821082 buf.erase (begin (buf), begin (buf) + http_size + 1 );
10831083 }
10841084
1085- msg.http_version_minor = minor;
1085+ msg.version = (http_version) minor;
10861086 }
10871087
10881088 // Not found
@@ -1131,45 +1131,39 @@ namespace http
11311131 {
11321132 const auto end = buf.find (" \r\n " );
11331133
1134- // Found
1134+ // Sufficient
11351135 if (end != std::string::npos)
11361136 {
11371137 state = header_line;
11381138 buf.erase (begin (buf), begin (buf) + end + 2 );
11391139 }
11401140
1141- // Not Found
1141+ // Insufficient
11421142 else
1143- ec = make_error_code (http_read_bad_status) ;
1143+ break ;
11441144 }
11451145
11461146 // Header line
11471147 else if (state == header_line)
11481148 {
1149- // Find EOL
1150- char * end = strstr (&buf[0 ], " \r\n " );
1149+ const auto end = buf.find (" \r\n " );
11511150
1152- // Not found
1153- if (end == nullptr )
1154- break ;
1155-
1156- // Found
1157- else
1151+ // Sufficient
1152+ if (end != std::string::npos)
11581153 {
1159- *end = ' \0 ' ;
1160-
1161- // Header line
1162- if (std::distance (&buf[0 ], end) > 0 )
1154+ // Found header
1155+ if (end > 0 )
11631156 {
1164- char * kend = strstr (&buf[0 ], " : " );
1157+ std::string_view line (&buf[0 ], end);
1158+ const auto kend = line.find (" : " );
11651159
1166- if (kend == nullptr )
1160+ if (kend == std::string_view::npos )
11671161 ec = make_error_code (http_read_header_kv_delimiter_not_found);
1168-
1162+
11691163 else
11701164 {
1171- auto field = field_enum (std::string_view (&buf[ 0 ], std::distance (&buf[ 0 ], kend) ));
1172- auto value = std::string_view (kend+2 , std::distance (kend+ 2 , end) );
1165+ auto field = field_enum (line. substr ( 0 , kend));
1166+ auto value = line. substr (kend+2 );
11731167
11741168 if (field == unknown_field)
11751169 ec = make_error_code (http_read_header_unsupported_field);
@@ -1196,8 +1190,12 @@ namespace http
11961190 state = done;
11971191 }
11981192
1199- buf.erase (begin (buf), begin (buf) + std::distance (&buf[ 0 ], end + 2 ) );
1193+ buf.erase (begin (buf), begin (buf) + end + 2 );
12001194 }
1195+
1196+ // Insufficient
1197+ else
1198+ break ;
12011199 }
12021200
12031201 // Body
@@ -1289,12 +1287,6 @@ namespace http
12891287 return ;
12901288 }
12911289
1292- if (!(req.http_version_minor == 0 || req.http_version_minor == 1 ))
1293- {
1294- ec = make_error_code (http::http_write_unsupported_http_version);
1295- return ;
1296- }
1297-
12981290 // HTTP requests require "host" field
12991291 if (!contains (req.headers , field::host))
13001292 {
@@ -1320,7 +1312,7 @@ namespace http
13201312 }
13211313
13221314 // Set request line
1323- const std::string status_str = format (" %s %s HTTP/1.%i\r\n " , verb_label (req.verb ).data (), uri_encoded.c_str (), req.http_version_minor );
1315+ const std::string status_str = format (" %s %s HTTP/1.%i\r\n " , verb_label (req.verb ).data (), uri_encoded.c_str (), ( int ) req.version );
13241316
13251317 // Add default connection string if empty
13261318 if (!contains (req.headers , field::connection))
@@ -1340,9 +1332,15 @@ namespace http
13401332
13411333 void serialize_header (response& resp, std::string& buf, std::error_code& ec)
13421334 {
1335+ if (resp.status == unknown)
1336+ {
1337+ ec = make_error_code (http_write_response_missing_status);
1338+ return ;
1339+ }
1340+
13431341 // Set status string
13441342 char status_str[64 ] = {0 };
1345- snprintf (status_str, sizeof (status_str), " HTTP/1.%i %i %s\r\n " , resp.http_version_minor , resp.status , status_label (resp.status ).data ());
1343+ snprintf (status_str, sizeof (status_str), " HTTP/1.%i %i %s\r\n " , ( int ) resp.version , resp.status , status_label (resp.status ).data ());
13461344
13471345 // Add default server string if empty
13481346 if (!contains (resp.headers , field::server))
@@ -1381,17 +1379,17 @@ namespace http
13811379 {
13821380 switch (static_cast <error>(ev))
13831381 {
1384- case http_read_header_line_too_big: return " HTTP header line is too big" ;
1385- case http_read_bad_method: return " HTTP request method bad" ;
1382+ case http_read_header_line_too_big: return " Header line is too big" ;
1383+ case http_read_bad_method: return " Request method bad" ;
13861384 case http_read_unsupported_http_version: return " HTTP version either bad or unsupported" ;
13871385 case http_read_bad_status: return " HTTP status code bad" ;
13881386 case http_read_bad_query_string: return " Bad query string formatting" ;
13891387 case http_read_header_kv_delimiter_not_found: return " Missing delimiter in HTTP header line" ;
13901388 case http_read_header_unsupported_field: return " HTTP header field unsupported" ;
1391- case http_write_unsupported_http_version: return " HTTP message contains bad or unsupported http minor version" ;
13921389 case http_write_request_bad_verb: return " HTTP request contains bad verb" ;
13931390 case http_write_request_missing_uri: return " HTTP request missing URI" ;
13941391 case http_write_request_missing_host: return " HTTP request missing 'host' filed" ;
1392+ case http_write_response_missing_status: return " Missing status code" ;
13951393 case ws_handshake_bad_status: return " Status code not 101 (Switching Protocol) in websocket upgrade response" ;
13961394 case ws_handshake_bad_headers: return " Missing connection: upgrade or upgrade: websocket in HTTP headers" ;
13971395 case ws_handshake_missing_seq_accept: return " Missing seq-websocket-accept in HTTP websocket switching response message" ;
0 commit comments