380 if (m_recv_all_headers) {
381 m_recv_all_headers =
false;
382 m_recv_status_line =
false;
385 if (!m_recv_status_line) {
386 m_recv_status_line =
true;
388 std::stringstream ss(header_line);
391 m_resp_protocol = item;
394 m_status_code = std::stol(item);
398 if (m_status_code < 100 || m_status_code >= 600) {
402 auto cr_loc = item.find(
'\r');
403 if (cr_loc != std::string::npos) {
404 m_resp_message = item.substr(0, cr_loc);
406 m_resp_message = item;
411 if (header_line.empty() || header_line ==
"\n" || header_line ==
"\r\n") {
412 m_recv_all_headers =
true;
416 auto found = header_line.find(
":");
417 if (found == std::string::npos) {
421 std::string header_name = header_line.substr(0, found);
427 while (found < header_line.size()) {
428 if (header_line[found] !=
' ') {
break;}
431 std::string header_value = header_line.substr(found);
434 header_value.erase(header_value.find_last_not_of(
" \r\n\t") + 1);
438 auto iter = m_headers.find(header_name);
439 if (iter == m_headers.end()) {
440 m_headers.insert(iter, {header_name, {header_value}});
442 iter->second.push_back(header_value);
445 if (header_name ==
"Allow") {
446 std::string_view val(header_value);
447 while (!val.empty()) {
448 auto found = val.find(
',');
449 auto method = val.substr(0, found);
450 if (method ==
"PROPFIND") {
454 if (found == std::string_view::npos)
break;
455 val = val.substr(found + 1);
460 }
else if (header_name ==
"Content-Length") {
462 m_content_length = std::stoll(header_value);
467 else if (header_name ==
"Content-Type") {
468 std::string_view val(header_value);
469 auto found = val.find(
";");
470 auto first_type = val.substr(0, found);
471 m_multipart_byteranges = first_type ==
"multipart/byteranges";
472 if (m_multipart_byteranges) {
473 auto remainder = val.substr(found + 1);
474 found = remainder.find(
"boundary=");
475 if (found != std::string_view::npos) {
480 else if (header_name ==
"Content-Range") {
481 auto found = header_value.find(
" ");
482 if (found == std::string::npos) {
485 std::string range_unit = header_value.substr(0, found);
486 if (range_unit !=
"bytes") {
489 auto range_resp = header_value.substr(found + 1);
490 found = range_resp.find(
"/");
491 if (found == std::string::npos) {
494 auto incl_range = range_resp.substr(0, found);
495 found = incl_range.find(
"-");
496 if (found == std::string::npos) {
499 auto first_pos = incl_range.substr(0, found);
501 m_response_offset = std::stoll(first_pos);
505 auto last_pos = incl_range.substr(found + 1);
508 last_byte = std::stoll(last_pos);
512 m_content_length = last_byte - m_response_offset + 1;
514 else if (header_name ==
"Location") {
515 m_location = header_value;
516 }
else if (header_name ==
"Digest") {
519 else if (header_name ==
"Etag")
523 m_etag = header_value;
524 m_etag.erase(remove(m_etag.begin(), m_etag.end(),
'\"'), m_etag.end());
526 else if (header_name ==
"Cache-Control")
528 m_cache_control = header_value;
void getline(uchar *buff, int blen)