"http.cookies" --- HTTPの状態管理
*********************************

**ソースコード:** Lib/http/cookies.py

======================================================================

"http.cookies" モジュールはHTTPの状態管理機能であるcookieの概念を抽象
化、定義しているクラスです。単純な文字列のみで構成されるcookieのほか、
シリアル化可能なあらゆるデータ型でクッキーの値を保持するための機能も備
えています。

このモジュールは元々 **RFC 2109** と **RFC 2068** に定義されている構文
解析の規則を厳密に守っていました。しかし、MSIE 3.0x がこれらの RFC で
定義された文字の規則に従っていないことが判明し、また、現代の多くのブラ
ウザとサーバも Cookie の処理に緩い解析をしており、結局、やや厳密さを欠
く構文解析規則にせざるを得ませんでした。

文字集合 "string.ascii_letters" 、 "string.digits" 、
"!#$%&'*+-.^_`|~:" を、このモジュールは Cookie 名 ("key") として有効と
認めています。

バージョン 3.3 で変更: ':' が有効な Cookie 名の文字として認められまし
た。

注釈:

  不正な cookie に遭遇した場合、 "CookieError" 例外を送出します。その
  ため、ブラウザから持ってきた cookie データをパースするときには常に不
  正なデータに備え "CookieError" 例外を捕捉してください。

exception http.cookies.CookieError

   属性や *Set-Cookie* ヘッダが正しくないなど、 **RFC 2109** に合致し
   ていないときに発生する例外です。

class http.cookies.BaseCookie([input])

   このクラスはキーが文字列、値が "Morsel" インスタンスで構成される辞
   書風オブジェクトです。値に対するキーを設定するときは、値がキーと値
   を含む "Morsel" に変換されることに注意してください。

   *input* が与えられたときは、そのまま "load()" メソッドへ渡されます
   。

class http.cookies.SimpleCookie([input])

   This class derives from "BaseCookie" and overrides "value_decode()"
   and "value_encode()". SimpleCookie supports strings as cookie
   values. When setting the value, SimpleCookie calls the builtin
   "str()" to convert the value to a string. Values received from HTTP
   are kept as strings.

参考:

  モジュール "http.cookiejar"
     Web *クライアント* 向けの HTTP クッキー処理です。
     "http.cookiejar" と "http.cookies" は互いに独立しています。

  **RFC 2109** - HTTP State Management Mechanism
     このモジュールが実装しているHTTPの状態管理に関する規格です。


Cookieオブジェクト
==================

BaseCookie.value_decode(val)

   Return a tuple "(real_value, coded_value)" from a string
   representation. "real_value" can be any type. This method does no
   decoding in "BaseCookie" --- it exists so it can be overridden.

BaseCookie.value_encode(val)

   Return a tuple "(real_value, coded_value)". *val* can be any type,
   but "coded_value" will always be converted to a string. This method
   does no encoding in "BaseCookie" --- it exists so it can be
   overridden.

   通常 "value_encode()" と "value_decode()" はともに *value_decode*
   の処理内容から逆算した範囲に収まっていなければなりません。

BaseCookie.output(attrs=None, header='Set-Cookie:', sep='\r\n')

   HTTPヘッダ形式の文字列表現を返します。 *attrs* と *header* はそれぞ
   れ "Morsel" の "output()" メソッドに送られます。 *sep* はヘッダの連
   結に用いられる文字で、デフォルトは "'\r\n'" (CRLF)となっています。

BaseCookie.js_output(attrs=None)

   ブラウザがJavaScriptをサポートしている場合、HTTPヘッダを送信した場
   合と同様に動作する埋め込み可能なJavaScript snippetを返します。

   *attrs* の意味は "output()" と同じです。

BaseCookie.load(rawdata)

   *rawdata* が文字列であれば、 "HTTP_COOKIE" として処理し、その値を
   "Morsel" として追加します。辞書の場合は次と同様の処理をおこないます
   。

      for k, v in rawdata.items():
          cookie[k] = v


Morselオブジェクト
==================

