Line data Source code
1 : #pragma once 2 : 3 : #include <functional> 4 : #include <iostream> 5 : #include <memory> 6 : #include <sstream> 7 : #include <vector> 8 : 9 : #include "absl/container/node_hash_map.h" 10 : #include "absl/strings/escaping.h" 11 : #include "fmt/format.h" 12 : #include "fmt/ostream.h" 13 : 14 : namespace Envoy { 15 : namespace Http { 16 : 17 : /** 18 : * Please refer to #2394 for more info about Envoy METADATA. 19 : * Envoy metadata docs can be found at source/docs/h2_metadata.md. 20 : */ 21 : constexpr uint8_t METADATA_FRAME_TYPE = 0x4d; 22 : constexpr uint8_t END_METADATA_FLAG = 0x4; 23 : 24 : // NGHTTP2_MAX_PAYLOADLEN in nghttp2. 25 : // TODO(soya3129): Respect max_frame_size after nghttp2 #1250 is resolved. 26 : constexpr uint64_t METADATA_MAX_PAYLOAD_SIZE = 16384; 27 : 28 : using UnorderedStringMap = absl::node_hash_map<std::string, std::string>; 29 : 30 : class MetadataMap : public UnorderedStringMap { 31 : public: 32 : using UnorderedStringMap::UnorderedStringMap; 33 : 34 0 : friend std::ostream& operator<<(std::ostream& out, const MetadataMap& metadata_map) { 35 0 : out << "metadata map:"; 36 0 : for (const auto& metadata : metadata_map) { 37 0 : out << "\nkey: " << absl::CEscape(metadata.first) 38 0 : << ", value: " << absl::CEscape(metadata.second) << std::endl; 39 0 : } 40 0 : return out; 41 0 : } 42 : }; 43 : 44 : using MetadataMapPtr = std::unique_ptr<MetadataMap>; 45 : 46 : using VectorMetadataMapPtr = std::vector<MetadataMapPtr>; 47 : 48 : class MetadataMapVector : public VectorMetadataMapPtr { 49 : public: 50 : using VectorMetadataMapPtr::VectorMetadataMapPtr; 51 : 52 0 : friend std::ostream& operator<<(std::ostream& out, const MetadataMapVector& metadata_map_vector) { 53 0 : out << "metadata_map_vector:\n"; 54 0 : for (const auto& metadata_map : metadata_map_vector) { 55 0 : out << *metadata_map; 56 0 : } 57 0 : return out; 58 0 : } 59 : }; 60 : 61 : using MetadataCallback = std::function<void(MetadataMapPtr&&)>; 62 : 63 : } // namespace Http 64 : } // namespace Envoy 65 : 66 : // NOLINT(namespace-envoy) 67 : namespace fmt { 68 : 69 : // Specialize printing Envoy::Http::MetadataMap as we need to escape possible 70 : // invalid utf8 string contained in MetadataMap. 71 : template <> struct formatter<Envoy::Http::MetadataMap> { 72 : template <typename ParseContext> 73 0 : FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { 74 0 : return ctx.begin(); 75 0 : } 76 : 77 : template <typename FormatContext> 78 0 : auto format(const Envoy::Http::MetadataMap& map, FormatContext& ctx) -> decltype(ctx.out()) { 79 0 : std::ostringstream out; 80 0 : out << map; 81 0 : auto str = out.str(); 82 0 : return fmt::formatter<std::string>().format(str, ctx); 83 0 : } 84 : }; 85 : 86 : template <> struct formatter<::Envoy::Http::MetadataMapVector> : fmt::ostream_formatter {}; 87 : 88 : } // namespace fmt