[1] [DFN[[CODE(HTTP)@en[[[Cookie:]]]]]] [[ヘッダー]]は、
[[利用者エージェント]]に保存されている[[クッキー]]を示します。

;; [95] [[クッキー]]一般に関しては、[[クッキー]]の項を参照。

* 仕様書

[REFS[
- [61] [CITE@en[RFC 6265 - HTTP State Management Mechanism]] ([TIME[2012-03-01 09:57:02 +09:00]] 版) <http://tools.ietf.org/html/rfc6265#section-3>
- [64] '''[CITE@en[RFC 6265 - HTTP State Management Mechanism]] ([TIME[2012-03-01 09:57:02 +09:00]] 版) <http://tools.ietf.org/html/rfc6265#section-4.2>'''
- [23] [CITE@en[RFC 6265 - HTTP State Management Mechanism]] ([TIME[2014-10-12 15:11:47 +09:00]] 版) <http://tools.ietf.org/html/rfc6265#section-5.4>
- [93] [CITE@en[RFC 6265 - HTTP State Management Mechanism]] ([TIME[2014-10-12 15:11:47 +09:00]] 版) <http://tools.ietf.org/html/rfc6265#section-7.2>
- [100] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2015-05-15 10:14:54 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-8.1.2.5>
]REFS]

* 構文

[65] [CODE(HTTP)@e[[[Cookie:]]]] [[ヘッダー]]の値は、 [[cookie-string]] です。
[SRC[[[RFC 6265]]]]

[101] [DFN[[[cookie-string]]]] は、
1個[[以上]]の [[cookie-pair]] の列です。[[cookie-pair]] 間には
[CODE[[[;]]]] と [CODE(charname)@en[[[SP]]]] の2文字の列が必要です。 [SRC[[[RFC 6265]]]]

[FIG(railroad)[
= [[cookie-string]]
= *
== [CODE(HTTP)[[[;]]]]
== [CODE(charname)@en[[[SP]]]]
== [[cookie-string]]
]FIG]

[66] [[鯖]]が [[RFC 6265]] に適合する [CODE(HTTP)@en[[[Set-Cookie:]]]] 欄を送信し、
[[利用者エージェント]]が [[RFC 6265]] に適合する処理を行った場合、
[[鯖]]は >>65 の構文に適合する [CODE(HTTP)@en[[[Cookie:]]]] 欄を受け取るはずです [SRC[>>64]]。

[67] ここで [[cookie-pair]] は[[鯖]]が送信し、[[利用者エージェント]]が蓄積していたものをそれぞれ表しています。
それぞれの名前と値の意味は [[RFC 6265]] では定義しておらず、当該[[アプリケーション]]における意味に従って処理されるべきものです。
[CODE(HTTP)@en[[[Set-Cookie:]]]] 時に指定した[[属性]]は [CODE(HTTP)@en[[[Cookie:]]]]
には含まれておらず、どの [CODE(HTTP)@en[[[Path]]]] に対して発行したものなのか、などを
[CODE(HTTP)@en[[[Cookie:]]]] だけから判定することはできません。 [SRC[>>64]]

[70] しかし実際には[[鯖]]も[[利用者エージェント]]も [[RFC 6265]] に適合するとは限りません。
[[利用者エージェント]]が [[RFC 6265]] に従って [CODE(HTTP)@en[[[Set-Cookie:]]]] 欄を構文解析していると仮定すると、
[[クッキー]]の名前や値は [CODE(HTTP)@en[[[token]]]] で認められない文字を含むことがあります。
先頭と末尾が[[空白]]ではなく、 [CODE(HTTP)[[[;]]]] と [CODE(HTTP)[[[=]]]]
を含まない任意の1文字以上の文字列が名前となり得ます。また値は先頭と末尾が[[空白]]ではなく、
[CODE(HTTP)[[[;]]]] を含まない任意の0文字以上の文字列となります。

* 文脈

[75] [[利用者エージェント]]は、蓄積されている[[クッキー]]があれば
[CODE(HTTP)@en[[[Cookie:]]]] [[ヘッダー]]を[[要求]]に含めます [SRC[>>24]]。

[5] [[利用者エージェント]]は、 [[HTTP/1.1]] [[以下]]の[[要求]]で複数の 
[CODE(HTTP)@en[[[Cookie:]]]] [[ヘッダー]]を[[生成]]しては[['''なりません''']] [SRC[>>24]]。

