【テクニカル・上級編】HTTPステータスコード405(Method Not Allowed)の仕様とAllowヘッダー – HTTPプロトコル・通信規格実践ガイド

405 Method Not Allowedの深淵:プロトコル設計者が守るべき「沈黙のルール」

HTTPステータスコード `405 Method Not Allowed`。多くの開発者にとっては、単なる「間違ったメソッドを送ったときのエラー」に過ぎないかもしれない。しかし、ネットワークの最前線でパケットの断片と格闘してきたエンジニアにとって、このコードはサーバーがリソースに対して「何を知っており、何を知らないか」を雄弁に物語る極めて重要なシグナルだ。

本稿では、この一見地味なステータスコードを、単なるエラーレスポンスではなく、セキュアで高効率なAPI設計における「防波堤」として再定義する。

—

なぜ「Allowヘッダー」が必須なのか

RFC 9110(旧RFC 7231)において、405を返す際に `Allow` ヘッダーをレスポンスに含めることは「MUST」とされている。これは単なる礼儀ではない。クライアント側のロジックが、次にどのメソッドを試すべきか、あるいは自分が何を見落としているかを即座に判断するための唯一のインジケーターだからだ。

もしサーバーが405を返しつつ `Allow` ヘッダーを欠けば、それはネットワーク上のブラックホールを生成するに等しい。クライアント(特に自動化されたクライアント)は、総当たり的なリトライを繰り返すか、タイムアウトまで待機し、結果として無駄なRTT(Round Trip Time)を消費する。

ネットワークパフォーマンスの視点:RTTとヘッダーの経済学

高レイテンシのモバイル環境では、不必要なリクエストは致命的だ。405レスポンスが適切に `Allow: GET, HEAD` を含んでいれば、クライアントは即座に無謀な `POST` を中止し、正規のメソッドに切り替えられる。

理想的な405レスポンスの例
HTTP/1.1 405 Method Not Allowed
Date: Fri, 24 May 2024 10:00:00 GMT
Content-Type: application/json
Allow: GET, HEAD # ここでサーバーが許可するメソッドを明示する
Content-Length: 42
Connection: keep-alive

{“error”: “Method POST is not supported.”}

—

内部実装における「落とし穴」とカーネルチューニング

Webサーバー(NginxやEnvoyなど)のレベルで405を返す際、我々はしばしば「リソースの探索」にコストを払いすぎる。

Nginxでの最適化例

`try_files` や `location` ブロックの設計ミスにより、405を返すためだけにディスクI/Oが発生するケースがある。これはTCPバッファを埋め、ハンドシェイクの完了を遅延させる要因になり得る。

最適化されたlocationブロックの例
location /api/v1/resource {
# limit_except を使い、最小限のコンテキストスイッチで405を生成させる
limit_except GET HEAD {
deny all;
}
# 許可されたメソッドのみをUpstreamへ流す
proxy_pass http://backend_cluster;
}

ここで重要なのは、「許可されていないメソッドは、アプリケーション層(GoやNode.js等)まで到達させてはならない」という鉄則だ。アプリケーション層でステータスコードを生成するのは、既にTLSハンドシェイクが完了し、リクエストのパースが済んだ後。これでは、悪意あるパケットや無知なクライアントに対する「防御壁」としては遅すぎる。L7ロードバランサーやWebサーバーの入り口で確実に遮断することが、インフラの堅牢性を担保する。

—

セキュリティ:405が暴く脆弱性

405エラーは、攻撃者に対して「このエンドポイントには何らかの処理ロジックが存在する」という情報を与えることになる。これは「メソッド列挙(Method Enumeration)」という偵察行為の足がかりとなる。

隠蔽とセキュリティのトレードオフ

「本当に許可されたメソッドだけを返す」のは正しい仕様だが、セキュリティを重視する環境では、意図的に `Allow` ヘッダーの内容を絞り込む、あるいは隠蔽することもある。ただし、これはRFC違反になる可能性があるため、APIの公開範囲に応じて以下のバランスを検討すべきだ。

  • パブリックAPI: RFC準拠を優先。適切な `Allow` を返し、クライアントの負荷を下げ、UXを最大化する。
  • クローズド/高セキュリティAPI: 405を返しつつ、`Allow` ヘッダーには最小限のメソッドのみを記述する、あるいは `404 Not Found` にすり替えることで、メソッドの存在そのものを秘匿する。

—

結論:パケットに「知性」を持たせる

HTTPステータスコードは、単なるサーバーからの応答ではない。それはクライアントとサーバーの間で交わされる、極めて高度な「対話」だ。

405と `Allow` ヘッダーを適切に実装することは、無駄な再送を防ぎ、TCPスループットを維持し、インフラ全体の計算リソースを最適化することに直結する。ネットワークアーキテクトとして、我々が目指すべきは、パケットが一つも無駄にならず、かつクライアントが迷うことのない「流れるような通信」だ。

コードを書くとき、設定を投入するとき、常に想像してほしい。今、その405レスポンスを受け取ったクライアントが、どのような挙動をとるのか。その判断を助ける情報を、あなたはヘッダーに載せているだろうか。

インフラは、細部へのこだわりによってのみ、真に強固なものとなる。

コメント

タイトルとURLをコピーしました