Add a maximum size for request

issue6619
review38441002
This commit is contained in:
Cédric Krier
2017-09-03 11:32:17 +02:00
parent f110fccf44
commit 5a1bc137a3
6 changed files with 60 additions and 7 deletions
+1
View File
@@ -1,3 +1,4 @@
* Add a maximum size for request
* Add support for single record report
* Add support for Flat OpenDocument
* Add get_email in trytond.report
+18
View File
@@ -119,6 +119,24 @@ table for translations.
Default: `en`
request
-------
max_size
~~~~~~~~
The maximum size in bytes of unauthenticated request (zero means no limit).
Default: 2MB
max_size_authenticated
~~~~~~~~~~~~~~~~~~~~~~
The maximum size in bytes of an authenticated request (zero means no limit).
Default: 2GB
cache
-----
+3
View File
@@ -25,6 +25,9 @@ Example::
Tryton also provides some wrappers in `trytond.protocols.wrappers` to ease the
creation of such route.
- `set_max_request_size(size)`: change the default limit of the request to
the size in bytes.
- `with_pool`: which takes the first parameter as database name and
replace it by the corresponding instance of the :ref:`Pool <ref-pool>`.
+3
View File
@@ -52,6 +52,9 @@ class TrytonConfigParser(ConfigParser.RawConfigParser):
self.set('database', 'list', 'True')
self.set('database', 'retry', 5)
self.set('database', 'language', 'en')
self.add_section('request')
self.set('request', 'max_size', 2 * 1024 * 1024)
self.set('request', 'max_size_authenticated', 2 * 1024 * 1024 * 1024)
self.add_section('cache')
self.set('cache', 'model', 200)
self.set('cache', 'record', 2000)
+11 -6
View File
@@ -54,20 +54,18 @@ class Request(_Request):
@cached_property
def user_id(self):
database_name = self.view_args['database_name']
database_name = self.view_args.get('database_name')
if not database_name:
return None
auth = self.authorization
if not auth:
abort(401)
return None
if auth.type == 'session':
user_id = security.check(
database_name, auth.get('userid'), auth.get('session'))
if not user_id:
abort(403)
else:
user_id = security.login(
database_name, auth.username, auth, cache=False)
if not user_id:
abort(401)
return user_id
@@ -94,6 +92,13 @@ def parse_authorization_header(value):
})
def set_max_request_size(size):
def decorator(func):
func.max_request_size = size
return func
return decorator
def with_pool(func):
@wraps(func)
def wrapper(request, database_name, *args, **kwargs):
+24 -1
View File
@@ -1,5 +1,6 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import httplib
import logging
import sys
import traceback
@@ -10,6 +11,7 @@ from werkzeug.exceptions import abort, HTTPException, InternalServerError
import wrapt
from trytond.config import config
from trytond.protocols.wrappers import Request
from trytond.protocols.jsonrpc import JSONProtocol
from trytond.protocols.xmlrpc import XMLProtocol
@@ -38,12 +40,33 @@ class TrytondWSGI(object):
if request.user_id:
return wrapped(*args, **kwargs)
else:
abort(303)
abort(httplib.UNAUTHORIZED)
def check_request_size(self, request, size=None):
if request.method not in {'POST', 'PUT', 'PATCH'}:
return
if size is None:
if request.user_id:
max_size = config.getint(
'request', 'max_size_authenticated')
else:
max_size = config.getint(
'request', 'max_size')
else:
max_size = size
if max_size:
content_length = request.content_length
if content_length is None:
abort(httplib.LENGTH_REQUIRED)
elif content_length > max_size:
abort(httplib.REQUEST_ENTITY_TOO_LARGE)
def dispatch_request(self, request):
adapter = self.url_map.bind_to_environ(request.environ)
try:
endpoint, request.view_args = adapter.match()
max_request_size = getattr(endpoint, 'max_request_size', None)
self.check_request_size(request, max_request_size)
return endpoint(request, **request.view_args)
except HTTPException, e:
return e