From 3a99f13381e5dd1a3e9b268382d430ba0f6f827e Mon Sep 17 00:00:00 2001 From: Abhijeet Raj Singh Date: Sat, 4 Apr 2026 22:56:51 +0530 Subject: [PATCH 1/4] Fix duplicate Date headers in Flask response middleware --- providers/fab/src/airflow/providers/fab/www/app.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/providers/fab/src/airflow/providers/fab/www/app.py b/providers/fab/src/airflow/providers/fab/www/app.py index 0ab94e4b7adb9..df2021e7937c7 100644 --- a/providers/fab/src/airflow/providers/fab/www/app.py +++ b/providers/fab/src/airflow/providers/fab/www/app.py @@ -59,6 +59,13 @@ def create_app(enable_plugins: bool): from airflow.providers.fab.auth_manager.fab_auth_manager import FabAuthManager flask_app = Flask(__name__) + + @flask_app.after_request + def remove_duplicate_date_header(response): + # Remove duplicate Date header added by Flask (Uvicorn already sets it) + response.headers.pop("Date", None) + response.headers.pop("date", None) + return response flask_app.secret_key = conf.get("api", "SECRET_KEY") flask_app.config["SQLALCHEMY_DATABASE_URI"] = conf.get("database", "SQL_ALCHEMY_CONN") flask_app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False From 8969ebc943b3d9effdd36523a7a0a7fea8efc489 Mon Sep 17 00:00:00 2001 From: Abhijeet Raj Singh Date: Wed, 8 Apr 2026 07:23:14 +0530 Subject: [PATCH 2/4] fix: keep last Date header when deduplicating --- providers/fab/src/airflow/providers/fab/www/app.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/providers/fab/src/airflow/providers/fab/www/app.py b/providers/fab/src/airflow/providers/fab/www/app.py index df2021e7937c7..3f08484bc7ce8 100644 --- a/providers/fab/src/airflow/providers/fab/www/app.py +++ b/providers/fab/src/airflow/providers/fab/www/app.py @@ -62,9 +62,11 @@ def create_app(enable_plugins: bool): @flask_app.after_request def remove_duplicate_date_header(response): - # Remove duplicate Date header added by Flask (Uvicorn already sets it) - response.headers.pop("Date", None) - response.headers.pop("date", None) + date_headers = response.headers.getlist("Date") + + if len(date_headers) > 1: + # Keep only the first one (typically from Uvicorn) + response.headers.set("Date", date_headers[0]) return response flask_app.secret_key = conf.get("api", "SECRET_KEY") flask_app.config["SQLALCHEMY_DATABASE_URI"] = conf.get("database", "SQL_ALCHEMY_CONN") From 02c14dc8f899c6c079601190b0e51755ce89a646 Mon Sep 17 00:00:00 2001 From: Abhijeet Raj Singh Date: Thu, 9 Apr 2026 06:54:54 +0530 Subject: [PATCH 3/4] Apply ruff formatting --- providers/fab/src/airflow/providers/fab/www/app.py | 1 + 1 file changed, 1 insertion(+) diff --git a/providers/fab/src/airflow/providers/fab/www/app.py b/providers/fab/src/airflow/providers/fab/www/app.py index 3f08484bc7ce8..1745054b83908 100644 --- a/providers/fab/src/airflow/providers/fab/www/app.py +++ b/providers/fab/src/airflow/providers/fab/www/app.py @@ -68,6 +68,7 @@ def remove_duplicate_date_header(response): # Keep only the first one (typically from Uvicorn) response.headers.set("Date", date_headers[0]) return response + flask_app.secret_key = conf.get("api", "SECRET_KEY") flask_app.config["SQLALCHEMY_DATABASE_URI"] = conf.get("database", "SQL_ALCHEMY_CONN") flask_app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False From ffb92406eacd6b80cff0a1691754d0d731939139 Mon Sep 17 00:00:00 2001 From: abhijeets25012-tech Date: Sat, 11 Apr 2026 10:43:53 +0530 Subject: [PATCH 4/4] Update providers/fab/src/airflow/providers/fab/www/app.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- providers/fab/src/airflow/providers/fab/www/app.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/providers/fab/src/airflow/providers/fab/www/app.py b/providers/fab/src/airflow/providers/fab/www/app.py index 1745054b83908..765d942ccc7a4 100644 --- a/providers/fab/src/airflow/providers/fab/www/app.py +++ b/providers/fab/src/airflow/providers/fab/www/app.py @@ -62,11 +62,9 @@ def create_app(enable_plugins: bool): @flask_app.after_request def remove_duplicate_date_header(response): - date_headers = response.headers.getlist("Date") - - if len(date_headers) > 1: - # Keep only the first one (typically from Uvicorn) - response.headers.set("Date", date_headers[0]) + # Remove the application-level Date header so the ASGI/WSGI server + # can emit a single Date header for the final response. + response.headers.pop("Date", None) return response flask_app.secret_key = conf.get("api", "SECRET_KEY")