I am writing an API for user upload file using multipart request. I see that Tornado version 4.5 has supported multipart request. But after that, I want to test this API.
My question is:
Thanks
Tornado does not have a built-in support for making multipart requests. You'll have to complie a multipart request manually.
Let's first look at how a multipart/form-data
request looks like.
Sample form:
<form method="POST" enctype="multipart/form-data">
<input type="text" name="field1">
<input type="file" name="field2">
<input type="submit">
</form>
If you enter Hello
in field1
and choose a file called myfile.png
for field2
,
the HTTP request will look like this:
POST /url HTTP/1.1
Content-Type: multipart/form-data; boundary="boundary"
--boundary
Content-Disposition: form-data; name="field1"
Hello
--boundary
Content-Disposition: form-data; name="field2"; filename="myfile.png"
Conent-Type: image/png
<binary content of myfile.png>
--boundary--
All you have to do is compile a similar request.
Before I show you an example, let me make something clear to you,
if you don't already know - in the raw HTTP request example above, at the end
of every line there are these characters - \r\n
. They aren't visible here but
they are present in an actual HTTP request. Even the blank lines have \r\n
characters present.
This is important to know. If you're gonna compile an HTTP request manually, you'll
have to add \r\n
characters at the end of every line.
Let's get to the example.
class MyTestCase(AsyncHTTPTestCase):
def test_something(self):
# create a boundary
boundary = 'SomeRandomBoundary'
# set the Content-Type header
headers = {
'Content-Type': 'multipart/form-data; boundary=%s' % boundary
}
# create the body
# opening boundary
body = '--%s\r\n' % boundary
# data for field1
body += 'Content-Disposition: form-data; name="field1"\r\n'
body += '\r\n' # blank line
body += 'Hello\r\n'
# separator boundary
body += '--%s\r\n' % boundary
# data for field2
body += 'Content-Disposition: form-data; name="field2"; filename="myfile.png"\r\n'
body += '\r\n' # blank line
# now read myfile.png and add that data to the body
with open('myfile.png', 'rb') as f:
body += '%s\r\n' % f.read()
# the closing boundary
body += "--%s--\r\n" % boundary
# make a request
self.fetch(url, method='POST', headers=headers, body=body)
The above code is very basic. If you have multiple files and arguments, you should
consider writing a separate function for that and make use of for
loops. Click here for an example code from Tornado's github repo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With