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

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

このコミットは、Go言語の標準ライブラリである net/http パッケージにおけるクッキー(Cookie)のテストを強化するものです。具体的には、Set-Cookie ヘッダーのパースに関する新たなテストケースが src/pkg/net/http/cookie_test.go に追加されました。これにより、より多様な形式のクッキー、特に HttpOnly フラグを持つクッキーの正確な処理が保証されます。また、将来的に検討される可能性のある、HTTPヘッダーの「折りたたみ(folding)」に関するコメントアウトされたテストケースも含まれており、ブラウザの挙動とRFCの規定との間の乖離に対するGoの net/http パッケージの堅牢性を高める意図が伺えます。

コミット

commit a5b59645240e2e7b5304d5d869acb801f2b7ef00
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date:   Thu Feb 23 15:51:53 2012 +1100

    net/http: some more cookie tests
    
    Including a commented-out test we might
    tackle later, after seeing what browsers do.
    
    R=dsymonds, rsc
    CC=golang-dev
    https://golang.org/cl/5694045

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

https://github.com/golang/go/commit/a5b59645240e2e7b5304d5d869acb801f2b7ef00

元コミット内容

net/http: some more cookie tests

Including a commented-out test we might
tackle later, after seeing what browsers do.

R=dsymonds, rsc
CC=golang-dev
https://golang.org/cl/5694045

変更の背景

この変更の背景には、net/http パッケージがHTTP通信においてクッキーを正確に処理することの重要性があります。特に、ウェブアプリケーションで広く利用されているASP.NET関連のクッキー(.ASPXAUTHASP.NET_SessionId)のような、特定の命名規則や属性を持つクッキーのパースが正しく行われることを保証する必要がありました。

また、コミットメッセージにある「commented-out test we might tackle later, after seeing what browsers do.」という記述は、HTTPヘッダーの「折りたたみ(header folding)」という、複数のヘッダーフィールドを単一の行にまとめる非推奨の慣行に対するGoの net/http パッケージの挙動を検討していることを示唆しています。RFC 6265(HTTP State Management Mechanism)では、Set-Cookie ヘッダーの折りたたみは推奨されていませんが、現実世界のシステムやブラウザがどのように振る舞うかを観察し、それに対応する必要があるという認識があったと考えられます。これにより、GoのHTTPクライアントおよびサーバーが、より多様な(時には非標準的な)HTTP実装と相互運用できるよう、堅牢性を高めることが目的です。

前提知識の解説

HTTP Cookieは、ウェブサーバーがユーザーのウェブブラウザに送信する小さなデータ片です。ブラウザはそれらを保存し、同じサーバーへの後続のリクエストとともに送り返します。これにより、サーバーはユーザーの状態を記憶したり、ユーザーを識別したりすることができます。クッキーは主にセッション管理、パーソナライゼーション、トラッキングに使用されます。

サーバーは Set-Cookie HTTPレスポンスヘッダーを使用してクッキーをブラウザに送信します。このヘッダーには、クッキーの名前と値、有効期限、パス、ドメイン、セキュリティ属性(HttpOnly, Secure, SameSite など)が含まれます。

HttpOnly フラグ

HttpOnlySet-Cookie ヘッダーに設定できる属性の一つです。このフラグが設定されたクッキーは、クライアントサイドのスクリプト(JavaScriptなど)からアクセスすることができません。これにより、クロスサイトスクリプティング(XSS)攻撃によって悪意のあるスクリプトがユーザーのセッションクッキーを盗むことを防ぐなど、セキュリティを向上させる効果があります。

RFC 6265 (HTTP State Management Mechanism)

RFC 6265は、HTTPクッキーの動作を定義する主要な標準仕様です。このRFCは、クッキーの構文、セマンティクス、およびブラウザとサーバーがクッキーをどのように処理すべきかについて詳細に記述しています。特に、Set-Cookie ヘッダーのパース規則や、複数のクッキーを送信する際の推奨される方法(複数の Set-Cookie ヘッダーを使用すること)などが定められています。コミットメッセージで言及されている「header folding」については、RFC 6265のセクション3で「don't do that」(そうしないこと)と明確に述べられており、単一の Set-Cookie ヘッダー内で複数のクッキーをカンマで区切って送信する形式は非推奨とされています。

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

