【问题标题】:Returning a HTTP 1xx code before the 200 one with WSGI使用 WSGI 返回 200 之前的 HTTP 1xx 代码
【发布时间】:2018-05-26 07:36:12
【问题描述】:

我编写了一个 Python+WSGI 应用程序,我想在返回最后的 200 和结果正文之前返回一个临时 1xx 状态代码,例如 102“处理中”或 103“早期提示”以及一些标题。

我知道,要在多个步骤中返回数据,我的应用程序需要是可迭代的,例如使用 yield(参见 In WSGI, send response without returning

但到目前为止我发现的所有示例都只使用一个状态码。我没有办法改变它。比如代码:

import wsgiref, wsgiref.simple_server, time

def app(environ, start):
    start('102 Processing', [('Foo', 'bar')])
    yield "More to come"
    time.sleep(2)

    start('200 OK', [('Content-Type', 'text/plain')])
    yield "hello, world"

httpd = wsgiref.simple_server.make_server('localhost', 8999, app)
httpd.serve_forever()

只发送 102 状态码,其余发送时崩溃:

Exception happened during processing of request from ('127.0.0.1', 53540)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 290, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 318, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 331, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 652, in __init__
    self.handle()
  File "/usr/lib/python2.7/wsgiref/simple_server.py", line 131, in handle
    handler.run(self.server.get_app())
  File "/usr/lib/python2.7/wsgiref/handlers.py", line 92, in run
    self.close()
  File "/usr/lib/python2.7/wsgiref/simple_server.py", line 33, in close
    self.status.split(' ',1)[0], self.bytes_sent
AttributeError: 'NoneType' object has no attribute 'split'
----------------------------------------

WSGI 中有没有办法做到这一点?

【问题讨论】:

  • 根据我看到的 RFC,这应该是可能的,但我认为您遇到的问题是在标头之后发送响应(文本)然后尝试发送另一个标头。尝试在计时器之前删除第一个“yield”,看看是否可以停止错误。临时标头只允许发送代码 100-199,因此只要您仅在 2xx、3xx、4xx 或 5xx 响应标头之前发送 1xx 代码,您就可以了。至少我是这么读的。
  • @DDeMartini 抱歉,删除第一个收益没有任何改变。
  • 该错误是因为“如果 start_response 已被调用,则在没有 exc_info 参数的情况下调用 start_response 是一个致命错误”(python.org/dev/peps/pep-3333/#the-start-response-callable)。我不确定 WSGI 是否支持你想要的。
  • 我怀疑这是一个非法操作,但对WSGI不是很熟悉,我不确定。我知道 Perl 和 PHP 都会对已经开始的标头大加抨击,但似乎 RFC 说这应该是可能的......但我们都知道 RFC 并不是关于某些软件如何实现任何东西的最终决定(就像来自 M$ 的历史垃圾,例如 IE)
  • 一种解决方法可能是使用此处描述的不推荐使用的方式:stackoverflow.com/a/16775731/6368697 并在此处解释:python.org/dev/peps/pep-0333/#the-write-callable;还确定客户端应用程序正确处理 1XX 标头吗?在(很久)过去,我在那里运气不佳。

标签: python http wsgi


【解决方案1】:

没有。在 WSGI 应用程序级别这是不可能的。

status 和 headers 只能更改到第一个响应内容生成之前的点,但此时还不允许将任何内容发送回客户端,因此不能用于发送多个status 和 headers,只替换将要发送的内容。

【讨论】:

    猜你喜欢
    • 2012-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-23
    • 2012-06-18
    相关资源
    最近更新 更多