From fb698ef0f7b5d88db4ad5416a66235bb95a1d6ba Mon Sep 17 00:00:00 2001 From: Eng Zer Jun Date: Tue, 10 Feb 2026 12:32:23 +0800 Subject: [PATCH 1/4] docs: update forwarded_allow_ips to Markdown Signed-off-by: Eng Zer Jun --- docs/content/reference/settings.md | 66 ++++++------------------------ 1 file changed, 13 insertions(+), 53 deletions(-) diff --git a/docs/content/reference/settings.md b/docs/content/reference/settings.md index 18023593..08ee4b0f 100644 --- a/docs/content/reference/settings.md +++ b/docs/content/reference/settings.md @@ -1356,60 +1356,20 @@ variable. If it is not defined, the default is ``"127.0.0.1,::1"``. In each case, we have a request from the remote address 134.213.44.18, and the default value of ``secure_scheme_headers``: - .. code:: + ```python + secure_scheme_headers = { + 'X-FORWARDED-PROTOCOL': 'ssl', + 'X-FORWARDED-PROTO': 'https', + 'X-FORWARDED-SSL': 'on' + } + ``` - secure_scheme_headers = { - 'X-FORWARDED-PROTOCOL': 'ssl', - 'X-FORWARDED-PROTO': 'https', - 'X-FORWARDED-SSL': 'on' - } - - .. list-table:: - :header-rows: 1 - :align: center - :widths: auto - - * - ``forwarded-allow-ips`` - - Secure Request Headers - - Result - - Explanation - * - .. code:: - - ["127.0.0.1"] - - .. code:: - - X-Forwarded-Proto: https - - .. code:: - - wsgi.url_scheme = "http" - - IP address was not allowed - * - .. code:: - - "*" - - - - .. code:: - - wsgi.url_scheme = "http" - - IP address allowed, but no secure headers provided - * - .. code:: - - "*" - - .. code:: - - X-Forwarded-Proto: https - - .. code:: - - wsgi.url_scheme = "https" - - IP address allowed, one request header matched - * - .. code:: - - ["134.213.44.18"] - - .. code:: - - X-Forwarded-Ssl: on - X-Forwarded-Proto: http - - ``InvalidSchemeHeaders()`` raised - - IP address allowed, but the two secure headers disagreed on if HTTPS was used + | forwarded-allow-ips | Secure Request Headers | Result | Explanation | + | ------------------- | -------------------------------------------------- | ------------------------------- | ----------------------------------------------------------------------------- | + | `"127.0.0.1"` | `X-Forwarded-Proto: https` | `wsgi.url_scheme = "http"` | IP address was not allowed | + | `"*"` | `` | `wsgi.url_scheme = "http"` | IP address allowed, but no secure headers provided | + | `"*"` | `X-Forwarded-Proto: https` | `wsgi.url_scheme = "https"` | IP address allowed, one request header matched | + | `"134.213.44.18"` | `X-Forwarded-Ssl: on`
`X-Forwarded-Proto: http` | `InvalidSchemeHeaders()` raised | IP address allowed, but the two secure headers disagreed on if HTTPS was used | ### `pythonpath` From cc974da87ebb5604e3185be5196baf59ec2c40cb Mon Sep 17 00:00:00 2001 From: Eng Zer Jun Date: Wed, 11 Feb 2026 05:40:34 +0800 Subject: [PATCH 2/4] Update config.py Signed-off-by: Eng Zer Jun --- gunicorn/config.py | 67 +++++++++------------------------------------- 1 file changed, 13 insertions(+), 54 deletions(-) diff --git a/gunicorn/config.py b/gunicorn/config.py index c391ae41..8a8c4b32 100644 --- a/gunicorn/config.py +++ b/gunicorn/config.py @@ -1346,61 +1346,20 @@ class ForwardedAllowIPS(Setting): In each case, we have a request from the remote address 134.213.44.18, and the default value of ``secure_scheme_headers``: - .. code:: + ```python + secure_scheme_headers = { + 'X-FORWARDED-PROTOCOL': 'ssl', + 'X-FORWARDED-PROTO': 'https', + 'X-FORWARDED-SSL': 'on' + } + ``` - secure_scheme_headers = { - 'X-FORWARDED-PROTOCOL': 'ssl', - 'X-FORWARDED-PROTO': 'https', - 'X-FORWARDED-SSL': 'on' - } - - - .. list-table:: - :header-rows: 1 - :align: center - :widths: auto - - * - ``forwarded-allow-ips`` - - Secure Request Headers - - Result - - Explanation - * - .. code:: - - ["127.0.0.1"] - - .. code:: - - X-Forwarded-Proto: https - - .. code:: - - wsgi.url_scheme = "http" - - IP address was not allowed - * - .. code:: - - "*" - - - - .. code:: - - wsgi.url_scheme = "http" - - IP address allowed, but no secure headers provided - * - .. code:: - - "*" - - .. code:: - - X-Forwarded-Proto: https - - .. code:: - - wsgi.url_scheme = "https" - - IP address allowed, one request header matched - * - .. code:: - - ["134.213.44.18"] - - .. code:: - - X-Forwarded-Ssl: on - X-Forwarded-Proto: http - - ``InvalidSchemeHeaders()`` raised - - IP address allowed, but the two secure headers disagreed on if HTTPS was used + | forwarded-allow-ips | Secure Request Headers | Result | Explanation | + | ------------------- | -------------------------------------------------- | ------------------------------- | ----------------------------------------------------------------------------- | + | `"127.0.0.1"` | `X-Forwarded-Proto: https` | `wsgi.url_scheme = "http"` | IP address was not allowed | + | `"*"` | `` | `wsgi.url_scheme = "http"` | IP address allowed, but no secure headers provided | + | `"*"` | `X-Forwarded-Proto: https` | `wsgi.url_scheme = "https"` | IP address allowed, one request header matched | + | `"134.213.44.18"` | `X-Forwarded-Ssl: on`
`X-Forwarded-Proto: http` | `InvalidSchemeHeaders()` raised | IP address allowed, but the two secure headers disagreed on if HTTPS was used | """ From c0959609ef6cc1bb2a9659905d2319ab77e6fa1a Mon Sep 17 00:00:00 2001 From: Eng Zer Jun Date: Thu, 12 Feb 2026 00:25:29 +0800 Subject: [PATCH 3/4] Use markdown-grid-tables for multiline table pycodestyle enforces 120-character line lengtn limit. Signed-off-by: Eng Zer Jun --- docs/content/reference/settings.md | 24 ++++++++++++++++++------ gunicorn/config.py | 24 ++++++++++++++++++------ mkdocs.yml | 2 ++ requirements_dev.txt | 1 + 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/docs/content/reference/settings.md b/docs/content/reference/settings.md index 08ee4b0f..dfac1048 100644 --- a/docs/content/reference/settings.md +++ b/docs/content/reference/settings.md @@ -1364,12 +1364,24 @@ variable. If it is not defined, the default is ``"127.0.0.1,::1"``. } ``` - | forwarded-allow-ips | Secure Request Headers | Result | Explanation | - | ------------------- | -------------------------------------------------- | ------------------------------- | ----------------------------------------------------------------------------- | - | `"127.0.0.1"` | `X-Forwarded-Proto: https` | `wsgi.url_scheme = "http"` | IP address was not allowed | - | `"*"` | `` | `wsgi.url_scheme = "http"` | IP address allowed, but no secure headers provided | - | `"*"` | `X-Forwarded-Proto: https` | `wsgi.url_scheme = "https"` | IP address allowed, one request header matched | - | `"134.213.44.18"` | `X-Forwarded-Ssl: on`
`X-Forwarded-Proto: http` | `InvalidSchemeHeaders()` raised | IP address allowed, but the two secure headers disagreed on if HTTPS was used | + +---------------------+----------------------------+-----------------------------+-------------------------+ + | forwarded-allow-ips | Secure Request Headers | Result | Explanation | + +=====================+============================+=============================+=========================+ + | `"127.0.0.1"` | `X-Forwarded-Proto: https` | `wsgi.url_scheme = "http"` | IP address was not | + | | | | allowed | + +---------------------+----------------------------+-----------------------------+-------------------------+ + | | | | IP address allowed, but | + | `"*"` | `` | `wsgi.url_scheme = "http"` | no secure headers | + | | | | provided | + +---------------------+----------------------------+-----------------------------+-------------------------+ + | `"*"` | `X-Forwarded-Proto: https` | `wsgi.url_scheme = "https"` | IP address allowed, one | + | | | | request header matched | + +---------------------+----------------------------+-----------------------------+-------------------------+ + | | | | IP address allowed, but | + | `"134.213.44.18"` | `X-Forwarded-Ssl: on` | `InvalidSchemeHeaders()` | the two secure headers | + | | `X-Forwarded-Proto: http` | raised | disagreed on if HTTPS | + | | | | was used | + +---------------------+----------------------------+-----------------------------+-------------------------+ ### `pythonpath` diff --git a/gunicorn/config.py b/gunicorn/config.py index 8a8c4b32..faffb6b7 100644 --- a/gunicorn/config.py +++ b/gunicorn/config.py @@ -1354,12 +1354,24 @@ class ForwardedAllowIPS(Setting): } ``` - | forwarded-allow-ips | Secure Request Headers | Result | Explanation | - | ------------------- | -------------------------------------------------- | ------------------------------- | ----------------------------------------------------------------------------- | - | `"127.0.0.1"` | `X-Forwarded-Proto: https` | `wsgi.url_scheme = "http"` | IP address was not allowed | - | `"*"` | `` | `wsgi.url_scheme = "http"` | IP address allowed, but no secure headers provided | - | `"*"` | `X-Forwarded-Proto: https` | `wsgi.url_scheme = "https"` | IP address allowed, one request header matched | - | `"134.213.44.18"` | `X-Forwarded-Ssl: on`
`X-Forwarded-Proto: http` | `InvalidSchemeHeaders()` raised | IP address allowed, but the two secure headers disagreed on if HTTPS was used | + +---------------------+----------------------------+-----------------------------+-------------------------+ + | forwarded-allow-ips | Secure Request Headers | Result | Explanation | + +=====================+============================+=============================+=========================+ + | `"127.0.0.1"` | `X-Forwarded-Proto: https` | `wsgi.url_scheme = "http"` | IP address was not | + | | | | allowed | + +---------------------+----------------------------+-----------------------------+-------------------------+ + | | | | IP address allowed, but | + | `"*"` | `` | `wsgi.url_scheme = "http"` | no secure headers | + | | | | provided | + +---------------------+----------------------------+-----------------------------+-------------------------+ + | `"*"` | `X-Forwarded-Proto: https` | `wsgi.url_scheme = "https"` | IP address allowed, one | + | | | | request header matched | + +---------------------+----------------------------+-----------------------------+-------------------------+ + | | | | IP address allowed, but | + | `"134.213.44.18"` | `X-Forwarded-Ssl: on` | `InvalidSchemeHeaders()` | the two secure headers | + | | `X-Forwarded-Proto: http` | raised | disagreed on if HTTPS | + | | | | was used | + +---------------------+----------------------------+-----------------------------+-------------------------+ """ diff --git a/mkdocs.yml b/mkdocs.yml index 03193260..8d7d98ca 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -105,6 +105,8 @@ markdown_extensions: - footnotes - md_in_html - tables + - markdown_grid_tables: + hard_linebreaks: false - toc: permalink: true - pymdownx.details diff --git a/requirements_dev.txt b/requirements_dev.txt index 40b6dae6..438b8084 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -8,5 +8,6 @@ setuptools>=68.0 mkdocs>=1.6 mkdocs-material>=9.5 mkdocs-gen-files>=0.5 +markdown-grid-tables>=0.6 mkdocs-macros-plugin>=1.0 pymdown-extensions>=10.0 From 54eb411d346e9cbd3c3904d57d8e8e926f7a3e42 Mon Sep 17 00:00:00 2001 From: Eng Zer Jun Date: Fri, 13 Feb 2026 09:31:17 +0800 Subject: [PATCH 4/4] Enable hard_linebreaks Signed-off-by: Eng Zer Jun --- mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index 8d7d98ca..d54e2463 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -106,7 +106,7 @@ markdown_extensions: - md_in_html - tables - markdown_grid_tables: - hard_linebreaks: false + hard_linebreaks: true - toc: permalink: true - pymdownx.details