Coverage Report

Created: 2024-09-19 09:45

/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
43.9k
  const char* prefix() {
21
43.9k
    absl::WriterMutexLock lock(&m_);
22
43.9k
    read_ = true;
23
43.9k
    return prefix_.c_str();
24
43.9k
  }
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
43.8k
  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 EnvoyLocalOverloaded{absl::StrCat(prefix(), "-local-overloaded")};
174
  const LowerCaseString EnvoyMaxRetries{absl::StrCat(prefix(), "-max-retries")};
175
  const LowerCaseString EnvoyNotForwarded{absl::StrCat(prefix(), "-not-forwarded")};
176
  const LowerCaseString EnvoyOriginalDstHost{absl::StrCat(prefix(), "-original-dst-host")};
177
  const LowerCaseString EnvoyOriginalMethod{absl::StrCat(prefix(), "-original-method")};
178
  const LowerCaseString EnvoyOriginalPath{absl::StrCat(prefix(), "-original-path")};
179
  const LowerCaseString EnvoyOverloaded{absl::StrCat(prefix(), "-overloaded")};
180
  const LowerCaseString EnvoyDropOverload{absl::StrCat(prefix(), "-drop-overload")};
181
  const LowerCaseString EnvoyRateLimited{absl::StrCat(prefix(), "-ratelimited")};
182
  const LowerCaseString EnvoyRetryOn{absl::StrCat(prefix(), "-retry-on")};
183
  const LowerCaseString EnvoyRetryGrpcOn{absl::StrCat(prefix(), "-retry-grpc-on")};
184
  const LowerCaseString EnvoyRetriableStatusCodes{
185
      absl::StrCat(prefix(), "-retriable-status-codes")};
186
  const LowerCaseString EnvoyRetriableHeaderNames{
187
      absl::StrCat(prefix(), "-retriable-header-names")};
188
  const LowerCaseString EnvoyUpstreamAltStatName{absl::StrCat(prefix(), "-upstream-alt-stat-name")};
189
  const LowerCaseString EnvoyUpstreamCanary{absl::StrCat(prefix(), "-upstream-canary")};
190
  const LowerCaseString EnvoyUpstreamHostAddress{absl::StrCat(prefix(), "-upstream-host-address")};
191
  const LowerCaseString EnvoyUpstreamHostname{absl::StrCat(prefix(), "-upstream-hostname")};
192
  const LowerCaseString EnvoyUpstreamRequestTimeoutAltResponse{
193
      absl::StrCat(prefix(), "-upstream-rq-timeout-alt-response")};
194
  const LowerCaseString EnvoyUpstreamRequestTimeoutMs{
195
      absl::StrCat(prefix(), "-upstream-rq-timeout-ms")};
196
  const LowerCaseString EnvoyUpstreamRequestPerTryTimeoutMs{
197
      absl::StrCat(prefix(), "-upstream-rq-per-try-timeout-ms")};
198
  const LowerCaseString EnvoyExpectedRequestTimeoutMs{
199
      absl::StrCat(prefix(), "-expected-rq-timeout-ms")};
200
  const LowerCaseString EnvoyUpstreamServiceTime{absl::StrCat(prefix(), "-upstream-service-time")};
201
  const LowerCaseString EnvoyUpstreamHealthCheckedCluster{
202
      absl::StrCat(prefix(), "-upstream-healthchecked-cluster")};
203
  const LowerCaseString EnvoyUpstreamStreamDurationMs{
204
      absl::StrCat(prefix(), "-upstream-stream-duration-ms")};
205
  const LowerCaseString EnvoyDecoratorOperation{absl::StrCat(prefix(), "-decorator-operation")};
206
  const LowerCaseString Expect{"expect"};
207
  const LowerCaseString ForwardedClientCert{"x-forwarded-client-cert"};
208
  const LowerCaseString ForwardedFor{"x-forwarded-for"};
209
  const LowerCaseString ForwardedHost{"x-forwarded-host"};
210
  const LowerCaseString ForwardedPort{"x-forwarded-port"};
211
  const LowerCaseString ForwardedProto{"x-forwarded-proto"};
212
  const LowerCaseString GrpcMessage{"grpc-message"};
213
  const LowerCaseString GrpcStatus{"grpc-status"};
214
  const LowerCaseString GrpcTimeout{"grpc-timeout"};
215
  const LowerCaseString GrpcStatusDetailsBin{"grpc-status-details-bin"};
216
  const LowerCaseString Host{":authority"};
217
  const LowerCaseString HostLegacy{"host"};
218
  const LowerCaseString Http2Settings{"http2-settings"};
219
  const LowerCaseString KeepAlive{"keep-alive"};
220
  const LowerCaseString Location{"location"};
221
  const LowerCaseString Method{":method"};
222
  const LowerCaseString Path{":path"};
223
  const LowerCaseString Protocol{":protocol"};
224
  const LowerCaseString ProxyConnection{"proxy-connection"};
225
  const LowerCaseString ProxyStatus{"proxy-status"};
226
  const LowerCaseString Range{"range"};
227
  const LowerCaseString RequestId{"x-request-id"};
228
  const LowerCaseString Scheme{":scheme"};
229
  const LowerCaseString Server{"server"};
230
  const LowerCaseString SetCookie{"set-cookie"};
231
  const LowerCaseString Status{":status"};
232
  const LowerCaseString TransferEncoding{"transfer-encoding"};
233
  const LowerCaseString TE{"te"};
234
  const LowerCaseString Upgrade{"upgrade"};
235
  const LowerCaseString UserAgent{"user-agent"};
236
  const LowerCaseString Via{"via"};