class http.cookies.Morsel

   **RFC 2109** の属性をキーと値で保持するabstractクラスです。

   Morselは辞書風のオブジェクトで、キーは次のような **RFC 2109** 準拠
   の定数となっています。

   * "expires"

   * "path"

   * "comment"

   * "domain"

   * "max-age"

   * "secure"

   * "version"

   * "httponly"

   * "samesite"

   "httponly" 属性は、 cookie が HTTP リクエストでのみ送信されて、
   JavaScript からのはアクセスできない事を示します。これはいくつかのク
   ロスサイトスクリプティングの脅威を和らげることを意図しています。

   The attribute "samesite" specifies that the browser is not allowed
   to send the cookie along with cross-site requests. This helps to
   mitigate CSRF attacks. Valid values for this attribute are "Strict"
   and "Lax".

   キーの大小文字は区別されません。そのデフォルト値は "''" です。

   バージョン 3.5 で変更: "__eq__()" は "key" 及び "value" を考慮する
   ようになりました。

   バージョン 3.7 で変更: Attributes "key", "value" and "coded_value"
   are read-only.  Use "set()" for setting them.

   バージョン 3.8 で変更: "samesite" 属性がサポートされました。

Morsel.value

   クッキーの値。

Morsel.coded_value

   実際に送信する形式にエンコードされたcookieの値。

Morsel.key

   cookieの名前。

Morsel.set(key, value, coded_value)

   属性 *key* 、 *value* 、 *coded_value* に値をセットします。

Morsel.isReservedKey(K)

   *K* が "Morsel" のキーであるかどうかを判定します。

Morsel.output(attrs=None, header='Set-Cookie:')

   MoselをHTTPヘッダ形式の文字列表現にして返します。 *attrs* を指定し
   ない場合、デフォルトですべての属性を含めます。 *attrs* を指定する場
   合、属性をリストで渡さなければなりません。 *header* のデフォルトは
   ""Set-Cookie:"" です。

Morsel.js_output(attrs=None)

   ブラウザがJavaScriptをサポートしている場合、HTTPヘッダを送信した場
   合と同様に動作する埋め込み可能なJavaScript snippetを返します。

   *attrs* の意味は "output()" と同じです。

Morsel.OutputString(attrs=None)

   Moselの文字列表現をHTTPやJavaScriptで囲まずに出力します。

   *attrs* の意味は "output()" と同じです。

Morsel.update(values)

   Morsel 辞書の値を辞書 *values* の値で更新します。*values* 辞書のキ
   ーのいずれかが有効な **RFC 2109** 属性でない場合エラーを送出します
   。

   バージョン 3.5 で変更: 不正なキーではエラーが送出されます。

Morsel.copy(value)

   Morsel オブジェクトの浅いコピーを返します。

   バージョン 3.5 で変更: 辞書ではなく Morsel オブジェクトを返します。

Morsel.setdefault(key, value=None)

   キーが有効な **RFC 2109** 属性でない場合エラーを送出します。そうで
   ない場合は "dict.setdefault()" と同じように振る舞います。


使用例
======

次の例は "http.cookies" の使い方を示したものです。

   >>> from http import cookies
   >>> C = cookies.SimpleCookie()
   >>> C["fig"] = "newton"
   >>> C["sugar"] = "wafer"
   >>> print(C) # generate HTTP headers
   Set-Cookie: fig=newton
   Set-Cookie: sugar=wafer
   >>> print(C.output()) # same thing
   Set-Cookie: fig=newton
   Set-Cookie: sugar=wafer
   >>> C = cookies.SimpleCookie()
   >>> C["rocky"] = "road"
   >>> C["rocky"]["path"] = "/cookie"
   >>> print(C.output(header="Cookie:"))
   Cookie: rocky=road; Path=/cookie
   >>> print(C.output(attrs=[], header="Cookie:"))
   Cookie: rocky=road
   >>> C = cookies.SimpleCookie()
   >>> C.load("chips=ahoy; vienna=finger") # load from a string (HTTP header)
   >>> print(C)
   Set-Cookie: chips=ahoy
   Set-Cookie: vienna=finger
   >>> C = cookies.SimpleCookie()
   >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
   >>> print(C)
   Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
   >>> C = cookies.SimpleCookie()
   >>> C["oreo"] = "doublestuff"
   >>> C["oreo"]["path"] = "/"
   >>> print(C)
   Set-Cookie: oreo=doublestuff; Path=/
   >>> C = cookies.SimpleCookie()
   >>> C["twix"] = "none for you"
   >>> C["twix"].value
   'none for you'
   >>> C = cookies.SimpleCookie()
   >>> C["number"] = 7 # equivalent to C["number"] = str(7)
   >>> C["string"] = "seven"
   >>> C["number"].value
   '7'
   >>> C["string"].value
   'seven'
   >>> print(C)
   Set-Cookie: number=7
   Set-Cookie: string=seven