;; [71] [[HTTP]] では一般に複数の同じ名前の[[ヘッダー]]を [CODE(HTTP)[[[,]]]]
で連結しても等価とされていますが、[[クッキー]]の名前や値に [CODE(HTTP)[[[,]]]]
が含まれる可能性があり、これが成立しません。 ([[RFC 6265]] の構文は [CODE(HTTP)[[[,]]]]
を名前や値に認めていないので、適合する[[鯖]]が発行した[[クッキー]]なら曖昧性はありませんが、
そうでないものを[[鯖]]側で処理する可能性を想定するのであれば、 [CODE(HTTP)[[[,]]]]
で結合・分割できません。)

[103] [[HTTP/2]] では、1つ[[以上]]の [[cookie-pair]] が値となる
[CODE(HTTP)@en[[[Cookie:]]]] [[ヘッダー]]複数個に分割して含めても構いません [SRC[>>100]]。

;; [104] これは、個々の [[cookie-pair]] が更新されることを想定した[[ヘッダー圧縮]]の効率の向上のための策です
[SRC[>>100]]。

[76] しかし[[利用者エージェント]]は [CODE(HTTP)@en[[[Cookie:]]]]
[[ヘッダー]]を省略しても構いません [SRC[>>24]]。

[EG[
[77] 例えば「[[第三者]]」[[要求]]で[[クッキー]]を送信しなくても構いません [SRC[>>24]]。
]EG]

[94] [[利用者エージェント]]は、[[クッキー]]が無効に設定されている時、
[CODE(HTTP)@en[[[Cookie:]]]] [[ヘッダー]]を[[要求]]に含めては[['''なりません''']] [SRC[>>93]]。

[99] [[WebSocket handshake]] でも使うことができます。

-*-*-

[110] 
[CODE[cookie-string]] は、
[[curl]]
の
[CODE[--cookie]] 
でも使われます。

* ヘッダーの生成

[78] [[利用者エージェント]]は、次の条件をすべて満たす[[クッキー]]を使って
[CODE(HTTP)@en[[[Cookie:]]]] [[ヘッダー]]を[[生成]]しなければ[['''なりません''']] [SRC[>>24]]。
[FIG(list)[
- [79] 次のいずれかを満たす
-- [80] [[クッキー]]のホストのみフラグが設定されていて、[[正準化要求ホスト]]が[[クッキー]]の[[ドメイン]]と同じである
-- [81] [[クッキー]]のホストのみフラグが設定されておらず、[[正準化要求ホスト]]が[[クッキー]]の[[ドメイン]]と[[ドメイン一致]]する
- [82] [[要求URL]]の[[パス]]が[[クッキー]]の[[パス]]と[[パス一致]]する
- [83] [[クッキー]]の保安のみフラグが設定されている場合、
[[要求URL]]の [[URL scheme]] が[[「保安」プロトコル]]を示している
]FIG]

;; [11] [[リダイレクト]]によって再度 [[HTTP]] [[要求]]を送信する場合であっても、
(新しい [[URL]] に関して) 通常通り適用される [[Cookie]] を調べて
[CODE(HTTP)@en[[[Cookie:]]]] [[頭欄]]を構築するべきです。

[74] [[利用者エージェント]]は、 [CODE(HTTP)@en[[[Cookie:]]]]
[[ヘッダー]]を[[生成]]する際に[[クッキー]]を次のように[[整列]]する[['''べき''']]です
[SRC[>>24]]。
[FIG(steps)[
= [84] [[クッキー]]の[[パス]]が長いものを短いものより先に
= [85] [[クッキー]]の[[パス]]の長さが同じものは、生成時刻が古いものを新しいものより前に
]FIG]

;; [86] この順序は [[RFC 6265]] の出版時点で一般的な習慣となっているものの、
すべての[[利用者エージェント]]がそうしているわけではないとされています [SRC[>>24]]。
そのために[['''必須''']]ではなく[['''推奨''']]に留まっているようです。
しかし (誤って) この順序に依存している[[鯖]]も歴史的には存在していることが知られています
[SRC[>>24]] から、本来は[['''必須''']]であるべきところのように思えます。

