Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 17018] ファイルの概要

このコミットは、Go言語の標準ライブラリである net/http パッケージ内の Response.Header フィールドに関するドキュメントの修正です。具体的には、HTTPレスポンスヘッダーにおいて、同じキーを持つ複数のヘッダーがどのように扱われるかについての記述をより正確にするための変更が行われました。

コミット

commit 910caf93454d177fee459a6e65cb4f5d8e0b56ad
Author: Josh Bleecher Snyder <josharian@gmail.com>
Date:   Sun Aug 4 11:23:17 2013 -0700

    net/http: fix Response.Header documentation for multiple headers with same key
    
    Whether the keys are concatenated or separate (or a mixture) depends on the server.
    
    Fixes #5979.
    
    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/12433043

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/910caf93454d177fee459a6e65cb4f5d8e0b56ad

元コミット内容

net/http: fix Response.Header documentation for multiple headers with same key

このコミットの目的は、net/http パッケージの Response.Header のドキュメントを修正し、同じキーを持つ複数のヘッダーの扱いに関する記述をより正確にすることです。元のドキュメントでは、同じキーを持つ複数のヘッダーは常にカンマ区切りで連結されると記述されていましたが、実際にはサーバーの実装によって連結される場合とされない場合があるため、その点を明確にする変更です。

変更の背景

Go言語の net/http パッケージは、HTTPクライアントおよびサーバーの実装を提供します。Response 構造体には、受信したHTTPレスポンスのヘッダー情報を含む Header フィールドがあります。この Header フィールドは map[string][]string 型であり、ヘッダー名(キー)からその値のリストへのマッピングを提供します。

HTTP/1.1の仕様であるRFC 2616のセクション4.2では、同じヘッダーフィールド名がメッセージ内で複数回出現する場合の扱いについて規定しています。このセクションでは、一部のヘッダーフィールド(例: Content-Type)は単一の値しか持てないが、他のヘッダーフィールド(例: Set-Cookie)は複数回出現することが許容されると述べています。また、同じヘッダーフィールド名が複数回出現する場合、それらはカンマで区切られた単一のフィールド値として扱われるべきであるとされています。

しかし、実際のサーバーの実装においては、このRFCの推奨に従わず、同じキーを持つ複数のヘッダーを個別のヘッダーとして送信する場合や、一部を連結し、一部を個別に送信するような混合した形式で送信する場合があります。Goの net/http パッケージは、このような多様なサーバーの挙動に対応する必要があります。

元の Response.Header のドキュメントでは、「If the response had multiple headers with the same key, they will be concatenated, with comma delimiters.」と記述されており、これは常に連結されるという誤解を招く可能性がありました。このコミットは、この記述が現実のHTTPサーバーの挙動と完全に一致しないことを認識し、より正確な表現に修正することを目的としています。具体的には、「they will be concatenated」を「they may be concatenated」に変更することで、サーバーの実装に依存するというニュアンスを加えています。

前提知識の解説

HTTPヘッダー

HTTPヘッダーは、HTTPリクエストまたはレスポンスのメタデータを提供するキーと値のペアです。これらは、クライアントとサーバーが通信する際に、コンテンツのタイプ、エンコーディング、キャッシュ制御、認証情報など、様々な情報を交換するために使用されます。

例:

Content-Type: application/json
Content-Length: 1234
Cache-Control: no-cache, no-store
Set-Cookie: sessionid=abc; Path=/
Set-Cookie: preferences=darkmode; Path=/

RFC 2616 (HTTP/1.1)

RFC 2616は、HTTP/1.1プロトコルの主要な仕様を定義した文書です。このRFCは、HTTPメッセージの構造、メソッド、ヘッダーフィールド、ステータスコードなど、HTTPのあらゆる側面を詳細に記述しています。

特に、セクション4.2「Message Headers」では、ヘッダーフィールドの構文と意味論について説明されています。このセクションには、同じヘッダーフィールド名が複数回出現する場合の扱いに関する規定が含まれています。RFC 2616は、複数のヘッダーフィールドが同じフィールド名を持つ場合、それらはカンマで区切られた単一のフィールド値として扱われるべきであると推奨しています。これは、HTTPヘッダーの解析において、同じキーを持つ複数の値をどのように解釈すべきかという指針を提供します。

Go言語の net/http パッケージ

net/http パッケージは、Go言語でHTTPクライアントとサーバーを構築するための基本的な機能を提供します。このパッケージは、HTTPプロトコルの詳細を抽象化し、開発者が簡単にWebアプリケーションを構築できるようにします。

  • http.Response 構造体: HTTPレスポンスを表す構造体です。サーバーからの応答のステータスコード、プロトコルバージョン、ヘッダー、ボディなどの情報を含みます。
  • http.Header: map[string][]string のエイリアスであり、HTTPヘッダーを表すために使用されます。キーはヘッダー名(例: "Content-Type")、値はそのヘッダー名に関連付けられた文字列のリストです。これにより、同じヘッダー名が複数回出現する場合でも、すべての値を保持できます。

HTTPヘッダーの連結と非連結

HTTPヘッダーの処理において、同じキーを持つ複数のヘッダー値は、RFCの推奨に従ってカンマで連結されることがあります。例えば、Cache-Control: no-cacheCache-Control: no-store が別々に送信された場合、クライアント側で Cache-Control: no-cache, no-store のように単一のヘッダーとして解釈されることがあります。