237
  const LowerCaseString WWWAuthenticate{"www-authenticate"};
238
  const LowerCaseString XContentTypeOptions{"x-content-type-options"};
239
  const LowerCaseString XSquashDebug{"x-squash-debug"};
240
  const LowerCaseString EarlyData{"early-data"};
241
242
  struct {
243
    const std::string Close{"close"};
244
    const std::string Http2Settings{"http2-settings"};
245
    const std::string KeepAlive{"keep-alive"};
246
    const std::string Upgrade{"upgrade"};
247
  } ConnectionValues;
248
249
  struct {
250
    const std::string H2c{"h2c"};
251
    const std::string WebSocket{"websocket"};
252
    const std::string ConnectUdp{"connect-udp"};
253
  } UpgradeValues;
254
255
  struct {
256
    const std::string Text{"text/plain"};
257
    const std::string TextEventStream{"text/event-stream"};
258
    const std::string TextUtf8{"text/plain; charset=UTF-8"}; // TODO(jmarantz): fold this into Text
259
    const std::string Html{"text/html; charset=UTF-8"};
260
    const std::string Connect{"application/connect"};
261
    const std::string ConnectProto{"application/connect+proto"};
262
    const std::string Grpc{"application/grpc"};
263
    const std::string GrpcWeb{"application/grpc-web"};
264
    const std::string GrpcWebProto{"application/grpc-web+proto"};
265
    const std::string GrpcWebText{"application/grpc-web-text"};
266
    const std::string GrpcWebTextProto{"application/grpc-web-text+proto"};
267
    const std::string Json{"application/json"};
268
    const std::string Protobuf{"application/x-protobuf"};
269
    const std::string FormUrlEncoded{"application/x-www-form-urlencoded"};
270
    const std::string Thrift{"application/x-thrift"};
271
  } ContentTypeValues;
272
273
  struct {
274
    const std::string True{"true"};
275
  } EnvoyImmediateHealthCheckFailValues;
276
277
  struct {
278
    const std::string True{"true"};
279
  } EnvoyInternalRequestValues;
280
281
  struct {
282
    const std::string True{"true"};
283
  } EnvoyOverloadedValues;
284
285
  struct {
286
    const std::string True{"true"};
287
  } EnvoyDropOverloadValues;
288
289
  struct {
290
    const std::string True{"true"};
291
  } EnvoyRateLimitedValues;
292
293
  struct {
294
    const std::string _5xx{"5xx"};
295
    const std::string GatewayError{"gateway-error"};
296
    const std::string ConnectFailure{"connect-failure"};
297
    const std::string EnvoyRateLimited{"envoy-ratelimited"};
298
    const std::string RefusedStream{"refused-stream"};
299
    const std::string Retriable4xx{"retriable-4xx"};
300
    const std::string RetriableStatusCodes{"retriable-status-codes"};
301
    const std::string RetriableHeaders{"retriable-headers"};
302
    const std::string Reset{"reset"};
303
    const std::string ResetBeforeRequest{"reset-before-request"};
304
    const std::string Http3PostConnectFailure{"http3-post-connect-failure"};
305
  } EnvoyRetryOnValues;
306
307
  struct {
308
    const std::string Cancelled{"cancelled"};
309
    const std::string DeadlineExceeded{"deadline-exceeded"};
310
    const std::string ResourceExhausted{"resource-exhausted"};
311
    const std::string Unavailable{"unavailable"};
312
    const std::string Internal{"internal"};
313
  } EnvoyRetryOnGrpcValues;
314
315
  struct {
316
    const std::string _100Continue{"100-continue"};
317
  } ExpectValues;
318
319
  struct {
320
    const std::string Connect{"CONNECT"};
321
    const std::string Delete{"DELETE"};
322
    const std::string Get{"GET"};
323
    const std::string Head{"HEAD"};
324
    const std::string Options{"OPTIONS"};
325
    const std::string Patch{"PATCH"};
326
    const std::string Post{"POST"};
327
    const std::string Put{"PUT"};
328
    const std::string Trace{"TRACE"};
329
  } MethodValues;
330
331
  struct {
332
    // per https://tools.ietf.org/html/draft-kinnear-httpbis-http2-transport-02
333
    const std::string Bytestream{"bytestream"};
334
  } ProtocolValues;
335
336
  struct {
337
    const std::string Http{"http"};
338
    const std::string Https{"https"};
339
  } SchemeValues;
340
341
  struct {
342
    const std::string Brotli{"br"};
343
    const std::string Compress{"compress"};
344
    const std::string Chunked{"chunked"};
345
    const std::string Deflate{"deflate"};
346
    const std::string Gzip{"gzip"};
347
    const std::string Identity{"identity"};
348
    const std::string Zstd{"zstd"};
349
  } TransferEncodingValues;
350
351
  struct {
352
    const std::string EnvoyHealthChecker{"Envoy/HC"};
353
    const std::string GoBrowser{"Go-browser"};
354
  } UserAgentValues;
355
356
  struct {
357
    const std::string Trailers{"trailers"};
358
  } TEValues;
359
360
  struct {
361
    const std::string Nosniff{"nosniff"};
362
  } XContentTypeOptionValues;
363
364
  struct {
365
    const std::string Http10String{"HTTP/1.0"};
366
    const std::string Http11String{"HTTP/1.1"};
367
    const std::string Http2String{"HTTP/2"};
368
    const std::string Http3String{"HTTP/3"};
369
  } ProtocolStrings;
370
};
371
372
using Headers = ConstSingleton<HeaderValues>;
373
374
} // namespace Http
375
} // namespace Envoy