Coverage Report

Created: 2024-09-19 09:45

/proc/self/cwd/source/common/router/header_parser.h
Line
Count
Source
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
  static absl::StatusOr<std::unique_ptr<HeadersToAddEntry>>
26
16.2k
  create(const HeaderValue& header_value, HeaderAppendAction append_action) {
27
16.2k
    absl::Status creation_status = absl::OkStatus();
28
16.2k
    auto ret = std::unique_ptr<HeadersToAddEntry>(
29
16.2k
        new HeadersToAddEntry(header_value, append_action, creation_status));
30
16.2k
    RETURN_IF_NOT_OK(creation_status);
31
16.2k
    return ret;
32
16.2k
  }
33
  static absl::StatusOr<std::unique_ptr<HeadersToAddEntry>>
34
304k
  create(const HeaderValueOption& header_value_option) {
35
304k
    absl::Status creation_status = absl::OkStatus();
36
304k
    auto ret = std::unique_ptr<HeadersToAddEntry>(
37
304k
        new HeadersToAddEntry(header_value_option, creation_status));
38
304k
    RETURN_IF_NOT_OK(creation_status);
39
304k
    return ret;
40
304k
  }
41
42
  std::string original_value_;
43
  bool add_if_empty_ = false;
44
45
  Formatter::FormatterPtr formatter_;
46
  HeaderAppendAction append_action_;
47
48
protected:
49
  HeadersToAddEntry(const HeaderValue& header_value, HeaderAppendAction append_action,
50
                    absl::Status& creation_status);
51
  HeadersToAddEntry(const HeaderValueOption& header_value_option, absl::Status& creation_status);
52
};
53
54
/**
55
 * HeaderParser manipulates Http::HeaderMap instances. Headers to be added are pre-parsed to select
56
 * between a constant value implementation and a dynamic value implementation based on
57
 * StreamInfo::StreamInfo fields.
58
 */
59
class HeaderParser : public Http::HeaderEvaluator {
60
public:
61
  /*
62
   * @param headers_to_add defines the headers to add during calls to evaluateHeaders
63
   * @return HeaderParserPtr a configured HeaderParserPtr
64
   */
65
  static absl::StatusOr<HeaderParserPtr>
66
  configure(const Protobuf::RepeatedPtrField<HeaderValueOption>& headers_to_add);
67
68
  /*
69
   * @param headers_to_add defines headers to add during calls to evaluateHeaders.
70
   * @param append_action defines action taken to append/overwrite the given value for an existing
71
   * header or to only add this header if it's absent.
72
   * @return HeaderParserPtr a configured HeaderParserPtr.
73
   */
74
  static absl::StatusOr<HeaderParserPtr>
75
  configure(const Protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>& headers_to_add,
76
            HeaderAppendAction append_action);
77
78
  /*
79
   * @param headers_to_add defines headers to add during calls to evaluateHeaders
80
   * @param headers_to_remove defines headers to remove during calls to evaluateHeaders
81
   * @return HeaderParserPtr a configured HeaderParserPtr
82
   */
83
  static absl::StatusOr<HeaderParserPtr>
84
  configure(const Protobuf::RepeatedPtrField<HeaderValueOption>& headers_to_add,
85
            const Protobuf::RepeatedPtrField<std::string>& headers_to_remove);
86
87
7.33k
  static const HeaderParser& defaultParser() {
88
7.33k
    static HeaderParser* instance = new HeaderParser();
89
7.33k
    return *instance;
90
7.33k
  }
91
92
  void evaluateHeaders(Http::HeaderMap& headers, const Formatter::HttpFormatterContext& context,
93
                       const StreamInfo::StreamInfo& stream_info) const override;
94
95
  void evaluateHeaders(Http::HeaderMap& headers, const Formatter::HttpFormatterContext& context,
96
                       const StreamInfo::StreamInfo* stream_info) const;
97
98
  /**
99
   * Helper methods to evaluate methods without explicitly passing request and response headers.
100
   * The method will try to fetch request headers from steam_info. Response headers will always be
101
   * empty.
102
   */
103
30.1k
  void evaluateHeaders(Http::HeaderMap& headers, const StreamInfo::StreamInfo& stream_info) const {
104
30.1k
    evaluateHeaders(headers, {stream_info.getRequestHeaders()}, &stream_info);
105
30.1k
  }
106
1.67k
  void evaluateHeaders(Http::HeaderMap& headers, const StreamInfo::StreamInfo* stream_info) const {
107
1.67k
    evaluateHeaders(headers,
108
1.67k
                    Formatter::HttpFormatterContext{
109
1.67k
                        stream_info == nullptr ? nullptr : stream_info->getRequestHeaders()},
110
1.67k
                    stream_info);
111
1.67k
  }
112
113
  /*
114
   * Same as evaluateHeaders, but returns the modifications that would have been made rather than
115
   * modifying an existing HeaderMap.
116
   * @param stream_info contains additional information about the request.
117
   * @param do_formatting whether or not to evaluate configured transformations; if false, returns
118
   * original values instead.
119
   */
120
  Http::HeaderTransforms getHeaderTransforms(const StreamInfo::StreamInfo& stream_info,
121
                                             bool do_formatting = true) const;
122
123
  static std::string translateMetadataFormat(const std::string& header_value);
124
  static std::string translatePerRequestState(const std::string& header_value);
125
126
protected:
127
85.0k
  HeaderParser() = default;
128
129
private:
130
  std::vector<std::pair<Http::LowerCaseString, std::unique_ptr<HeadersToAddEntry>>> headers_to_add_;
131
  std::vector<Http::LowerCaseString> headers_to_remove_;
132
};
133
134
} // namespace Router
135
} // namespace Envoy