diff --git a/CHANGELOG.md b/CHANGELOG.md index ac70ac20..4d14969c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Enable templating for alert escalation mobile app push notifications by @joeyorlando ([#3845](https://github.com/grafana/oncall/pull/3845)) - Change email notification template to not wrap user template @mderynck ([#3862](https://github.com/grafana/oncall/pull/3862)) - Update integration name uniqueness check to be per team ([#3863](https://github.com/grafana/oncall/pull/3863)) +- Remove explicit uWSGI and Django request size limits by @vadimkerr ([#3878](https://github.com/grafana/oncall/pull/3878)) ### Fixed diff --git a/engine/apps/integrations/tests/test_views.py b/engine/apps/integrations/tests/test_views.py index 111ac850..656cc232 100644 --- a/engine/apps/integrations/tests/test_views.py +++ b/engine/apps/integrations/tests/test_views.py @@ -38,44 +38,6 @@ def setup_failing_redis_cache(settings): } -@pytest.mark.django_db -def test_integration_json_data_too_big(settings, make_organization_and_user, make_alert_receive_channel): - settings.DATA_UPLOAD_MAX_MEMORY_SIZE = 50 - - organization, user = make_organization_and_user() - alert_receive_channel = make_alert_receive_channel( - organization=organization, - author=user, - integration=AlertReceiveChannel.INTEGRATION_ALERTMANAGER, - ) - - client = APIClient() - url = reverse("integrations:alertmanager", kwargs={"alert_channel_key": alert_receive_channel.token}) - - data = {"value": "a" * settings.DATA_UPLOAD_MAX_MEMORY_SIZE} - response = client.post(url, data, format="json") - assert response.status_code == status.HTTP_400_BAD_REQUEST - - -@pytest.mark.django_db -def test_integration_form_data_too_big(settings, make_organization_and_user, make_alert_receive_channel): - settings.DATA_UPLOAD_MAX_MEMORY_SIZE = 50 - - organization, user = make_organization_and_user() - alert_receive_channel = make_alert_receive_channel( - organization=organization, - author=user, - integration=AlertReceiveChannel.INTEGRATION_ALERTMANAGER, - ) - - client = APIClient() - url = reverse("integrations:alertmanager", kwargs={"alert_channel_key": alert_receive_channel.token}) - - data = {"value": "a" * settings.DATA_UPLOAD_MAX_MEMORY_SIZE} - response = client.post(url, data, content_type="application/x-www-form-urlencoded") - assert response.status_code == status.HTTP_400_BAD_REQUEST - - @patch("apps.integrations.views.create_alert") @pytest.mark.parametrize( "integration_type", diff --git a/engine/engine/parsers.py b/engine/engine/parsers.py deleted file mode 100644 index 2a37816a..00000000 --- a/engine/engine/parsers.py +++ /dev/null @@ -1,48 +0,0 @@ -from django.conf import settings -from rest_framework import parsers, renderers - - -def check_content_length(parser_context): - """Enforce DATA_UPLOAD_MAX_MEMORY_SIZE for json rest framework API requests.""" - if parser_context and settings.DATA_UPLOAD_MAX_MEMORY_SIZE and "request" in parser_context: - try: - content_length = int(parser_context["request"].META.get("CONTENT_LENGTH", 0)) - except (ValueError, TypeError): - content_length = 0 - - if content_length and content_length > settings.DATA_UPLOAD_MAX_MEMORY_SIZE or content_length < 0: - raise parsers.ParseError("RequestDataTooBig") - - -class JSONParser(parsers.JSONParser): - """ - Parse JSON-serialized data. - Enforce django setting for DATA_UPLOAD_MAX_MEMORY_SIZE. - """ - - media_type = "application/json" - renderer_class = renderers.JSONRenderer - - def parse(self, stream, media_type=None, parser_context=None): - """Parse incoming bytestream as JSON and returns the resulting data.""" - # see https://github.com/encode/django-rest-framework/issues/4760 - check_content_length(parser_context) - return super(JSONParser, self).parse(stream, media_type, parser_context) - - -class FormParser(parsers.FormParser): - """ - Parse form data. - Enforce django setting for DATA_UPLOAD_MAX_MEMORY_SIZE. - """ - - media_type = "application/x-www-form-urlencoded" - - def parse(self, stream, media_type=None, parser_context=None): - """ - Parses the incoming bytestream as a URL encoded form, - and returns the resulting QueryDict. - """ - # see https://github.com/encode/django-rest-framework/issues/4760 - check_content_length(parser_context) - return super(FormParser, self).parse(stream, media_type, parser_context) diff --git a/engine/settings/base.py b/engine/settings/base.py index 3ad446c3..5fbda163 100644 --- a/engine/settings/base.py +++ b/engine/settings/base.py @@ -284,8 +284,8 @@ INSTALLED_APPS = [ REST_FRAMEWORK = { "DEFAULT_PARSER_CLASSES": ( - "engine.parsers.JSONParser", - "engine.parsers.FormParser", + "rest_framework.parsers.JSONParser", + "rest_framework.parsers.FormParser", "rest_framework.parsers.MultiPartParser", ), "DEFAULT_AUTHENTICATION_CLASSES": [], @@ -731,7 +731,6 @@ SELF_HOSTED_SETTINGS = { GRAFANA_INCIDENT_STATIC_API_KEY = os.environ.get("GRAFANA_INCIDENT_STATIC_API_KEY", None) -DATA_UPLOAD_MAX_MEMORY_SIZE = getenv_integer("DATA_UPLOAD_MAX_MEMORY_SIZE", 1_048_576) # 1mb by default JINJA_TEMPLATE_MAX_LENGTH = 50000 JINJA_RESULT_TITLE_MAX_LENGTH = 500 JINJA_RESULT_MAX_LENGTH = 50000 diff --git a/engine/uwsgi.ini b/engine/uwsgi.ini index ff0922ab..8782d81e 100644 --- a/engine/uwsgi.ini +++ b/engine/uwsgi.ini @@ -74,9 +74,6 @@ post-buffering=1 ; leave it ‘on’ by default and remove it on a case-by-case basis. enable-threads=true -; drop requests with CONTENT_LENGTH bigger than 15MB -route-if=ishigher:${CONTENT_LENGTH};15000000 break:413 Request Entity Too Large - ; Till uWSGI 2.1, by default, sending the SIGTERM signal to uWSGI means “brutally reload the stack” while the ; convention is to shut an application down on SIGTERM. To shutdown uWSGI, use SIGINT or SIGQUIT instead. If you ; absolutely can not live with uWSGI being so disrespectful towards SIGTERM, by all means, enable the die-on-term