# `http.cookies` --- HTTP の状態管理

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

The `http.cookies` module defines classes for abstracting the concept of cookies, an HTTP state management mechanism. It supports both simple string-only cookies, and provides an abstraction for having any serializable data-type as cookie value.

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

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

バージョン 3.3 で変更: Allowed '`:`' as a valid cookie name character.

バージョン 3.15 で変更: Allowed '`"`' as a valid cookie value character.

注釈

不正な 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])

  このクラスは `BaseCookie` を継承し、 `value_decode()` と `value_encode()` をオーバーライドします。 `SimpleCookie` は文字列と cookie 値をサポートします。値を設定するとき、 `SimpleCookie` は組み込みの `str()` を呼び出して値を文字列に変換します。HTTP から受け取った値は文字列として保持されます。

参考

モジュール `http.cookiejar`

  HTTP cookie handling for web clients. The `http.cookiejar` and `http.cookies` modules do not depend on each other.

RFC 2109 - HTTP State Management Mechanism

  このモジュールが実装しているHTTPの状態管理に関する規格です。

## Cookieオブジェクト

BaseCookie.value_decode(val)

  文字列表現のタプル `(real_value, coded_value)` を返します。 `real_value` の型はどのようなものでも許容されます。このメソッドは `BaseCookie` においてデコードを行わず、オーバーライドされるためにだけ存在します。

BaseCookie.value_encode(val)

  タプル `(real_value, coded_value)` を返します。 val の型はどのようなものでも許容されますが、 `coded_value` は常に文字列に変換されます。このメソッドは `BaseCookie` においてエンコードを行わず、オーバーライドされるためにだけ存在します。

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

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

  Return a string representation suitable to be sent as HTTP headers. attrs and header are sent to each `Morsel`'s `output()` method. sep is used to join the headers together, and is by default the combination `'\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
  > partitioned

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

  The attribute `samesite` controls when the browser sends the cookie with cross-site requests. This helps to mitigate CSRF attacks. Valid values are "Strict" (only sent with same-site requests), "Lax" (sent with same-site requests and top-level navigations), and "None" (sent with same-site and cross-site requests). When using "None", the "secure" attribute must also be set, as required by modern browsers.

  The attribute `partitioned` indicates to user agents that these cross-site cookies should only be available in the same top-level context that the cookie was first set in. For this to be accepted by the user agent, you must also set `Secure`.

  In addition, it is recommended to use the `__Host` prefix when setting partitioned cookies to make them bound to the hostname and not the registrable domain. Read CHIPS (Cookies Having Independent Partitioned State) for full details and examples.

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

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

  バージョン 3.7 で変更: `key` と `value` 、 `coded_value` 属性は読み出し専用です。設定には、 `set()` を使用してください。

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

  バージョン 3.14 で変更: Added support for the `partitioned` attribute.

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()` と同じように振る舞います。

## 使用例

The following example demonstrates how to use the `http.cookies` module.

    >>> 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=;";')
    >>> print(C)
    Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=;"
    >>> 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
    >>> import json
    >>> C = cookies.SimpleCookie()
    >>> C.load(f'cookies=7; mixins="{json.dumps({"chips": "dark chocolate"})}"; state=gooey')
    >>> print(C)
    Set-Cookie: cookies=7
    Set-Cookie: mixins="{"chips": "dark chocolate"}"
    Set-Cookie: state=gooey