Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/source/common/http/headers.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <string>
4
5
#include "envoy/http/header_map.h"
6
7
#include "source/common/singleton/const_singleton.h"
8
#include "source/common/singleton/threadsafe_singleton.h"
9
10
namespace Envoy {
11
namespace Http {
12
13
// This class allows early override of the x-envoy prefix from bootstrap config,
14
// so that servers can configure their own x-custom-string prefix.
15
//
16
// Once the HeaderValues const singleton has been created, changing the prefix
17
// is disallowed. Essentially this is write-once then read-only.
18
class PrefixValue {
19
public:
20
37.1k
  const char* prefix() {
21
37.1k
    absl::WriterMutexLock lock(&m_);
22
37.1k
    read_ = true;
23
37.1k
    return prefix_.c_str();
24
37.1k
  }
25
26
  // The char* prefix is used directly, so must be available for the interval where prefix() may be
27
  // called.
28
0
  void setPrefix(const char* prefix) {
29
0
    absl::WriterMutexLock lock(&m_);
30
    // The check for unchanged string is purely for integration tests - this
31
    // should not happen in production.
32
0
    RELEASE_ASSERT(!read_ || prefix_ == std::string(prefix),
33
0
                   "Attempting to change the header prefix after it has been used!");
34
0
    if (!read_) {
35
0
      prefix_ = prefix;
36
0
    }
37
0
  }
Unexecuted instantiation: Envoy::Http::PrefixValue::setPrefix(char const*)
Unexecuted instantiation: Envoy::Http::PrefixValue::setPrefix(char const*)
38
39
private:
40
  absl::Mutex m_;
41
  bool read_ = false;
42
  std::string prefix_ = "x-envoy";
43
};
44
45
/**
46
 * These are headers that are used in extension custom O(1) header registration. These headers
47
 * *must* not contain any prefix override headers, as static init order requires that HeaderValues
48
 * be instantiated for the first time after bootstrap is loaded and before the header maps are
49
 * finalized.
50
 */
51
class CustomHeaderValues {
52
public:
53
  const LowerCaseString Accept{"accept"};
54
  const LowerCaseString AcceptEncoding{"accept-encoding"};
55
  const LowerCaseString AccessControlRequestHeaders{"access-control-request-headers"};
56
  const LowerCaseString AccessControlRequestMethod{"access-control-request-method"};
57
  const LowerCaseString AccessControlAllowOrigin{"access-control-allow-origin"};
58
  const LowerCaseString AccessControlAllowHeaders{"access-control-allow-headers"};
59
  const LowerCaseString AccessControlAllowMethods{"access-control-allow-methods"};
60
  const LowerCaseString AccessControlExposeHeaders{"access-control-expose-headers"};
61
  const LowerCaseString AccessControlMaxAge{"access-control-max-age"};
62
  const LowerCaseString AccessControlAllowCredentials{"access-control-allow-credentials"};
63
  const LowerCaseString AccessControlRequestPrviateNetwork{
64
      "access-control-request-private-network"};
65
  const LowerCaseString AccessControlAllowPrviateNetwork{"access-control-allow-private-network"};
66
  const LowerCaseString Age{"age"};
67
  const LowerCaseString AltSvc{"alt-svc"};
68
  const LowerCaseString Authentication{"authentication"};
69
  const LowerCaseString Authorization{"authorization"};
70
  const LowerCaseString CacheControl{"cache-control"};
71
  const LowerCaseString CacheStatus{"cache-status"};
72
  const LowerCaseString CdnLoop{"cdn-loop"};
73
  const LowerCaseString ContentEncoding{"content-encoding"};
74
  const LowerCaseString ConnectAcceptEncoding{"connect-accept-encoding"};
75
  const LowerCaseString ConnectContentEncoding{"connect-content-encoding"};
76
  const LowerCaseString ConnectProtocolVersion{"connect-protocol-version"};
77
  const LowerCaseString ConnectTimeoutMs{"connect-timeout-ms"};
78
  const LowerCaseString Etag{"etag"};
79
  const LowerCaseString Expires{"expires"};
80
  const LowerCaseString GrpcAcceptEncoding{"grpc-accept-encoding"};
81
  const LowerCaseString GrpcEncoding{"grpc-encoding"};
82
  const LowerCaseString GrpcMessageType{"grpc-message-type"};
83
  const LowerCaseString GrpcTimeout{"grpc-timeout"};
84
  const LowerCaseString IfMatch{"if-match"};
85
  const LowerCaseString IfNoneMatch{"if-none-match"};
86
  const LowerCaseString IfModifiedSince{"if-modified-since"};
87
  const LowerCaseString IfUnmodifiedSince{"if-unmodified-since"};
88
  const LowerCaseString IfRange{"if-range"};
89
  const LowerCaseString LastModified{"last-modified"};
90
  const LowerCaseString Origin{"origin"};
91
  const LowerCaseString OtSpanContext{"x-ot-span-context"};
92
  const LowerCaseString Pragma{"pragma"};
93
  const LowerCaseString Referer{"referer"};
94
  const LowerCaseString Vary{"vary"};
95
96
  struct {
97
    const std::string Gzip{"gzip"};
98
    const std::string Identity{"identity"};
99
    const std::string Wildcard{"*"};
100
  } AcceptEncodingValues;
101
102
  struct {
103
    const std::string All{"*"};
104
  } AccessControlAllowOriginValue;
105
106
  struct {
107
    const std::string NoCache{"no-cache"};
108
    const std::string NoCacheMaxAge0{"no-cache, max-age=0"};
109
    const std::string NoTransform{"no-transform"};
110
    const std::string Private{"private"};
111
  } CacheControlValues;
112
113
  struct {
114
    const std::string Brotli{"br"};
115
    const std::string Gzip{"gzip"};
116
    const std::string Zstd{"zstd"};
117
  } ContentEncodingValues;
118
119
  struct {
120
    const std::string True{"true"};
121
  } CORSValues;
122
123
  struct {
124
    const std::string Default{"identity"};
125
  } GrpcAcceptEncodingValues;
126
127
  struct {
128
    const std::string AcceptEncoding{"Accept-Encoding"};
129
    const std::string Wildcard{"*"};
130
  } VaryValues;
131
};
132
133
using CustomHeaders = ConstSingleton<CustomHeaderValues>;
134
135
/**
136
 * Constant HTTP headers and values. All lower case. This group of headers can contain prefix
137
 * override headers.
138
 */
139
class HeaderValues {
140
public:
141
37.1k
  const char* prefix() const { return ThreadSafeSingleton<PrefixValue>::get().prefix(); }
142
143
  const LowerCaseString ProxyAuthenticate{"proxy-authenticate"};
144
  const LowerCaseString ProxyAuthorization{"proxy-authorization"};
145
  const LowerCaseString CapsuleProtocol{"capsule-protocol"};
146
  const LowerCaseString ClientTraceId{"x-client-trace-id"};
147
  const LowerCaseString Connection{"connection"};
148
  const LowerCaseString ContentLength{"content-length"};
149
  const LowerCaseString ContentRange{"content-range"};
150
  const LowerCaseString ContentType{"content-type"};
151
  const LowerCaseString Cookie{"cookie"};
152
  const LowerCaseString Date{"date"};
153
  const LowerCaseString EnvoyAttemptCount{absl::StrCat(prefix(), "-attempt-count")};
154
  const LowerCaseString EnvoyCluster{absl::StrCat(prefix(), "-cluster")};
155
  const LowerCaseString EnvoyDegraded{absl::StrCat(prefix(), "-degraded")};
156
  const LowerCaseString EnvoyDownstreamServiceCluster{
157
      absl::StrCat(prefix(), "-downstream-service-cluster")};
158
  const LowerCaseString EnvoyDownstreamServiceNode{
159
      absl::StrCat(prefix(), "-downstream-service-node")};
160
  const LowerCaseString EnvoyExternalAddress{absl::StrCat(prefix(), "-external-address")};
161
  const LowerCaseString EnvoyForceTrace{absl::StrCat(prefix(), "-force-trace")};
162
  const LowerCaseString EnvoyHedgeOnPerTryTimeout{
163
      absl::StrCat(prefix(), "-hedge-on-per-try-timeout")};
164
  const LowerCaseString EnvoyImmediateHealthCheckFail{
165
      absl::StrCat(prefix(), "-immediate-health-check-fail")};
166
  const LowerCaseString EnvoyIsTimeoutRetry{absl::StrCat(prefix(), "-is-timeout-retry")};
167
  const LowerCaseString EnvoyOriginalUrl{absl::StrCat(prefix(), "-original-url")};
168
  const LowerCaseString EnvoyInternalRequest{absl::StrCat(prefix(), "-internal")};
169
  // TODO(mattklein123): EnvoyIpTags should be a custom header registered with the IP tagging
170
  // filter. We need to figure out if we can remove this header from the set of headers that
171
  // participate in prefix overrides.
172
  const LowerCaseString EnvoyIpTags{absl::StrCat(prefix(), "-ip-tags")};
173
  const LowerCaseString EnvoyMaxRetries{absl::StrCat(prefix(), "-max-retries")};
174
  const LowerCaseString EnvoyNotForwarded{absl::StrCat(prefix(), "-not-forwarded")};
175
  const LowerCaseString EnvoyOriginalDstHost{absl::StrCat(prefix(), "-original-dst-host")};
176
  const LowerCaseString EnvoyOriginalMethod{absl::StrCat(prefix(), "-original-method")};
177
  const LowerCaseString EnvoyOriginalPath{absl::StrCat(prefix(), "-original-path")};
178
  const LowerCaseString EnvoyOverloaded{absl::StrCat(prefix(), "-overloaded")};
179
  const LowerCaseString EnvoyRateLimited{absl::StrCat(prefix(), "-ratelimited")};
180
  const LowerCaseString EnvoyRetryOn{absl::StrCat(prefix(), "-retry-on")};
181
  const LowerCaseString EnvoyRetryGrpcOn{absl::StrCat(prefix(), "-retry-grpc-on")};
182
  const LowerCaseString EnvoyRetriableStatusCodes{
183
      absl::StrCat(prefix(), "-retriable-status-codes")};
184
  const LowerCaseString EnvoyRetriableHeaderNames{
185
      absl::StrCat(prefix(), "-retriable-header-names")};
186
  const LowerCaseString EnvoyUpstreamAltStatName{absl::StrCat(prefix(), "-upstream-alt-stat-name")};
187
  const LowerCaseString EnvoyUpstreamCanary{absl::StrCat(prefix(), "-upstream-canary")};
188
  const LowerCaseString EnvoyUpstreamHostAddress{absl::StrCat(prefix(), "-upstream-host-address")};
189
  const LowerCaseString EnvoyUpstreamHostname{absl::StrCat(prefix(), "-upstream-hostname")};
190
  const LowerCaseString EnvoyUpstreamRequestTimeoutAltResponse{
191
      absl::StrCat(prefix(), "-upstream-rq-timeout-alt-response")};
192
  const LowerCaseString EnvoyUpstreamRequestTimeoutMs{
193
      absl::StrCat(prefix(), "-upstream-rq-timeout-ms")};
194
  const LowerCaseString EnvoyUpstreamRequestPerTryTimeoutMs{
195
      absl::StrCat(prefix(), "-upstream-rq-per-try-timeout-ms")};
196
  const LowerCaseString EnvoyExpectedRequestTimeoutMs{
197
      absl::StrCat(prefix(), "-expected-rq-timeout-ms")};
198
  const LowerCaseString EnvoyUpstreamServiceTime{absl::StrCat(prefix(), "-upstream-service-time")};
199
  const LowerCaseString EnvoyUpstreamHealthCheckedCluster{
200
      absl::StrCat(prefix(), "-upstream-healthchecked-cluster")};
201
  const LowerCaseString EnvoyUpstreamStreamDurationMs{
202
      absl::StrCat(prefix(), "-upstream-stream-duration-ms")};
203
  const LowerCaseString EnvoyDecoratorOperation{absl::StrCat(prefix(), "-decorator-operation")};
204
  const LowerCaseString Expect{"expect"};
205
  const LowerCaseString ForwardedClientCert{"x-forwarded-client-cert"};
206
  const LowerCaseString ForwardedFor{"x-forwarded-for"};
207
  const LowerCaseString ForwardedHost{"x-forwarded-host"};
208
  const LowerCaseString ForwardedPort{"x-forwarded-port"};
209
  const LowerCaseString ForwardedProto{"x-forwarded-proto"};
210
  const LowerCaseString GrpcMessage{"grpc-message"};
211
  const LowerCaseString GrpcStatus{"grpc-status"};
212
  const LowerCaseString GrpcTimeout{"grpc-timeout"};
213
  const LowerCaseString GrpcStatusDetailsBin{"grpc-status-details-bin"};
214
  const LowerCaseString Host{":authority"};
215
  const LowerCaseString HostLegacy{"host"};
216
  const LowerCaseString Http2Settings{"http2-settings"};
217
  const LowerCaseString KeepAlive{"keep-alive"};
218
  const LowerCaseString Location{"location"};
219
  const LowerCaseString Method{":method"};
220
  const LowerCaseString Path{":path"};
221
  const LowerCaseString Protocol{":protocol"};
222
  const LowerCaseString ProxyConnection{"proxy-connection"};
223
  const LowerCaseString ProxyStatus{"proxy-status"};
224
  const LowerCaseString Range{"range"};
225
  const LowerCaseString RequestId{"x-request-id"};
226
  const LowerCaseString Scheme{":scheme"};
227
  const LowerCaseString Server{"server"};
228
  const LowerCaseString SetCookie{"set-cookie"};
229
  const LowerCaseString Status{":status"};
230
  const LowerCaseString TransferEncoding{"transfer-encoding"};
231
  const LowerCaseString TE{"te"};
232
  const LowerCaseString Upgrade{"upgrade"};
233
  const LowerCaseString UserAgent{"user-agent"};
234
  const LowerCaseString Via{"via"};
235
  const LowerCaseString WWWAuthenticate{"www-authenticate"};
236
  const LowerCaseString XContentTypeOptions{"x-content-type-options"};
237
  const LowerCaseString XSquashDebug{"x-squash-debug"};
238
  const LowerCaseString EarlyData{"early-data"};
239
240
  struct {
241
    const std::string Close{"close"};
242
    const std::string Http2Settings{"http2-settings"};
243
    const std::string KeepAlive{"keep-alive"};
244
    const std::string Upgrade{"upgrade"};
245
  } ConnectionValues;
246
247
  struct {
248
    const std::string H2c{"h2c"};
249
    const std::string WebSocket{"websocket"};
250
    const std::string ConnectUdp{"connect-udp"};
251
  } UpgradeValues;
252
253
  struct {
254
    const std::string Text{"text/plain"};
255
    const std::string TextEventStream{"text/event-stream"};
256
    const std::string TextUtf8{"text/plain; charset=UTF-8"}; // TODO(jmarantz): fold this into Text
257
    const std::string Html{"text/html; charset=UTF-8"};
258
    const std::string Connect{"application/connect"};
259
    const std::string ConnectProto{"application/connect+proto"};
260
    const std::string Grpc{"application/grpc"};
261
    const std::string GrpcWeb{"application/grpc-web"};
262
    const std::string GrpcWebProto{"application/grpc-web+proto"};
263
    const std::string GrpcWebText{"application/grpc-web-text"};
264
    const std::string GrpcWebTextProto{"application/grpc-web-text+proto"};
265
    const std::string Json{"application/json"};
266
    const std::string Protobuf{"application/x-protobuf"};
267
    const std::string FormUrlEncoded{"application/x-www-form-urlencoded"};
268
  } ContentTypeValues;
269
270
  struct {
271
    const std::string True{"true"};
272
  } EnvoyImmediateHealthCheckFailValues;
273
274
  struct {
275
    const std::string True{"true"};
276
  } EnvoyInternalRequestValues;
277
278
  struct {
279
    const std::string True{"true"};
280
  } EnvoyOverloadedValues;
281
282
  struct {
283
    const std::string True{"true"};
284
  } EnvoyRateLimitedValues;
285
286
  struct {
287
    const std::string _5xx{"5xx"};
288
    const std::string GatewayError{"gateway-error"};
289
    const std::string ConnectFailure{"connect-failure"};
290
    const std::string EnvoyRateLimited{"envoy-ratelimited"};
291
    const std::string RefusedStream{"refused-stream"};
292
    const std::string Retriable4xx{"retriable-4xx"};
293
    const std::string RetriableStatusCodes{"retriable-status-codes"};
294
    const std::string RetriableHeaders{"retriable-headers"};
295
    const std::string Reset{"reset"};
296
    const std::string Http3PostConnectFailure{"http3-post-connect-failure"};
297
  } EnvoyRetryOnValues;
298
299
  struct {
300
    const std::string Cancelled{"cancelled"};
301
    const std::string DeadlineExceeded{"deadline-exceeded"};
302
    const std::string ResourceExhausted{"resource-exhausted"};
303
    const std::string Unavailable{"unavailable"};
304
    const std::string Internal{"internal"};
305
  } EnvoyRetryOnGrpcValues;
306
307
  struct {
308
    const std::string _100Continue{"100-continue"};
309
  } ExpectValues;
310
311
  struct {
312
    const std::string Connect{"CONNECT"};
313
    const std::string Delete{"DELETE"};
314
    const std::string Get{"GET"};
315
    const std::string Head{"HEAD"};
316
    const std::string Options{"OPTIONS"};
317
    const std::string Patch{"PATCH"};
318
    const std::string Post{"POST"};
319
    const std::string Put{"PUT"};
320
    const std::string Trace{"TRACE"};
321
  } MethodValues;
322
323
  struct {
324
    // per https://tools.ietf.org/html/draft-kinnear-httpbis-http2-transport-02
325
    const std::string Bytestream{"bytestream"};
326
  } ProtocolValues;
327
328
  struct {
329
    const std::string Http{"http"};
330
    const std::string Https{"https"};
331
  } SchemeValues;
332
333
  struct {
334
    const std::string Brotli{"br"};
335
    const std::string Compress{"compress"};
336
    const std::string Chunked{"chunked"};
337
    const std::string Deflate{"deflate"};
338
    const std::string Gzip{"gzip"};
339
    const std::string Identity{"identity"};
340
    const std::string Zstd{"zstd"};
341
  } TransferEncodingValues;
342
343
  struct {
344
    const std::string EnvoyHealthChecker{"Envoy/HC"};
345
  } UserAgentValues;
346
347
  struct {
348
    const std::string Trailers{"trailers"};
349
  } TEValues;
350
351
  struct {
352
    const std::string Nosniff{"nosniff"};
353
  } XContentTypeOptionValues;
354
355
  struct {
356
    const std::string Http10String{"HTTP/1.0"};
357
    const std::string Http11String{"HTTP/1.1"};
358
    const std::string Http2String{"HTTP/2"};
359
    const std::string Http3String{"HTTP/3"};
360
  } ProtocolStrings;
361
};
362
363
using Headers = ConstSingleton<HeaderValues>;
364
365
} // namespace Http
366
} // namespace Envoy