275 if (m_recv_all_headers) {
276 m_recv_all_headers =
false;
277 m_recv_status_line =
false;
280 if (!m_recv_status_line) {
281 m_recv_status_line =
true;
283 std::stringstream ss(header_line);
286 m_resp_protocol = item;
289 m_status_code = std::stol(item);
293 if (m_status_code < 100 || m_status_code >= 600) {
297 auto cr_loc = item.find(
'\r');
298 if (cr_loc != std::string::npos) {
299 m_resp_message = item.substr(0, cr_loc);
301 m_resp_message = item;
306 if (header_line.empty() || header_line ==
"\n" || header_line ==
"\r\n") {
307 m_recv_all_headers =
true;
311 auto found = header_line.find(
":");
312 if (found == std::string::npos) {
316 std::string header_name = header_line.substr(0, found);
322 while (found < header_line.size()) {
323 if (header_line[found] !=
' ') {
break;}
326 std::string header_value = header_line.substr(found);
329 header_value.erase(header_value.find_last_not_of(
" \r\n\t") + 1);
333 auto iter = m_headers.find(header_name);
334 if (iter == m_headers.end()) {
335 m_headers.insert(iter, {header_name, {header_value}});
337 iter->second.push_back(header_value);
340 if (header_name ==
"Allow") {
341 std::string_view val(header_value);
342 while (!val.empty()) {
343 auto found = val.find(
',');
344 auto method = val.substr(0, found);
345 if (method ==
"PROPFIND") {
349 if (found == std::string_view::npos)
break;
350 val = val.substr(found + 1);
355 }
else if (header_name ==
"Content-Length") {
357 m_content_length = std::stoll(header_value);
362 else if (header_name ==
"Content-Type") {
363 std::string_view val(header_value);
364 auto found = val.find(
";");
365 auto first_type = val.substr(0, found);
366 m_multipart_byteranges = first_type ==
"multipart/byteranges";
367 if (m_multipart_byteranges) {
368 auto remainder = val.substr(found + 1);
369 found = remainder.find(
"boundary=");
370 if (found != std::string_view::npos) {
375 else if (header_name ==
"Content-Range") {
376 auto found = header_value.find(
" ");
377 if (found == std::string::npos) {
380 std::string range_unit = header_value.substr(0, found);
381 if (range_unit !=
"bytes") {
384 auto range_resp = header_value.substr(found + 1);
385 found = range_resp.find(
"/");
386 if (found == std::string::npos) {
389 auto incl_range = range_resp.substr(0, found);
390 found = incl_range.find(
"-");
391 if (found == std::string::npos) {
394 auto first_pos = incl_range.substr(0, found);
396 m_response_offset = std::stoll(first_pos);
400 auto last_pos = incl_range.substr(found + 1);
403 last_byte = std::stoll(last_pos);
407 m_content_length = last_byte - m_response_offset + 1;
409 else if (header_name ==
"Location") {
410 m_location = header_value;
411 }
else if (header_name ==
"Digest") {
414 else if (header_name ==
"Etag")
418 m_etag = header_value;
419 m_etag.erase(remove(m_etag.begin(), m_etag.end(),
'\"'), m_etag.end());
421 else if (header_name ==
"Cache-Control")
423 m_cache_control = header_value;
void getline(uchar *buff, int blen)