Remove explicit request size limits (#3878)

# What this PR does

Remove explicit request size limits both for uwsgi & Django. After this
change, the effective request size limit will be 2.5MB as the default
Django value for
[DATA_UPLOAD_MAX_MEMORY_SIZE](https://docs.djangoproject.com/en/4.2/ref/settings/#data-upload-max-memory-size).

## Checklist

- [x] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not
required)
This commit is contained in:
Vadim Stepanov 2024-02-22 15:00:33 +00:00 committed by GitHub
parent 5b37a7d2ef
commit 2b5554c079
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 3 additions and 92 deletions

View file

@ -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

View file

@ -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",

View file

@ -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)

View file

@ -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

View file

@ -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