39

私が理解していることから、HTTP接続はまたはのいずれかである可能性がありkeep-aliveますclose

サーバーにHTTPリクエストを送信しました:

GET /page1/ HTTP/1.1
Host: server.com
Connection: keep-alive

そしてそれは次のように答えました:

HTTP/1.1 200 OK
Connection: keep-alive, close

基本的に、のような応答keep-alive, closeがあいまいなため、サーバーにバグがあると思います。

しかし、受信者として、このようなメッセージをどのように処理する必要がありますか?このヘッダー値をまたはとして解釈する必要がありますか?keep-aliveclose

4

4 に答える 4

29

TL; DR:Chromeはこの応答ヘッダーを解釈しkeep-alive、Firefoxが各接続を閉じる間、永続的な接続を維持します。

私は自分のウェブサイトのページ読み込み時間を最適化しようとしたときに、この質問に出くわしました。

Connection参照されているRFCでは、ヘッダー内の複数のエントリを適切に処理する方法については何も見つかりませんでした。実装は2つの可能性から選択できるように私には思えました:

  1. 複数のエントリがある場合は、ニーズに最適なものを選択できます
  2. 内部にある場合は、close送信後に接続を閉じることができます

だから、私は見つける必要がありました。さらに詳しく調べてみましょう。

Connection: keep-aliveChromeは常にHTTP/1.1リクエストを送信しており、Apacheのデフォルト設定は常にConnection: closeヘッダーで応答していることに気付きました。そこで、私は調査を開始し、Wiresharkを使用してTCPセグメントを調べました。

Chromeは、ウェブサイトを表示するために14個の要素をフェッチする必要があります。そのほとんどは、画像やcssファイルなどの静的な要素です。そして、それは完全な14のTCP接続を取り、それは多くの時間(約1.2秒)を要しました。画像を要求するたびに(たとえば)、FINフラグが1に設定されたTCPセグメントが発生しました。

では、ChromeとFirefoxはどうですか?Chromeには、1台のサーバーへの同時接続の最大数が6であるようです。Firefoxはよりきめ細かい構成であり、永続的(about:configで見られる最大6)と非永続的(最大数はソースによって大きく異なります)を区別します。 )。しかし待ってください...ChromeとFirefoxはどちらもHTTP/1.1リクエストヘッダーを送信してConnection: keep-aliveいるので、両方とも6に制限する必要があります(これは永続的な接続を開くためのリクエストであるため)。

私は簡単なトリックを試してみることに.htaccessし、Webルートフォルダの自分に次の行を追加しました。

<ifModule mod_headers.c>
Header set Connection keep-alive
</ifModule>

サーバーは次のように応答します。

Connection: keep-alive, close

ここで、TCPセグメントをもう一度確認しました。Chromeからサーバーへの接続は9つだけで、FINフラグが1に設定されているのは3つだけでした。したがって、このトリックは機能しているように見えました。しかし、なぜデータ送信後に接続を閉じた3つの接続があったのでしょうか。HTTPヘッダーでX-Powered-By: PHP/5.4.11確認されたように、これらはPHPリクエストでした。

そしてFirefoxはどうですか?まだ14件のリクエストがありました!

それを修正し、fcgiプロセスをkeep-aliveでも動作させるにはどうすればよいですか?

httpd.conf構成のvirtualhostセクションに次の行を追加しました。

KeepAlive On
KeepAliveTimeout 5
MaxKeepAliveRequests 100

に追加されたものを削除しました.htaccess。これで、サーバーは混乱を招くような送信を送信していませんConnection: keep-alive, closeConnection: keep-alive、すべてが正常に機能します。

結論:

接続フィールドがに設定されたヘッダー

HTTP/1.1 200 OK
Connection: keep-alive, close

keep-aliveFirefoxが各接続を閉じているように見える間、Chromeによって解釈されます。実際の実装に依存しているようです。

したがって、を含む応答ヘッダーを処理するためのクライアントを実装する場合はConnection: keep-alive, close、複数のリクエストが必要な場合は、keep-aliveを使用してみることをお勧めします。発生する可能性のある最悪の事態:サーバーが接続を閉じ、再度接続する必要があります(これは、他のオプションです!)

于 2014-03-03T09:44:29.050 に答える
3

これは、サーバーが永続的な接続を行わず、この要求の後に接続を閉じることを意味します。

于 2012-07-12T01:17:21.717 に答える
2

答えはRFC7230—6.1にあります。接続。それは言う:

Connectionヘッダーフィールドの値の文法は次のとおりです。

 Connection        = 1#connection-option
 connection-option = token

インターネットRFC用語では、1#connection-optionは少なくとも1つ、多くても任意の数を意味しconnection-optionます。これは、受信者が好みの人を選択するオプションが複数ある可能性があることを意味します。それは曖昧さではなく、選択です。

于 2015-03-02T15:15:58.437 に答える
2

を使用HTTP/1.1していて、を指定していConnection: keep-aliveます。

すべての接続でHTTP/1.1デフォルトで維持され、Connection: keep-aliveヘッダーは非推奨になっているため、送信しないでください。

Connection: keep-aliveいわゆるHTTP/1.0+時代に使用された小さなハックです。(+「それを機能させるために必要なハック」の略です。)

HTTP:Brian Totty、Marjorie Sayer、 Sailu Reddy、Anshu Aggarwal、DavidGourleyによるTheDefinitive Guide by O'Reilly:

Keep-aliveは非推奨になり、現在のHTTP/1.1仕様では文書化されなくなりました。ただし、キープアライブハンドシェイクはブラウザやサーバーで比較的一般的に使用されているため、HTTP実装者はそれと相互運用できるように準備する必要があります。

サーバーが「相互運用」していて、冗長であるためにユーザーを制御している可能性があります。

于 2017-04-17T12:24:20.543 に答える