diff --git a/sxg_rs/Cargo.toml b/sxg_rs/Cargo.toml index 28721c8f..13db1cb7 100644 --- a/sxg_rs/Cargo.toml +++ b/sxg_rs/Cargo.toml @@ -21,9 +21,11 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] +default = ["strip_id_headers"] js_fetcher = [] js_signer = [] rust_signer = [] +strip_id_headers = [] [dependencies] async-trait = "0.1.50" diff --git a/sxg_rs/src/headers.rs b/sxg_rs/src/headers.rs index 9813d282..f3dad47d 100644 --- a/sxg_rs/src/headers.rs +++ b/sxg_rs/src/headers.rs @@ -12,6 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::http_parser::{ + parse_accept_header, + parse_cache_control_header, + parse_content_type_header, + media_type::MediaType, +}; use std::collections::{BTreeSet, HashMap, HashSet}; use once_cell::sync::Lazy; use crate::http::HeaderFields; @@ -88,7 +94,7 @@ impl Headers { } pub fn validate_as_sxg_payload(&self) -> Result<(), String> { for (k, v) in self.0.iter() { - if STATEFUL_HEADERS.contains(k.as_str()) { + if DONT_SIGN_RESPONSE_HEADERS.contains(k.as_str()) { return Err(format!(r#"A stateful header "{}" is found."#, k)); } if CACHE_CONTROL_HEADERS.contains(k.as_str()) { @@ -122,8 +128,15 @@ impl Headers { use crate::cbor::DataItem; let connection = self.connection_headers(); let mut fields: Vec<(&str, &str)> = vec![]; + let html = self.0.get("content-type").map_or(false, |t| + matches!(parse_content_type_header(t), + Ok(MediaType {primary_type, sub_type, ..}) + if primary_type.eq_ignore_ascii_case("text") && sub_type.eq_ignore_ascii_case("html"))); for (k, v) in self.0.iter() { - if UNCACHED_HEADERS.contains(k.as_str()) || STATEFUL_HEADERS.contains(k.as_str()) || connection.contains(k) { + if STRIP_RESPONSE_HEADERS.contains(k.as_str()) || DONT_SIGN_RESPONSE_HEADERS.contains(k.as_str()) || connection.contains(k) { + continue; + } + if !html && (STRIP_SUBRESOURCE_RESPONSE_HEADERS.contains(k.as_str()) || crate::id_headers::ID_HEADERS.contains(k.as_str())) { continue; } fields.push((k, v)); @@ -156,7 +169,7 @@ impl Headers { pub fn signature_duration(&self) -> Result { // Default to 7 days unless a cache-control directive lowers it. if let Some(value) = self.0.get("cache-control") { - if let Ok(duration) = crate::http_parser::parse_cache_control_header(value) { + if let Ok(duration) = parse_cache_control_header(value) { // https://github.com/google/webpackager/blob/main/docs/cache_requirements.md const MIN_DURATION: Duration = Duration::from_secs(120); return if duration >= MIN_DURATION { @@ -171,7 +184,8 @@ impl Headers { } } -static UNCACHED_HEADERS: Lazy> = Lazy::new(|| { +// These headers are always stripped before signing. +static STRIP_RESPONSE_HEADERS: Lazy> = Lazy::new(|| { vec![ // https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#name-uncached-header-fields "connection", @@ -190,10 +204,37 @@ static UNCACHED_HEADERS: Lazy> = Lazy::new(|| { // https://github.com/google/webpackager/blob/master/docs/cache_requirements.md "variant-key-04", "variants-04", + + ].into_iter().collect() +}); + +// These headers don't affect the semantics of the response inside an +// SXG, but they vary frequently. This prevents the SXG from being used +// as a subresource due to the header-integrity requirement: +// https://github.com/WICG/webpackage/blob/main/explainers/signed-exchange-subresource-substitution.md. +static STRIP_SUBRESOURCE_RESPONSE_HEADERS: Lazy> = Lazy::new(|| { + vec![ + // These headers are standard, but signed headers don't affect the + // browser caching behavior, because the SXG is only stored in the + // referring document's prefetch cache, per + // https://wicg.github.io/webpackage/loading.html#document-prefetched-signed-exchanges-for-navigation. + // The Date header could theoretically have an impact on SXG loading, + // according to + // https://wicg.github.io/webpackage/loading.html#mp-http-network-or-cache-fetch, + // but I don't see evidence of that in + // https://source.chromium.org/chromium/chromium/src/+/main:content/browser/web_package/. + "age", + "date", + "expires", + "last-modified", + "server-timing", + "via", + "warning", ].into_iter().collect() }); -static STATEFUL_HEADERS: Lazy> = Lazy::new(|| { +// These headers prevent signing, unless stripped by the strip_response_headers param. +static DONT_SIGN_RESPONSE_HEADERS: Lazy> = Lazy::new(|| { vec![ // https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#stateful-headers "authentication-control", @@ -229,7 +270,7 @@ static CACHE_CONTROL_HEADERS: Lazy> = Lazy::new(|| { // and either accept_filter != PrefersSxg or its `q` value is 1. fn validate_accept_header(accept: &str, accept_filter: AcceptFilter) -> Result<(), String> { let accept = accept.trim(); - let accept = crate::http_parser::parse_accept_header(accept)?; + let accept = parse_accept_header(accept)?; if accept.len() == 0 { return Err(format!("Accept header is empty")); } @@ -383,4 +424,13 @@ mod tests { assert_eq!(headers(vec![("cache-control", "doesn't even parse")]).signature_duration().unwrap(), SEVEN_DAYS); assert_eq!(headers(vec![("cache-control", "max=, max-age=3600")]).signature_duration().unwrap(), SEVEN_DAYS); } + + // === get_signed_headers_bytes === + #[test] + fn strip_id_headers() { + assert_eq!(headers(vec![("content-type", "image/jpeg"), ("x-request-id", "abcdef123")]).get_signed_headers_bytes(200, &[]), + b"\xA4FdigestMmi-sha256-03=G:statusC200Lcontent-typeJimage/jpegPcontent-encodingLmi-sha256-03"); + assert_eq!(headers(vec![("content-type", "text/html;charset=utf-8"), ("x-request-id", "abcdef123")]).get_signed_headers_bytes(200, &[]), + b"\xA5FdigestMmi-sha256-03=G:statusC200Lcontent-typeWtext/html;charset=utf-8Lx-request-idIabcdef123Pcontent-encodingLmi-sha256-03"); + } } diff --git a/sxg_rs/src/http_parser/mod.rs b/sxg_rs/src/http_parser/mod.rs index fc20e98d..e4eb2a6e 100644 --- a/sxg_rs/src/http_parser/mod.rs +++ b/sxg_rs/src/http_parser/mod.rs @@ -15,11 +15,12 @@ mod accept; mod base; mod cache_control; -mod media_type; +pub mod media_type; use nom::{ IResult, character::complete::char as char1, + combinator::complete, eof, separated_list0, separated_pair, @@ -49,6 +50,12 @@ pub fn parse_accept_header(input: &str) -> Result, String> { parse_vec(input, accept::accept) } +pub fn parse_content_type_header(input: &str) -> Result { + complete(media_type::media_type)(input) + .map(|(_, output)| output) + .map_err(format_nom_err) +} + // Returns the freshness lifetime for a shared cache. pub fn parse_cache_control_header(input: &str) -> Result { let directives = parse_vec(input, cache_control::directive)?; diff --git a/sxg_rs/src/id_headers.rs b/sxg_rs/src/id_headers.rs new file mode 100644 index 00000000..3b78a9f9 --- /dev/null +++ b/sxg_rs/src/id_headers.rs @@ -0,0 +1,1163 @@ +use std::collections::HashSet; +use once_cell::sync::Lazy; + +// The full list of id headers is adds about 37K to the binary, as of writing, +// so users may choose to exclude it. +#[cfg(not(feature="strip_id_headers"))] +pub static ID_HEADERS: Lazy> = Lazy::new(|| HashSet::new()); + +#[cfg(feature="strip_id_headers")] +pub static ID_HEADERS: Lazy> = Lazy::new(|| { + vec![ + // These headers are nonstandard, and don't affect browser behavior at + // all, but appear to be a source of entropy. If included in an SXG, + // they prevent that SXG from being useful as a signed subresource. See + // the comment on STRIP_SUBRESOURCE_RESPONSE_HEADERS for details. + // + // These are things like request IDs, backend server IDs, and cache hit + // status. A useful resource for surveying HTTP response headers is + // https://webtechsurvey.com/common-response-headers. + r#"ag-correlation-id"#, + r#"age"#, + r#"akamai-cache-status"#, + r#"akamai-grn-leg2"#, + r#"akamai-grn"#, + r#"ali-swift-global-savetime"#, + r#"apigw-requestid"#, + r#"apple-timing-app"#, + r#"ar-atime"#, + r#"ar-request-id"#, + r#"ar-sid"#, + r#"art-pagecache-status"#, + r#"auid"#, + r#"authorization"#, + r#"autype"#, + r#"b3"#, + r#"backend-name"#, + r#"backend"#, + r#"be"#, + r#"belfrage-cache-status"#, + r#"bid"#, + r#"bln-server"#, + r#"brequestid"#, + r#"cache-flow"#, + r#"cache-instance-id"#, + r#"cache-miss-to-origin"#, + r#"cache-provider"#, + r#"cache-provider"#, + r#"cache-status"#, + r#"cache-tag"#, + r#"cache-tags"#, + r#"cache"#, + r#"categoryid"#, + r#"cd"#, + r#"cdn-host"#, + r#"cdn-ip"#, + r#"cdn-request-time"#, + r#"cdn-source"#, + r#"cdn-user-ip"#, + r#"cdncip"#, + r#"ce-cache"#, + r#"ce-version"#, + r#"cf-apo-via"#, + r#"cf-cache-status"#, + r#"cf-child-ray"#, + r#"cf-railgun"#, + r#"cf-ray"#, + r#"cf-request-id"#, + r#"ch-request-id"#, + r#"chimera-api-server"#, + r#"cl-cache"#, + r#"cleantemp"#, + r#"client-authentic-ip"#, + r#"client-id"#, + r#"clientip"#, + r#"cluster-host"#, + r#"cluster"#, + r#"cm-edge-cache"#, + r#"cm-route"#, + r#"cm-tx-id"#, + r#"cmsfirstpublishtimestamp"#, + r#"cmsid"#, + r#"cmsts"#, + r#"composite"#, + r#"compression-time"#, + r#"contao-cache"#, + r#"correlation-id"#, + r#"correlationid"#, + r#"cp"#, + r#"cpc-cache"#, + r#"cs-server"#, + r#"cx-notice"#, + r#"date"#, + r#"db-time"#, + r#"dc"#, + r#"debug"#, + r#"deploy-instance"#, + r#"discourse-proxy-id"#, + r#"dn-cache-status"#, + r#"dn-request-id"#, + r#"drupal-pagecache-memcache"#, + r#"du"#, + r#"dynatrace"#, + r#"eagleeye-traceid"#, + r#"eagleid"#, + r#"edge-copy-time"#, + r#"edgeroutingkey"#, + r#"eomportal-instance"#, + r#"excuteaetime"#, + r#"excuteretime"#, + r#"exec-time"#, + r#"execution-time"#, + r#"fai-cache-status"#, + r#"fai-w-agent-aid"#, + r#"fai-w-flow"#, + r#"fastcgi-cache"#, + r#"fc"#, + r#"fnac-datacenter"#, + r#"fnac-modulerouting"#, + r#"fpc-cache-id"#, + r#"fpc-cache-id"#, + r#"fss-cache"#, + r#"fss-proxy"#, + r#"function-execution-id"#, + r#"galileo-status-cache"#, + r#"ghost-age"#, + r#"ghost-cache"#, + r#"global-cdn-age"#, + r#"group"#, + r#"grp"#, + r#"handle-fetch-duration"#, + r#"header"#, + r#"healthy"#, + r#"hn"#, + r#"host-header"#, + r#"hostname"#, + r#"hs-cf-worker-build-number"#, + r#"hs-cf-worker-version"#, + r#"hummingbird-cache"#, + r#"id"#, + r#"idc"#, + r#"ids"#, + r#"igor-pid"#, + r#"iid"#, + r#"imghost"#, + r#"inserted-into-cache-at"#, + r#"ip"#, + r#"is-akamai-cdn"#, + r#"isvarnish"#, + r#"joe-x"#, + r#"ki-edge"#, + r#"kp-cache-status"#, + r#"l5d-success-class"#, + r#"latitude"#, + r#"lb"#, + r#"lmserver"#, + r#"log-origin"#, + r#"log-origin"#, + r#"longitude"#, + r#"m-cache-status"#, + r#"map"#, + r#"medium-fulfilled-by"#, + r#"medium-missing-time"#, + r#"memento-datetime"#, + r#"message-id"#, + r#"meta-geo-continent"#, + r#"meta-geo"#, + r#"microsoftsharepointteamservices"#, + r#"moz-cache-status"#, + r#"mrf-cache-status"#, + r#"mrf-swcacheversion"#, + r#"mrf-tech"#, + r#"ms-cv"#, + r#"n-cache-date"#, + r#"n-cache"#, + r#"name"#, + r#"nc"#, + r#"ncbi-phid"#, + r#"ncbi-sid"#, + r#"nd"#, + r#"nginx-cache"#, + r#"nginx-cqvip"#, + r#"nginx-version"#, + r#"nikkei-app-version"#, + r#"no"#, + r#"node"#, + r#"nodecache"#, + r#"notes"#, + r#"number"#, + r#"o-host"#, + r#"object-status"#, + r#"onion-location"#, + r#"origin-server"#, + r#"ostk-callchainid"#, + r#"pageid"#, + r#"pagesurlcustomfieldinfo"#, + r#"pantheon-trace-id"#, + r#"param"#, + r#"patch-surrogate-key"#, + r#"path"#, + r#"pbs"#, + r#"pd"#, + r#"pinterest-generated-by"#, + r#"pinterest-version"#, + r#"pl-location"#, + r#"popmenu-version"#, + r#"pressidium-rid"#, + r#"processtime"#, + r#"protected"#, + r#"publish-time-in-millis"#, + r#"quizlet-auth-uid"#, + r#"rating"#, + r#"redirectstableidentifier"#, + r#"render-time"#, + r#"req-svc-chain"#, + r#"request-context"#, + r#"request-id"#, + r#"resin-trace"#, + r#"resourcetag"#, + r#"response-time"#, + r#"rlogid"#, + r#"rt-fastcgi-cache"#, + r#"rt-proxy-cache"#, + r#"rtss"#, + r#"s-1k-s"#, + r#"sbgi-rendertime"#, + r#"sd"#, + r#"selected-fe"#, + r#"selected-route"#, + r#"selected"#, + r#"seo-cost-millis"#, + r#"seo-from-app"#, + r#"seo-now-time"#, + r#"seq"#, + r#"ser"#, + r#"served-by"#, + r#"served"#, + r#"servedby"#, + r#"server-host"#, + r#"server-hostname"#, + r#"server-info"#, + r#"server-node"#, + r#"serverid"#, + r#"servername"#, + r#"service-request-id"#, + r#"sesese"#, + r#"sg-optimizer-worker-status"#, + r#"shankrouter"#, + r#"shanktracerid"#, + r#"sii"#, + r#"sn-cache-status"#, + r#"sn-cache"#, + r#"source"#, + r#"spiislatency"#, + r#"spotify-request-id"#, + r#"sprequestduration"#, + r#"sprequestguid"#, + r#"state"#, + r#"sv"#, + r#"tag"#, + r#"tail"#, + r#"tcdn-l2-backend"#, + r#"tcdn-l2-client-ip"#, + r#"tcdn-l2-hits"#, + r#"tcdn-l2-host"#, + r#"tid"#, + r#"time"#, + r#"tmp-set-cookie"#, + r#"tp-cache"#, + r#"tp-l2-cache"#, + r#"trace-id"#, + r#"tracecode"#, + r#"traceid"#, + r#"traceparent"#, + r#"tracking-code"#, + r#"true-client-ip"#, + r#"ts"#, + r#"tsreq"#, + r#"ttl"#, + r#"twc-ak-req-id"#, + r#"twc-connection-speed"#, + r#"twc-geoip-city"#, + r#"twc-geoip-country"#, + r#"twc-geoip-dma"#, + r#"twc-geoip-latlong"#, + r#"twc-geoip-region"#, + r#"twc-locale-group"#, + r#"twc-path-locale"#, + r#"twc-privacy"#, + r#"uber-trace-id"#, + r#"utab"#, + r#"uuid"#, + r#"varnish-age"#, + r#"varnish-cache"#, + r#"vartuoso-cache"#, + r#"versao"#, + r#"visitor-id"#, + r#"vx-cache"#, + r#"w"#, + r#"washserver"#, + r#"wcdn-cacheid"#, + r#"wcdn-connection-duration"#, + r#"wcdn-delivery-duration"#, + r#"wcdn-edge-id"#, + r#"wcdn-edge"#, + r#"wcdn-hosting-waiting-duration"#, + r#"wcdn-nfc-reason"#, + r#"wcdn-rayid"#, + r#"wcdn-status"#, + r#"wcdn-total-duration"#, + r#"webcakes-region"#, + r#"webserver"#, + r#"who-ip"#, + r#"wp-bullet-fastcgi-cache"#, + r#"wp-from-cache-domain"#, + r#"wpo-cache-status"#, + r#"wwgmui"#, + r#"wxu-next-hostname"#, + r#"wzws-ray"#, + r#"x-20m-cache"#, + r#"x-20m-webserver"#, + r#"x-ab-cache"#, + r#"x-ac"#, + r#"x-action-cache"#, + r#"x-activity-id"#, + r#"x-adblock-key"#, + r#"x-adv-varnish"#, + r#"x-age"#, + r#"x-ak-client-rtt"#, + r#"x-ak-country"#, + r#"x-ak-countrydetails"#, + r#"x-ak-request-id"#, + r#"x-akam-sw-version"#, + r#"x-akamai-fwd-auth-data"#, + r#"x-akamai-fwd-auth-sha"#, + r#"x-akamai-fwd-auth-sign"#, + r#"x-akamai-http2"#, + r#"x-akamai-lattitude"#, + r#"x-akamai-longitude"#, + r#"x-akamai-transformed"#, + r#"x-alcache"#, + r#"x-amz-apigw-id"#, + r#"x-amz-cf-id"#, + r#"x-amz-cf-pop"#, + r#"x-amz-id-2"#, + r#"x-amz-meta-mtime"#, + r#"x-amz-meta-publish-time-in-millis"#, + r#"x-amz-meta-shard"#, + r#"x-amz-replication-status"#, + r#"x-amz-request-id"#, + r#"x-amz-rid"#, + r#"x-amz-storage-class"#, + r#"x-amz-version-id"#, + r#"x-amzn-remapped-connection"#, + r#"x-amzn-remapped-date"#, + r#"x-amzn-requestid"#, + r#"x-amzn-trace-id"#, + r#"x-apm-inst-hash"#, + r#"x-apm-svc-key"#, + r#"x-app-info"#, + r#"x-app-server"#, + r#"x-app-version"#, + r#"x-app"#, + r#"x-apple-application-instance"#, + r#"x-apple-application-site"#, + r#"x-apple-jingle-correlation-key"#, + r#"x-apple-partner"#, + r#"x-apple-request-uuid"#, + r#"x-application-context"#, + r#"x-appserver"#, + r#"x-appversion"#, + r#"x-archive-orig-cf-ray"#, + r#"x-archive-orig-cf-request-id"#, + r#"x-archive-orig-connection"#, + r#"x-archive-orig-date"#, + r#"x-archive-orig-expires"#, + r#"x-archive-orig-last-modified"#, + r#"x-archive-src"#, + r#"x-asen"#, + r#"x-atg-version"#, + r#"x-az"#, + r#"x-azure-ref"#, + r#"x-b-cache"#, + r#"x-b-cookie"#, + r#"x-b3-parentspanid"#, + r#"x-b3-sampled"#, + r#"x-b3-spanid"#, + r#"x-b3-traceid-primal"#, + r#"x-b3-traceid"#, + r#"x-b"#, + r#"x-ba-0"#, + r#"x-backend-apache-name"#, + r#"x-backend-id"#, + r#"x-backend-info"#, + r#"x-backend-instance"#, + r#"x-backend-ip"#, + r#"x-backend-name"#, + r#"x-backend-response"#, + r#"x-backend-server"#, + r#"x-backend-time"#, + r#"x-backend"#, + r#"x-balancer"#, + r#"x-bapp-server"#, + r#"x-batcache"#, + r#"x-bb-srvr"#, + r#"x-bbc-edge-cache-status"#, + r#"x-bby-instance-id"#, + r#"x-be2"#, + r#"x-beatles"#, + r#"x-bench-id"#, + r#"x-bereq"#, + r#"x-bigteams-btpfs-schoolid"#, + r#"x-bip"#, + r#"x-bitrix-composite"#, + r#"x-bk"#, + r#"x-bksrc"#, + r#"x-blackstone-api"#, + r#"x-block-status"#, + r#"x-blopf"#, + r#"x-bs"#, + r#"x-byteark-cache"#, + r#"x-byteark-reqid"#, + r#"x-c-cache"#, + r#"x-c"#, + r#"x-cache-action"#, + r#"x-cache-age"#, + r#"x-cache-backend"#, + r#"x-cache-date"#, + r#"x-cache-debug-ttl-convert"#, + r#"x-cache-detail"#, + r#"x-cache-expired-at"#, + r#"x-cache-expiry"#, + r#"x-cache-hit"#, + r#"x-cache-hit"#, + r#"x-cache-hits"#, + r#"x-cache-id"#, + r#"x-cache-lc"#, + r#"x-cache-lookup"#, + r#"x-cache-miss-from"#, + r#"x-cache-missreason"#, + r#"x-cache-namespace"#, + r#"x-cache-node"#, + r#"x-cache-place-uuid"#, + r#"x-cache-ratelimit-remaining"#, + r#"x-cache-reason"#, + r#"x-cache-remote"#, + r#"x-cache-server"#, + r#"x-cache-status-nginx"#, + r#"x-cache-status"#, + r#"x-cache-time"#, + r#"x-cache-timestamp"#, + r#"x-cache-via"#, + r#"x-cache-webcdn"#, + r#"x-cache-why"#, + r#"x-cache"#, + r#"x-cached-by"#, + r#"x-cached-id"#, + r#"x-cached"#, + r#"x-cacheid"#, + r#"x-cachel1n"#, + r#"x-cachel2"#, + r#"x-cachel2n"#, + r#"x-cachestatus"#, + r#"x-cachev"#, + r#"x-cb-server"#, + r#"x-ccdn-origin-time"#, + r#"x-cdn-cache-status"#, + r#"x-cdn-fetch"#, + r#"x-cdn-origin"#, + r#"x-cdn-origin"#, + r#"x-cdn-pop-ip"#, + r#"x-cdn-pop"#, + r#"x-cdn-provider"#, + r#"x-cdn"#, + r#"x-cdnhost"#, + r#"x-cf-ipcountry"#, + r#"x-cf-rayx"#, + r#"x-cgp-info"#, + r#"x-cicero-cache"#, + r#"x-cip"#, + r#"x-city-code"#, + r#"x-city"#, + r#"x-cityhive-cf-mapping"#, + r#"x-ckpd-fst-backend"#, + r#"x-clara-backend-id"#, + r#"x-clara-wadp"#, + r#"x-client-geo-location"#, + r#"x-client-ip"#, + r#"x-clientip"#, + r#"x-cloud-trace-context"#, + r#"x-cloudez-verify"#, + r#"x-cloudmap"#, + r#"x-cluster-name"#, + r#"x-cluster-node"#, + r#"x-cluster"#, + r#"x-comingfrom"#, + r#"x-confluence-request-time"#, + r#"x-connection-hash"#, + r#"x-container-cache-status"#, + r#"x-container-name"#, + r#"x-content"#, + r#"x-context-guid"#, + r#"x-contextid"#, + r#"x-cool"#, + r#"x-correlation-id"#, + r#"x-corvair-pool"#, + r#"x-cos-hash-crc64ecma"#, + r#"x-cos-request-id"#, + r#"x-country-code-real"#, + r#"x-country-code"#, + r#"x-cpu-time"#, + r#"x-csdl-request-id"#, + r#"x-csrf-token"#, + r#"x-d2id"#, + r#"x-daa-tunnel"#, + r#"x-daiquiri-instance"#, + r#"x-data-origin"#, + r#"x-datacenter"#, + r#"x-datadog-origin"#, + r#"x-datadog-parent-id"#, + r#"x-datadog-trace-id"#, + r#"x-datadome-timer"#, + r#"x-date-cache"#, + r#"x-date"#, + r#"x-dbg-cache-miss"#, + r#"x-dbg-process-uptime"#, + r#"x-dbg-request-duration"#, + r#"x-dbg-requests-count"#, + r#"x-dbg-streamdb-requests-bytes"#, + r#"x-dbg-streamdb-requests-count"#, + r#"x-dbg-streamdb-requests-durations"#, + r#"x-dbg-streamdb-requests-items"#, + r#"x-dbg-used-memory-mb"#, + r#"x-dbg-weather-from-ddbb"#, + r#"x-dbg-weather-from-redis"#, + r#"x-dc"#, + r#"x-ddg-cachegen"#, + r#"x-ddosx-request-id"#, + r#"x-debug-cache"#, + r#"x-debug-date"#, + r#"x-debug-featureflag-releaseinprogress"#, + r#"x-debug-here"#, + r#"x-debug-info"#, + r#"x-debug-origin"#, + r#"x-debug-service"#, + r#"x-debug"#, + r#"x-deflate-key"#, + r#"x-dibs-backend"#, + r#"x-dibs-trace-guid"#, + r#"x-dis-request-id"#, + r#"x-dispatcher"#, + r#"x-domain-filter-expire"#, + r#"x-douban-newbid"#, + r#"x-drupal-cache-tags"#, + r#"x-drupal-cache-tags"#, + r#"x-drupal-cache"#, + r#"x-drupal-dynamic-cache"#, + r#"x-dw-request-base-id"#, + r#"x-dw-trace-id"#, + r#"x-dws-c"#, + r#"x-dynatrace"#, + r#"x-e-id"#, + r#"x-ebay-c-request-id"#, + r#"x-ebay-capi-request-correlation-id"#, + r#"x-ebay-core-request-correlation-id"#, + r#"x-ebay-pop-id"#, + r#"x-ebay-pop-id"#, + r#"x-ecache"#, + r#"x-edge-ip"#, + r#"x-edge-location-klb"#, + r#"x-edge-location"#, + r#"x-edge-server"#, + r#"x-edge-timing"#, + r#"x-edge"#, + r#"x-edgeconnect-cache-status"#, + r#"x-edgeconnect-midmile-rtt"#, + r#"x-edgeconnect-origin-mex-latency"#, + r#"x-elapsed-time"#, + r#"x-ems-server"#, + r#"x-end-user-ip"#, + r#"x-end-user-visit-id"#, + r#"x-end-user-visitor-id"#, + r#"x-endurance-cache-level"#, + r#"x-envoy-attempt-count"#, + r#"x-envoy-decorator-operation"#, + r#"x-envoy-upstream-address"#, + r#"x-envoy-upstream-service-time"#, + r#"x-epages-requestid"#, + r#"x-epages-site"#, + r#"x-erf-bev-bev"#, + r#"x-extlb"#, + r#"x-ez-minify-html"#, + r#"x-ez-proxy-out"#, + r#"x-ezoic-cdn"#, + r#"x-f-cache"#, + r#"x-f5-node"#, + r#"x-fa-backend"#, + r#"x-fa-cache"#, + r#"x-farmid"#, + r#"x-faso-server-execution-time"#, + r#"x-faso-timer-multiples-section"#, + r#"x-faso-timer-replace-hw"#, + r#"x-fastcgi-cache-status"#, + r#"x-fastcgi-cache"#, + r#"x-fastly-backend-reqs"#, + r#"x-fastly-backend"#, + r#"x-fastly-cache-status"#, + r#"x-fastly-country-code"#, + r#"x-fastly-info"#, + r#"x-fb-debug"#, + r#"x-fb-trip-id"#, + r#"x-flo-backend-name"#, + r#"x-flo-ff-server-identity"#, + r#"x-flo-geo-conn-speed"#, + r#"x-flo-geo-country-code"#, + r#"x-flo-geo-gmt-offset"#, + r#"x-flo-geo-latitude"#, + r#"x-flo-geo-longitude"#, + r#"x-flo-geo-postal-code"#, + r#"x-flo-info-state-shield"#, + r#"x-flo-info-state"#, + r#"x-flow-id"#, + r#"x-folios-response-time"#, + r#"x-forwarded-backend"#, + r#"x-forwarded-for"#, + r#"x-fpc-key"#, + r#"x-fpc"#, + r#"x-fpfis"#, + r#"x-from-src"#, + r#"x-from"#, + r#"x-frontend"#, + r#"x-fs-uuid"#, + r#"x-ftr-backend-server"#, + r#"x-ftr-balancer"#, + r#"x-ftr-cache-status"#, + r#"x-ftr-expires"#, + r#"x-ftr-request-id"#, + r#"x-fw-hash"#, + r#"x-gag-lb"#, + r#"x-generator-ip"#, + r#"x-generator-reqid"#, + r#"x-generator-time"#, + r#"x-geo-location"#, + r#"x-geoip"#, + r#"x-gg-cache-date"#, + r#"x-gg-cache-status"#, + r#"x-github-request-id"#, + r#"x-gocache-cachestatus"#, + r#"x-goog-generation"#, + r#"x-goog-hash"#, + r#"x-goog-meta-goog-reserved-file-mtime"#, + r#"x-goog-storage-class"#, + r#"x-grid-srcache-fetch"#, + r#"x-grid-srcache-store"#, + r#"x-gt-cache-status"#, + r#"x-gt-from"#, + r#"x-guid"#, + r#"x-guploader-uploadid"#, + r#"x-ha-application-name"#, + r#"x-ha-bot-classification"#, + r#"x-ha-device-type"#, + r#"x-ha-hostname"#, + r#"x-ha-upstream"#, + r#"x-handled-by"#, + r#"x-hashtwo"#, + r#"x-hcom-ctx"#, + r#"x-hcom-info"#, + r#"x-hcom-kes-info"#, + r#"x-hcom-origin-id"#, + r#"x-hcom-styx-info"#, + r#"x-heroku-version"#, + r#"x-highwire-filestream-for"#, + r#"x-highwire-sitecode"#, + r#"x-highwire-smart-code"#, + r#"x-hit"#, + r#"x-hits"#, + r#"x-hostname-vm"#, + r#"x-hs"#, + r#"x-http-via"#, + r#"x-i-sp"#, + r#"x-id"#, + r#"x-idadd"#, + r#"x-idc-id"#, + r#"x-idrequete"#, + r#"x-ig-origin-region"#, + r#"x-ig-push-state"#, + r#"x-ihs-time"#, + r#"x-iij-cache"#, + r#"x-iinfo"#, + r#"x-im-api-version"#, + r#"x-in-apigateway"#, + r#"x-in-apigatewayssl"#, + r#"x-info-template"#, + r#"x-instance"#, + r#"x-internal-host"#, + r#"x-iplb-instance"#, + r#"x-iplb-request-id"#, + r#"x-iprice-cache"#, + r#"x-ips-cached-response"#, + r#"x-irc-cached"#, + r#"x-ireland-cache-status"#, + r#"x-ix-cache-status"#, + r#"x-jets-call-count"#, + r#"x-jets-prewarm-count"#, + r#"x-jimdo-instance"#, + r#"x-jimdo-wid"#, + r#"x-jstor-restarts"#, + r#"x-kinja-build"#, + r#"x-kinja-revision"#, + r#"x-kinja-server"#, + r#"x-kinja"#, + r#"x-kinsta-cache"#, + r#"x-kong-proxy-latency"#, + r#"x-kong-upstream-latency"#, + r#"x-kube-cluster"#, + r#"x-lagoon"#, + r#"x-last-modified"#, + r#"x-lastmod"#, + r#"x-latency"#, + r#"x-lb-cache"#, + r#"x-lb-debug"#, + r#"x-lb-id"#, + r#"x-lb-timing"#, + r#"x-lb"#, + r#"x-li-fabric"#, + r#"x-li-pop"#, + r#"x-li-source-fabric"#, + r#"x-li-uuid"#, + r#"x-lima-id"#, + r#"x-linio-id"#, + r#"x-listing-id"#, + r#"x-litespeed-cache"#, + r#"x-llid"#, + r#"x-loc-id"#, + r#"x-locale"#, + r#"x-location-countrycode"#, + r#"x-location-id"#, + r#"x-location-state"#, + r#"x-location-statelong"#, + r#"x-location"#, + r#"x-log-country"#, + r#"x-logjam-request-id"#, + r#"x-loopia-node"#, + r#"x-lp"#, + r#"x-lt-backend"#, + r#"x-m-log"#, + r#"x-m-reqid"#, + r#"x-magento-cache-debug"#, + r#"x-magento-debug"#, + r#"x-managed-by"#, + r#"x-market-req-id"#, + r#"x-mc-cache"#, + r#"x-mcache"#, + r#"x-mcf-id"#, + r#"x-media"#, + r#"x-meli-trace-site"#, + r#"x-midtier"#, + r#"x-miniprofiler-ids"#, + r#"x-miss"#, + r#"x-mns-back"#, + r#"x-mns-cache-hits"#, + r#"x-mns-cache"#, + r#"x-mns-front"#, + r#"x-mol-georesp"#, + r#"x-mono"#, + r#"x-mp-caching-rules"#, + r#"x-mp-node"#, + r#"x-mp-pxnode"#, + r#"x-mrf-age"#, + r#"x-mrf-lastmod"#, + r#"x-mrf-rendered"#, + r#"x-mrs-age"#, + r#"x-mrs-cache-hits"#, + r#"x-mrs-cache"#, + r#"x-ms-invokeapp"#, + r#"x-msedge-ref"#, + r#"x-mshield-cache-status"#, + r#"x-msig"#, + r#"x-mti"#, + r#"x-n-operationid"#, + r#"x-nbi-powered-by"#, + r#"x-neowing-server"#, + r#"x-newrelic-app-data"#, + r#"x-nf-request-id"#, + r#"x-nga-server"#, + r#"x-nginx-cache-status"#, + r#"x-nginx-cache"#, + r#"x-nginx-country"#, + r#"x-nginx-host"#, + r#"x-nginx-hostname"#, + r#"x-nginx-ip"#, + r#"x-nginx-pool"#, + r#"x-nginx-upstream-cache-status"#, + r#"x-nginx"#, + r#"x-niconico-sid"#, + r#"x-nids-serverid"#, + r#"x-nitro-cache"#, + r#"x-nlb"#, + r#"x-nocache"#, + r#"x-node-id"#, + r#"x-node-name"#, + r#"x-node-ref"#, + r#"x-node-updated-at"#, + r#"x-node"#, + r#"x-note"#, + r#"x-np-uuid"#, + r#"x-ntj-investigation-id"#, + r#"x-nws-log-uuid"#, + r#"x-nws-uuid-verify"#, + r#"x-nyt-data-last-modified"#, + r#"x-nyt-route"#, + r#"x-o3-trace-id"#, + r#"x-ocm-cache"#, + r#"x-ocm-geo"#, + r#"x-ocm-srv"#, + r#"x-ocs-country-gid"#, + r#"x-opencart-lightning"#, + r#"x-opnet-transaction-trace"#, + r#"x-origin-cache-status"#, + r#"x-origin-cache"#, + r#"x-origin-date"#, + r#"x-origin-region"#, + r#"x-origin-response-time"#, + r#"x-origin-server"#, + r#"x-origin-time"#, + r#"x-origin-timestamp"#, + r#"x-origin"#, + r#"x-original-request-id"#, + r#"x-oss-hash-crc64ecma"#, + r#"x-oss-request-id"#, + r#"x-oss-server-time"#, + r#"x-oss-storage-class"#, + r#"x-page-cache"#, + r#"x-page-generation-duration-ms"#, + r#"x-page-impression-id"#, + r#"x-pantheon-styx-hostname"#, + r#"x-parent-response-time"#, + r#"x-passed-to-beforedispatch"#, + r#"x-passed-to-dll"#, + r#"x-passed-to-postprocessresponse"#, + r#"x-passed-to"#, + r#"x-patreon-uuid"#, + r#"x-phapp"#, + r#"x-pid"#, + r#"x-pindex"#, + r#"x-pinterest-rid"#, + r#"x-platform-cache"#, + r#"x-platform-cluster"#, + r#"x-platform-processor"#, + r#"x-platform-router"#, + r#"x-platform-server"#, + r#"x-plenty-shop-version"#, + r#"x-pool"#, + r#"x-postal-code"#, + r#"x-powered-by"#, + r#"x-powered-cms"#, + r#"x-prerender-requestid"#, + r#"x-presslabs-stats"#, + r#"x-process-id"#, + r#"x-processing-time"#, + r#"x-prophoto-cache"#, + r#"x-proxied"#, + r#"x-proxy-backend"#, + r#"x-proxy-build"#, + r#"x-proxy-cache-g-jp"#, + r#"x-proxy-cache"#, + r#"x-proxy-cacher9"#, + r#"x-proxy-host"#, + r#"x-proxy-id-backend"#, + r#"x-proxy-node"#, + r#"x-proxy-serve"#, + r#"x-proxy"#, + r#"x-ps"#, + r#"x-px"#, + r#"x-q-stat"#, + r#"x-qiniu-zone"#, + r#"x-queue-time"#, + r#"x-rack-cache"#, + r#"x-ratelimit-remaining"#, + r#"x-ratelimit-reset"#, + r#"x-ray-id"#, + r#"x-ray"#, + r#"x-rcms-hash"#, + r#"x-rcs-cachezone"#, + r#"x-re-ref"#, + r#"x-readtime"#, + r#"x-real-ip"#, + r#"x-redis-calls"#, + r#"x-redis-time"#, + r#"x-redis"#, + r#"x-region"#, + r#"x-removed-set-cookie"#, + r#"x-renderdate"#, + r#"x-renderer-svc"#, + r#"x-rendertron-cached"#, + r#"x-reqid"#, + r#"x-request-device-id"#, + r#"x-request-guid"#, + r#"x-request-host"#, + r#"x-request-id"#, + r#"x-request-processing-time"#, + r#"x-request-received-at"#, + r#"x-request-received"#, + r#"x-request-remains"#, + r#"x-request-source"#, + r#"x-request-time"#, + r#"x-request-uuid"#, + r#"x-requestid"#, + r#"x-requestuuid"#, + r#"x-resource-location"#, + r#"x-resp-is-stale"#, + r#"x-responding-instance"#, + r#"x-response-served-from"#, + r#"x-response-server"#, + r#"x-response-source"#, + r#"x-response-start-timestamp-ms"#, + r#"x-response-time"#, + r#"x-returned-from-beforedispatch"#, + r#"x-returned-from-dll"#, + r#"x-returned-from-postprocessresponse"#, + r#"x-returned-from"#, + r#"x-rev2-worker"#, + r#"x-revision"#, + r#"x-rid"#, + r#"x-rn-rsrv"#, + r#"x-robots-tag"#, + r#"x-route"#, + r#"x-routing-service"#, + r#"x-rpw-version"#, + r#"x-rq"#, + r#"x-rs-ben-time"#, + r#"x-rs-ben"#, + r#"x-rs-ops"#, + r#"x-rs-time"#, + r#"x-runtime"#, + r#"x-s-cookie"#, + r#"x-s"#, + r#"x-safe-firewall"#, + r#"x-save-date"#, + r#"x-sb"#, + r#"x-sbistracker"#, + r#"x-sc"#, + r#"x-scale"#, + r#"x-scl-version"#, + r#"x-scm-server-number"#, + r#"x-scoop-last-modified"#, + r#"x-scope-id"#, + r#"x-scouter-gxid"#, + r#"x-sdfe-corr-id"#, + r#"x-secng-response"#, + r#"x-sedo-campaign-id"#, + r#"x-sedo-request-id"#, + r#"x-seen-by"#, + r#"x-ser"#, + r#"x-served-by-cc"#, + r#"x-served-by-fetch"#, + r#"x-served-by"#, + r#"x-servedby"#, + r#"x-server-cache"#, + r#"x-server-cookie"#, + r#"x-server-etag"#, + r#"x-server-id"#, + r#"x-server-identity"#, + r#"x-server-info"#, + r#"x-server-ip"#, + r#"x-server-l"#, + r#"x-server-name"#, + r#"x-server-w"#, + r#"x-server"#, + r#"x-serverd-by"#, + r#"x-servername"#, + r#"x-session-id"#, + r#"x-sessionid"#, + r#"x-sgs-source"#, + r#"x-sh-cache-status"#, + r#"x-shardid"#, + r#"x-shield-request-id"#, + r#"x-shopid"#, + r#"x-shopify-stage"#, + r#"x-shopkit-environment"#, + r#"x-shops-show-cache-hit"#, + r#"x-shp-request-id"#, + r#"x-sid"#, + r#"x-simplero-server"#, + r#"x-site-speedup"#, + r#"x-site"#, + r#"x-siteid"#, + r#"x-sitename"#, + r#"x-so"#, + r#"x-songwhip-edge-cache"#, + r#"x-soro"#, + r#"x-source"#, + r#"x-sp-farm"#, + r#"x-sp-uniquename"#, + r#"x-speed-cache"#, + r#"x-sql-calls"#, + r#"x-sql-time"#, + r#"x-srcache-fetch-status"#, + r#"x-srcache-store-status"#, + r#"x-srv-ip"#, + r#"x-srv"#, + r#"x-sso"#, + r#"x-ssr-cache-expires"#, + r#"x-ssr-cache-refresh-s"#, + r#"x-stackifyid"#, + r#"x-storage"#, + r#"x-stream-path"#, + r#"x-stx-cdn"#, + r#"x-stx-fetch"#, + r#"x-stx-now"#, + r#"x-styx-info"#, + r#"x-styx-req-id"#, + r#"x-sucuri-cache"#, + r#"x-sucuri-id"#, + r#"x-svr-id"#, + r#"x-svr"#, + r#"x-swift-cachetime"#, + r#"x-swift-savetime"#, + r#"x-symfony-cache"#, + r#"x-targeo-seoproxy"#, + r#"x-tb-optimization-total-bytes-saved"#, + r#"x-td-group"#, + r#"x-td-idcontent"#, + r#"x-thanos"#, + r#"x-thinkindot-l1"#, + r#"x-time-exec"#, + r#"x-time"#, + r#"x-timeas"#, + r#"x-timer"#, + r#"x-timestamp"#, + r#"x-timing-wait"#, + r#"x-tip"#, + r#"x-tlo-hostname"#, + r#"x-tm-source"#, + r#"x-tncms"#, + r#"x-tr"#, + r#"x-trace-id"#, + r#"x-trace"#, + r#"x-traceid"#, + r#"x-tracking-id"#, + r#"x-tradeindia-request-guid"#, + r#"x-trans-id"#, + r#"x-transaction-id"#, + r#"x-transaction"#, + r#"x-transip-backend"#, + r#"x-transip-balancer"#, + r#"x-true-client-ip"#, + r#"x-tserver"#, + r#"x-tt-logid"#, + r#"x-tt-trace-host"#, + r#"x-tt-trace-tag"#, + r#"x-tumblr-pixel-0"#, + r#"x-tumblr-pixel-1"#, + r#"x-tumblr-pixel-2"#, + r#"x-tumblr-pixel-2"#, + r#"x-tumblr-pixel-3"#, + r#"x-tumblr-pixel-4"#, + r#"x-tumblr-pixel"#, + r#"x-tx-id"#, + r#"x-typo3-parsetime"#, + r#"x-uber-edge"#, + r#"x-ufs-node"#, + r#"x-uin"#, + r#"x-unbounce-pageid"#, + r#"x-unbounce-visitorid"#, + r#"x-uniq-id"#, + r#"x-unique-id"#, + r#"x-unit"#, + r#"x-upstream-address"#, + r#"x-upstream-ct"#, + r#"x-upstream-ht"#, + r#"x-upstream-ip"#, + r#"x-upstream"#, + r#"x-urp"#, + r#"x-uuid"#, + r#"x-v-cache"#, + r#"x-vanilla-version"#, + r#"x-var-cache"#, + r#"x-var-stor"#, + r#"x-varcache"#, + r#"x-varcache"#, + r#"x-variti-ccr"#, + r#"x-varnish-age"#, + r#"x-varnish-cache"#, + r#"x-varnish-cache"#, + r#"x-varnish-debug-age"#, + r#"x-varnish-debug-hits"#, + r#"x-varnish-debug-ttl"#, + r#"x-varnish-host"#, + r#"x-varnish-ip"#, + r#"x-varnish-secret"#, + r#"x-varnish-server"#, + r#"x-varnish"#, + r#"x-varnishpool"#, + r#"x-varnishrequesttime"#, + r#"x-vc-age"#, + r#"x-vc-cache"#, + r#"x-vc"#, + r#"x-vcache"#, + r#"x-vcap-request-id"#, + r#"x-vercel-cache"#, + r#"x-vercel-id"#, + r#"x-version"#, + r#"x-via-cdn"#, + r#"x-via-edge"#, + r#"x-via-jsl"#, + r#"x-via-ssl"#, + r#"x-via"#, + r#"x-vimeo-dc"#, + r#"x-visitor-id"#, + r#"x-vserver"#, + r#"x-vtex-cache-backend-connect-time"#, + r#"x-vtex-cache-backend-header-time"#, + r#"x-vtex-cache-server"#, + r#"x-vtex-cache-status-janus-apicache"#, + r#"x-vtex-cache-time"#, + r#"x-vtex-janus-router-backend-app"#, + r#"x-vtex-processado-em"#, + r#"x-vtex-processed-at"#, + r#"x-wadp-cache"#, + r#"x-wb-version-expiry"#, + r#"x-webcom-cache-status"#, + r#"x-webmgr-cache"#, + r#"x-webserver"#, + r#"x-webstats-respid"#, + r#"x-whoami"#, + r#"x-whom"#, + r#"x-wikidot-backend"#, + r#"x-wikidot-static-cache"#, + r#"x-wikiloc-cache"#, + r#"x-windy-backend"#, + r#"x-wish-hostname"#, + r#"x-wix-request-id"#, + r#"x-wolf-app-server-info"#, + r#"x-worker"#, + r#"x-wp-cf-super-cache-cookies-bypass"#, + r#"x-wp-cf-super-cache"#, + r#"x-wp-lb"#, + r#"x-ws-request-id"#, + r#"x-ws"#, + r#"x-wserver"#, + r#"x-www-served-by"#, + r#"x-x-distributive"#, + r#"x-xcar-cache"#, + r#"x-xcar-via"#, + r#"x-xf-debug-stats"#, + r#"x-xff"#, + r#"x-xn-trace-token"#, + r#"x-yandexuid"#, + r#"x-yoda-cache-control"#, + r#"x-yottaa-metrics"#, + r#"x-yottaa-optimizations"#, + r#"x-yp-info"#, + r#"x-ys1"#, + r#"x-yubin-info"#, + r#"x-zalando-child-request-id"#, + r#"x-zen-fury"#, + r#"x-zipkin-id"#, + r#"xhs-request-time"#, + r#"y-who"#, + r#"yjs-cachestatus"#, + r#"yjs-id"#, + ].into_iter().collect() +}); diff --git a/sxg_rs/src/lib.rs b/sxg_rs/src/lib.rs index 6808364f..ba0b4703 100644 --- a/sxg_rs/src/lib.rs +++ b/sxg_rs/src/lib.rs @@ -18,6 +18,7 @@ pub mod fetcher; pub mod headers; pub mod http; mod http_parser; +mod id_headers; mod mice; mod ocsp; pub mod signature;