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

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

このコミットは、Go言語の実験的な exp/cookiejar パッケージに、ポート処理とIDNA (Internationalized Domain Names in Applications) ドメインに関する追加のテストケースを追加するものです。これにより、クッキーのドメイン処理に関する既存のルールがより堅牢に検証され、その動作が明確に文書化されます。特に、IPアドレス、ポートの無視、IDNAドメイン、トップレベルドメイン (TLD)、およびパブリックサフィックスリストに関するクッキーの挙動が詳細にテストされています。

コミット

commit 1069d25e37e741a70977a42e60395923f9662778
Author: Volker Dobler <dr.volker.dobler@gmail.com>
Date:   Thu Feb 28 11:18:39 2013 +1100

    exp/cookiejar: add some more tests
    
    New tests added for port handling and IDNA domains.
    A new test case contains several redundant
    tests but provides a nice documentation of the
    implemented rules for domain handling.
    
    R=nigeltao
    CC=golang-dev
    https://golang.org/cl/7393070

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

https://github.com/golang/go/commit/1069d25e37e741a70977a42e60395923f9662778

元コミット内容

exp/cookiejar パッケージに、ポート処理とIDNAドメインに関する追加のテストが追加されました。新しいテストケースには、実装されているドメイン処理ルールの優れたドキュメントとなる、いくつかの冗長なテストが含まれています。

変更の背景

HTTPクッキーは、Webアプリケーションにおいてセッション管理、パーソナライゼーション、トラッキングなど多岐にわたる用途で利用される重要なメカニズムです。しかし、その挙動はRFC 6265 (HTTP State Management Mechanism) で厳密に定義されており、特にドメインマッチングやパス、セキュリティ属性に関するルールは複雑です。

Go言語の exp/cookiejar パッケージは、このRFCに準拠したクッキー管理機能を提供することを目的としています。しかし、クッキーの仕様には、ポートの扱い、国際化ドメイン名 (IDNA) の解決、トップレベルドメイン (TLD) やパブリックサフィックスの扱いなど、実装が複雑になりがちなエッジケースが多数存在します。

このコミットの背景には、これらのエッジケースにおける cookiejar の挙動をより明確にし、堅牢性を高めるという目的があります。特に、以下の点が課題として認識されていた可能性があります。

  1. ポートの無視: HTTPクッキーは通常、ドメインマッチングにおいてポート番号を無視します。この挙動が正しく実装されているかを確認する必要がありました。
  2. IDNAドメインのサポート: bücher.test のような非ASCII文字を含むドメイン名 (IDNA) は、内部的には Punycode (例: xn--bcher-kva.test) に変換されて処理されます。クッキーのドメインマッチングが、これらの変換されたドメイン名と元のドメイン名の両方で正しく機能するかを検証する必要がありました。
  3. ドメイン処理ルールの明確化: クッキーの Domain 属性の解釈は、ホストクッキーとドメインクッキーの違い、そしてパブリックサフィックスリストの適用によって複雑になります。これらのルールが cookiejar で正確に実装されていることを、具体的なテストケースを通じて文書化し、将来のメンテナンスや理解を容易にすることが求められました。

これらのテストを追加することで、exp/cookiejar パッケージの信頼性が向上し、開発者がクッキーの挙動をより正確に理解できるようになります。

前提知識の解説

HTTPクッキーは、WebサーバーがユーザーのWebブラウザに送信し、ブラウザが保存する小さなデータのことです。ブラウザは、そのクッキーが関連付けられたドメインへの後続のリクエストごとに、そのクッキーをサーバーに送り返します。これにより、サーバーはステートレスなHTTPプロトコル上でユーザーの状態を維持することができます。

クッキーにはいくつかの重要な属性があります。

  • Name-Value Pair: name=value の形式でデータが格納されます。
  • Expires / Max-Age: クッキーの有効期限を指定します。期限が過ぎるとブラウザはクッキーを削除します。
  • Domain: クッキーが送信されるドメインを指定します。この属性がない場合、クッキーは設定されたホストにのみ送信される「ホストオンリークッキー」となります。指定された場合、そのドメインとそのサブドメインに送信される「ドメインクッキー」となります。
  • Path: クッキーが送信されるパスを指定します。
  • Secure: この属性が設定されている場合、クッキーはHTTPS接続でのみ送信されます。
  • HttpOnly: この属性が設定されている場合、JavaScriptからクッキーにアクセスできなくなります。クロスサイトスクリプティング (XSS) 攻撃からの保護に役立ちます。
  • SameSite: クロスサイトリクエストフォージェリ (CSRF) 攻撃からの保護を目的とした属性です。Strict, Lax, None の値があります。

