279 if (m_recv_all_headers) {
280 m_recv_all_headers =
false;
281 m_recv_status_line =
false;
284 if (!m_recv_status_line) {
285 m_recv_status_line =
true;
287 std::stringstream ss(header_line);
290 m_resp_protocol = item;
293 m_status_code = std::stol(item);
297 if (m_status_code < 100 || m_status_code >= 600) {
301 auto cr_loc = item.find(
'\r');
302 if (cr_loc != std::string::npos) {
303 m_resp_message = item.substr(0, cr_loc);
305 m_resp_message = item;
310 if (header_line.empty() || header_line ==
"\n" || header_line ==
"\r\n") {
311 m_recv_all_headers =
true;
315 auto found = header_line.find(
":");
316 if (found == std::string::npos) {
320 std::string header_name = header_line.substr(0, found);
326 while (found < header_line.size()) {
327 if (header_line[found] !=
' ') {
break;}
330 std::string header_value = header_line.substr(found);
333 header_value.erase(header_value.find_last_not_of(
" \r\n\t") + 1);
337 auto iter = m_headers.find(header_name);
338 if (iter == m_headers.end()) {
339 m_headers.insert(iter, {header_name, {header_value}});
341 iter->second.push_back(header_value);
344 if (header_name ==
"Allow") {
345 std::string_view val(header_value);
346 while (!val.empty()) {
347 auto found = val.find(
',');
348 auto method = val.substr(0, found);
349 if (method ==
"PROPFIND") {
353 if (found == std::string_view::npos)
break;
354 val = val.substr(found + 1);
359 }
else if (header_name ==
"Content-Length") {
361 m_content_length = std::stoll(header_value);
366 else if (header_name ==
"Content-Type") {
367 std::string_view val(header_value);
368 auto found = val.find(
";");
369 auto first_type = val.substr(0, found);
370 m_multipart_byteranges = first_type ==
"multipart/byteranges";
371 if (m_multipart_byteranges) {
372 auto remainder = val.substr(found + 1);
373 found = remainder.find(
"boundary=");
374 if (found != std::string_view::npos) {
379 else if (header_name ==
"Content-Range") {
380 auto found = header_value.find(
" ");
381 if (found == std::string::npos) {
384 std::string range_unit = header_value.substr(0, found);
385 if (range_unit !=
"bytes") {
388 auto range_resp = header_value.substr(found + 1);
389 found = range_resp.find(
"/");
390 if (found == std::string::npos) {
393 auto incl_range = range_resp.substr(0, found);
394 found = incl_range.find(
"-");
395 if (found == std::string::npos) {
398 auto first_pos = incl_range.substr(0, found);
400 m_response_offset = std::stoll(first_pos);
404 auto last_pos = incl_range.substr(found + 1);
407 last_byte = std::stoll(last_pos);
411 m_content_length = last_byte - m_response_offset + 1;
413 else if (header_name ==
"Location") {
414 m_location = header_value;
415 }
else if (header_name ==
"Digest") {
418 else if (header_name ==
"Etag")
422 m_etag = header_value;
423 m_etag.erase(remove(m_etag.begin(), m_etag.end(),
'\"'), m_etag.end());
425 else if (header_name ==
"Cache-Control")
427 m_cache_control = header_value;
void getline(uchar *buff, int blen)