write the protocol stack to the @a via_string. If @a detailed then do the full stack, otherwise just the "top level" protocol. Returns the number of characters appended to hdr_string (no nul appended).
| 629 | /// If @a detailed then do the full stack, otherwise just the "top level" protocol. |
| 630 | /// Returns the number of characters appended to hdr_string (no nul appended). |
| 631 | int |
| 632 | HttpTransactHeaders::write_hdr_protocol_stack(char *hdr_string, size_t len, ProtocolStackDetail pSDetail, |
| 633 | std::string_view *proto_buf, int n_proto, char separator) |
| 634 | { |
| 635 | char *hdr = hdr_string; // keep original pointer for size computation later. |
| 636 | char *limit = hdr_string + len; |
| 637 | |
| 638 | if (n_proto <= 0 || hdr == nullptr || len <= 0) { |
| 639 | // nothing |
| 640 | } else if (ProtocolStackDetail::Full == pSDetail) { |
| 641 | for (std::string_view *v = proto_buf, *v_limit = proto_buf + n_proto; v < v_limit && (hdr + v->size() + 1) < limit; ++v) { |
| 642 | if (v != proto_buf) { |
| 643 | *hdr++ = separator; |
| 644 | } |
| 645 | memcpy(hdr, v->data(), v->size()); |
| 646 | hdr += v->size(); |
| 647 | } |
| 648 | } else { |
| 649 | std::string_view *proto_end = proto_buf + n_proto; |
| 650 | bool http_1_0_p = std::find(proto_buf, proto_end, IP_PROTO_TAG_HTTP_1_0) != proto_end; |
| 651 | bool http_1_1_p = std::find(proto_buf, proto_end, IP_PROTO_TAG_HTTP_1_1) != proto_end; |
| 652 | |
| 653 | if ((http_1_0_p || http_1_1_p) && hdr + 10 < limit) { |
| 654 | bool tls_p = std::find_if(proto_buf, proto_end, [](std::string_view tag) { return IsPrefixOf("tls/"sv, tag); }) != proto_end; |
| 655 | |
| 656 | memcpy(hdr, "http", 4); |
| 657 | hdr += 4; |
| 658 | if (tls_p) { |
| 659 | *hdr++ = 's'; |
| 660 | } |
| 661 | |
| 662 | // If detail level is compact (RFC 7239 compliant "proto" value for Forwarded field), stop here. |
| 663 | |
| 664 | if (ProtocolStackDetail::Standard == pSDetail) { |
| 665 | *hdr++ = '/'; |
| 666 | bool http_2_p = std::find(proto_buf, proto_end, IP_PROTO_TAG_HTTP_2_0) != proto_end; |
| 667 | bool http_3_p = std::find(proto_buf, proto_end, IP_PROTO_TAG_HTTP_3) != proto_end; |
| 668 | if (http_2_p) { |
| 669 | *hdr++ = '2'; |
| 670 | } else if (http_3_p) { |
| 671 | *hdr++ = '3'; |
| 672 | } else if (http_1_0_p) { |
| 673 | memcpy(hdr, "1.0", 3); |
| 674 | hdr += 3; |
| 675 | } else if (http_1_1_p) { |
| 676 | memcpy(hdr, "1.1", 3); |
| 677 | hdr += 3; |
| 678 | } |
| 679 | } |
| 680 | } |
| 681 | } |
| 682 | return hdr - hdr_string; |
| 683 | } |
| 684 | |
| 685 | /////////////////////////////////////////////////////////////////////////////// |
| 686 | // Name : insert_via_header_in_request |
nothing calls this directly
no test coverage detected