プログラミングにおける「クッキージャー」とは、HTTPクライアントが複数のHTTPリクエスト間でクッキーを保存、管理、および送信するためのメカニズムを指します。Webブラウザがクッキーを管理するのと同様に、プログラムがWebサイトとやり取りする際に、セッション情報を維持するために使用されます。Go言語の net/http/cookiejar (または実験的な exp/cookiejar) パッケージは、この機能を提供します。

クッキージャーの主な機能は以下の通りです。

  • クッキーの保存: サーバーから受信した Set-Cookie ヘッダーを解析し、クッキーを保存します。
  • クッキーの取得: 特定のURLへのリクエストを送信する際に、そのURLに適用可能なクッキーを検索し、Cookie ヘッダーとして追加します。
  • クッキーの有効期限管理: 有効期限が切れたクッキーを自動的に削除します。
  • ドメインとパスのマッチング: RFC 6265 に基づいて、クッキーがどのドメインとパスに適用されるかを正確に判断します。

IDNA (Internationalized Domain Names in Applications)

IDNAは、ドメイン名にASCII文字以外の文字 (例: 日本語、アラビア語、キリル文字など) を使用できるようにするための標準です。これらの国際化ドメイン名は、DNS (Domain Name System) で処理できるように、内部的にはASCII互換エンコーディング (ACE) である Punycode (ピュニコード) に変換されます。

  • Punycode: 非ASCII文字を含むドメイン名を、ASCII文字とハイフンのみで構成される形式に変換するエンコーディング方式です。例えば、bücher.test は Punycode で xn--bcher-kva.test となります。xn-- は、そのドメイン名がPunycodedであることを示すプレフィックスです。

WebブラウザやHTTPクライアントは、ユーザーが入力した国際化ドメイン名を自動的にPunycodeに変換してDNSルックアップを行い、サーバーとの通信を行います。クッキーのドメインマッチングにおいても、このIDNAの変換を考慮に入れる必要があります。つまり、bücher.testxn--bcher-kva.test は同じドメインとして扱われるべきです。

RFC 6265 (HTTP State Management Mechanism)

RFC 6265 は、HTTPクッキーの動作を定義する主要な標準ドキュメントです。このRFCは、クッキーの構文、セマンティクス、およびブラウザとサーバーがクッキーをどのように処理すべきかに関する詳細なルールを規定しています。

このコミットで追加されたテストは、特にRFC 6265の以下の側面に関連しています。

  • ドメインマッチング: クッキーの Domain 属性がどのように解釈され、どのホストにクッキーが送信されるかに関するルール。これには、ホストオンリークッキーとドメインクッキーの違い、およびパブリックサフィックスリストの概念が含まれます。
  • ポートの無視: クッキーのドメインマッチングにおいて、ポート番号が考慮されないというルール。
  • IDNAの考慮: ドメイン名が国際化されている場合の処理。

技術的詳細

このコミットは、Go言語の exp/cookiejar パッケージにおけるクッキーのドメイン処理の堅牢性を高めるためのテストを追加しています。特に、以下の技術的な側面が詳細に検証されています。

ポート処理のテスト

HTTPクッキーの仕様 (RFC 6265) では、クッキーのドメインマッチングにおいてポート番号は無視されると規定されています。これは、同じホスト名であれば、異なるポートでアクセスしても同じクッキーが共有されるべきであることを意味します。

追加された Port is ignored #1. および Port is ignored #2. テストケースは、この挙動を検証しています。

  • http://www.host.test で設定されたクッキーが、http://www.host.test:8080/http://www.host.test:1234/ といった異なるポート番号を持つURLに対しても正しく送信されることを確認しています。
  • 逆に、http://www.host.test:8080/ で設定されたクッキーが、ポート番号なしの http://www.host.test や他のポート番号を持つURLに対しても有効であることを確認しています。

これにより、cookiejar がRFCの規定通りにポートを無視してクッキーを管理していることが保証されます。

IDNA (Internationalized Domain Names in Applications) ドメインのテスト

