Lon*_*ner 4 python wsgi python-3.x
这是一个简单的 WSGI 应用程序,它应该在标头中打印 Content-Length 和请求正文。
def application(environ, start_response):
start_response('200 OK', [('Content-Type','text/plain')])
content_length = int(environ['CONTENT_LENGTH'])
print('---- Begin ----')
print('CONTENT_LENGTH:', content_length)
print('wsgi.input:', environ['wsgi.input'].read())
print('---- End ----')
return [b'Foo\n']
if __name__ == '__main__':
from wsgiref import simple_server
server = simple_server.make_server('0.0.0.0', 8080, application)
server.serve_forever()
Run Code Online (Sandbox Code Playgroud)
当我运行此应用程序时,它在以下调用中被阻止:environ['wsgi.input'].read().
我使用 Python 3 解释器运行该应用程序,并使用 curl 向它提交 HTTP post 请求。
lone@debian:~$ curl --data "a=1&b=2" http://localhost:8080/
Run Code Online (Sandbox Code Playgroud)
curl 命令被阻塞等待输出。python 解释器在environ['wsgi.input'].read()调用时被阻塞。
lone@debian:~$ python3 foo.py
---- Begin ----
CONTENT_LENGTH: 7
Run Code Online (Sandbox Code Playgroud)
正如您在上面的输出中看到的,该application()函数在 print 后被阻塞CONTENT_LENGTH。
我知道如何解决这个问题:通过将 Content-Length 标头值传递给read()调用。
修改代码以解决该问题:
def application(environ, start_response):
start_response('200 OK', [('Content-Type','text/plain')])
content_length = int(environ['CONTENT_LENGTH'])
print('---- Begin ----')
print('CONTENT_LENGTH:', content_length)
print('wsgi.input:', environ['wsgi.input'].read(content_length))
print('---- End ----')
return [b'Foo\n']
if __name__ == '__main__':
from wsgiref import simple_server
server = simple_server.make_server('0.0.0.0', 8080, application)
server.serve_forever()
Run Code Online (Sandbox Code Playgroud)
curl 命令现在获得有效的 HTTP 响应。
lone@debian:~$ curl --data "a=1&b=2" http://localhost:8080/
Foo
lone@debian:~$
Run Code Online (Sandbox Code Playgroud)
该application()函数也完成了它的执行。
lone@debian:~$ python3 foo.py
---- Begin ----
CONTENT_LENGTH: 7
wsgi.input: b'a=1&b=2'
---- End ----
127.0.0.1 - - [06/Apr/2014 17:53:21] "POST / HTTP/1.1" 200 4
Run Code Online (Sandbox Code Playgroud)
为什么environ['wsgi.input'].read()call 在read没有任何参数的情况下被调用时会阻塞?
该PEP-3333文件似乎暗示它应该工作。这是相关的文字。
服务器不需要读取超过客户端指定的
Content-Length,并且如果应用程序尝试读取超过该点,则应该模拟文件结束条件。应用程序 不应尝试读取比CONTENT_LENGTH变量指定的更多的数据。服务器应该允许
read()在没有参数的情况下调用,并返回客户端输入流的其余部分。
我了解应用程序不应尝试读取比CONTENT_LENGTH变量指定的更多的数据。我违反了这个指令。但是服务器应该允许read()在没有参数的情况下调用并将整个输入流返回给我。为什么不这样做?
因为它只实现了 PEP 333 而不是 PEP 3333。
PEP 333 没有通过返回空字符串来模拟流结束的条件。
在 PEP 333 中,如果 WSGI 服务器支持 HTTP 1.1 并且正在使用请求管道(保持活动),如果您尝试读取超过 CONTENT_LENGTH 的内容,则会出现问题。
我建议您阅读 PEP 333 并将该语言与 PEP 3333 进行比较。
另请阅读:
在那里我描述了整个问题,因此在为 Python 3 更新 PEP 时促成了 PEP 的变化。
| 归档时间: |
|
| 查看次数: |
2145 次 |
| 最近记录: |