将HTTP / 1.1与SimpleHTTPRequestHandler一起使用

时间:2013-04-05 17:16:05

标签: 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()

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

<html>
    <body>
        <img src="a.png">
        <img src="b.png">
    </body>
</html>

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

1 个答案:

答案 0 :(得分:6)

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

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

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

我要感谢来自freenode.net上#python IRC频道的 marienz ,感谢他对这个问题的帮助。