IDNAは、非ASCII文字を含むドメイン名 (例: bücher.test) を扱うための標準です。これらのドメイン名は、DNSシステムで処理するために Punycode (例: xn--bcher-kva.test) に変換されます。クッキーのドメインマッチングは、ユーザーが入力した国際化ドメイン名と、そのPunycode形式の両方で正しく機能する必要があります。

追加された Host cookie on IDNA domain #1, Host cookie on IDNA domain #2, Domain cookie on IDNA domain #1, Domain cookie on IDNA domain #2 テストケースは、IDNAドメインにおけるクッキーの挙動を詳細に検証しています。

  • ホストクッキー: http://www.bücher.test (Unicode) または http://www.xn--bcher-kva.test (Punycode) で設定されたホストクッキーが、両方の形式のURLに対して正しく機能することを確認しています。また、サブドメインや異なるドメインに対しては送信されないことも検証しています。
  • ドメインクッキー: domain=xn--bcher-kva.test のようにPunycode形式で設定されたドメインクッキーが、www.bücher.test, bücher.test, bar.bücher.test など、Unicode形式およびPunycode形式の様々なサブドメインに対して正しく送信されることを確認しています。これは、cookiejar がIDNAドメインを適切に正規化し、ドメインマッチングを行っていることを示しています。

ドメイン処理ルールの詳細なテストと文書化

