Add a maximum size for request
issue6619 review38441002
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
-----
|
||||
|
||||
|
||||
@@ -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>`.
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user