;; [98] >>84 の条件より、より深い[[ディレクトリー]]向けの[[クッキー]]が先に来ますから、
[[鯖]]としてはより前にある[[クッキー]]を使うのがより良い方針のように思われます。
一方 >>85 の方針より、既存の[[クッキー]]を上書きするべき[[クッキー]]がなぜか上書きされなかった場合により後の[[クッキー]]を取るのがより良い方針とも思えます。
名前とパスが同じ重複した[[クッキー]]が保存される場合というのは[[ドメイン]]が異なる[[クッキー]]が存在する場合です ([CODE(HTTP)@en[[[Set-Cookie:]]]] 参照)。

[87] [[利用者エージェント]]は、>>78 で得られた[[クッキー]]を >>74
で[[整列]]し、 [CODE(HTTP)[[[;]]]] と [CODE(charname)@en[[[SPACE]]]] の列で区切って連結したものを
[CODE(HTTP)@en[[[Cookie:]]]] [[ヘッダー]]として使わなければ[['''なりません''']]。ただし、
各[[クッキー]]は名前と値を [CODE(HTTP)[[[=]]]] で連結したものとしなければ[['''なりません''']]。
[SRC[>>24]]

;; [90] 蓄積されていた[[クッキー]]に [[RFC 6265]] の構文に適合しない名前や値が含まれていた場合には、
ここでそのまま出力することになりますから、 [[RFC 6265]] の
[CODE(HTTP)@en[[[Cookie:]]]] [[ヘッダー]]の構文に適合しない結果になることもあります。

;; [91] [[クッキー]]の名前や値は[[バイト列]]で、ここで連結して得られる結果も[[バイト列]]です。

;; [89] 該当する[[クッキー]]が一つもない場合には、 [CODE(HTTP)@en[[[Cookie:]]]]
[[ヘッダー]]自体を[[生成]]しません。

[88] また[[利用者エージェント]]は >>78 で得られた[[クッキー]]の最終アクセス時刻を現在日時に設定しなければ[['''なりません''']] [SRC[>>24]]。

* 処理

[63] [[起源鯖]]は [CODE(HTTP)@en[[[Cookie:]]]] 欄やその中身を無視して構いません。 [SRC[>>61]]

[68] [[クッキー]]は順番に並べることになってはいますが、[[鯖]]ではそれに依存する[['''べきではありません''']]。
特に、同じ名前の[[クッキー]]が複数ある場合に、これがどの順番で現れるかに依存する[['''べきではありません''']]。
[SRC[>>64]]

;; [73] [[RFC 6265]] は ([[利用者エージェント]]による [CODE(HTTP)@en[[[Set-Cookie:]]]]
[[ヘッダー]]の構文解析を詳細に規定しているのに対して) [[起源鯖]]による
[CODE(HTTP)@en[[[Cookie:]]]] [[ヘッダー]]の構文解析の方法を詳細には規定していません。
[[鯖]]が適合する [CODE(HTTP)@en[[[Set-Cookie:]]]] [[ヘッダー]]を出力し、
[[利用者エージェント]]が適合する方法で処理する限り、
[CODE(HTTP)@en[[[Cookie:]]]] [[ヘッダー]]の値は常に [[ABNF]]
構文に適合するはずなので、それ以上に構文解析法を規定する必要もないのかもしれません。
あるいは[[鯖]]が内部でどのように[[ヘッダー]]の値を解釈するかは[[鯖]]側の[[著者]] (開発者)
以外には観測できず、適合性を議論するのが難しいという事情もあるかもしれません。

;; [92] [[起源鯖]]は、[[クライアント]]が仕様に適合しない [CODE(HTTP)@en[[[Cookie:]]]]
[[ヘッダー]]を送信してきた場合にも (エラーを返すなど) 適当な処理を行えなければなりません。
[[Webブラウザー]]以外から適合しない [CODE(HTTP)@en[[[Cookie:]]]]
[[ヘッダー]]が送られたり、 [[Webブラウザー]]からも ([[著者]]のミスや悪意ある[[利用者]]により)
適合しない [CODE(HTTP)@en[[[Cookie:]]]] [[ヘッダー]]が送られたりする可能性は排除できません。
また[[ライブラリー]]の類は、[[Webアプリケーション]]の開発者が不適合な
[CODE(HTTP)@en[[[Set-Cookie:]]]] [[ヘッダー]]を送信している可能性を排除できませんから、
不適合な [CODE(HTTP)@en[[[Cookie:]]]] [[ヘッダー]]であってもできるだけ“正しく”
処理できることが求められます。