domainHandlingTests は、クッキーのドメイン属性に関するRFC 6265の複雑なルールを、多数の具体的なシナリオを通じてテストし、同時にその挙動を文書化することを目的としています。

  • ホストクッキー (Host cookie): Domain 属性が指定されていない場合、クッキーは設定されたホストにのみ適用され、そのサブドメインや親ドメインには適用されないことを確認します。
  • ドメインクッキー (Domain cookie #1, Domain cookie #2): Domain 属性が指定されている場合 (例: domain=host.test または domain=.host.test)、クッキーは指定されたドメインとそのサブドメインに適用されることを確認します。. の有無は、RFC 6265では同じ意味として扱われます。
  • TLD (トップレベルドメイン) の扱い (Host cookie on TLD., Domain cookie on TLD becomes a host cookie.):
    • http://com のようなTLD自体に設定されたホストクッキーは、そのTLDにのみ適用され、any.com のようなサブドメインには適用されないことを確認します。
    • domain=com のようにTLDに対してドメインクッキーを設定しようとした場合、RFC 6265のルールにより、それはホストクッキーとして扱われるべきであり、サブドメインには適用されないことを確認します。これは、TLDに対してドメインクッキーを設定することを防ぎ、セキュリティ上のリスクを軽減するための重要なルールです。
  • パブリックサフィックスの扱い (Host cookie on public suffix., Domain cookie on public suffix is ignored.):
    • http://co.uk のようなパブリックサフィックス (Public Suffix List に登録されているドメイン) に設定されたホストクッキーは、そのホストにのみ適用され、some.co.uk のようなサブドメインには適用されないことを確認します。
    • domain=co.uk のようにパブリックサフィックスに対してドメインクッキーを設定しようとした場合、RFC 6265のルールにより、それは無視されるべきであることを確認します。これは、悪意のあるサイトが co.uk のようなパブリックサフィックスに対してクッキーを設定し、そのサフィックス下の他のサイトのクッキーを盗むことを防ぐための重要なセキュリティメカニズムです。

これらのテストは、cookiejar がRFC 6265の複雑なドメインマッチングルール、特にセキュリティに関連する制約を正確に実装していることを保証します。

テスト構造 (jarTestquery)

テストは jarTest 構造体と query 構造体を使用して記述されています。

type jarTest struct {
	description string
	setURL      string
	setCookies  []string
	wantSet     string
	queries     []query
}

type query struct {
	url  string
	want string
}
  • jarTest: 個々のテストケースを定義します。
    • description: テストの目的を説明する文字列。
    • setURL: クッキーを設定するURL。
    • setCookies: 設定するクッキーの文字列スライス (例: {"a=1", "b=2; domain=example.com"})。
    • wantSet: setCookies が設定された後に期待されるクッキーの文字列。
    • queries: クッキーが設定された後に、異なるURLでクッキーを問い合わせるテストのリスト。
  • query: 特定のURLに対するクッキーの問い合わせを定義します。
    • url: クッキーを問い合わせるURL。
    • want: そのURLで期待されるクッキーの文字列。

この構造により、各テストケースはクッキーの設定、その後の様々なURLでのクッキーの取得という一連のフローを明確に記述できます。特に domainHandlingTests では、一つの jarTest 内に複数の query を含めることで、特定のクッキーが様々なドメインやサブドメインに対してどのように振る舞うかを包括的に検証しています。

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

変更は src/pkg/exp/cookiejar/jar_test.go ファイルに集中しており、主に以下の2つの新しいテストスライスが追加されています。

  1. basicsTests スライスへの追加:
    • IPアドレスに対するホストクッキーのテスト。
    • ポートが無視されることを確認するテスト (2つのケース)。
  2. domainHandlingTests スライスの新規追加:
    • ホストクッキーとドメインクッキーの基本的な挙動。
    • IDNAドメイン (UnicodeとPunycodeの両方) におけるホストクッキーとドメインクッキーの挙動。
    • TLD (トップレベルドメイン) に対するクッキーの挙動。
    • パブリックサフィックスに対するクッキーの挙動。
  3. TestDomainHandling 関数の新規追加:
    • domainHandlingTests スライス内の各テストケースを実行するためのテスト関数。
--- a/src/pkg/exp/cookiejar/jar_test.go
+++ b/src/pkg/exp/cookiejar/jar_test.go
@@ -471,6 +471,34 @@ var basicsTests = [...]jarTest{
 		"a=1",
 		[]query{{"http://www.bbc.co.uk", "a=1"}},
 	},
+	{
+		"Host cookie on IP.",
+		"http://192.168.0.10",
+		[]string{"a=1"},
+		"a=1",
+		[]query{{"http://192.168.0.10", "a=1"}},
+	},
+	{
+		"Port is ignored #1.",
+		"http://www.host.test/",
+		[]string{"a=1"},
+		"a=1",
+		[]query{
+			{"http://www.host.test", "a=1"},
+			{"http://www.host.test:8080/", "a=1"},
+		},
+	},
+	{
+		"Port is ignored #2.",
+		"http://www.host.test:8080/",
+		[]string{"a=1"},
+		"a=1",
+		[]query{
+			{"http://www.host.test", "a=1"},
+			{"http://www.host.test:8080/", "a=1"},
+			{"http://www.host.test:1234/", "a=1"},
+		},
+	},
 }
 
 func TestBasics(t *testing.T) {
@@ -989,3 +1017,177 @@ func TestChromiumDeletion(t *testing.T) {
 		test.run(t, jar)
 	}\n}\n+\n+// domainHandlingTests tests and documents the rules for domain handling.\n+// Each test must be performed on an empty new Jar.\n+var domainHandlingTests = [...]jarTest{\n+\t{\n+\t\t\"Host cookie\",\n+\t\t\"http://www.host.test\",\n+\t\t[]string{\"a=1\"},\n+\t\t\"a=1\",\n+\t\t[]query{\n+\t\t\t{\"http://www.host.test\", \"a=1\"},\n+\t\t\t{\"http://host.test\", \"\"},\n+\t\t\t{\"http://bar.host.test\", \"\"},\n+\t\t\t{\"http://foo.www.host.test\", \"\"},\n+\t\t\t{\"http://other.test\", \"\"},\n+\t\t\t{\"http://test\", \"\"},\n+\t\t},\n+\t},\n+\t{\n+\t\t\"Domain cookie #1\",\n+\t\t\"http://www.host.test\",\n+\t\t[]string{\"a=1; domain=host.test\"},\n+\t\t\"a=1\",\n+\t\t[]query{\n+\t\t\t{\"http://www.host.test\", \"a=1\"},\n+\t\t\t{\"http://host.test\", \"a=1\"},\n+\t\t\t{\"http://bar.host.test\", \"a=1\"},\n+\t\t\t{\"http://foo.www.host.test\", \"a=1\"},\n+\t\t\t{\"http://other.test\", \"\"},\n+\t\t\t{\"http://test\", \"\"},\n+\t\t},\n+\t},\n+\t{\n+\t\t\"Domain cookie #2\",\n+\t\t\"http://www.host.test\",\n+\t\t[]string{\"a=1; domain=.host.test\"},\n+\t\t\"a=1\",\n+\t\t[]query{\n+\t\t\t{\"http://www.host.test\", \"a=1\"},\n+\t\t\t{\"http://host.test\", \"a=1\"},\n+\t\t\t{\"http://bar.host.test\", \"a=1\"},\n+\t\t\t{\"http://foo.www.host.test\", \"a=1\"},\n+\t\t\t{\"http://other.test\", \"\"},\n+\t\t\t{\"http://test\", \"\"},\n+\t\t},\n+\t},\n+\t{\n+\t\t\"Host cookie on IDNA domain #1\",\n+\t\t\"http://www.bücher.test\",\n+\t\t[]string{\"a=1\"},\n+\t\t\"a=1\",\n+\t\t[]query{\n+\t\t\t{\"http://www.bücher.test\", \"a=1\"},\n+\t\t\t{\"http://www.xn--bcher-kva.test\", \"a=1\"},\n+\t\t\t{\"http://bücher.test\", \"\"},\n+\t\t\t{\"http://xn--bcher-kva.test\", \"\"},\n+\t\t\t{\"http://bar.bücher.test\", \"\"},\n+\t\t\t{\"http://bar.xn--bcher-kva.test\", \"\"},\n+\t\t\t{\"http://foo.www.bücher.test\", \"\"},\n+\t\t\t{\"http://foo.www.xn--bcher-kva.test\", \"\"},\n+\t\t\t{\"http://other.test\", \"\"},\n+\t\t\t{\"http://test\", \"\"},\n+\t\t},\n+\t},\n+\t{\n+\t\t\"Host cookie on IDNA domain #2\",\n+\t\t\"http://www.xn--bcher-kva.test\",\n+\t\t[]string{\"a=1\"},\n+\t\t\"a=1\",\n+\t\t[]query{\n+\t\t\t{\"http://www.bücher.test\", \"a=1\"},\n+\t\t\t{\"http://www.xn--bcher-kva.test\", \"a=1\"},\n+\t\t\t{\"http://bücher.test\", \"\"},\n+\t\t\t{\"http://xn--bcher-kva.test\", \"\"},\n+\t\t\t{\"http://bar.bücher.test\", \"\"},\n+\t\t\t{\"http://bar.xn--bcher-kva.test\", \"\"},\n+\t\t\t{\"http://foo.www.bücher.test\", \"\"},\n+\t\t\t{\"http://foo.www.xn--bcher-kva.test\", \"\"},\n+\t\t\t{\"http://other.test\", \"\"},\n+\t\t\t{\"http://test\", \"\"},\n+\t\t},\n+\t},\n+\t{\n+\t\t\"Domain cookie on IDNA domain #1\",\n+\t\t\"http://www.bücher.test\",\n+\t\t[]string{\"a=1; domain=xn--bcher-kva.test\"},\n+\t\t\"a=1\",\n+\t\t[]query{\n+\t\t\t{\"http://www.bücher.test\", \"a=1\"},\n+\t\t\t{\"http://www.xn--bcher-kva.test\", \"a=1\"},\n+\t\t\t{\"http://bücher.test\", \"a=1\"},\n+\t\t\t{\"http://xn--bcher-kva.test\", \"a=1\"},\n+\t\t\t{\"http://bar.bücher.test\", \"a=1\"},\n+\t\t\t{\"http://bar.xn--bcher-kva.test\", \"a=1\"},\n+\t\t\t{\"http://foo.www.bücher.test\", \"a=1\"},\n+\t\t\t{\"http://foo.www.xn--bcher-kva.test\", \"a=1\"},\n+\t\t\t{\"http://other.test\", \"\"},\n+\t\t\t{\"http://test\", \"\"},\n+\t\t},\n+\t},\n+\t{\n+\t\t\"Domain cookie on IDNA domain #2\",\n+\t\t\"http://www.xn--bcher-kva.test\",\n+\t\t[]string{\"a=1; domain=xn--bcher-kva.test\"},\n+\t\t\"a=1\",\n+\t\t[]query{\n+\t\t\t{\"http://www.bücher.test\", \"a=1\"},\n+\t\t\t{\"http://www.xn--bcher-kva.test\", \"a=1\"},\n+\t\t\t{\"http://bücher.test\", \"a=1\"},\n+\t\t\t{\"http://xn--bcher-kva.test\", \"a=1\"},\n+\t\t\t{\"http://bar.bücher.test\", \"a=1\"},\n+\t\t\t{\"http://bar.xn--bcher-kva.test\", \"a=1\"},\n+\t\t\t{\"http://foo.www.bücher.test\", \"a=1\"},\n+\t\t\t{\"http://foo.www.xn--bcher-kva.test\", \"a=1\"},\n+\t\t\t{\"http://other.test\", \"\"},\n+\t\t\t{\"http://test\", \"\"},\n+\t\t},\n+\t},\n+\t{\n+\t\t\"Host cookie on TLD.\",\n+\t\t\"http://com\",\n+\t\t[]string{\"a=1\"},\n+\t\t\"a=1\",\n+\t\t[]query{\n+\t\t\t{\"http://com\", \"a=1\"},\n+\t\t\t{\"http://any.com\", \"\"},\n+\t\t\t{\"http://any.test\", \"\"},\n+\t\t},\n+\t},\n+\t{\n+\t\t\"Domain cookie on TLD becomes a host cookie.\",\n+\t\t\"http://com\",\n+\t\t[]string{\"a=1; domain=com\"},\n+\t\t\"a=1\",\n+\t\t[]query{\n+\t\t\t{\"http://com\", \"a=1\"},\n+\t\t\t{\"http://any.com\", \"\"},\n+\t\t\t{\"http://any.test\", \"\"},\n+\t\t},\n+\t},\n+\t{\n+\t\t\"Host cookie on public suffix.\",\n+\t\t\"http://co.uk\",\n+\t\t[]string{\"a=1\"},\n+\t\t\"a=1\",\n+\t\t[]query{\n+\t\t\t{\"http://co.uk\", \"a=1\"},\n+\t\t\t{\"http://uk\", \"\"},\n+\t\t\t{\"http://some.co.uk\", \"\"},\n+\t\t\t{\"http://foo.some.co.uk\", \"\"},\n+\t\t\t{\"http://any.uk\", \"\"},\n+\t\t},\n+\t},\n+\t{\n+\t\t\"Domain cookie on public suffix is ignored.\",\n+\t\t\"http://some.co.uk\",\n+\t\t[]string{\"a=1; domain=co.uk\"},\n+\t\t\"\",\n+\t\t[]query{\n+\t\t\t{\"http://co.uk\", \"\"},\n+\t\t\t{\"http://uk\", \"\"},\n+\t\t\t{\"http://some.co.uk\", \"\"},\n+\t\t\t{\"http://foo.some.co.uk\", \"\"},\n+\t\t\t{\"http://any.uk\", \"\"},\n+\t\t},\n+\t},\n+}\n+\n+func TestDomainHandling(t *testing.T) {\n+\tfor _, test := range domainHandlingTests {\n+\t\tjar := newTestJar()\n+\t\ttest.run(t, jar)\n+\t}\n+}\n```

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

