Line data Source code
1 : #pragma once 2 : 3 : #include <string> 4 : #include <vector> 5 : 6 : #include "envoy/access_log/access_log.h" 7 : #include "envoy/config/core/v3/base.pb.h" 8 : #include "envoy/http/header_evaluator.h" 9 : #include "envoy/http/header_map.h" 10 : 11 : #include "source/common/http/header_map_impl.h" 12 : #include "source/common/protobuf/protobuf.h" 13 : 14 : namespace Envoy { 15 : namespace Router { 16 : 17 : class HeaderParser; 18 : using HeaderParserPtr = std::unique_ptr<HeaderParser>; 19 : 20 : using HeaderAppendAction = envoy::config::core::v3::HeaderValueOption::HeaderAppendAction; 21 : using HeaderValueOption = envoy::config::core::v3::HeaderValueOption; 22 : using HeaderValue = envoy::config::core::v3::HeaderValue; 23 : 24 : struct HeadersToAddEntry { 25 : HeadersToAddEntry(const HeaderValue& header_value, HeaderAppendAction append_action); 26 : HeadersToAddEntry(const HeaderValueOption& header_value_option); 27 : 28 : std::string original_value_; 29 : bool add_if_empty_ = false; 30 : 31 : Formatter::FormatterPtr formatter_; 32 : HeaderAppendAction append_action_; 33 : }; 34 : 35 : /** 36 : * HeaderParser manipulates Http::HeaderMap instances. Headers to be added are pre-parsed to select 37 : * between a constant value implementation and a dynamic value implementation based on 38 : * StreamInfo::StreamInfo fields. 39 : */ 40 : class HeaderParser : public Http::HeaderEvaluator { 41 : public: 42 : /* 43 : * @param headers_to_add defines the headers to add during calls to evaluateHeaders 44 : * @return HeaderParserPtr a configured HeaderParserPtr 45 : */ 46 : static HeaderParserPtr 47 : configure(const Protobuf::RepeatedPtrField<HeaderValueOption>& headers_to_add); 48 : 49 : /* 50 : * @param headers_to_add defines headers to add during calls to evaluateHeaders. 51 : * @param append_action defines action taken to append/overwrite the given value for an existing 52 : * header or to only add this header if it's absent. 53 : * @return HeaderParserPtr a configured HeaderParserPtr. 54 : */ 55 : static HeaderParserPtr 56 : configure(const Protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>& headers_to_add, 57 : HeaderAppendAction append_action); 58 : 59 : /* 60 : * @param headers_to_add defines headers to add during calls to evaluateHeaders 61 : * @param headers_to_remove defines headers to remove during calls to evaluateHeaders 62 : * @return HeaderParserPtr a configured HeaderParserPtr 63 : */ 64 : static HeaderParserPtr 65 : configure(const Protobuf::RepeatedPtrField<HeaderValueOption>& headers_to_add, 66 : const Protobuf::RepeatedPtrField<std::string>& headers_to_remove); 67 : 68 1386 : static const HeaderParser& defaultParser() { 69 1386 : static HeaderParser* instance = new HeaderParser(); 70 1386 : return *instance; 71 1386 : } 72 : 73 : void evaluateHeaders(Http::HeaderMap& headers, const Formatter::HttpFormatterContext& context, 74 : const StreamInfo::StreamInfo& stream_info) const override; 75 : 76 : void evaluateHeaders(Http::HeaderMap& headers, const Formatter::HttpFormatterContext& context, 77 : const StreamInfo::StreamInfo* stream_info) const; 78 : 79 : /** 80 : * Helper methods to evaluate methods without explicitly passing request and response headers. 81 : * The method will try to fetch request headers from steam_info. Response headers will always be 82 : * empty. 83 : */ 84 648 : void evaluateHeaders(Http::HeaderMap& headers, const StreamInfo::StreamInfo& stream_info) const { 85 648 : evaluateHeaders(headers, {stream_info.getRequestHeaders()}, &stream_info); 86 648 : } 87 70 : void evaluateHeaders(Http::HeaderMap& headers, const StreamInfo::StreamInfo* stream_info) const { 88 70 : evaluateHeaders(headers, 89 70 : Formatter::HttpFormatterContext{ 90 70 : stream_info == nullptr ? nullptr : stream_info->getRequestHeaders()}, 91 70 : stream_info); 92 70 : } 93 : 94 : /* 95 : * Same as evaluateHeaders, but returns the modifications that would have been made rather than 96 : * modifying an existing HeaderMap. 97 : * @param stream_info contains additional information about the request. 98 : * @param do_formatting whether or not to evaluate configured transformations; if false, returns 99 : * original values instead. 100 : */ 101 : Http::HeaderTransforms getHeaderTransforms(const StreamInfo::StreamInfo& stream_info, 102 : bool do_formatting = true) const; 103 : 104 : static std::string translateMetadataFormat(const std::string& header_value); 105 : static std::string translatePerRequestState(const std::string& header_value); 106 : 107 : protected: 108 428 : HeaderParser() = default; 109 : 110 : private: 111 : std::vector<std::pair<Http::LowerCaseString, HeadersToAddEntry>> headers_to_add_; 112 : std::vector<Http::LowerCaseString> headers_to_remove_; 113 : }; 114 : 115 : } // namespace Router 116 : } // namespace Envoy