クッキーの最大サイズ制限について

Updated: 2004-01-11 22:26:43+0900 - [ HOME ]

はじめに

この文書は、クッキーの最大サイズの制限について説明したものです。なぜこんなことを調べ始めたかについては、日記もじら組のスレッド、および、実際に問題を再現するこちらのページをご覧下さい。

この文書を書くに当たって、もじら組での議論が非常に参考になりました。ありがとうございます。自分は最初クッキーの仕様について勘違いしていて、いろいろ問題のある発言をしていて恥ずかしいのですが……。まだ間違っている個所があるかもしれません。間違いを発見されましたら、ご連絡いただけると嬉しいです。

クッキーの個数

クッキーは、「名前=値」の1つの組みを1個と数えます。変数1個がクッキー1個に相当します。Netscapeの仕様およびRFC 2109(obsolete)によると、クライアントは1つのホストまたはドメイン名につき最低でも20個のクッキーをサポートする必要があります。20個の変数が使えることになります。

20 cookies per server or domain. (note that completely specified hosts and domains are treated as separate entities and have a 20 cookie limitation for each, not combined)
* at least 20 cookies per unique host or domain name

クッキーのサイズ

Netscapeの仕様によると、クライアントは1個のクッキーにつき名前と値の合計で最低でも4 kilobytes(4096バイト)をサポートする必要があります。

4 kilobytes per cookie, where the name and the OPAQUE_STRING combine to form the 4 kilobyte limit.

OPAQUE_STRINGはクッキーの値を指します。更に、4kbを超える場合、クライアントは値を4kbに収まるようにトリミングすると述べています。名前は4kbを超えない限り手をつけずに残します。

When a cookie larger than 4 kilobytes is encountered the cookie should be trimmed to fit, but the name should remain intact as long as it is less than 4 kilobytes.

一方、RFC 2109(obsolete)では、Set-Cookie構文規則のcookie非終端記号を使って数えるとあります(6.3)。

* at least 4096 bytes per cookie (as measured by the size of the characters that comprise the cookie non-terminal in the syntax description of the Set-Cookie header)

cookie非終端記号とは、4.2.2にある

cookie          =       NAME "=" VALUE *(";" cookie-av)

を指します。cookie-avは、有効期限やPath、ドメインやコメントなどの属性です。

cookie-av       =       "Comment" "=" value
                |       "Domain" "=" value
                |       "Max-Age" "=" value
                |       "Path" "=" value
                |       "Secure"
                |       "Version" "=" 1*DIGIT

属性の指定も含めて4096バイトと数える点が、Netscapeの仕様とは異なります。さらに、4096バイトを超える場合、Set-cookieヘッダ全てを廃棄するとあります。この点も、トリミングすると述べているNetscapeの仕様とは異なります。

The information in a Set-Cookie response header must be retained in its entirety. If for some reason there is inadequate space to store the cookie, it must be discarded, not truncated.

Netscapeの仕様とRFC 2109の違い

上に述べたサイズの計算方法以外にも、いくつかの点でNetscapeの仕様RFC 2109は異なります。RFC 2109Netscapeの仕様と異なる点として、

などが挙げられます。RFC 2109はobsoleteとなっており、一般的には使用されていないようです。代わりにSet-cookie2/Cookie2という新しいヘッダを定義したRFC 2965が提出されています。

実装はどうなっているのか

IE 6.0、Netscape 7.1、Opera 7.0 を使用して、以下の CGI を作成しテストを行いました。

cookie_size.cgi は、例えば a=1000 を渡すと名前 a、値 1000 バイトのクッキーを設定します。 a=1000&b=500 などのように複数のクッキーを作成することもできます。この CGI を使用して、

の (m) (n) (o) (p) に設定できる最大値と、最大値を超えた場合の動作を調べました。

IE 6.0

クッキーは5kb近くまで保存することができます。このサイズを超えた場合、クッキーは保存されません(古い値が保存済みであれば、そちらが送信されます)。pathやexpiresを追加するとこの値は減少します。

Set-Cookie: + 5kb(5120bytes)

まで使用できるようです。

Netscape 7.1

このサイズを超えた場合、クッキーは保存されません(古い値が保存済みであれば、そちらが送信されます)。IEと異なり、pathやexpiresを追加しても値は変化しません。Netscapeの仕様通り、値の名前と値を合計して4096バイトまで保存できるようです。

クッキーの値+名前 = 4kb(4096bytes)

ただし、4096バイトを超えた場合、トリミングするのではなくSet-Cookieヘッダを破棄する点はRFC 2109で記述されている動作と符合します。

Opera 7.0

値がaもしくはaaだけの場合は、

Set-Cookie: + 4kb(4096bytes)

が使用できるようです。これを超える場合、クッキーは保存されません。ところが、oやpではサイズが減少し、4kbも保存できなくなります。さらに以下のような問題があるようでした。

同様に、

という動作をしています。

JavaScriptで設定する場合

クッキーはレスポンスヘッダだけでなく、JavaScriptで設定される場合もあります。JavaScriptで設定した場合の動作が、レスポンスヘッダで設定する場合と同じなのかどうかを調べました。

IE 6.0

このサイズを超えると、値の末尾がサイズに合うように切り落とされるようです。また、全クッキーのサイズの合計が4096バイトを超えると、document.cookieから読み込むことができなくなります。current valueの欄に何も表示されない場合でも、サーバには送信されています。

Netscape 7.1

レスポンスヘッダと同様に動作しているようです。

Opera 7.0

レスポンスヘッダと同様に動作しているようです。複数の値が設定されたときに、値の末尾が切り落とされる問題もそのままでした。

Apacheのリクエストヘッダ最大サイズの制限によって起こる問題

こちらをご覧下さい。

参考

クッキーの仕様について、以下の文書を参考にしました。


KOSEKI Kengo <kengo at tt.rim.or.jp>