追加されたテストケースは、`exp/cookiejar` パッケージがHTTPクッキーの仕様 (RFC 6265) にどれだけ厳密に準拠しているかを検証し、その挙動を明確に文書化することを目的としています。

### `basicsTests` への追加

*   **`Host cookie on IP.`**:
    *   `http://192.168.0.10` のようなIPアドレスに対してクッキーが設定された場合、そのIPアドレスへのリクエストでのみクッキーが返されることを確認します。これは、IPアドレスもホスト名と同様に扱われるべきであることを示しています。
*   **`Port is ignored #1.`** および **`Port is ignored #2.`**:
    *   これらのテストは、クッキーのドメインマッチングにおいてポート番号が無視されるというRFC 6265の重要なルールを検証します。
    *   `http://www.host.test` で設定されたクッキーが、`http://www.host.test:8080/` や `http://www.host.test:1234/` のように異なるポート番号を持つURLに対しても有効であることを確認しています。
    *   これは、Webサーバーが異なるポートでサービスを提供していても、同じドメインであればクッキーを共有できることを保証します。

### `domainHandlingTests` の新規追加と `TestDomainHandling`

この新しいテストスライスは、クッキーの `Domain` 属性の解釈に関する複雑なルールを網羅的にテストします。各テストは新しい空の `Jar` インスタンスで実行されるため、他のテストからの影響を受けません。

