Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions airflow/config_templates/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2052,6 +2052,22 @@ webserver:
type: boolean
example: ~
default: "False"
max_form_memory_size:
description: |
The maximum size in bytes any non-file form field may be in a multipart/form-data body.
If this limit is exceeded, a 413 RequestEntityTooLarge error is raised by webserver.
version_added: 2.10.5
type: integer
example: ~
default: "500000"
max_form_parts:
description: |
The maximum number of fields that may be present in a multipart/form-data body.
If this limit is exceeded, a 413 RequestEntityTooLarge error is raised by webserver.
version_added: 2.10.5
type: integer
example: ~
default: "1000"
email:
description: |
Configuration email backend and whether to
Expand Down
2 changes: 2 additions & 0 deletions airflow/www/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ def create_app(config=None, testing=False):
flask_app.config["PERMANENT_SESSION_LIFETIME"] = timedelta(minutes=settings.get_session_lifetime_config())

flask_app.config["MAX_CONTENT_LENGTH"] = conf.getfloat("webserver", "allowed_payload_size") * 1024 * 1024
flask_app.config["MAX_FORM_PARTS"] = conf.getint("webserver", "max_form_parts")
flask_app.config["MAX_FORM_MEMORY_SIZE"] = conf.getint("webserver", "max_form_memory_size")

webserver_config = conf.get_mandatory_value("webserver", "config_file")
# Enable customizations in webserver_config.py to be applied via Flask.current_app.
Expand Down
17 changes: 17 additions & 0 deletions airflow/www/extensions/init_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from connexion.decorators.validation import RequestBodyValidator
from connexion.exceptions import BadRequestProblem
from flask import request
from werkzeug import Request

from airflow.api_connexion.exceptions import common_error_handler
from airflow.api_fastapi.app import get_auth_manager
Expand Down Expand Up @@ -189,6 +190,21 @@ def set_cors_headers_on_response(response):
return response


def init_data_form_parameters():
"""
Initialize custom values for data form parameters.

This is a workaround for Flask versions prior to 3.1.0.
In order to allow users customizing form data parameters, we need these two fields to be configurable.
Starting from Flask 3.1.0 these two parameters can be configured through Flask config, but unfortunately,
current version of flask supported in Airflow is way older. That's why this workaround was introduced.
See https://flask.palletsprojects.com/en/stable/api/#flask.Request.max_form_memory_size
# TODO: remove it when Flask upgraded to version 3.1.0 or higher.
"""
Request.max_form_parts = conf.getint("webserver", "max_form_parts")
Request.max_form_memory_size = conf.getint("webserver", "max_form_memory_size")


class _LazyResolution:
"""
OpenAPI endpoint that lazily resolves the function on first use.
Expand Down Expand Up @@ -281,6 +297,7 @@ def init_api_connexion(app: Flask) -> None:
validate_responses=True,
validator_map={"body": _CustomErrorRequestBodyValidator},
).blueprint
api_bp.before_app_request(init_data_form_parameters)
api_bp.after_request(set_cors_headers_on_response)

app.register_blueprint(api_bp)
Expand Down
Loading