Go言語の標準ライブラリである net/http パッケージは、HTTPクライアントとサーバーの実装を提供します。このパッケージは、HTTPリクエストの送信、レスポンスの受信、ヘッダーのパース、クッキーの処理など、HTTP通信に必要な基本的な機能を提供します。開発者はこのパッケージを使用して、ウェブサーバー、RESTful APIクライアント、またはその他のHTTPベースのアプリケーションを簡単に構築できます。クッキーの処理は、このパッケージの重要な機能の一つであり、http.Cookie 構造体や http.Request.Cookie()http.ResponseWriter.SetCookie() などのメソッドを通じて行われます。

技術的詳細

このコミットは、net/http パッケージの cookie_test.go ファイルに、Set-Cookie ヘッダーのパースに関するテストケースを追加することで、クッキー処理の堅牢性を高めています。

追加されたテストケースは、readSetCookiesTests というスライスに追加されています。このスライスは、Set-Cookie ヘッダーの生の値(Header フィールド)と、それが正しくパースされた場合の期待される *Cookie 構造体のスライス(Want フィールド)をペアにしたものです。

新しいテストケースの具体例

  1. .ASPXAUTH クッキーのテスト:

    {
    	Header{"Set-Cookie": {".ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly"}},
    	[]*Cookie{{
    		Name:       ".ASPXAUTH",
    		Value:      "7E3AA",
    		Path:       "/",
    		Expires:    time.Date(2012, 3, 7, 14, 25, 6, 0, time.UTC),
    		RawExpires: "Wed, 07-Mar-2012 14:25:06 GMT",
    		HttpOnly:   true,
    		Raw:        ".ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly",
    	}},
    },
    

    このテストケースは、.ASPXAUTH という名前のクッキーが、値、パス、有効期限、HttpOnly フラグといった属性とともに正しくパースされることを確認します。特に HttpOnly: true の検証が含まれている点が重要です。

  2. ASP.NET_SessionId クッキーのテスト:

    {
    	Header{"Set-Cookie": {"ASP.NET_SessionId=foo; path=/; HttpOnly"}},
    	[]*Cookie{{
    		Name:     "ASP.NET_SessionId",
    		Value:    "foo",
    		Path:     "/",
    		HttpOnly: true,
    		Raw:      "ASP.NET_SessionId=foo; path=/; HttpOnly",
    	}},
    },
    

    こちらも ASP.NET_SessionId という名前のクッキーが、値、パス、HttpOnly フラグとともに正しくパースされることを確認します。

コメントアウトされたテストケースと「ヘッダー折りたたみ」

コミットには、以下のコメントアウトされたテストケースが含まれています。

	// TODO(bradfitz): users have reported seeing this in the
	// wild, but do browsers handle it? RFC 6265 just says "don't
	// do that" (section 3) and then never mentions header folding
	// again.
	// Header{"Set-Cookie": {"ASP.NET_SessionId=foo; path=/; HttpOnly, .ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly"}},

この部分は、単一の Set-Cookie ヘッダー内で複数のクッキーがカンマで区切られて送信される「ヘッダー折りたたみ」という非標準的な形式を扱おうとしていることを示しています。RFC 6265ではこのような形式は推奨されていませんが、実際のウェブ環境では一部のシステムがこのような形式でクッキーを送信する場合があります。このコメントは、Goの net/http パッケージが、RFCに厳密に従うべきか、それとも現実世界の非標準的な挙動にも対応すべきか、という設計上の課題に直面していることを示しています。ブラウザの挙動を調査し、それに基づいて将来的にこのケースを処理するかどうかを決定する意図が読み取れます。これは、標準への準拠と実用性(相互運用性)のバランスを取るという、ライブラリ開発における一般的な課題を浮き彫りにしています。

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

src/pkg/net/http/cookie_test.go ファイルに以下の変更が加えられました。

