Upgradeヘッダーとは
Upgradeヘッダーは、HTTP/1.1で導入されたHTTPヘッダーフィールドの一つです。このヘッダーは、通信中にクライアントが最初にクリアテキストでリクエストを行い、その後、新しいHTTPプロトコルバージョンにアップグレードしたり、別のプロトコルに切り替えたりする際に使用されます。接続のアップグレードは、クライアントからのリクエストによって開始される必要があります。
サーバー側がアップグレードを強制したい場合は、`426 Upgrade Required`というレスポンスを返すことで、クライアントにアップグレードが必要であることを通知できます。このレスポンスを受け取ったクライアントは、接続を維持したまま、適切なUpgradeヘッダーを付加した新しいリクエストを送信する必要があります。
TLSでの利用
Upgradeヘッダーの利用例として、リクエストを通常のHTTPポートで開始し、その後
Transport Layer Security(TLS)に切り替えるケースがあります。しかし、実際にはこのような利用は稀であり、暗号化されたHTTP通信を開始する際には
HTTPSを直接利用する方が一般的です。
サーバーは、`426`ステータスコードを返すことで、従来のクライアントに対して、エラーの原因がクライアント側にあることを明確に伝えることができます(`400`番台のエラーコードはクライアント側のエラーを示すため)。
セキュアな接続を確立する方法としてのUpgradeヘッダーには、以下の利点があります。
複雑で問題が起こりやすいサーバーサイドのURLリダイレクトが不要になる。
セキュアなWebサイトのバーチャルホスティングが可能になる(
HTTPSでは
Server Name Indicationも利用可能)。
特定のリソースへのアクセス方法を一本化することで、ユーザーの混乱を防ぐことができる。
しかし、この手法には欠点もあります。
クライアントがURI内にセキュアなHTTPの要件を指定できない(ただし、Upgradeのネゴシエーションで要求することは可能)。
HTTPがホップベースで定義されているため、HTTPトンネルを確立するにはプロキシサーバーが必要になる場合がある。
WebSocketも、HTTPサーバーと互換性のある方法で接続を確立するためにこの仕組みを利用します。
WebSocketプロトコルは、
ハンドシェイクとデータ転送の2つの部分に分かれています。クライアントは最初に`Upgrade:
WebSocket`と`Connection: Upgrade`ヘッダーを使用して
WebSocket接続をリクエストします。サーバーは、このプロトコルをサポートしていれば、同じ`Upgrade:
WebSocket`と`Connection: Upgrade`ヘッダーで応答し、
ハンドシェイクを完了させます。
ハンドシェイクが完了すると、データの転送が開始されます。
以前は、HTTP Upgradeを利用して、
平文のHTTP/1.1接続から
HTTP/2|HTTP_2を確立する方法が規定されていました。クライアントはHTTP/1.1接続を開始し、`Upgrade: h2c`ヘッダーを送信します。サーバーが
HTTP/2|HTTP_2をサポートしている場合、`101 Switching Protocol`ステータスコードを付加して応答します。この方法は、クリアテキストのHTTP2(h2c)でのみ使用されていました。
しかし、この方法は後のRFC 9113によって廃止されました。
補足
セキュアな接続の確立において、サーバーとの暗号化された接続を維持している場合でも、中間者がクライアントとの接続を暗号化されていない状態に保つ可能性があるという問題点があります。これは、同一のリソースが暗号化された方法とそうでない方法の両方でサーバーから取得できる場合に発生しうるリスクです。
関連事項
日和見暗号化
Secure
Hypertext Transfer Protocol
参考情報
Hypertext Transfer Protocol (HTTP) Upgrade Token Registry at IANA