65 if (
cur ==
end || *cur < '0' || *cur++ >
'1') {
67 "Expected HTTP/1.0 or HTTP/1.1");
72 if (
cur ==
end || *cur < '1' || *cur++ >
'9') {
75 if (
cur ==
end || *cur < '0' || *cur++ >
'9') {
78 if (
cur ==
end || *cur < '0' || *cur++ >
'9') {
81 parser->http.response->status =
82 (
cur[-3] -
'0') * 100 + (
cur[-2] -
'0') * 10 + (
cur[-1] -
'0');
103 "No method on HTTP request line");
105 parser->http.request->method =
106 buf2str(beg,
static_cast<size_t>(
cur - beg - 1));
114 parser->http.request->path =
buf2str(beg,
static_cast<size_t>(
cur - beg - 1));
131 vers_major =
static_cast<uint8_t>(*
cur++ -
'1' + 1);
135 "End of line in HTTP version string");
137 vers_minor =
static_cast<uint8_t>(*
cur++ -
'1' + 1);
139 if (vers_major == 1) {
140 if (vers_minor == 0) {
142 }
else if (vers_minor == 1) {
146 "Expected one of HTTP/1.0, HTTP/1.1, or HTTP/2.0");
148 }
else if (vers_major == 2) {
149 if (vers_minor == 0) {
153 "Expected one of HTTP/1.0, HTTP/1.1, or HTTP/2.0");
157 "Expected one of HTTP/1.0, HTTP/1.1, or HTTP/2.0");
178 size_t* hdr_count =
nullptr;
186 if (*
cur ==
' ' || *
cur ==
'\t') {
188 "Continued header lines not supported yet");
197 "Didn't find ':' in header string");
216 hdr_count = &
parser->http.response->hdr_count;
218 if ((strcmp(hdr.
key,
"Transfer-Encoding") == 0) &&
219 (strcmp(hdr.
value,
"chunked") == 0)) {
224 hdr_count = &
parser->http.request->hdr_count;
229 if (*hdr_count ==
parser->hdr_capacity) {
235 (*hdrs)[(*hdr_count)++] = hdr;
246 bool* found_body_start) {
256 if (
parser->cur_line_length ==
parser->cur_line_end_length) {
259 *found_body_start =
true;
274 "Should never reach here"));
277 parser->cur_line_length = 0;
282 size_t* body_length =
nullptr;
283 char** body =
nullptr;
286 switch (
parser->http.response->chunked_state) {
288 if ((
byte ==
'\r') || (
byte ==
';')) {
289 parser->http.response->chunked_state =
291 }
else if ((
byte >=
'0') && (
byte <=
'9')) {
292 parser->http.response->chunk_length *= 16;
293 parser->http.response->chunk_length +=
byte -
'0';
294 }
else if ((
byte >=
'a') && (
byte <=
'f')) {
295 parser->http.response->chunk_length *= 16;
296 parser->http.response->chunk_length +=
byte -
'a' + 10;
297 }
else if ((
byte >=
'A') && (
byte <=
'F')) {
298 parser->http.response->chunk_length *= 16;
299 parser->http.response->chunk_length +=
byte -
'A' + 10;
302 "Expected chunk size in hexadecimal");
307 if (
parser->http.response->chunk_length == 0) {
315 if (
parser->http.response->chunk_length == 0) {
318 "Expected '\\r\\n' after chunk body");
321 parser->http.response->chunk_length = 0;
324 parser->http.response->chunk_length--;
331 "Expected '\\r\\n' after chunk body");
339 body_length = &
parser->http.response->body_length;
340 body = &
parser->http.response->body;
342 body_length = &
parser->http.request->body_length;
343 body = &
parser->http.request->body;
349 if (*body_length ==
parser->body_capacity) {
353 (*body)[*body_length] =
static_cast<char>(
byte);
360 if (
parser->cur_line_length >= 2 &&
361 parser->cur_line[
parser->cur_line_length - 2] ==
'\r' &&
362 parser->cur_line[
parser->cur_line_length - 1] ==
'\n') {
367 else if (
parser->cur_line_length >= 2 &&
368 parser->cur_line[
parser->cur_line_length - 2] ==
'\n' &&
369 parser->cur_line[
parser->cur_line_length - 1] ==
'\r') {
374 else if (
parser->cur_line_length >= 1 &&
375 parser->cur_line[
parser->cur_line_length - 1] ==
'\n') {
376 parser->cur_line_end_length = 1;
384 bool* found_body_start) {
395 "HTTP header max line length exceeded");
398 parser->cur_line_length++;
412 void* request_or_response) {
416 parser->http.request_or_response = request_or_response;
417 parser->cur_line_end_length = 2;
446 size_t* start_of_body) {
448 bool found_body_start =
false;
452 if (found_body_start && start_of_body !=
nullptr) *start_of_body =
i + 1;