[インデックス 15434] ファイルの概要
このコミットは、Go言語の実験的な cookiejar
パッケージに、IDNA (Internationalized Domain Names in Applications) および Punycode の toASCII
変換を実装するものです。これにより、クッキーが国際化ドメイン名(日本語や中国語などの非ASCII文字を含むドメイン名)を正しく処理できるようになります。具体的には、jar.go
内の canonicalHost
関数が、ホスト名を正規化する際に toASCII
変換を適用するように変更され、Punycodeのエンコード/デコードロジックを実装した punycode.go
とそのテストファイル punycode_test.go
が新規追加されています。
コミット
commit ffa0f8306020387ed7004b680f678473bf9fa65d
Author: Nigel Tao <nigeltao@golang.org>
Date: Tue Feb 26 11:55:41 2013 +1100
exp/cookiejar: implement IDNA/Punycode's toASCII.
R=dr.volker.dobler
CC=golang-dev
https://golang.org/cl/7398049
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/ffa0f8306020387ed7004b680f678473bf9fa65d
元コミット内容
exp/cookiejar: implement IDNA/Punycode's toASCII.
R=dr.volker.dobler
CC=golang-dev
https://golang.org/cl/7398049
変更の背景
Webの国際化が進むにつれて、ドメイン名にASCII文字以外の文字(例: bücher.de
の ü
)を使用する国際化ドメイン名 (IDN) が普及しました。しかし、DNS (Domain Name System) は元々ASCII文字のみを扱うように設計されています。このギャップを埋めるために、IDNをASCII互換エンコーディング (ACE) に変換するメカニズムが必要となります。これがPunycodeであり、IDNAの主要な構成要素です。
HTTPクッキーは、特定のドメインに関連付けられて送受信されます。RFC 6265 (HTTP State Management Mechanism) は、クッキーのドメイン属性を処理する際に、ホスト名を「正規化されたホスト名」に変換する必要があると規定しています。この正規化プロセスには、IDNAの ToASCII
変換が含まれます。
このコミット以前の exp/cookiejar
パッケージでは、この ToASCII
変換が実装されていませんでした。そのため、国際化ドメイン名を含むURLからクッキーを設定したり、国際化ドメイン名を持つサイトにクッキーを送信したりする際に、RFCの仕様に準拠せず、予期せぬ動作やセキュリティ上の問題が発生する可能性がありました。コミットメッセージの jar.go
の変更箇所にあるコメントアウトされた TODO
にも、「RFC 6265 の『正規化されたホスト名』は idna ToASCII 変換を必要とする」と明記されており、この機能の必要性が認識されていたことが伺えます。
このコミットは、cookiejar
が国際化ドメイン名を正しく処理し、RFC 6265 に完全に準拠するための重要なステップです。
前提知識の解説
国際化ドメイン名 (IDN: Internationalized Domain Names)
IDNは、ASCII文字セットに含まれない文字(例: 日本語、中国語、アラビア語、キリル文字など)を含むドメイン名です。これにより、世界中のユーザーが自国語でドメイン名を登録・利用できるようになり、Webのアクセシビリティと使いやすさが向上します。
Punycode
Punycodeは、Unicode文字列をASCII文字のみで表現するためのエンコーディング方式です。IDNをDNSで扱えるようにするために開発されました。Punycodeでエンコードされたドメイン名は、通常 xn--
というプレフィックスで始まります。例えば、bücher.de
は Punycode で xn--bcher-kva.de
となります。
IDNA (Internationalized Domain Names in Applications)
IDNAは、アプリケーションがIDNを処理するための標準プロトコルです。IDNAは、IDNをPunycodeに変換する ToASCII
変換と、PunycodeをIDNに戻す ToUnicode
変換を定義しています。これにより、ユーザーはブラウザのアドレスバーに自国語のドメイン名を入力でき、内部的にはそれがPunycodeに変換されてDNSクエリが実行され、結果がユーザーには元のIDNで表示される、というシームレスな体験が実現されます。
RFC 6265 (HTTP State Management Mechanism)
HTTPクッキーの動作を定義する主要なRFCです。このRFCでは、クッキーのドメイン属性の処理において、ホスト名を「正規化されたホスト名」に変換する必要があることが明記されており、その変換にはIDNAの ToASCII
変換が含まれるとされています。
技術的詳細
このコミットは、主に以下の技術的側面を含んでいます。
-
Punycodeエンコーディングアルゴリズムの実装:
punycode.go
ファイルは、RFC 3492で定義されているPunycodeエンコーディングアルゴリズムをGo言語で実装しています。このアルゴリズムは、Unicodeコードポイントの差分を効率的にASCII文字で表現するための複雑な数学的処理を含みます。base
,damp
,initialBias
,initialN
,skew
,tmax
,tmin
などの定数は、RFC 3492のセクション5で指定されたPunycodeのパラメータです。encode
関数は、Punycodeのエンコーディングプロセスの中核をなします。これは、入力文字列をASCII部分と非ASCII部分に分け、非ASCII部分をPunycodeアルゴリズムに従ってエンコードします。encodeDigit
関数は、Punycodeの数字をASCII文字に変換します。adapt
関数は、Punycodeのバイアス適応関数であり、エンコーディング効率を最適化するために使用されます。
-
IDNA
toASCII
変換の実装:punycode.go
の後半部分では、IDNAのtoASCII
変換が実装されています。acePrefix
定数 (xn--
) は、ASCII互換エンコーディングのプレフィックスです。toASCII
関数は、ドメイン名またはドメインラベルを受け取り、それが既にASCIIである場合はそのまま返し、そうでない場合はPunycodeエンコードを適用してxn--
プレフィックスを付加します。ドメイン名が複数のラベル(例:www.bücher.de
のwww
,bücher
,de
)で構成されている場合、各ラベルに対して個別にtoASCII
変換を適用し、最後にドットで結合します。ascii
関数は、文字列が完全にASCII文字で構成されているかをチェックするヘルパー関数です。
-
cookiejar
パッケージへの統合:jar.go
ファイルのcanonicalHost
関数が変更され、ホスト名を正規化する際に新しく実装されたtoASCII
関数を使用するようになりました。これにより、cookiejar
は国際化ドメイン名をRFC 6265の仕様に従って処理できるようになります。 -
テストケースの追加:
punycode_test.go
ファイルには、PunycodeエンコーディングおよびIDNAtoASCII
変換の正確性を検証するための広範なテストケースが追加されています。これらのテストケースには、RFC 3492のセクション7.1で提供されている公式のテストベクトルが含まれており、実装の信頼性を保証します。
コアとなるコードの変更箇所
src/pkg/exp/cookiejar/jar.go
--- a/src/pkg/exp/cookiejar/jar.go
+++ b/src/pkg/exp/cookiejar/jar.go
@@ -301,18 +301,11 @@ func canonicalHost(host string) (string, error) {
return "", err
}
}
-
if strings.HasSuffix(host, ".") {
// Strip trailing dot from fully qualified domain names.
host = host[:len(host)-1]
}
-
- // TODO: the "canonicalized host name" of RFC 6265 requires the idna ToASCII
- // transformation. Possible solutions:
- // - promote package idna from go.net to go and import "net/idna"
- // - document behavior as a BUG
-
- return host, nil
+ return toASCII(host)
}
// hasPort returns whether host contains a port number. host may be a host
canonicalHost
関数が、ホスト名の末尾のドットを削除した後、toASCII(host)
を呼び出すように変更されました。これにより、ホスト名がIDNAのToASCII
変換を経て正規化されるようになります。以前のTODO
コメントが解決されています。
src/pkg/exp/cookiejar/jar_test.go
--- a/src/pkg/exp/cookiejar/jar_test.go
+++ b/src/pkg/exp/cookiejar/jar_test.go
@@ -49,8 +49,8 @@ var canonicalHostTests = map[string]string{
"192.168.0.5:8080": "192.168.0.5",
"2001:4860:0:2001::68": "2001:4860:0:2001::68",
"[2001:4860:0:::68]:8080": "2001:4860:0:::68",
-\t// "www.bücher.de": "www.xn--bcher-kva.de", // TODO de-comment once proper idna is available
-\t"www.example.com.": "www.example.com",
+\t"www.bücher.de": "www.xn--bcher-kva.de",
+\t"www.example.com.": "www.example.com",
}
func TestCanonicalHost(t *testing.T) {
canonicalHostTests
のテストケースで、"www.bücher.de"
の期待値が"www.xn--bcher-kva.de"
となるようにコメントアウトが解除され、IDNA変換が正しく行われることを検証するようになりました。
src/pkg/exp/cookiejar/punycode.go
(新規ファイル)
PunycodeエンコーディングアルゴリズムとIDNA toASCII
変換の実装が含まれています。
src/pkg/exp/cookiejar/punycode_test.go
(新規ファイル)
punycode.go
で実装されたPunycodeエンコーディングおよびIDNA toASCII
変換のテストケースが含まれています。RFC 3492の公式テストベクトルが多数含まれています。
コアとなるコードの解説
このコミットの核心は、src/pkg/exp/cookiejar/punycode.go
に新規追加された toASCII
関数と、それを呼び出すように変更された src/pkg/exp/cookiejar/jar.go
の canonicalHost
関数です。
punycode.go
の toASCII
関数は、国際化ドメイン名(例: bücher.de
)を受け取り、それをDNSで扱えるASCII互換形式(例: xn--bcher-kva.de
)に変換します。この変換は、ドメイン名をドットで区切られた各ラベルに分割し、各ラベルが非ASCII文字を含む場合にPunycodeエンコーディングを適用することで行われます。Punycodeエンコーディング自体は、RFC 3492に厳密に従って実装された encode
関数によって行われます。
jar.go
の canonicalHost
関数は、HTTPクッキーのドメイン属性を処理する際に、ホスト名を正規化するために使用されます。この関数が toASCII
を呼び出すようになったことで、cookiejar
は国際化ドメイン名を含むクッキーをRFC 6265の仕様に準拠して正しく処理できるようになりました。これにより、Go言語の cookiejar
は、より広範なWeb環境で適切に機能するようになります。
関連リンク
- RFC 3492 - Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA): https://datatracker.ietf.org/doc/html/rfc3492
- RFC 5890 - Internationalized Domain Names for Applications (IDNA): Definitions and Document Framework: https://datatracker.ietf.org/doc/html/rfc5890
- RFC 6265 - HTTP State Management Mechanism: https://datatracker.ietf.org/doc/html/rfc6265
参考にした情報源リンク
- 上記のRFCドキュメント
- Go言語の公式ドキュメントおよびソースコード
- Punycodeに関する一般的な技術解説記事