diff options
author | Aleksey Lim <alsroot@sugarlabs.org> | 2012-03-19 17:18:52 (GMT) |
---|---|---|
committer | Aleksey Lim <alsroot@sugarlabs.org> | 2012-03-19 17:18:52 (GMT) |
commit | 45c019f47786e6cb63f1d85a19992d0010975076 (patch) | |
tree | 3554e0c8fce66e3e54828e3e0bec10becb43f327 | |
parent | 38528f7c492b469e1a5b797efa5fd40e8e259907 (diff) |
Handle multi-part uploads
-rw-r--r-- | restful_document/env.py | 41 | ||||
-rw-r--r-- | restful_document/router.py | 44 |
2 files changed, 47 insertions, 38 deletions
diff --git a/restful_document/env.py b/restful_document/env.py index bdab624..e9c4dbf 100644 --- a/restful_document/env.py +++ b/restful_document/env.py @@ -13,10 +13,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -import json -import urllib import threading -from urlparse import parse_qsl from gettext import gettext as _ import active_document as ad @@ -141,40 +138,12 @@ class Request(threading.local): content_stream = None content_length = None - def set(self, environ): - self.environ = environ - - path = environ['PATH_INFO'] or '/' - __, path = urllib.splittype(path) - __, path = urllib.splithost(path) - self.url = path - self.path = [i for i in path.strip('/').split('/') if i] - self.method = environ['REQUEST_METHOD'] - self.query = {} - self.content = None - self.content_stream = environ.get('wsgi.input') - self.content_length = 0 - - for attr, value in parse_qsl(environ.get('QUERY_STRING', '')): - self.query[str(attr)] = value - - if self.query: - self.url += '?' + environ.get('QUERY_STRING') - - content_length = environ.get('CONTENT_LENGTH') - if content_length: - self.content_length = int(content_length) - if environ.get('CONTENT_TYPE', '').lower() == 'application/json': - content = self.read() - if content: - self.content = json.loads(content) - def read(self, size=None): - if size is None: - size = self.content_length - if not size: + if self.content_stream is None: + return '' + result = self.content_stream.read(size or self.content_length) + if not result: return '' - result = self.content_stream.read(size) self.content_length -= len(result) return result @@ -191,7 +160,7 @@ class Responce(threading.local): status = None _headers = None - def set(self): + def reset(self): self.status = '200 OK' self._headers = {} diff --git a/restful_document/router.py b/restful_document/router.py index 99dd24f..5848dd0 100644 --- a/restful_document/router.py +++ b/restful_document/router.py @@ -14,9 +14,12 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. import os +import cgi import json import types +import urllib import logging +from urlparse import parse_qsl from gettext import gettext as _ import active_document as ad @@ -39,8 +42,8 @@ class Router(object): del os.environ['SSH_ASKPASS'] def __call__(self, environ, start_response): - env.request.set(environ) - env.responce.set() + _parse_request(environ) + env.responce.reset() _logger.debug('Processing %s request %s: %s', env.request.method, env.request.url, @@ -197,3 +200,40 @@ def _authenticate(): env.principal.authenticated.add(signature) env.principal.user = user + + +def _parse_request(environ): + request = env.request + + request.environ = environ + path = environ['PATH_INFO'] or '/' + __, path = urllib.splittype(path) + __, path = urllib.splithost(path) + request.url = path + request.path = [i for i in path.strip('/').split('/') if i] + request.method = environ['REQUEST_METHOD'] + request.query = {} + request.content = None + request.content_stream = environ.get('wsgi.input') + request.content_length = 0 + + for attr, value in parse_qsl(environ.get('QUERY_STRING', '')): + request.query[str(attr)] = value + + if request.query: + request.url += '?' + environ.get('QUERY_STRING') + + content_length = environ.get('CONTENT_LENGTH') + if content_length: + request.content_length = int(content_length) + ctype, __ = cgi.parse_header(environ.get('CONTENT_TYPE', '')) + if ctype.lower() == 'application/json': + content = request.read() + if content: + request.content = json.loads(content) + elif ctype.lower() == 'multipart/form-data': + files = cgi.FieldStorage(fp=environ['wsgi.input'], + environ=environ) + enforce(len(files.list) == 1, + _('Multipart request should contain only one file')) + request.content_stream = files.list[0].file |