将HTTP/1.1与SimpleHTTPRequestHandler一起使用

kan*_*aka 4 python http http-1.1

当我将HTTP/1.1与SimpleHTTPRequestHandler一起使用时,加载一个引入其他资源的页面将在第二个资源之后挂起.

这是一个小型的复制品:

from SimpleHTTPServer import SimpleHTTPRequestHandler
from BaseHTTPServer import HTTPServer

class MyRequestHandler(SimpleHTTPRequestHandler):
    #protocol_version = "HTTP/1.0"   # works
    protocol_version = "HTTP/1.1"   # hangs

server = HTTPServer(("localhost", 7080), MyRequestHandler)
server.serve_forever()
Run Code Online (Sandbox Code Playgroud)

使用上述服务器,当浏览器尝试加载时,以下HTML将挂起b.png:

<html>
    <body>
        <img src="a.png">
        <img src="b.png">
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

HTTP/1.1可以与SimpleHTTPServer模块一起使用吗?如果可以,如何使用?请注意,将ForkingMixIn或ThreadingMixIn添加到服务器将允许事情进展,但是,似乎没有任何一个mixin它应该是可能的.

Pio*_*ost 6

您看到的行为有三个原因:

  • BaseHTTPServer.HTTPServer 默认情况下,一次只能处理一个请求
  • 大多数用户代理(浏览器)一次打开与任何给定主机的多个连接
  • 大多数用户代理使用keep-aliveHTTP 1.1的功能,并且在收到请求的实体后不立即关闭连接

您看到的是浏览器能够使用它打开到服务器的第一个连接获取所请求的所有实体.这是页面本身,可能还有一些资源.同时浏览器打开其他连接以获取其余资源,但这些连接无法继续,因为服务器与第一个连接.服务器与第一个绑定的原因是虽然浏览器已经收到使用此连接请求的实体,但它不会立即关闭它,以防它可以在不久的将来被重用以获取更多实体(服务器不会关闭连接它的一面或者作为浏览器指定的HTTP版本1.1和发送标头).只有在第一次连接超时后,服务器才会开始处理下一个等待连接,以便下载其他资源(所有这些资源都是使用此特定连接请求的).如果你等待足够长的时间,浏览器会设法获得所有资源.在Firefox 中将首选项设置为1(而不是默认值6)或在其他浏览器中类似时,可以观察到差异.然后,由于使用相同的连接请求所有资源,所以每次检索都会在没有任何延迟的情况下检索到前一个.Connection: keep-alivenetwork.http.max-persistent-connections-per-server

我要感谢marienz从#python IRC频道上freenode.net他此问题的帮助.