diff options
Diffstat (limited to 'apifw/bottleapp.py')
-rw-r--r-- | apifw/bottleapp.py | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/apifw/bottleapp.py b/apifw/bottleapp.py index 377e49e..0aa403d 100644 --- a/apifw/bottleapp.py +++ b/apifw/bottleapp.py @@ -231,7 +231,11 @@ class BottleApplication: routes = self._api.find_missing_route(bottle.request.path) if routes: for route in routes: - callback = self._callback_with_body(route['callback']) + if self._big_blob_route(route): + callback = self._callback_with_big_blob( + route['callback']) + else: + callback = self._callback_with_body(route['callback']) route_dict = { 'method': route.get('method', 'GET'), 'path': route['path'], @@ -242,6 +246,9 @@ class BottleApplication: else: raise + def _big_blob_route(self, route): + return route.get('big-blobs', False) + def add_routes_for_resource_type(self, rt): routes = self._api.find_missing_route(rt.get_path()) for route in routes: @@ -254,6 +261,25 @@ class BottleApplication: self._bottleapp.route(**route_dict) self._authz.set_route_authorization(route) + def _callback_with_big_blob(self, callback): + def wrapper(*args, **kwargs): + kwargs['raw_uri_path'] = bottle.request.environ.get('RAW_URI', '') + content_type = self._get_content_type() + body = self._read_body + response = callback(content_type, body, *args, **kwargs) + return bottle.HTTPResponse( + status=response['status'], body=response['body'], + headers=response['headers']) + return wrapper + + def _get_content_type(self): + return bottle.request.get_header('Content-Type') + + def _read_body(self, max_bytes): + read = bottle.request.environ['wsgi.input'].read + for part in bottle.request._iter_body(read, max_bytes): + yield part + def _callback_with_body(self, callback): def wrapper(*args, **kwargs): kwargs['raw_uri_path'] = bottle.request.environ.get('RAW_URI', '') @@ -265,7 +291,7 @@ class BottleApplication: return wrapper def _get_request_body(self): - raw_body = bottle.request.body.read() + raw_body = b''.join(self._read_body(1024**2)) if bottle.request.method in ('POST', 'PUT'): if len(raw_body) == 0: raise bottle.HTTPError( @@ -273,7 +299,7 @@ class BottleApplication: body='Empty body not allowed for PUT/POST') json_type = 'application/json' - content_type = bottle.request.get_header('Content-Type') + content_type = self._get_content_type() if content_type != json_type: return content_type, raw_body |