[102] [[HTTP/1.1]] [[以下]]で [CODE(HTTP)@en[[[Cookie:]]]] [[ヘッダー]]が複数ある場合にどう処理するべきかは不明です。

;; [72] [[RFC 6165]] は[[鯖]]がこの辺りをどう処理するべきか特に規定していません。
通常は[[鯖]]が名前や値を制御できるので、そのようなものを出力しなければ良いだけです。
ただ実際には他の[[鯖]]から第三者的に発行することもできてしまいますし、
[[鯖]]側の実装と [[JavaScript]] の実装を別の著者が行なってい (て [[HTTP]]
の制限を見落としてい) る場合など、まったく無視できる問題でもありません。
>>73 の制限があるので、これに従う (一般的な) [[利用者エージェント]]を想定するなら、
[CODE(HTTP)[[[,]]]] は[[ヘッダー]]の連結ではなく、名前や値の一部と常に仮定していいかもしれません。

[105] [[HTTP/2]] で複数の [CODE(HTTP)@en[[[Cookie:]]]] [[ヘッダー]]がある場合、
[[HTTP/1.1]] [[接続]]や汎用 [[HTTP]] サーバー応用など [[HTTP/2]]
以外へと引き渡される時は、 [CODE[[[;]]]] と [CODE(charname)@en[[[SP]]]]
の列によって連結して1つにしなければ[['''なりません''']] [SRC[>>100]]。

[62] [CODE(HTTP)@en[[[Cookie:]]]] 欄の有無は[[キャッシュ可能性]]に影響しません [SRC[>>61]]。

[10] [[串]]は [CODE(HTTP)@en[[[Cookie:]]]] をそのまま[[鯖]]へと転送するべきです。
それがたとえ [CODE(HTTP)@en[[[If-Modified-Since:]]]] つきの[[条件付き要求]]であってもです。
[SRC[>>2]]

* 歴史

** Netscape Cookie

[REFS[
- [2] [[Netscape Cookie]]: [CITE[Client Side State - HTTP Cookies]]
<http://web.archive.org/web/19961125090609/http://www2.netscape.com/newsref/std/cookie_spec.html>
]REFS]

[FIG[
[3] 
>
When requesting a URL from an HTTP server, the browser will match the URL against all cookies and if any of them match, a line containing the name/value pairs of all matching cookies will be included in the HTTP request. Here is the format of that line:
>
Cookie: NAME1=OPAQUE_STRING1; NAME2=OPAQUE_STRING2 ...

;; [SRC[>>2]]
]FIG]

[4] [[HTTP]] [[要求]]を構築する際に、[[要求URL]] と[[利用者エージェント]]が保持している [[Cookie]] 
を比較し、[[一致]]するものであれば [CODE(HTTP)@en[[[Cookie:]]]] [[要求頭欄]]に入れます。
[CODE(HTTP)@en[[[Cookie:]]]] [[欄]]には [[Cookie]] の名前と値の組を
[PRE(HTTP example code)[
Cookie: NAME1=OPAQUE_STRING1; NAME2=OPAQUE_STRING2 ...
]PRE]
のように並べて記述します。 [SRC[>>2]]

[7] 同じ名前の値は、[CODE(HTTP)@en[[[Domain]]]] や [CODE(HTTP)@en[[[Path]]]] 
が同じなら設定時に古いものが上書きされますが、
違っていれば両方共残ります。その場合には [CODE(HTTP)@en[[[Cookie:]]]]
[[頭欄]]にも両方共含められます。 [SRC[>>2]]

[9] より具体的な [CODE(HTTP)@en[[[Path]]]] の [[Cookie]] はより一般的な [CODE(HTTP)@en[[[Path]]]]
の [[Cookie]] よりも先にくるべきです。例えば [CODE(HTTP)@en[a=1; path=/foo]] と
[CODE(HTTP)@en[b=2; path=/foo/bar]] があれば、 [CODE(HTTP)@en[b=2; a=1]]
のように送るべきです。 [SRC[>>2]]

[8] 同じ [CODE(HTTP)@en[[[Path]]]] の時の名前と値の組の順序は明確に規定されていません。