しかし、すべてのヘッダーがこのように連結されるわけではありません。特に Set-Cookie ヘッダーのように、個々の値が独立した意味を持つ場合は、連結されずに複数回出現することが一般的です。サーバーの実装によっては、RFCの推奨に従わず、連結可能なヘッダーであっても個別に送信する場合があります。

このコミットは、Goの net/http パッケージが、このようなサーバー側の多様な挙動を考慮し、ドキュメントをより正確に記述することの重要性を示しています。

技術的詳細

このコミットの技術的な変更は非常に小さいですが、その背後にある意味は重要です。変更は src/pkg/net/http/response.go ファイルの Response 構造体の Header フィールドのコメントにあります。

元のコメント:

	// Header maps header keys to values.  If the response had multiple
	// headers with the same key, they will be concatenated, with comma
	// delimiters.  (Section 4.2 of RFC 2616 requires that multiple headers
	// be semantically equivalent to a comma-delimited sequence.) Values
	// duplicated by other fields in this struct (e.g., ContentLength) are

変更後のコメント:

	// Header maps header keys to values.  If the response had multiple
	// headers with the same key, they may be concatenated, with comma
	// delimiters.  (Section 4.2 of RFC 2616 requires that multiple headers
	// be semantically equivalent to a comma-delimited sequence.) Values
	// duplicated by other fields in this struct (e.g., ContentLength) are

変更点は they will be concatenatedthey may be concatenated になった点です。

この変更は、Goの net/http パッケージがHTTPレスポンスヘッダーをどのように処理するかという内部的なロジックを変更するものではありません。むしろ、そのロジックが外部からどのように見えるか、つまりドキュメントがその挙動をどのように説明するかを修正しています。

Response.Headermap[string][]string 型であるため、Goの内部では同じキーを持つ複数のヘッダー値は常に文字列のスライスとして保持されます。例えば、サーバーが X-Custom-Header: value1X-Custom-Header: value2 を送信した場合、Goの Response.Header["X-Custom-Header"][]string{"value1", "value2"} となります。

問題は、この []string がどのように生成されるか、そしてその生成過程でサーバーが送信した複数のヘッダーが連結される可能性があるという点です。RFC 2616は、一部のヘッダーについてはカンマ区切りで連結された単一のヘッダーとして扱われるべきだと推奨していますが、すべてのサーバーがこの推奨に厳密に従うわけではありません。また、Set-Cookie のように、連結されるべきではないヘッダーも存在します。

このドキュメントの修正は、Goの net/http パッケージが受信したヘッダーを処理する際に、サーバーが複数のヘッダーを送信した場合に、それらが必ずしもGoの内部でカンマ区切りで連結された単一の文字列として表現されるわけではない、という事実を反映しています。Goは、サーバーから受信した生のヘッダーを可能な限り忠実に []string として保持しようとしますが、その過程で一部のヘッダーがRFCの推奨に従って連結される可能性も示唆しています。

「Whether the keys are concatenated or separate (or a mixture) depends on the server.」というコミットメッセージの追加説明は、この点をさらに強調しています。つまり、Goのクライアント側でのヘッダーの解釈は、サーバーがどのようにヘッダーを送信したかに依存するということを明確にしています。これは、Goの net/http パッケージが堅牢であり、多様なサーバーの実装に対応できることを示唆しています。

コアとなるコードの変更箇所

変更は src/pkg/net/http/response.go ファイルの33行目です。

--- a/src/pkg/net/http/response.go
+++ b/src/pkg/net/http/response.go
@@ -32,7 +32,7 @@ type Response struct {
 	ProtoMinor int    // e.g. 0
 
 	// Header maps header keys to values.  If the response had multiple
-	// headers with the same key, they will be concatenated, with comma
+	// headers with the same key, they may be concatenated, with comma
 	// delimiters.  (Section 4.2 of RFC 2616 requires that multiple headers
 	// be semantically equivalent to a comma-delimited sequence.) Values
 	// duplicated by other fields in this struct (e.g., ContentLength) are

コアとなるコードの解説

変更された行は、Response 構造体の Header フィールドのドキュメンテーションコメントの一部です。

元のコメント: // headers with the same key, they will be concatenated, with comma

修正後のコメント: // headers with the same key, they may be concatenated, with comma

この変更は、will be (〜されるだろう、確実に〜される) を may be (〜されるかもしれない、可能性として〜される) に置き換えることで、同じキーを持つ複数のHTTPヘッダーがGoの Response.Header に格納される際に、必ずしもカンマ区切りで連結されるわけではないという事実を反映しています。

これは、HTTPプロトコルの柔軟性と、サーバーの実装がRFCの推奨に常に厳密に従うとは限らないという現実を考慮したものです。Goの net/http パッケージは、可能な限り正確に受信したヘッダーを表現しようとしますが、その最終的な形式(連結されるか、個別の値として保持されるか)は、サーバーの挙動に依存するというニュアンスをドキュメントに加えています。

この修正は、Goの net/http パッケージのユーザーが、Response.Header を扱う際に、同じキーを持つ複数のヘッダー値が常に連結された単一の文字列として扱われると誤解するのを防ぐことを目的としています。これにより、開発者はより堅牢なコードを記述し、多様なHTTPサーバーからのレスポンスを適切に処理できるようになります。

関連リンク

参考にした情報源リンク