HTTP流水线请求文本示例

时间:2013-10-27 14:25:03

标签: apache http-request http-1.1 php-socket

以下是请求单页的HTTP 1.1调用示例:

GET /jq.js HTTP/1.1
Host: 127.0.0.1
Accept: */*

我理解HTTP Pipelining,可以在不中断连接的情况下发送多个请求。

  • 有人可以发布一些文本示例,说明如何将此请求发送到服务器,我希望能够通过命令行或PHP套接字执行此操作。
  • 是否还需要在Web服务器上启用对流水线的支持?
  • 默认情况下主流Web服务器(apache,nginx)是否支持流水线操作,或者是否需要启用流水线
  • 1 个答案:

    答案 0 :(得分:18)

    来自w3c protocol details

      

    8.1.2.2流水线

         

    支持持久连接 MAY “管道化”其请求的客户端(即,在不等待每个响应的情况下发送多个请求)。服务器必须按照收到请求的顺序发送对这些请求的响应。

         

    在连接建立后立即采用持久连接和管道的客户端应该准备好在第一次流水线尝试失败时重试其连接。如果客户端进行了这样的重试,那么必须管道才知道连接是持久的。如果服务器在发送所有相应的响应之前关闭连接,客户必须也准备好重新发送请求。

         

    客户端不应该使用非幂等方法或非幂等方法序列的管道请求(请参阅第9.1.2节)。否则,过早终止传输连接可能导致不确定的结果。希望发送非幂等请求的客户应该等待发送该请求,直到收到上一个请求的响应状态为止。

    所以,首先要确保你应该处于KeepAlive状态。因此,在您的请求标头中添加Connection: keep-alive关键字,但某些网络服务器仍可接受流水线操作而不保持此状态。另一方面,这可能被服务器拒绝,服务器可能会或可能不会在保持连接模式下接受您的连接。因此,在任何时候,保持与否,您可以在一个连接中发送3个流水线请求,并且只获得一个响应。

    this gist我们可以找到一种使用telnet测试它的好方法。

    使用Connection: keep-alive标题请求keepalive:

    (echo -en "GET /index.html HTTP/1.1\nHost: foo.com\nConnection: keep-alive\n\nGET /index.html HTTP/1.1\nHost: foo.com\n\n"; sleep 10) | telnet localhost 80
    
    Trying 127.0.0.1...
    Connected to localhost.lan.
    Escape character is '^]'.
    HTTP/1.1 200 OK
    Date: Sun, 27 Oct 2013 17:51:58 GMT
    Server: Apache/2.2.22 (Debian)
    Last-Modified: Sun, 04 Mar 2012 15:00:29 GMT
    ETag: "56176e-3e-4ba6c121c4761"
    Accept-Ranges: bytes
    Content-Length: 62
    Vary: Accept-Encoding
    Keep-Alive: timeout=5, max=100  <======= Keepalive!
    Connection: Keep-Alive
    Content-Type: text/html; charset=utf-8
    
    <html>
        <body>
            <h1>test</h1>
        </body>
    </html>
    HTTP/1.1 200 OK
    Date: Sun, 27 Oct 2013 17:51:58 GMT
    Server: Apache/2.2.22 (Debian)
    Last-Modified: Sun, 04 Mar 2012 15:00:29 GMT
    ETag: "56176e-3e-4ba6c121c4761"
    Accept-Ranges: bytes
    Content-Length: 62
    Vary: Accept-Encoding
    Content-Type: text/html; charset=utf-8
    
    <html>
        <body>
            <h1>test</h1>
        </body>
    </html>
    

    有效。

    不要求Keepalive:

    (echo -en "GET /index.html HTTP/1.1\nHost: foo.com\nConnection: keep-alive\n\nGET /index.html HTTP/1.1\nHost: foo.com\n\n"; sleep 10) | telnet localhost 80
    
    Trying 127.0.0.1...
    Connected to localhost.lan.
    Escape character is '^]'.
    HTTP/1.1 200 OK
    Date: Sun, 27 Oct 2013 17:49:37 GMT
    Server: Apache/2.2.22 (Debian)
    Last-Modified: Sun, 04 Mar 2012 15:00:29 GMT
    ETag: "56176e-3e-4ba6c121c4761"
    Accept-Ranges: bytes
    Content-Length: 62
    Vary: Accept-Encoding
    Content-Type: text/html; charset=utf-8
    
    <html>
        <body>
            <h1>test</h1>
        </body>
    </html>
    HTTP/1.1 200 OK
    Date: Sun, 27 Oct 2013 17:49:37 GMT
    Server: Apache/2.2.22 (Debian)
    Last-Modified: Sun, 04 Mar 2012 15:00:29 GMT
    ETag: "56176e-3e-4ba6c121c4761"
    Accept-Ranges: bytes
    Content-Length: 62
    Vary: Accept-Encoding
    Content-Type: text/html; charset=utf-8
    
    <html>
        <body>
            <h1>test</h1>
        </body>
    </html>
    Connection closed by foreign host.
    

    同样的结果,我没有要求它,但它看起来像一个Keepalive答案(在5s后关闭,这是在Apache中设置的值)。一个流水线的答案,我得到了我的两页。

    现在,如果我通过设置阻止在Apache中使用任何Keepalive连接:

    Keepalive Off
    

    然后重新启动它:

    (echo -en "GET /index.html HTTP/1.1\nHost: foo.com\nConnection: keep-alive\n\nGET /index.html HTTP/1.1\nHost: foo.com\n\n"; sleep 10) | telnet localhost 80
    
    Trying 127.0.0.1...
    Connected to localhost.lan.
    Escape character is '^]'.
    HTTP/1.1 200 OK
    Date: Sun, 27 Oct 2013 18:02:41 GMT
    Server: Apache/2.2.22 (Debian)
    Last-Modified: Sun, 04 Mar 2012 15:00:29 GMT
    ETag: "56176e-3e-4ba6c121c4761"
    Accept-Ranges: bytes
    Content-Length: 62
    Vary: Accept-Encoding
    Connection: close
    Content-Type: text/html; charset=utf-8
    
    <html>
        <body>
            <h1>test</h1>
        </body>
    </html>
    Connection closed by foreign host.
    

    只有一个答案......所以服务器可以拒绝我的流水线请求。

    现在,对于服务器和浏览器的支持,我认为您的维基百科消息来源告诉我们: - )