*   **`Host cookie`**:
    *   `http://www.host.test` で `domain` 属性なしで設定されたクッキー (`a=1`) が、設定されたホスト (`www.host.test`) にのみ適用され、その親ドメイン (`host.test`) やサブドメイン (`bar.host.test`, `foo.www.host.test`)、あるいは全く異なるドメイン (`other.test`, `test`) には適用されないことを確認します。これは「ホストオンリークッキー」の挙動を検証しています。
*   **`Domain cookie #1`** および **`Domain cookie #2`**:
    *   `domain=host.test` または `domain=.host.test` のように `domain` 属性が明示的に指定されたクッキーが、指定されたドメイン (`host.test`) とそのすべてのサブドメイン (`www.host.test`, `bar.host.test`, `foo.www.host.test`) に適用されることを確認します。RFC 6265では、`domain=example.com` と `domain=.example.com` は同じ意味として扱われます。
*   **`Host cookie on IDNA domain #1`** および **`Host cookie on IDNA domain #2`**:
    *   `http://www.bücher.test` (Unicode) または `http://www.xn--bcher-kva.test` (Punycode) で設定されたホストクッキーが、両方の形式のURLに対して有効であることを確認します。これは、`cookiejar` がIDNAドメインを適切に処理し、UnicodeとPunycodeの間で相互に認識できることを示しています。サブドメインや異なるドメインには適用されないことも検証しています。
