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