[69] [CODE[CGI::Cookie]] ([TIME[2011-12-30 23:35:34 +09:00]] 版) <http://cpansearch.perl.org/src/MARKSTOS/CGI.pm-3.59/lib/CGI/Cookie.pm>
は、古い [[Netscape]] が複数の同じ名前の[[クッキー]]を送ることがあり、一番前のものが最新であるとしてそれを使っています。

** RFC の [CODE(HTTP)@en[Cookie:]] 頭欄の定義

[19] [[RFC 2109]], [[RFC 2965]] では [[Netscape Cookie]] とはあまり互換性がない
[CODE(HTTP)@en[[[Cookie:]]]] [[頭欄]]が定義されていました [SRC[>>17, >>18]]。 

概要:
- [20] 名前と値の組が1つ以上含まれるのは [[Netscape Cookie]] と同じでした。
- [35] 名前は [CODE(HTTP)@en[[[token]]]]、値は [CODE(HTTP)@en[[[token]]]]
または [CODE(HTTP)@en[[[quoted-string]]]] でなければなりません [SRC[>>17, >>18]]。
- [21] 名前と値の組の前に [[Cookie]] の[[版]]を [CODE(HTTP)@en[[[$Version]]=1]] のように指定することになっていました [SRC[>>17, >>18]]。
-- [22] [DFN[[CODE(HTTP)@en[$Version]]]] には送信する [[Cookie]] に対応する 
[CODE(HTTP)@en[[[Set-Cookie]]]]、[CODE(HTTP)@en[[[Set-Cookie2]]]] の [CODE(HTTP)@en[[[Version]]]] と同じものを指定することになっていました。それがない時は [CODE(HTTP)[[[0]]]] を使うことになっていました [SRC[>>17, >>18]]。
-- [24] 混在する場合どうするのでしょうか。
-- [33] [CODE(HTTP)@en[[[Set-Cookie]]]], [CODE(HTTP)@en[[[Set-Cookie2]]]] のどちらも
[CODE(HTTP)@en[[[Version]]]] は 1 で区別できませんが、それでいいのでしょうか。。。
-- [34] [CODE(HTTP)@en[[[Set-Cookie2]]]] は [CODE(HTTP)@en[[[Version]]]]
が必須のはずですが、ない時の規定が残っているのは消し忘れでしょうか。。。
- [25] 名前と値の組の後に [CODE(HTTP)@en[; [[$Path]]=...]] のように[[属性]]を指定することになっていました
[SRC[>>17, >>18]]。
-- [26] [DFN[[CODE(HTTP)@en[[[$Path]]]]]] [SRC[>>17, >>18]],
[DFN[[CODE(HTTP)@en[[[$Domain]]]]]] [SRC[>>17, >>18]], 
[DFN[[CODE(HTTP)[[[$Port]]]]]] [SRC[>>18]] がありました。
-- [27] [CODE(HTTP)@en[[[Set-Cookie]]]], [CODE(HTTP)@en[[[Set-Cookie2]]]] に 
[CODE(HTTP)@en[[[Path]]]], [CODE(HTTP)@en[[[Domain]]]], [CODE(HTTP)@en[[[Port]]]]
各[[属性]]があった場合は同じ値 (または同じように値なし) でなければ[['''なりません''']]でした
[SRC[>>17, >>18]]。[[属性]]自体がなかった場合には [CODE(HTTP)@en[[[$Path]]]],
[CODE(HTTP)@en[[[$Domain]]]] は省略する[['''べき''']] [SRC[>>17, >>18]]、 [CODE(HTTP)@en[[[$Port]]]]
は省略しなければ[['''ならない''']] [SRC[>>18]] とされていました。
-- [28] つまり、[[属性]]がなくて既定値が補われた場合と明示的に値が指定されていた場合は区別して蓄積しておく必要があるということですね。
- [29] 名前と値の組の順序は、[CODE(HTTP)@en[[[Path]]]] がより具体的なものほど前に来る
[SRC[>>17, >>18]] とされていました。
-- [30] [[Netscape Cookie]] と同じですね。
-- [31] それ以外の [CODE(HTTP)@en[[[Domain]]]] 等と順序の関係は[RUBYB[規定しない]@en[unspecified]]
[SRC[>>17, >>18]] とされていました。
- [32] 名前と値の組同士の区切りは[[後方互換性]]のため [CODE(HTTP)[[[;]]]] とされていました。
一方で将来との互換性のため[[鯖]]は [CODE(HTTP)[[[,]]]] も受け付けなければ[['''ならない''']]とされていて、
[[ABNF]] 構文上もそうなっていました。 [SRC[>>17, >>18]]
- [38] [[鯖]]は、 [CODE(char)[[[$]]]] からはじまる名前を特別な意味を持つものとして解釈する[['''べきです''']]
[SRC[>>36, >>37]] とされていました。
-- [39] なぜか MUST ではなくて SHOULD でした。
- [40] [CODE(char)[[[$]]]] 付きの[[属性]]は、前から順に調べていって、一番最初の [CODE(char)[[[$]]]] 無しの[[属性]]の手前までは全体に適用される[[属性]]、その後は直前の [CODE(char)[[[$]]]] 無しの[[属性]]に適用される[[属性]]と解釈するとされていました [SRC[>>36]]。
-- [41] この規定は [[RFC 2109]] にはありましたが、なぜか [[RFC 2965]] にはありませんでした。
- [44] [[串]]は自身で勝手に [CODE(HTTP)@en[[[Cookie:]]]] を[[応答]]に付け足しては[['''なりません''']]
[SRC[>>42, >>43]]。

