diff --git a/tornado/httpserver.py b/tornado/httpserver.py index 70e23c20a2..6f448aded6 100644 --- a/tornado/httpserver.py +++ b/tornado/httpserver.py @@ -305,11 +305,21 @@ def _on_request_body(self, data): self._request.arguments.setdefault(name, []).extend( values) elif content_type.startswith("multipart/form-data"): - boundary = content_type[30:] - if boundary: self._parse_mime_body(boundary, data) + if 'boundary=' in content_type: + boundary = content_type.split('boundary=',1)[1] + if boundary: self._parse_mime_body(boundary, data) + else: + logging.warning("Invalid multipart/form-data") self.request_callback(self._request) def _parse_mime_body(self, boundary, data): + # The standard allows for the boundary to be quoted in the header, + # although it's rare (it happens at least for google app engine + # xmpp). I think we're also supposed to handle backslash-escapes + # here but I'll save that until we see a client that uses them + # in the wild. + if boundary.startswith('"') and boundary.endswith('"'): + boundary = boundary[1:-1] if data.endswith("\r\n"): footer_length = len(boundary) + 6 else: diff --git a/tornado/wsgi.py b/tornado/wsgi.py index c14bab9ca4..181429cb32 100644 --- a/tornado/wsgi.py +++ b/tornado/wsgi.py @@ -126,8 +126,11 @@ def __init__(self, environ): for name, values in cgi.parse_qs(self.body).iteritems(): self.arguments.setdefault(name, []).extend(values) elif content_type.startswith("multipart/form-data"): - boundary = content_type[30:] - if boundary: self._parse_mime_body(boundary) + if 'boundary=' in content_type: + boundary = content_type.split('boundary=',1)[1] + if boundary: self._parse_mime_body(boundary) + else: + logging.warning("Invalid multipart/form-data") self._start_time = time.time() self._finish_time = None @@ -148,6 +151,8 @@ def request_time(self): return self._finish_time - self._start_time def _parse_mime_body(self, boundary): + if boundary.startswith('"') and boundary.endswith('"'): + boundary = boundary[1:-1] if self.body.endswith("\r\n"): footer_length = len(boundary) + 6 else: