Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTTP pipelining request text example

Below is an example HTTP 1.1 call with a single page requested :

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

I understand with HTTP Pipelining, multiple requests can be sent without breaking the connection.

  • Can someone post, some text example of how this request will be sent to the server, I want to be able to do it over the command line or with PHP sockets.
  • Does support for pipelining need to enabled on the web-server as well?
  • Is pipelining supported by major Web-servers(apache, nginx) by default or does it need to be enabled
  • like image 967
    DMin Avatar asked Oct 27 '13 14:10

    DMin


    1 Answers

    From w3c protocol details:

    8.1.2.2 Pipelining

    A client that supports persistent connections MAY "pipeline" its requests (i.e., send multiple requests without waiting for each response). A server MUST send its responses to those requests in the same order that the requests were received.

    Clients which assume persistent connections and pipeline immediately after connection establishment SHOULD be prepared to retry their connection if the first pipelined attempt fails. If a client does such a retry, it MUST NOT pipeline before it knows the connection is persistent. Clients MUST also be prepared to resend their requests if the server closes the connection before sending all of the corresponding responses.

    Clients SHOULD NOT pipeline requests using non-idempotent methods or non-idempotent sequences of methods (see section 9.1.2). Otherwise, a premature termination of the transport connection could lead to indeterminate results. A client wishing to send a non-idempotent request SHOULD wait to send that request until it has received the response status for the previous request.

    So, first fact is that you should be in a KeepAlive status. So you should add Connection: keep-alive keyword in your request headers, but some webservers may still accept pipelining without this keep alive status. On the other hand, this could be rejected by the server, the server may or may not accept your connection in keepalive mode. So, at any time, being in keepalived or not, you may send 3 requests pipelined in one connection, and get only one response.

    From this gist we can find a nice way to test it with telnet.

    Asking for keepalive with Connection: keep-alive header:

    (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>
    

    It works.

    Without asking for 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.
    

    Same result, I did not ask for it but it looks like a Keepalive answer (closing after 5s which is the value set in Apache). And a pipelined answer, I get my two pages.

    Now if I prevent usage of any Keepalive connection in Apache by setting:

    Keepalive Off
    

    And restarting it:

    (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.
    

    Only one answer... So the server can reject my request for pipelining.

    Now, for support on servers and browsers, I think your wikipedia source tells enough :-)

    like image 56
    regilero Avatar answered Oct 05 '22 03:10

    regilero