Tornado:使用 AsyncHTTPTestCase 测试多部分请求
Tornado: testing multipart request using AsyncHTTPTestCase
我正在为使用多部分请求的用户上传文件编写 API。我看到 Tornado 4.5 版支持多部分请求。但在那之后,我想测试这个 API.
我的问题是:
- 如何在 Tornado 上测试多部分请求。我有 google 很多参考资料,但找不到有用的资源。
- 如果不能在 Tornado 中执行此操作,我如何提出一个多部分请求以便我可以与 Tornado 的 AsyncHTTPTestCase 一起使用。
谢谢
Tornado 没有对发出多部分请求的内置支持。你会
必须手动编写多部分请求。
让我们先看看 multipart/form-data
请求是什么样子的。
示例表格:
<form method="POST" enctype="multipart/form-data">
<input type="text" name="field1">
<input type="file" name="field2">
<input type="submit">
</form>
如果您在 field1
中输入 Hello
并为 field2
选择一个名为 myfile.png
的文件,
HTTP 请求将如下所示:
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--
您所要做的就是编写一个类似的请求。
在我给你举个例子之前,让我先向你说明一些事情,
如果您还不知道 - 在上面的原始 HTTP 请求示例中,最后
每行都有这些字符 - \r\n
。它们在这里不可见但是
它们存在于实际的 HTTP 请求中。连空行都有\r\n
字符存在。
了解这一点很重要。如果你要手动编译一个 HTTP 请求,你会
必须在每行末尾添加 \r\n
个字符。
让我们来看例子。
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)
以上代码非常基础。如果你有多个文件和参数,你应该
考虑为此编写一个单独的函数并使用 for
循环。 Click here 来自 Tornado 的 github 存储库的示例代码。
我正在为使用多部分请求的用户上传文件编写 API。我看到 Tornado 4.5 版支持多部分请求。但在那之后,我想测试这个 API.
我的问题是:
- 如何在 Tornado 上测试多部分请求。我有 google 很多参考资料,但找不到有用的资源。
- 如果不能在 Tornado 中执行此操作,我如何提出一个多部分请求以便我可以与 Tornado 的 AsyncHTTPTestCase 一起使用。
谢谢
Tornado 没有对发出多部分请求的内置支持。你会 必须手动编写多部分请求。
让我们先看看 multipart/form-data
请求是什么样子的。
示例表格:
<form method="POST" enctype="multipart/form-data">
<input type="text" name="field1">
<input type="file" name="field2">
<input type="submit">
</form>
如果您在 field1
中输入 Hello
并为 field2
选择一个名为 myfile.png
的文件,
HTTP 请求将如下所示:
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--
您所要做的就是编写一个类似的请求。
在我给你举个例子之前,让我先向你说明一些事情,
如果您还不知道 - 在上面的原始 HTTP 请求示例中,最后
每行都有这些字符 - \r\n
。它们在这里不可见但是
它们存在于实际的 HTTP 请求中。连空行都有\r\n
字符存在。
了解这一点很重要。如果你要手动编译一个 HTTP 请求,你会
必须在每行末尾添加 \r\n
个字符。
让我们来看例子。
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)
以上代码非常基础。如果你有多个文件和参数,你应该
考虑为此编写一个单独的函数并使用 for
循环。 Click here 来自 Tornado 的 github 存储库的示例代码。