Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@sugarlabs.org>2012-03-19 17:18:52 (GMT)
committer Aleksey Lim <alsroot@sugarlabs.org>2012-03-19 17:18:52 (GMT)
commit45c019f47786e6cb63f1d85a19992d0010975076 (patch)
tree3554e0c8fce66e3e54828e3e0bec10becb43f327
parent38528f7c492b469e1a5b797efa5fd40e8e259907 (diff)
Handle multi-part uploads
-rw-r--r--restful_document/env.py41
-rw-r--r--restful_document/router.py44
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