*   **`Domain cookie on IDNA domain #1`** および **`Domain cookie on IDNA domain #2`**:
    *   `domain=xn--bcher-kva.test` のようにPunycode形式で設定されたドメインクッキーが、`www.bücher.test`, `bücher.test`, `bar.bücher.test` など、Unicode形式およびPunycode形式の様々なサブドメインに対して正しく送信されることを確認します。これは、IDNAドメインに対するドメインクッキーの挙動がRFCに準拠していることを保証します。
*   **`Host cookie on TLD.`**:
    *   `http://com` のようなトップレベルドメイン (TLD) 自体に設定されたホストクッキーが、そのTLDにのみ適用され、`http://any.com` のようなそのTLDのサブドメインには適用されないことを確認します。これは、TLDが特別な扱いを受けることを示しています。
*   **`Domain cookie on TLD becomes a host cookie.`**:
    *   `http://com` で `domain=com` のようにTLDに対してドメインクッキーを設定しようとした場合、RFC 6265のルールにより、それはホストクッキーとして扱われるべきであり、`http://any.com` のようなサブドメインには適用されないことを確認します。これは、TLDに対する広範なクッキー設定を防ぐためのセキュリティメカニズムです。
*   **`Host cookie on public suffix.`**:
    *   `http://co.uk` のようなパブリックサフィックス (Public Suffix List に登録されているドメイン) に設定されたホストクッキーが、そのホストにのみ適用され、`http://some.co.uk` のようなサブドメインには適用されないことを確認します。
*   **`Domain cookie on public suffix is ignored.`**:
    *   `http://some.co.uk` で `domain=co.uk` のようにパブリックサフィックスに対してドメインクッキーを設定しようとした場合、RFC 6265のルールにより、そのクッキーは無視されるべきであることを確認します。これは、悪意のあるサイトが `co.uk` のようなパブリックサフィックスに対してクッキーを設定し、そのサフィックス下の他のサイトのクッキーを盗むことを防ぐための重要なセキュリティ対策です。

これらのテストは、`exp/cookiejar` がクッキーのドメイン処理に関する複雑なルール、特にセキュリティ上の考慮事項を正確に実装していることを保証し、その挙動を詳細に文書化する役割も果たしています。

## 関連リンク

*   Go CL 7393070: [https://golang.org/cl/7393070](https://golang.org/cl/7393070)
*   GitHub Commit: [https://github.com/golang/go/commit/1069d25e37e741a70977a42e60395923f9662778](https://github.com/golang/go/commit/1069d25e37e741a70977a42e60395923f9662778)

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

*   RFC 6265 - HTTP State Management Mechanism: [https://datatracker.ietf.org/doc/html/rfc6265](https://datatracker.ietf.org/doc/html/rfc6265)
*   Internationalized Domain Names (IDN): [https://www.icann.org/resources/pages/idn-2012-02-25-en](https://www.icann.org/resources/pages/idn-2012-02-25-en)
*   Punycode: [https://en.wikipedia.org/wiki/Punycode](https://en.wikipedia.org/wiki/Punycode)
*   Public Suffix List: [https://publicsuffix.org/](https://publicsuffix.org/)
*   Go `net/http/cookiejar` package documentation: [https://pkg.go.dev/net/http/cookiejar](https://pkg.go.dev/net/http/cookiejar) (Note: `exp/cookiejar` は実験的なパッケージであり、最終的には `net/http/cookiejar` に統合されました。)
*   MDN Web Docs - HTTP Cookies: [https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies](https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies)