web-dev-qa-db-ja.com

NginxはクライアントのHTTP 1.0リクエストを無視してHTTP 1.1で応答します

コードでnginx/php5-fpmを使用してテストしています

<?php

header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found"); 
// also tested: header("Status: 404 Not Found");

echo $_SERVER["SERVER_PROTOCOL"];

そして、curlコマンドでHTTP 1.を強制的に使用します。

curl -0 -v 'http://www.example.com/test.php'


> GET /test.php HTTP/1.0

< HTTP/1.1 404 Not Found
< Server: nginx
< Date: Sat, 27 Oct 2012 08:51:27 GMT
< Content-Type: text/html
< Connection: close
< 
* Closing connection #0
HTTP/1.0

ご覧のとおり、私はすでにHTTP 1.0を使用してリクエストしていますが、nginxはHTTP 1.1で返信します

バウンティ

@ MaximDounin、@ MichaelHamptonはすでに仕様への回答を提供してくれてありがとう。この質問を将来の読者のために少し拡張します。

Q.クライアントがHTTP 1.0を要求したときにHTTP 1.1に応答する利点は何ですか? Googleが採用したアプローチはより合理的ではないでしょうか。つまり、クライアントが1.0を要求した場合、1.0で応答しますか?

7
Ryan

これは正常で予期される動作です RFC 2616に準拠

この仕様に少なくとも条件付きで準拠しているアプリケーションは、メッセージ内で「HTTP/1.1」のHTTP-Versionを使用する必要があり(SHOULD)、HTTP/1.0と互換性のないメッセージに対しては必ず使用する必要があります。特定のHTTP-Version値を送信するタイミングの詳細については、RFC 2145を参照してください。

RFC 2145はこれを拡張します

HTTPサーバーは、サーバーが少なくとも条件付きで準拠している最も高いバージョンに等しい応答バージョンを送信する必要があります(SHOULD)。そのメジャーバージョンは、要求で受信したバージョン以下です。 HTTPサーバーは、少なくとも条件付きで準拠していないバージョンを送信してはなりません(MUST NOT)。クライアントのリクエストで使用されているメジャーバージョンを使用して応答を送信できない場合、サーバーは505(HTTPバージョンはサポートされていません)応答を送信できます(MAY)。

クライアントがHTTP仕様を誤って実装していることがわかっているか疑われる場合、HTTPサーバーはより低い応答バージョンを送信してもよい(MAY)が、これはデフォルトではないはずであり、要求バージョンがHTTP/1.1以上の場合、これは行われるべきではない(SHOULD NOT)。

これが英語で何を意味するか:クライアントがHTTP/1.0要求を送信する場合、HTTP/1.0応答またはHTTP/1.1のいずれかが受け入れられますが、HTTP/1.1が推奨されます。

これが行われる理由は、一方の端がサポートできるHTTPの最も高いバージョンをアドバタイズし、もう一方の端がプロトコルサポートをアップグレードすることを選択できるようにするためです(可能な場合)。次に、両端で、どちらが使用できるプロトコルのバージョンを決定します。 RFC 2145で述べられているように、この設計はバグのある実装への対処にも役立ちます。

また、HTTPプロトコルにはマイナーバージョンとメジャーバージョンの両方のバージョンが存在する可能性があることも想定されていました。このルールは相互運用性を確保するためのものでした。 GoogleのRFCを無視したアプローチは、一度失敗すると HTTP/2. が確定します。 (あなたはそれをドラフト形式で [〜#〜] spdy [〜#〜] として知っています。)

20
Michael Hampton

Q.クライアントがHTTP 1.0を要求したときにHTTP 1.1に応答する利点は何ですか?

実際には、HTTP/1.0準拠の応答を送信しています。 HTTP/1.1を必要とするキープアライブなどの機能は使用しません。

これを行う理由は、サーバーが次のように言うための安価な方法だからです。

「ねえ、あなたがHTTP/1.0を使って私にリクエストを送ったのを知っていますが、あなたに知らせるためだけに[〜#〜] am [〜#〜]HTTP /1.1。に対応し、元のリクエストに対する応答は次のとおりです:[..]

(注:サーバーが架空のHTTP/1.8をサポートしている場合、サーバーはそれで応答します。)

これにより、状況によっては追加のリクエストを節約できます。サーバーから3つの異なるURIを取得する必要がある場合は、最初のURIをHTTP/1.0として送信し、それ以降の要求に対してユーザーとサーバーの両方がサポートする最高バージョンに移動できます。

5
mh.