[インデックス 14503] ファイルの概要
このコミットは、Go言語の標準ライブラリにHTTPクッキーを管理するための新しいパッケージ exp/cookiejar
を導入するものです。このコミット自体はAPIの定義のみを含み、実際の機能実装は後続のコミットで行われる予定です。
コミット
commit 478aff3d4d7eea7f9980f960957eb21ae77aa2c2
Author: Nigel Tao <nigeltao@golang.org>
Date: Tue Nov 27 18:20:44 2012 +1100
exp/cookiejar: new package.
This CL defines the API. Implementation will come in follow-up CLs.
Update #1960.
R=bradfitz, dr.volker.dobler, rsc
CC=golang-dev
https://golang.org/cl/6849092
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/478aff3d4d7eea7f9980f960957eb21ae77aa2c2
元コミット内容
exp/cookiejar: new package.
This CL defines the API. Implementation will come in follow-up CLs.
Update #1960.
変更の背景
このコミットは、Go言語の標準ライブラリにRFC 6265に準拠したHTTPクッキー管理機能を追加するための第一歩です。既存のnet/http
パッケージにはhttp.CookieJar
インターフェースが存在しますが、その具体的な実装は提供されていませんでした。そのため、ユーザーは独自のクッキージャーを実装するか、サードパーティのライブラリを使用する必要がありました。
この変更の背景には、Go言語のIssue #1960があります。このIssueは、GoのHTTPクライアントがクッキーを適切に処理できるように、RFC 6265に準拠したクッキージャーの実装を求めるものでした。RFC 6265は、HTTP State Management Mechanism(HTTPステート管理メカニズム)を定義しており、WebブラウザやHTTPクライアントがどのようにクッキーを保存、送信、および管理すべきかを詳細に規定しています。
このコミットは、まずAPIを定義することで、将来的な実装の基盤を築くことを目的としています。これにより、GoのHTTPクライアントがより堅牢で標準に準拠したクッキー処理を行えるようになり、Webアプリケーションとの連携がスムーズになります。
前提知識の解説
HTTP Cookie (クッキー)
HTTPクッキーは、WebサーバーがユーザーのWebブラウザに送信する小さなデータの一部です。ブラウザは、そのクッキーを保存し、同じサーバーへの後続のリクエストとともに送り返します。これにより、サーバーはユーザーの状態(ログイン情報、ショッピングカートの内容、ユーザー設定など)を記憶することができます。
RFC 6265: HTTP State Management Mechanism
RFC 6265は、HTTPクッキーの動作を定義する標準仕様です。これには、クッキーの属性(Expires
, Max-Age
, Domain
, Path
, Secure
, HttpOnly
, SameSite
など)、クッキーの生成、保存、送信、削除のルールが含まれます。このRFCに準拠することで、異なるブラウザやクライアント間でのクッキーの互換性とセキュリティが保証されます。
http.CookieJar
インターフェース (Go言語)
Go言語のnet/http
パッケージには、CookieJar
というインターフェースが定義されています。これは、HTTPクライアントがクッキーを保存および取得するためのメカニズムを提供します。
type CookieJar interface {
SetCookies(u *url.URL, cookies []*Cookie)
Cookies(u *url.URL) []*Cookie
}
SetCookies(u *url.URL, cookies []*Cookie)
: 指定されたURLに対して、サーバーから受信したクッキーを保存します。Cookies(u *url.URL) []*Cookie
: 指定されたURLに対して送信すべきクッキーを返します。
このインターフェースを実装することで、HTTPクライアントは自動的にクッキーを管理できるようになります。
Public Suffix List (公開サフィックスリスト)
公開サフィックスリストは、ドメイン名の「公開サフィックス」を定義するリストです。例えば、example.com
の公開サフィックスはcom
、foo.co.uk
の公開サフィックスはco.uk
です。このリストは、セキュリティ上の理由から非常に重要です。クッキーは、そのドメインの公開サフィックスよりも上位のドメインに対して設定されるべきではありません。例えば、example.com
がcom
に対してクッキーを設定することはできません。これは、悪意のあるサイトが他のサイトのクッキーを盗むことを防ぐためです。
技術的詳細
このコミットでは、exp/cookiejar
パッケージ内に以下の主要なインターフェースと構造体が定義されています。
-
PublicSuffixList
インターフェース:PublicSuffix(domain string) string
: 与えられたドメインの公開サフィックスを返します。String() string
: この公開サフィックスリストのソースに関する説明(タイムスタンプやバージョン番号など)を返します。これは、クッキージャーがリストの変更を検出し、必要に応じてクッキーを更新するために使用されます。- このインターフェースは、クッキーのセキュリティとプライバシーを確保するために不可欠です。クッキーが設定されるドメインが、その公開サフィックスを超えていないことを保証するために使用されます。
-
Storage
インターフェース:Lock()
/Unlock()
: ストレージへの並行アクセスを制御するためのロックメカニズムを提供します。Add(key string, entries ...Entry) error
: 指定されたキーにエントリを追加します。既存のエントリがある場合は更新されます。Delete(key string) error
: 指定されたキーに関連する全てのエントリを削除します。Entries(key string, f func(entry Entry) (Action, time.Time, error)) error
: 指定されたキーのエントリをイテレートし、各エントリに対して関数f
を呼び出します。f
は、エントリの更新(Update
)または削除(Delete
)を指示できます。Keys(f func(key string) error) error
: ストレージ内の全てのキーをイテレートし、各キーに対して関数f
を呼び出します。Entry
構造体:Subkey
,Data
,Creation
,LastAccess
を含む、ストレージ内の単一のエントリを表します。Action
型:Pass
,Update
,Delete
の3つの定数を持つ列挙型で、Entries
メソッドのコールバック関数が返すアクションを定義します。ValidStorageKey(key string) bool
: ストレージキーが有効な形式であるかを検証するヘルパー関数です。キーは小文字の英数字、ハイフン、ドットのみを含み、少なくとも1つの非ドット文字を持つ必要があります。
-
Options
構造体:Storage Storage
: クッキージャーが使用するストレージ実装を指定します。nil
であってはなりません。PublicSuffixList PublicSuffixList
: クッキージャーが使用する公開サフィックスリスト実装を指定します。nil
であってはなりません。
-
Jar
構造体:storage Storage
: 内部で使用するStorage
インターフェースの実装。psList PublicSuffixList
: 内部で使用するPublicSuffixList
インターフェースの実装。New(o *Options) *Jar
: 新しいJar
インスタンスを作成するコンストラクタ関数。
-
Jar
構造体のメソッド (未実装):Cookies(u *url.URL) []*http.Cookie
:http.CookieJar
インターフェースのCookies
メソッドの実装(TODOコメントあり)。SetCookies(u *url.URL, cookies []*http.Cookie)
:http.CookieJar
インターフェースのSetCookies
メソッドの実装(TODOコメントあり)。
このコミットでは、これらのインターフェースと構造体の定義に焦点を当てており、実際のクッキーの保存・取得ロジックはまだ実装されていません。これは、API設計を先行させ、その後の実装を段階的に進めるという開発アプローチを示しています。
コアとなるコードの変更箇所
このコミットで追加されたファイルは以下の3つです。
-
src/pkg/exp/cookiejar/jar.go
:PublicSuffixList
インターフェースの定義。Options
構造体の定義。Jar
構造体の定義。New
コンストラクタ関数の定義。Jar.Cookies
およびJar.SetCookies
メソッドのシグネチャ定義(実装はTODO)。
-
src/pkg/exp/cookiejar/storage.go
:Storage
インターフェースの定義。Entry
構造体の定義。Action
型と関連する定数(Pass
,Update
,Delete
)の定義。ValidStorageKey
ヘルパー関数の定義。
-
src/pkg/exp/cookiejar/storage_test.go
:ValidStorageKey
関数のテストケースを定義するvalidStorageKeyTests
マップ。TestValidStorageKey
テスト関数。
コアとなるコードの解説
jar.go
jar.go
では、http.CookieJar
インターフェースを実装するための主要な構造体Jar
と、その依存関係であるPublicSuffixList
インターフェースが定義されています。
PublicSuffixList
インターフェースは、ドメインの公開サフィックスを特定するための抽象化を提供します。これにより、クッキージャーは、悪意のあるクッキー設定を防ぐために、ドメインのセキュリティ境界を尊重することができます。String()
メソッドは、リストのバージョン管理を可能にし、リストが更新された場合にクッキーを再評価するメカニズムを提供します。
Options
構造体は、Jar
を初期化する際に必要な設定(Storage
とPublicSuffixList
の実装)をカプセル化します。これにより、Jar
の作成が柔軟になります。
Jar
構造体は、http.CookieJar
インターフェースの具体的な実装となることを意図しており、内部にStorage
とPublicSuffixList
のインスタンスを保持します。New
関数は、これらの依存関係を注入してJar
のインスタンスを生成します。
Cookies
とSetCookies
メソッドは、http.CookieJar
インターフェースの要件を満たすために定義されていますが、このコミット時点ではまだ実装されていません。これは、API設計と実装を分離する一般的なソフトウェア開発プラクティスに従っています。
storage.go
storage.go
では、クッキーデータを永続化または一時的に保存するための抽象化であるStorage
インターフェースが定義されています。このインターフェースは、クッキーの追加、削除、およびイテレーションのためのメソッドを提供します。
Storage
インターフェースは、Lock()
とUnlock()
メソッドを通じて、並行アクセスに対する安全性を考慮しています。これは、複数のゴルーチンが同時にクッキージャーにアクセスする可能性があるため、データの一貫性を保つ上で重要です。
Add
メソッドは、新しいクッキーエントリをストレージに追加します。既存のエントリと同じキーとサブキーを持つ場合は、古いエントリが新しいエントリに置き換えられます。これは、クッキーの更新動作を反映しています。
Delete
メソッドは、特定のキーに関連するすべてのクッキーエントリを削除します。
Entries
メソッドは、特定のキーに関連するクッキーエントリをイテレートするための強力なメカニズムを提供します。コールバック関数f
を使用することで、イテレーション中に各エントリに対してカスタムロジック(例えば、有効期限のチェックやアクセス時間の更新)を適用できます。Action
型は、このコールバック関数がストレージに対してどのような操作を行うべきかを指示するために使用されます。
Keys
メソッドは、ストレージ内のすべてのキーをイテレートするために使用されます。
ValidStorageKey
関数は、ストレージキーの形式を検証するためのユーティリティです。これは、ストレージ実装が期待するキーの形式を強制し、潜在的な問題を防止するのに役立ちます。
storage_test.go
storage_test.go
は、ValidStorageKey
関数の基本的な単体テストを提供します。このテストは、有効なキーと無効なキーの様々な組み合わせを検証し、関数が期待通りに動作することを確認します。これは、新しい機能が追加される際に、その動作が正しく、将来の変更によって壊れないことを保証するための良いプラクティスです。
関連リンク
- Go Issue 1960: https://github.com/golang/go/issues/1960
- Go CL 6849092: https://golang.org/cl/6849092
参考にした情報源リンク
- RFC 6265: HTTP State Management Mechanism: https://datatracker.ietf.org/doc/html/rfc6265
- Public Suffix List: https://publicsuffix.org/
- Go
net/http
package documentation: https://pkg.go.dev/net/http - Go
net/url
package documentation: https://pkg.go.dev/net/url