この文書は、 L. Dusseault, J. Snell: PATCH Method for HTTP (RFC 5789), March 2010. を 橋本英彦 が日本語訳した物です。 この文書の取り扱いについては、[Studying HTTP] の RFC 日本語訳を利用するにあたってに従って下さい。
Internet Engineering Task Force (IETF) Request for Comments: 5789 Category: Standards Track ISSN: 2070-1721
L. Dusseault
Linden Lab
J. Snell
March 2010
ハイパーテキスト転送プロトコル(HTTP)を拡張するいくつかのアプリケーションが、部分的なリソースの修正を行うという特徴を必要とする。 既存のHTTP PUTメソッドは、文書の完全な置き換えを許すのみである。 この提案では、既存のHTTPリソースを修正するために、新たなHTTPメソッドであるPATCHを追加する。
This is an Internet Standards Track document.
This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Further information on Internet Standards is available in Section 2 of RFC 5741.
Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at http://www.rfc-editor.org/info/rfc5789.
Copyright © 2010 IETF Trust and the persons identified as the document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.
本仕様書は、新たなHTTP/1.1 [RFC2616]メソッドである、PATCHメソッドを定義する。 これは、リソースに対して部分的な修正を適用するために使用される。
新たなメソッドは、相互互換性を改善し、エラーを排除するために必要である。 既にPUTメソッドが、完全に新たな本体{body}をもってリソースを上書きするために定義されているが、このメソッドでは部分的な変更を行うために再利用することはできない。 一方、その操作の結果として、プロクシやキャッシュ、さらにクライアントやサーバでさえも、混乱させるかもしれない。 また、既にPOSTメソッドも使用されているが、広い相互互換性はない(人々にとって、パッチフォーマットのサポートを発見するための標準的な道のりはない)。 PATCHは、初期のHTTP仕様書にて言及されていたが、完全には定義されていなかった。
本書において、“MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL”の各キーワードは、[RFC2119]にて説明されるとおりに解釈されなければならない。
さらに、本書では[RFC2616]のSection 2.1にて定義されるABNF構文を使用する。
PATCHメソッドは、リクエストエンティティ内に記述される変更の集合がリクエストURIによって識別されるリソースに適用されることを要求する。 変更の集合は、メディアタイプによって識別された“パッチドキュメント{patch document}”と呼ばれるフォーマットにて表現される。 リクエストURIが既存のリソースを指し示すものでなければ、サーバは新たなリソースを生成することができるが、パッチドキュメントのタイプ(存在しないリソースを論理的に修正できるかどうか)や、権限{permissions}などに依存する。
PUTリクエストとPATCHリクエストの違いは、サーバがリクエストに同封されたエンティティをリクエストURIによって識別されるリソースの修正の処理をする方法の中で反映される。 PUTリクエストでは、同封されたエンティティはオリジンサーバ上に保存されるリソースの修正バージョンであるとみなされ、クライアントは保存されるバージョンが置き換えられることを要求している。 しかし、PATCHリクエストでは、同封されたエンティティは、現在オリジンサーバ上に存在するリソースから新たなバージョンを生成するためにどのように修正するかを指し示す命令の集合を含む。 PATCHメソッドは、リクエストURIによって識別されるリソースに影響を与え、またその他のリソース; すなわち、PATCHのアプリケーションによって生成された新たなリソース、または修正された既存のリソースへの副作用を持っているかもしれない;
PATCHは、[RFC2616]のSection 9.1にて定義されるような安全性も冪等性もない。
PATCHリクエストは、冪等であるような方法で発行することができる。 これはまた同じ時間枠内での同じリソースへの二つのPATCHリクエスト間の衝突から悪い結果を防ぐ助けとなる。 いくつかのパッチ形式では、よく知られた基点{known base-point}から操作する必要があり、さもなくばそれらはリソースを破壊するであろうから、複数のPATCHリクエストからの衝突はPUTによる衝突よりも危険であるかもしれない。 この種のパッチアプリケーションを使用するクライアントは、クライアントが最後にリソースにアクセスした以降にリソースが更新されている場合はリクエストが失敗するように、条件付きリクエストを使用すべきである。 たとえば、クライアントは、PATCHリクエスト上でIf-Matchヘッダ内に強いETag [RFC2616]を使用することができる。
また、パッチ形式がよく知られた基点から操作する必要がないような(たとえば、テキスト行をログファイルに、あるいは衝突しない列をデータベーステーブルに追加する)場合もある。 その場合、クライアントリクエストにおける同様の注意は必要ない。
サーバは、変更の集合全てを不可分操作として{atomically}適用しなければならないし、また決して部分的に修正された表現を(たとえば、この操作中のGETに対するレスポンスとして)提供してはならない。 全てのパッチドキュメントを適用することに成功できない場合、サーバはいかなる変更も適用しててはならない。 成功するPATCHを構成するものの決定は、パッチドキュメントや修正されているリソースの種別に応じて変えることができる。 例えば、一般的な 'diff' ユーティリティは、ディレクトリ階層の中の複数のファイルに適用されるパッチドキュメントを生成することができる。 不可分性の要件は、直接的に影響を受けるすべてのファイルに当てはまる。 ステータスコードと起こり得るエラー条件の詳細については、Section 2.2“エラー処理”を参照。
もしリクエストがキャッシュを通過し、リクエストURIが一つ以上の現在キャッシュされているエンティティを識別するならば、それらのエンティティは古いものとして扱われるべきである。 このメソッドへのレスポンスは、(Expiresヘッダや“Cache-Control: max-age”指示子のような)明示的な有効期限情報{freshness information}と、リクエストURIに一致するContent-Locationヘッダが含まれる場合のみ、キャッシュ可能であり、この場合PATCHのレスポンスボディはリソース表現であることを示す。 キャッシュされたPATCHレスポンスは、 その後のGETやHEADリクエストに対する応答としてのみ使用することができる; その他のメソッド(特に、PATCH)に対する応答として使用してはならない。
リクエストに含まれるエンティティヘッダは同封するパッチドキュメントのみに適用され、修正されているリソースには適用されてはならないということに注意せよ。 したがって、Content-Languageヘッダがリクエスト上に存在していたとしても、それはそのパッチドキュメントが言語を持っていたということを(価値があるあらゆることのために)意味するだけである。 サーバは、追跡情報を除いてそのようなヘッダを保存すべきではないし、PUTリクエストにおいて使用されるようなやり方でそのようなヘッダの値を使用すべきではない。 それ故に、パッチドキュメントを通して、文書のContent-TypeやContent-Languageを変更するという目標を達成するためのメカニズムは十分に設計されているであろうが、本書ではヘッダを通してそれらを変更するための方法は規定しない。
リソースは、PATCHメソッドによって修正することができるという保証は無い。 さらに、異なるパッチドキュメント形式が異なる種類のリソースに適切であり、すべての種類のリソースに適切であるような単一の形式というものは無いはずである。 したがって、実装がサポートする必要があるデフォルトのパッチドキュメント形式というものは一つも無い。 サーバは、受信されるパッチドキュメントがリクエストURIによって識別される種類のリソースにとって適切であることを保証しなければならない。
クライアントは、PUTよりもPATCHを使用する時を選択する必要がある。 たとえば、パッチドキュメントのサイズがPUTにて使用されるであろう新たなリソースデータのサイズより大きいならば、それはPATCHの代わりにPUTを使用することが道理にかなうかもしれない。 POSTとの比較は、POSTが広い変更用途に使用されており、サーバがPOSTを選択した場合にPUTとPATCHのような操作を網羅できるので、さらに難しい。 その操作がリクエストURIによって識別されるリソースを予測可能な方法をもって修正するのでなければ、POSTはPATCHかPUTの代わりに考慮されるべきである。
PATCH /file.txt HTTP/1.1 Host: www.example.com Content-Type: application/example If-Match: "e0023aa4e" Content-Length: 100 [description of changes]
この例は、既存のリソース上への仮想的なパッチドキュメントの使用を表している。
既存のテキストファイルに対してPATCHレスポンスが成功した場合:
HTTP/1.1 204 No Content Content-Location: /file.txt ETag: "e0023aa4f"
レスポンスは(コード200のレスポンスでは転送するであろう)メッセージボディを転送しないので、204レスポンスコードが使用される。 他の成功用コードも同様に使用されるであろうことに注意せよ。
加えて、Etagレスポンスヘッダフィールドは、PATCHを適用することによって生成され、Content-Locationレスポンスヘッダフィールドによって示されるように、http://www.example.com/file.txt として利用可能なエンティティのETagを含む。
PATCHリクエストが失敗するであろういくつかの既知の条件がある。
409 Conflict レスポンスは、合理的に一貫した情報をクライアントに与えることに注意せよ。 クライアントはアプリケーションとパッチ形式の性質によって、リクエストそのまま(たとえば、行をログファイルに追加する指示)を再発行することができるが、そうでなければパッチを再検証するためにリソースの内容を取得するか、あるいはその操作を失敗としなければならない。
また、他のHTTPステータスコードも適切な状況下で使用される。
エラーレスポンスのエンティティボディは、エラーの性質をクライアントに伝えるのに十分な情報を含むべきである。 レスポンスエンティティのcontent-typeは、実装を超えて変換することができる。(訳注:プロクシなどを経由する場合)
サーバは、HTTP/1.1にて定義されている(OPTIONSリクエストに対する)"Allow"レスポンスヘッダ内に許可されるメソッドの一覧にPATCHメソッドを加えることによって、そのサポートを通知することができる。 PATCHメソッドは、Accept-Patchヘッダがなくても、"Allow"ヘッダ内に現れるかもしれないが、その場合は許可されるパッチドキュメントのリストは通知されない。
本仕様書では、サーバによって受け入れられるパッチドキュメントフォーマットを特定するために使用される新たなレスポンスヘッダAccept-Patchを導入する。 Accept-Patchは、PATCHメソッドの使用をサポートするあらゆるリソースのためのOPTIONSへのレスポンス中に現れるべきである。 任意のメソッドに対するレスポンス中にAccept-Patchがあれば、それは暗黙的にPATCHがRequest-URIによって識別されるリソースに対して許可されているということを表す。 このヘッダ内に特定のパッチドキュメントフォーマットがあれば、それはその特定のフォーマットがRequest-URIによって識別されるリソースに対して許可されているということを表す。
Accept-Patch = "Accept-Patch" ":" 1#media-type
Accept-Patchヘッダは、[RFC2616]のSection 3.7にて定義されるようなメディアタイプ(とオプションのパラメータ)をカンマ区切りで列挙する。
例: Accept-Patch: text/example;charset=utf-8
[request] OPTIONS /example/buddies.xml HTTP/1.1 Host: www.example.com [response] HTTP/1.1 200 OK Allow: GET, PUT, POST, OPTIONS, HEAD, DELETE, PATCH Accept-Patch: application/example, text/example
この例では、通常二つの仮想的なパッチドキュメントフォーマットを使用してPATCHをサポートするサーバを示している。
Accept-Patchレスポンスヘッダは、恒久的レジストリに追加されている([RFC3864]参照)。
PATCHに関するセキュリティについての問題は、PUT([RFC2616], Section 9.6)に関するセキュリティについての問題とほぼ同一である。 これらは、リクエストを認証する(場合によってはアクセス制御を経由しての認証)ということや、データが転送上のエラーや偶然の上書きによって破損されないことを保証することを含む。 PUTのために使用されるメカニズムはどんなものでも、PATCHに対しても使用されうる。 以下の問題は、特にPATCHに対して適用される。
パッチがなされる文書は、文書全体が上書きされる文書よりも破壊されやすそうであるが、そのような懸念は、Section 2にて記述されるように、ETagsとIf-Matchリクエストヘッダを使用する条件付リクエストのようなメカニズムの使用を通じて対処できる。 PATCHリクエストが失敗した場合、クライアントはそのリソースがどんな状態であるかを確認するためにGETリクエストを発行することができる。 場合によっては、クライアントはPATCHリクエストが再送されたかどうかを見るためにリソースの内容を調べるということができるかもしれないが、そうでなければ、その試みは単に失敗するだけで、ユーザは(PATCHリクエストが失敗した)真意を検証しなければならないであろう。 根本的な転送経路上の失敗の場合、PATCHレスポンスは経路確立が失敗するより前、あるいは他のタイムアウトが起こるより前には受信されないので、クライアントはそのリクエストが適用されたかどうかを見るためにGETリクエストを発行しなければならないかもしれない。 クライアントは、GETリクエストがHTTP仕様書内で説明されるメカニズムを使用してキャッシュを回避することを保証したいかもしれない(たとえば、[RFC2616]のSection 13.1.6を参照)。
時として、HTTPの中継物は、PUT/POSTリクエストかGETレスポンスのボディをチェックすることによって、HTTPを経由して送られるウイルスを検出しようとするかもしれない。 PATCHメソッドは、元となるドキュメントとパッチドキュメントが共にウイルスではないものの、PATCHの結果がウイルスとなるかもしれないので、 そのような監視を継続すること{watch-keeping}を困難にする。 このセキュリティ上の問題は、バイトレンジのダウンロード、パッチドキュメントをダウンロードすること、ZIP(圧縮)されたファイルをアップロードすること、などによって既に取り込まれている問題と実質的に異なるものではない。
個別のパッチドキュメントには、おそらくパッチされているリソースの種別に依存して変わるような、それら自身の特有なセキュリティ問題があるだろう。 たとえば、パッチされたバイナリのリソースに関する問題は、パッチされたXML文書に関する問題とは異なるであろう。 サーバは、悪意があるクライアントがクライアントのPATCHの使用によって過度のサーバリソース(例えば、CPUや、ディスクI/O)を消費できないということを保証するために適切な予防措置を取らなければならない。
PATCHとは新しい概念ではなく、HTTPにおいて初めて登場したのはRoy FieldingとHenrik Frystykによって記述されたバージョン1.1のドラフト内であり、またRFC 2068のSection 19.6.1.1の中にも登場した。
本書の精査、および助言をくれた Adam Roach, Chris Sharp, Julian Reschke, Geoff Clemm, Scott Lawrence, Jeffrey Mogul, Roy Fielding, Greg Stein, Jim Luther, Alex Rousskov, Jamie Lokier, Joe Hildebrand, Mark Nottingham, Michael Balloni, Cyrus Daboo, Brian Carpenter, John Klensin, Eliot Lear, SM, Bernie Hoeneisenの各氏に感謝する。 特に、Julian Reschkeは、繰り返しの精査と、多くの有用な提言をしてくれた、本書の発行に関して決定的に重要な存在であった。
Lisa Dusseault Linden Lab 945 Battery Street San Francisco, CA 94111 USA EMail: lisa.dusseault@gmail.com James M. Snell EMail: jasnell@gmail.com URI: http://www.snellspace.com