# Headers

リクエストおよびレスポンスのヘッダーは、それぞれRequestオブジェクトとHTTPResponseオブジェクトで使用できます。単一のキーが複数の値を持つことを可能にする [multidictパッケージ] (https://multidict.readthedocs.io/en/stable/multidict.html#cimultidict) を利用します。

FYI

ヘッダキーは、解析時に小文字に変換されます。ヘッダーでは大文字と小文字は区別されません。

# Request

Sanicは、リクエストヘッダーを開発者に提示する前に正規化を試み、一般的なユースケースのために潜在的に意味のある抽出を行います。

# Tokens

TokenまたはBearer形式の認可トークンは、リクエスト・オブジェクトrequest.tokenに抽出されます。

@app.route("/")
async def handler(request):
    return text(request.token)
$ curl localhost:8000 \
    -H "Authorization: Token ABCDEF12345679"
ABCDEF12345679
$ curl localhost:8000 \
    -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

# Proxy headers

Sanicはプロキシヘッダを特別に扱います。詳細については、 [proxy headers] (/guide/advanced/proxy-headers.md) セクションを参照してください。

# Host header and dynamic URL construction

実効ホストrequest.hostを介して使用できます。これは、プロキシ転送されたホストを優先し、サーバ名の設定によって強制される可能性があるため、必ずしもホストヘッダーと同じではありません。

Webアプリケーションは通常、どのようにデプロイされても同じように機能できるように、このアクセサを使用する必要があります。実際のホストヘッダーは、必要に応じてrequest.headers

実効ホストは、ハンドラの外部アドレスを決定するためにリクエストを使用するrequest.url_forを介して動的URL構築でも使用されます。

Be wary of malicious clients

これらのURLは、誤ったホストヘッダーを送信することで操作できます。これが懸念される場合は、代わりにapp.url_forを使用する必要があります。

app.config.SERVER_NAME = "https://example.com"
@app.route("/hosts", name="foo")
async def handler(request):
    return json(
        {
            "effective host": request.host,
            "host header": request.headers.get("host"),
            "forwarded host": request.forwarded.get("host"),
            "you are here": request.url_for("foo"),
        }
    )
$ curl localhost:8000/hosts
{
  "effective host": "example.com",
  "host header": "localhost:8000",
  "forwarded host": null,
  "you are here": "https://example.com/hosts"
}

# Other headers

すべてのリクエストヘッダーはrequest.headersで使用でき、辞書形式でアクセスできます。大文字はヘッダーでは考慮されず、大文字または小文字のキーを使用してアクセスできます。

@app.route("/")
async def handler(request):
    return json(
        {
            "foo_weakref": request.headers["foo"],
            "foo_get": request.headers.get("Foo"),
            "foo_getone": request.headers.getone("FOO"),
            "foo_getall": request.headers.getall("fOo"),
            "all": list(request.headers.items()),
        }
    )
$ curl localhost:9999/headers -H "Foo: one" -H "FOO: two"|jq
{
  "foo_weakref": "one",
  "foo_get": "one",
  "foo_getone": "one",
  "foo_getall": [
    "one",
    "two"
  ],
  "all": [
    [
      "host",
      "localhost:9999"
    ],
    [
      "user-agent",
      "curl/7.76.1"
    ],
    [
      "accept",
      "*/*"
    ],
    [
      "foo",
      "one"
    ],
    [
      "foo",
      "two"
    ]
  ]
}

FYI

💡 request.headersオブジェクトは、辞書のタイプの1つで、各値はリストです。これは、HTTPでは1つのキーを再利用して複数の値を送信できるためです。

ほとんどの場合、リストではなく最初の要素にアクセスするには、.get () または.getone () メソッドを使用します。すべての項目のリストが必要な場合は、.getall () を使用できます。

# Request ID

多くの場合、 「X-Request-ID」 ヘッダーを使用してリクエストを追跡すると便利です。次の方法で簡単にアクセスできます。 request.id.

@app.route("/")
async def handler(request):
    return text(request.id)
$ curl localhost:8000 \
    -H "X-Request-ID: ABCDEF12345679"
ABCDEF12345679

# Response

必要に応じて、以下のレスポンスヘッダが自動的に設定されます。

  • content-length
  • content-type
  • connection
  • transfer-encoding

ほとんどの場合、これらのヘッダーの設定について心配する必要はありません。

設定するその他のヘッダーは、ルートハンドラまたは応答ミドルウェアで実行できます。

@app.route("/")
async def handler(request):
    return text("Done.", headers={"content-language": "en-US"})
@app.middleware("response")
async def add_csp(request, response):
    response.headers["content-security-policy"] = "default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self';base-uri 'self';form-action 'self'"

一般的な [ミドルウェア] (middleware.md) は、すべての応答にX-Request-IDヘッダーを追加することです。前述のように、request.idは着信要求からIDを提供します。ただし、リクエストヘッダーにIDが指定されていない場合でも、自動的にIDが指定されます。

詳細については、APIドキュメントを参照してください。 (opens new window)

@app.route("/")
async def handler(request):
    return text(str(request.id))
@app.on_response
async def add_request_id_header(request, response):
    response.headers["X-Request-ID"] = request.id
$ curl localhost:8000 -i
HTTP/1.1 200 OK
X-Request-ID: 805a958e-9906-4e7a-8fe0-cbe83590431b
content-length: 36
connection: keep-alive
content-type: text/plain; charset=utf-8
805a958e-9906-4e7a-8fe0-cbe83590431b
MIT Licensed
Copyright © 2018-present Sanic Community Organization

~ Made with ❤️ and ☕️ ~