[46] [[Netscape Cookie]] の互換性について、次のようなことが言われていました [SRC[>>45]]。
- [47] 旧クライアントは新しい Cookie を受け取ると知らないものは無視し、理解できるものを使って 
[CODE(HTTP)@en[[[Cookie:]]]] を送る
- [48] 新クライアントは Cookie を常に新形式で送る
- [49] 旧鯖は「[CODE(HTTP)[[[$]]]」で始まる[[属性]]をそういう [[Cookie]] だと思って無視する
-- [50] ただし「[CODE(HTTP)[[[,]]]]」区切りではなく「[CODE(HTTP)[[[;]]]]」区切りだと思っている
- [51] 新鯖は「[CODE(HTTP)@en[[[$Version]]]]」の有無で新旧クライアントを区別できる

[52] >>46 を読むと一見[[後方互換性]]が保たれていると錯覚してしまいがちですが、
新 Cookie では[[属性]]の値が[[引用文字列]]でもあり得るので、
旧クライアント・旧鯖は引用符も値の一部だと思ってしまうという問題があります。
- [54] [[起源鯖]]はクライアントが新 Cookie を理解すると分かっていないときは、引用符が必要な値に注意するべきです。 [SRC[>>53]]
- [55] 新しいクライアントは [[Cookie]] の版がすべて [[RFC 2109]] 以降であるときだけ値を引用符で括るべきです。 [SRC[>>53]]

[56] >>48 より新クライアントは常に新 Cookie を送ることになっているので、
常に[[引用文字列]]で送る新クライアントは旧鯖とは正しくやり取りできなくなり、 >>55
のような注意が必要になるわけです。でも >>54 のように注意しろと言われても困った話です。
引用符が必要な値だけど引用符を使えないときは引用符を外していいのでしょうか。
でも外すと [[RFC 2109]] には適合しなくなります。

[57] また、 [[RFC 2109]] は「[CODE(HTTP)[[[=]]]]」の周りの[[空白]]についても、
[[Netscape Cookie]] では認められていなかったので注意するよう書いています [SRC[>>53]]。

;; [16] [[RFC 2109]] と [[RFC 2965]] は、[[利用者エージェント]]は各種規則に基づき 
[CODE(HTTP)@en[[[Cookie:]]]] [[応答]]頭欄を送信する[['''べきである''']]、としていました。
[SRC[>>14, >>15]]

[REFS[
- [12] [DEL[[[RFC 2109]]]] ([[廃止]]済み)
-- [14] [CSECTION@en[4.2.1 General]]
-- [17] '''[CSECTION@en[4.3.4  Sending Cookies to the Origin Server]]'''
-- [36] [CSECTION@en[4.4  How an Origin Server Interprets the Cookie Header]]
-- [42] [CSECTION@en[4.5  Caching Proxy Role]]
-- [45] [CSECTION@en[10.1.1  Extended Cookie Header]]
-- [53] [CSECTION@en[10.1.3  Punctuation]]
- [13] [[RFC 2965]]
-- [15] [CSECTION@en[3.2.1 General]]
-- [18] '''[CSECTION@en[3.3.4  Sending Cookies to the Origin Server]]'''
-- [37] [CSECTION@en[3.4  How an Origin Server Interprets the Cookie Header]]
-- [43] [CSECTION@en[3.5  Caching Proxy Role]]
]REFS]

* 実装

[58] [CITE[Mojo::Cookie::Request - search.cpan.org]] ([TIME[2010-08-01 16:26:16 +09:00]] 版) <http://search.cpan.org/~kraih/Mojolicious-0.999926/lib/Mojo/Cookie/Request.pm>

[[Netscape Cookie]] に加え、
[[RFC 2109]] か [[RFC 2965]] の [CODE(HTTP)@en[[[Cookie:]]]] の構文解析に対応しています。

* CGI メタ変数

[59] [[CGIメタ変数]] [DFN[[CODE(HTTP)@en[[[HTTP_COOKIE]]]]]] は [[HTTP]]
の [CODE(HTTP)@en[[[Cookie:]]]] 欄に対応します。詳しくは [CODE(CGI)[[[HTTP_*]]]] を参照してください。

[60] [[WebSite]] は [CODE(CGI)@en[[[HTTP_COOKIE]]]] のかわりに[[メタ変数]]
[DFN[[CODE(CGI)@en[[[COOKIE]]]]]] を使っているそうです。

* 関連

[6] [[Cookie]] を設定する [CODE(HTTP)@en[[[Set-Cookie:]]]] [[頭欄]]と同じように[[名前]]と値の組を並べる形式ではありますが、
[CODE(HTTP)@en[[[Set-Cookie:]]]] は1つの名前と値の組を設定するのに対し、
[CODE(HTTP)@en[[[Cookie:]]]] は複数の名前と値の組を1つにまとめて記述できます。

[96] [CITE@en[draft-pettersen-cookie-origin-02 - Identifying origin server of HTTP Cookies]]
( ([TIME[2014-10-16 15:24:02 +09:00]] 版))
<http://tools.ietf.org/html/draft-pettersen-cookie-origin-02>

[97] [CITE@en[draft-willis-sip-cookies-00 - SIP Cookies]]
( ([TIME[2014-10-18 18:10:29 +09:00]] 版))
<https://tools.ietf.org/html/draft-willis-sip-cookies-00#section-4>

[106] [CITE@en[Clarify the hooks into RFC6265 · whatwg/fetch@5a324a8]]
([TIME[2016-03-01 11:27:58 +09:00]] 版)
<https://github.com/whatwg/fetch/commit/5a324a891c42d42de09a01e03c3a063b9a4f882b>

[FIG(quote)[
[FIGCAPTION[
[107] [CITE@en[CVE-2016-7401 CSRF protection bypass on a site with Google Analytics の解説 · GitHub]]
( ([TIME[2017-04-23 17:08:39 +09:00]]))
<https://gist.github.com/mala/457a25650950d4daf4144f98159802cc>
]FIGCAPTION]

> 多くのcookie parserは、pairsの区切りとして ; と , を許容しているのでdjango以外にも影響がある。 ブラウザが使用するcookie pairの区切りは実際には ;
> CGI::Cookieでは "'''[''';,''']''' ?"

]FIG]

[108] [CODE[,]] を区切りとする元凶は [[RFC 2965]] とのこと...

[FIG(quote)[
[FIGCAPTION[
[109] [CITE@en[Configuration • Akka HTTP]]
([TIME[2018-03-27 23:00:57 +09:00]])
<https://doc.akka.io/docs/akka-http/current/configuration.html>
]FIGCAPTION]

>     # Sets the parsing mode for parsing cookies.
>     # The following value are defined:
>     #
>     # `rfc6265`: Only RFC6265-compliant cookies are parsed. Surrounding double-quotes are accepted and
>     #   automatically removed. Non-compliant cookies are silently discarded.
>     # `raw`: Raw parsing allows any non-control character but ';' to appear in a cookie value. There's no further
>     #   post-processing applied, so that the resulting value string may contain any number of whitespace, unicode,
>     #   double quotes, or '=' characters at any position.
>     #   The rules for parsing the cookie name are the same ones from RFC 6265.
>     #
>     cookie-parsing-mode = rfc6265

]FIG]
