14

以下は、単一ページが要求された HTTP 1.1 呼び出しの例です。

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

HTTP Pipeliningを使用すると、接続を切断することなく複数のリクエストを送信できることを理解しています。

  • 誰かが投稿できますか、このリクエストがサーバーに送信される方法のテキスト例をいくつか投稿してください。コマンドラインまたはPHPソケットを使用して実行できるようにしたいです。
  • パイプラインのサポートは Web サーバーでも有効にする必要がありますか?
  • パイプラインは主要な Web サーバー (Apache、nginx) でデフォルトでサポートされていますか、それとも有効にする必要がありますか?
  • 4

    1 に答える 1

    23

    w3c プロトコルの詳細から:

    8.1.2.2 パイプライン

    永続的な接続をサポートするクライアントは、その要求を「パイプライン化」することができます (つまり、各応答を待たずに複数の要求を送信します)。サーバーは、要求が受信されたのと同じ順序で、それらの要求に応答を送信する必要があります。

    接続が確立された直後に永続的な接続とパイプラインを想定するクライアントは、最初のパイプライン試行が失敗した場合に接続を再試行する準備ができている必要がありますクライアントがそのような再試行を行う場合、接続が永続的であることを知る前にパイプラインしてはなりません。サーバーが対応するすべての応答を送信する前に接続を閉じた場合、クライアントは要求を再送信する準備もできている必要があります。

    クライアントは、非冪等メソッドまたは非冪等メソッド シーケンスを使用してリクエストをパイプライン処理するべきではありません(セクション 9.1.2 を参照)。そうしないと、トランスポート接続が途中で終了し、不確定な結果になる可能性があります。冪等でないリクエストを送信したいクライアントは、前のリクエストのレスポンスステータスを受信するまで、そのリクエストの送信を待つ必要があります。

    したがって、最初の事実は、KeepAlive ステータスにある必要があるということです。そのため、リクエスト ヘッダーにキーワードを追加する必要Connection: keep-aliveがありますが、一部の Web サーバーでは、このキープ アライブ ステータスがなくてもパイプラインを受け入れる場合があります。一方、これはサーバーによって拒否される可能性があり、サーバーはキープアライブ モードで接続を受け入れる場合と受け入れない場合があります。そのため、キープアライブの有無に関係なく、1 つの接続でパイプライン化された 3 つの要求を送信し、1 つの応答しか取得できません。

    この要点から、telnet でテストする良い方法を見つけることができます。

    Connection: keep-aliveヘッダーでキープアライブを要求する:

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

    できます。

    キープアライブを要求しない場合:

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

    同じ結果、私はそれを求めませんでしたが、キープアライブの回答のように見えます (Apache で設定された値である 5 秒後に閉じます)。パイプライン化された回答で、2 つのページが表示されます。

    Apache でキープアライブ接続を使用しないようにするには、次のように設定します。

    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.
    

    答えは 1 つだけです。サーバーはパイプラインのリクエストを拒否できます。

    さて、サーバーとブラウザでのサポートについては、ウィキペディアのソースで十分だと思います:-)

    于 2013-10-27T18:09:14.243 に答える