.. attribute:: files
File uploads are available in the files property, which maps file
- names to list of files. Each file is a dictionary of the form
- {"filename":..., "content_type":..., "body":...}. The content_type
- comes from the provided HTTP header and should not be trusted
- outright given that it can be easily forged.
+ names to lists of :class:`HTTPFile`.
.. attribute:: connection
url += '&' if ('?' in url) else '?'
return url + urllib.urlencode(args)
+
+class HTTPFile(ObjectDict):
+ """Represents an HTTP file. For backwards compatibility, its instance
+ attributes are also accessible as dictionary keys.
+
+ :ivar filename:
+ :ivar body:
+ :ivar content_type: The content_type comes from the provided HTTP header
+ and should not be trusted outright given that it can be easily forged.
+ """
+ pass
+
+
def parse_multipart_form_data(boundary, data, arguments, files):
"""Parses a multipart/form-data body.
name = disp_params["name"]
if disp_params.get("filename"):
ctype = headers.get("Content-Type", "application/unknown")
- files.setdefault(name, []).append(dict(
+ files.setdefault(name, []).append(HTTPFile(
filename=disp_params["filename"], body=value,
content_type=ctype))
else:
def post(self):
self.finish({"header": self.request.headers["X-Header-Encoding-Test"],
"argument": self.get_argument("argument"),
- "filename": self.request.files["files"][0]["filename"],
+ "filename": self.request.files["files"][0].filename,
"filebody": _unicode(self.request.files["files"][0]["body"]),
})