From 30f45fdc1e5d7011df6c41168d997d10e2e2459c Mon Sep 17 00:00:00 2001 From: Pedro Sousa <680496+pedrosousa@users.noreply.github.com> Date: Tue, 3 Dec 2024 17:40:15 +0000 Subject: [PATCH 1/4] [Speed] Notes about the Content-Length header in responses --- .../docs/speed/optimization/content/compression.mdx | 8 ++++++-- src/content/partials/speed/brotli-compression-warning.mdx | 6 ++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/content/docs/speed/optimization/content/compression.mdx b/src/content/docs/speed/optimization/content/compression.mdx index f9b6e847438a6c9..1eadef5d72508dc 100644 --- a/src/content/docs/speed/optimization/content/compression.mdx +++ b/src/content/docs/speed/optimization/content/compression.mdx @@ -151,11 +151,15 @@ If you do not want a particular response from your origin to be encoded with Bro Cloudflare will take into consideration the `accept-encoding` header value in website visitors' requests when sending responses to those visitors. However, when requesting content from your origin server, Cloudflare will send a different `Accept-Encoding` header, supporting Brotli and Gzip compression. ::: +### Content-Length header handling + +When Cloudflare compresses a response, it may omit the `Content-Length` HTTP header to avoid delivering incorrect length information caused by dynamic transformations. To preserve the `Content-Length` header, add `cache-control: no-transform` to the origin server's response. This directive prevents Cloudflare from altering compression on responses, allowing the `Content-Length` header to pass through as-is. The `cache-control: no-transform` header must be set by the origin — it cannot be added by client requests. + --- -## Compression methods by plan +## Compression methods by plan ### Between visitors and Cloudflare @@ -167,4 +171,4 @@ By default, Cloudflare uses the following compression methods for content delive ### Between Cloudflare and the origin server -On all plans, Cloudflare requests content from the origin server using the `accept-encoding: br, gzip` header. This means that Cloudflare asks the origin to send the content compressed using Brotli or Gzip, depending on which method the origin server supports. \ No newline at end of file +On all plans, Cloudflare requests content from the origin server using the `accept-encoding: br, gzip` header. This means that Cloudflare asks the origin to send the content compressed using Brotli or Gzip, depending on which method the origin server supports. diff --git a/src/content/partials/speed/brotli-compression-warning.mdx b/src/content/partials/speed/brotli-compression-warning.mdx index 0a4a1b408634405..26fa4d59d9db266 100644 --- a/src/content/partials/speed/brotli-compression-warning.mdx +++ b/src/content/partials/speed/brotli-compression-warning.mdx @@ -4,6 +4,8 @@ ## Notes about end-to-end compression +### Content recompression due to dynamic transformations + Even when using the same compression algorithm end to end (between your origin server and Cloudflare, and between the Cloudflare global network and your website visitor), Cloudflare will need to decompress the response and compress it again if you enable any of the following settings for the request: - [Automatic HTTPS Rewrites](/ssl/edge-certificates/additional-options/automatic-https-rewrites/) @@ -20,3 +22,7 @@ To disable these settings for specific URI paths, create a [configuration rule]( :::note Additionally, the [Replace insecure JS libraries](/waf/tools/replace-insecure-js-libraries/) setting also requires Cloudflare to decompress the response and compress it again. At this time, you cannot turn it off using Configuration Rules. ::: + +### Content-Length header + +Cloudflare may remove the `Content-Length` HTTP header of responses delivered to website visitors. To ensure that the header is preserved, add a `cache-control: no-transform` HTTP header to the response at the origin server. From 41917d01271ad986562423d11d172ffce3c9fd22 Mon Sep 17 00:00:00 2001 From: Pedro Sousa <680496+pedrosousa@users.noreply.github.com> Date: Tue, 3 Dec 2024 18:16:21 +0000 Subject: [PATCH 2/4] Move section and update text --- .../docs/speed/optimization/content/compression.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/content/docs/speed/optimization/content/compression.mdx b/src/content/docs/speed/optimization/content/compression.mdx index 1eadef5d72508dc..4cc316fb8fd6f70 100644 --- a/src/content/docs/speed/optimization/content/compression.mdx +++ b/src/content/docs/speed/optimization/content/compression.mdx @@ -112,6 +112,10 @@ Smaller responses will not be compressed, regardless of their content type. ::: +### Content-Length header handling + +When Cloudflare compresses a response sent to the website visitor, it may omit the `Content-Length` HTTP header to avoid delivering incorrect length information caused by dynamic transformations. To preserve the `Content-Length` header set by the origin server, add `cache-control: no-transform` to the origin server's response. This directive prevents Cloudflare from altering compression on responses, allowing the `Content-Length` header to pass through as-is. The `cache-control: no-transform` header must be set by the origin — it cannot be added in client requests. + --- ## Content compression from origin servers to the Cloudflare network @@ -151,10 +155,6 @@ If you do not want a particular response from your origin to be encoded with Bro Cloudflare will take into consideration the `accept-encoding` header value in website visitors' requests when sending responses to those visitors. However, when requesting content from your origin server, Cloudflare will send a different `Accept-Encoding` header, supporting Brotli and Gzip compression. ::: -### Content-Length header handling - -When Cloudflare compresses a response, it may omit the `Content-Length` HTTP header to avoid delivering incorrect length information caused by dynamic transformations. To preserve the `Content-Length` header, add `cache-control: no-transform` to the origin server's response. This directive prevents Cloudflare from altering compression on responses, allowing the `Content-Length` header to pass through as-is. The `cache-control: no-transform` header must be set by the origin — it cannot be added by client requests. - --- From 112bbb385bf10b8975832e8ace5a7968cb96fc17 Mon Sep 17 00:00:00 2001 From: Pedro Sousa <680496+pedrosousa@users.noreply.github.com> Date: Tue, 3 Dec 2024 18:34:28 +0000 Subject: [PATCH 3/4] Added troubleshooting entry in Rules --- .../docs/rules/reference/troubleshooting.mdx | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/content/docs/rules/reference/troubleshooting.mdx b/src/content/docs/rules/reference/troubleshooting.mdx index 6ca9ad02f844d53..3a6704344da2b51 100644 --- a/src/content/docs/rules/reference/troubleshooting.mdx +++ b/src/content/docs/rules/reference/troubleshooting.mdx @@ -7,10 +7,9 @@ head: - tag: title content: Rules troubleshooting description: Review common troubleshooting scenarios for Rules features. - --- -import { Example, Render } from "~/components" +import { Example, Render } from "~/components"; ## Interaction between Cloudflare challenges and Rules features @@ -28,6 +27,12 @@ For example, define a compound expression for your rule using the `and` operator If you are using [HTTP DCV](/ssl/edge-certificates/changing-dcv-method/methods/http/) and also have [Single Redirects](/rules/url-forwarding/single-redirects/) set up in your zone, consider excluding the `/.well-known/*` path from your rule to avoid DCV issues. For details and other resources refer to the [SSL/TLS documentation](/ssl/edge-certificates/changing-dcv-method/). +## Content-Length header removed from response + +Cloudflare may remove the `Content-Length` header from responses delivered to website visitors. If the visitor must receive the `Content-Length` header, configure the origin server to include a `cache-control: no-transform` HTTP header in the response. + +Alternatively, disable compression using a [compression rule](/rules/compression-rules/) and ensure that no Cloudflare settings are changing the response received from the origin server. For details on which products can change the response content, refer to [Notes about end-to-end compression](/speed/optimization/content/compression/#notes-about-end-to-end-compression). + ## URL rewrites affect other Rules features executed later If you rewrite a URI path using a [URL rewrite](/rules/transform/url-rewrite/), this may affect other Rules features executed later — such as [Origin Rules](/rules/origin-rules/) — if they include the URI path in their filter expression. @@ -36,8 +41,8 @@ Consider the following origin rule configuration: -* Rule expression: `http.host == "example.com" and starts_with(http.request.uri.path, "/downloads/")` -* **Host header** > **Rewrite to**: `assets.example.com` +- Rule expression: `http.host == "example.com" and starts_with(http.request.uri.path, "/downloads/")` +- **Host header** > **Rewrite to**: `assets.example.com` @@ -45,8 +50,8 @@ If you configure a new URL rewrite with the following configuration: -* Rule expression: `http.host == "example.com" and starts_with(http.request.uri.path, "/downloads/")` -* **Path** > **Rewrite to** > **Dynamic**: `regex_replace(http.request.uri.path, "^/downloads/", "/")` +- Rule expression: `http.host == "example.com" and starts_with(http.request.uri.path, "/downloads/")` +- **Path** > **Rewrite to** > **Dynamic**: `regex_replace(http.request.uri.path, "^/downloads/", "/")` @@ -62,8 +67,8 @@ In the current example, you could use the `raw.http.request.uri.path` field in b -* Rule expression: `http.host == "example.com" and starts_with(raw.http.request.uri.path, "/downloads/")` -* **Path** > **Rewrite to** > **Dynamic**: `regex_replace(raw.http.request.uri.path, "^/downloads/", "/")` +- Rule expression: `http.host == "example.com" and starts_with(raw.http.request.uri.path, "/downloads/")` +- **Path** > **Rewrite to** > **Dynamic**: `regex_replace(raw.http.request.uri.path, "^/downloads/", "/")` @@ -71,8 +76,8 @@ In the current example, you could use the `raw.http.request.uri.path` field in b -* Rule expression: `http.host == "example.com" and starts_with(raw.http.request.uri.path, "/downloads/")` -* **Host header** > **Rewrite to**: `assets.example.com` +- Rule expression: `http.host == "example.com" and starts_with(raw.http.request.uri.path, "/downloads/")` +- **Host header** > **Rewrite to**: `assets.example.com` From 3d5bbb9c4b5378d757b741c7e6d56c06f1819ee0 Mon Sep 17 00:00:00 2001 From: Pedro Sousa <680496+pedrosousa@users.noreply.github.com> Date: Thu, 5 Dec 2024 14:36:46 +0000 Subject: [PATCH 4/4] Changes from received feedback --- src/content/docs/rules/reference/troubleshooting.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/content/docs/rules/reference/troubleshooting.mdx b/src/content/docs/rules/reference/troubleshooting.mdx index 3a6704344da2b51..7f3a3dbd07978e0 100644 --- a/src/content/docs/rules/reference/troubleshooting.mdx +++ b/src/content/docs/rules/reference/troubleshooting.mdx @@ -31,8 +31,6 @@ If you are using [HTTP DCV](/ssl/edge-certificates/changing-dcv-method/methods/h Cloudflare may remove the `Content-Length` header from responses delivered to website visitors. If the visitor must receive the `Content-Length` header, configure the origin server to include a `cache-control: no-transform` HTTP header in the response. -Alternatively, disable compression using a [compression rule](/rules/compression-rules/) and ensure that no Cloudflare settings are changing the response received from the origin server. For details on which products can change the response content, refer to [Notes about end-to-end compression](/speed/optimization/content/compression/#notes-about-end-to-end-compression). - ## URL rewrites affect other Rules features executed later If you rewrite a URI path using a [URL rewrite](/rules/transform/url-rewrite/), this may affect other Rules features executed later — such as [Origin Rules](/rules/origin-rules/) — if they include the URI path in their filter expression.