--- a/src/pkg/net/http/cookie_test.go
+++ b/src/pkg/net/http/cookie_test.go
@@ -128,6 +128,34 @@ var readSetCookiesTests = []struct {
 			Raw:        "NID=99=YsDT5i3E-CXax-; expires=Wed, 23-Nov-2011 01:05:03 GMT; path=/; domain=.google.ch; HttpOnly",
 		}},
 	},\
+\t{\n+\t\tHeader{\"Set-Cookie\": {\".ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly\"}},\n+\t\t[]*Cookie{{\n+\t\t\tName:       \".ASPXAUTH\",\n+\t\t\tValue:      \"7E3AA\",\n+\t\t\tPath:       \"/\",\n+\t\t\tExpires:    time.Date(2012, 3, 7, 14, 25, 6, 0, time.UTC),\n+\t\t\tRawExpires: \"Wed, 07-Mar-2012 14:25:06 GMT\",\n+\t\t\tHttpOnly:   true,\n+\t\t\tRaw:        \".ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly\",\n+\t\t}},\n+\t},\n+\t{\n+\t\tHeader{\"Set-Cookie\": {\"ASP.NET_SessionId=foo; path=/; HttpOnly\"}},\n+\t\t[]*Cookie{{\n+\t\t\tName:     \"ASP.NET_SessionId\",\n+\t\t\tValue:    \"foo\",\n+\t\t\tPath:     \"/\",\n+\t\t\tHttpOnly: true,\n+\t\t\tRaw:      \"ASP.NET_SessionId=foo; path=/; HttpOnly\",\n+\t\t}},\n+\t},\n+\n+\t// TODO(bradfitz): users have reported seeing this in the\n+\t// wild, but do browsers handle it? RFC 6265 just says "don\'t\n+\t// do that" (section 3) and then never mentions header folding\n+\t// again.\n+\t// Header{\"Set-Cookie\": {\"ASP.NET_SessionId=foo; path=/; HttpOnly, .ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly\"}},\n }\n \n func toJSON(v interface{}) string {\n```

## コアとなるコードの解説

変更箇所は、`readSetCookiesTests` というグローバル変数(スライス)への追加です。このスライスは、`Set-Cookie` ヘッダーのパース機能をテストするために使用されます。各要素は匿名構造体であり、以下の2つのフィールドを持ちます。

*   `Header`: `http.Header` 型で、テスト対象の `Set-Cookie` ヘッダーの生の値を含みます。キーは `"Set-Cookie"` で、値は文字列のスライスです。
*   `Want`: `[]*Cookie` 型で、`Header` が正しくパースされた場合に期待される `http.Cookie` 構造体のスライスです。

追加された各テストケースは、特定のクッキーの属性(`Name`, `Value`, `Path`, `Expires`, `RawExpires`, `HttpOnly`, `Raw`)が、`Set-Cookie` ヘッダーの文字列から正確に抽出されることを検証します。

特に注目すべきは、`HttpOnly: true` の検証が含まれている点です。これは、`HttpOnly` フラグが正しく認識され、`http.Cookie` 構造体の対応するフィールドに反映されることを保証します。

コメントアウトされたテストケースは、前述の通り、単一の `Set-Cookie` ヘッダー内に複数のクッキーがカンマで区切られて含まれる場合の挙動を将来的にテストするためのプレースホルダーです。これは、Goの `net/http` パッケージが、RFCに準拠しつつも、現実世界の多様なHTTP実装との相互運用性を考慮していることを示しています。

## 関連リンク

*   Gerrit Change-ID: [https://golang.org/cl/5694045](https://golang.org/cl/5694045)

## 参考にした情報源リンク

*   RFC 6265 - HTTP State Management Mechanism: [https://datatracker.ietf.org/doc/html/rfc6265](https://datatracker.ietf.org/doc/html/rfc6265)
*   MDN Web Docs - Set-Cookie: [https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Set-Cookie](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Set-Cookie)
*   MDN Web Docs - HttpOnly: [https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies#httponly](https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies#httponly)