[1] [[HTTP]] において[[メソッド]]や[[要求]]が[DFN[[RUBYB[[[安全]]]@en[safe]]]]であるとは、
[[副作用]]が無い (少なくても[[利用者]]は求めていない) ことを表します。

* 仕様書

[REFS[
- [6] '''[CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-06-07 01:55:45 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#section-4.2.1>'''
- [3] [CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-08-07 05:54:02 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#section-8.1.1>
- [18] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-4.4>
- [24] [CITE@en[RFC 2310 - The Safe Response Header Field]] ([TIME[2014-11-03 00:32:42 +09:00]] 版) <http://tools.ietf.org/html/rfc2310>
- [45] [CITE@en[RFC 2324 - Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0)]] ([TIME[2014-10-06 15:21:16 +09:00]] 版) <http://tools.ietf.org/html/rfc2324#section-2.2.1.1>
]REFS]

* 定義

[8] [[要求メソッド]]は、その[[意味]]が[[読み取り専用]]と定義されていれば、
「[DFN[[RUBYB[[[安全]]]@en[safe]]]]」です。[[安全なメソッド]]では、
[[クライアント]]は[[起源鯖]]が[[対象資源]]の状態を変化させることを要求も期待もしませんし、
普通に[[安全なメソッド]]を使っても、[[起源鯖]]で有害な事象やおかしなことは起こらないと期待されます。
[SRC[>>6]]

[9] [[実装]]が >>8 の条件を満たしている保証はなく、何かを変化させたり、
[[副作用]]を起こしたりすることはあり得ます。しかし、それは[[クライアント]]が要求したことではなく、
[[クライアント]]が責任を持つものではない、ということが重要とされています。 [SRC[>>6]]

[EG[
[10] 例えばほとんどの[[鯖]]は[[アクセスログ]]にすべての[[要求]]を記録しています。
それによって[[鯖]]の[[ストレージ]]が満杯になってクラッシュする可能性があっても、
[[安全]]かどうかには影響しません。また、[[広告]]の取得であれば、
[[広告]]主への[[課金]]という[[副作用]]を持つかもしれませんが、やはり[[安全]]性とは関係ありません。
[SRC[>>6]]
]EG]

;; [11] ここでの「安全」は、[[セキュリティー]]とは関係ありません。

* 処理モデル

[13] [[安全]]と[[非安全]]の区別は、無害な形で自動的な取得 ([[ボット]])
やキャッシュ処理 ([[先読み]]) を実行できるようにするためのものです。 [SRC[>>6]]

[14] [[利用者エージェント]]は、信頼できないかもしれない[[内容]]の処理時に[[安全]]でない[[メソッド]]の自動利用を制限することもできます。
[SRC[>>6]]

[15] [[利用者エージェント]]は、可能な操作を提示する時に[[安全]]か[[非安全]]かを明確に区別して、
[[非安全]]な操作を実行する前に[[利用者]]が気付けるようにする[['''べきです''']] [SRC[>>6]]。

[16] [[実効要求URL]]の一部が動作を表す場合、例えば [CODE[page?do=delete]]
のような [[URL]] の場合、[[資源]]の所有者は、[[安全なメソッド]]の時はその動作を無効にするか、
認めないようにしなければ[['''なりません''']] [SRC[>>6]]。

[19] [[キャッシュ]]が[[非安全メソッド]]に対する[[応答]]を受信したら、
次のようにしなければ[['''なりません''']] [SRC[>>18]]。

[FIG(steps)[
= [20] [[状態符号]]が誤りでない ([CODE(HTTP)[[[2xx]]]] か
[CODE(HTTP)[[[3xx]]]]) なら、
== [21] [[非安全]]な[[要求メソッド]]なら、[[実効要求URL]]について、[[非妥当化]]します。
== [22] [[非安全]]な[[要求メソッド]]か、[[安全]]かどうかわからない[[要求メソッド]]なら、
[CODE(HTTP)@en[[[Location:]]]] と [CODE(HTTP)@en[[[Content-Location:]]]]
の [[URL]] (あれば) について、
=== [23] [[host]] が[[実効要求URL]]と同じなら、[[非妥当化]]します。
]FIG]

* 安全なメソッドの一覧

[7] 次の[[要求メソッド]]は、[[安全]]です。

[FIG(list short)[
- [CODE(HTTP)@en[[[GET]]]]
- [CODE(HTTP)@en[[[HEAD]]]]
- [CODE(HTTP)@en[[[OPTIONS]]]]
- [CODE(HTTP)@en[[[TRACE]]]]
- [CODE(HTTP)@en[[[PROPFIND]]]]
]FIG]

;; [12] [[RFC 2616]] までは [CODE(HTTP)@en[[[GET]]]] と [CODE(HTTP)@en[[[HEAD]]]]
のみ[[安全]]とされていましたが、 [[RFC 7231]] で [CODE(HTTP)@en[[[OPTIONS]]]]
と [CODE(HTTP)@en[[[TRACE]]]] も追加されました。

[4] [[要求メソッド]]を [[IANA]] に登録する際に、[[安全]]か否かも記載することになっています
[SRC[>>3]]。

* [CODE(HTTP)@en[Safe:]] ヘッダー

[25] [CODE(HTTP)@en[[[Safe:]]]] [[ヘッダー]]は、
[[要求]]を繰り返しても[[安全]]であるか否かを示します [SRC[>>24]]。

** 意味

[37] [CODE(HTTP)@en[[[Safe:]]]] [[ヘッダー]]は、[[要求]]を[[反復]]しても[[安全]]かどうかを示します。

[32] ある[[要求]]が以前の[[要求]]の[[反復]]であるとは、両[[要求]]が次の条件をすべて満たすことをいいます [SRC[>>24]]。
[FIG(list)[
- [33] 同じ[[利用者エージェント]]が発行したものである
- [34] 同じ[[資源]]に適用される
- [35] 同じ[[要求メソッド]]である
- [36] [[要求本体]]をどちらも有しないか、または[[内容符号化]]と[[転送符号化]]を[[復号]]すると[[バイト列]]として同じである
]FIG]

** 構文

[38] [CODE(HTTP)@en[[[Safe:]]]] [[ヘッダー]]の値は、[[字句]]です。
[[大文字・小文字不区別]]です。

[FIG(railroad)[
= [[字句]]
]FIG]

[46] 現在次の値が定義されています。
[FIG(short list)[
- [CODE(HTTP)@en[[[yes]]]]
- [CODE(HTTP)@en[[[no]]]]
- [CODE(HTTP)@en[[[if-user-awake]]]]
]FIG]

[48] [[RFC 2310]] では値として [CODE(HTTP)@en[[[yes]]]] と [CODE(HTTP)@en[[[no]]]] 
を規定しています。[CODE(HTTP)@en[[[yes]]]] は[[安全]]、 [CODE(HTTP)@en[[[no]]]] 
は[[非安全]]を表します。

[47] [[HTCPCP]] は [CODE(HTTP)@en[[[if-]]]] を条件付きで安全であることを表すよう拡張しています。
具体的な値として、 [CODE(HTTP)@en[[[if-user-awake]]]] を規定してます。 [SRC[>>45]]

;; [[4月1日]]に公開された [[RFC]] でもあり、意味は明確には定義されていません。

;; [49] [[RFC 2310]] では値は2つだけで、拡張可能とはされていません。
[[HTCPCP]] が >>47 の通り拡張しており、それを含めると値は[[字句]]となります。
[[RFC 2310]] でも [[HTCPCP]] でも [[ABNF]] 構文より定義済みの値および接頭辞
[CODE(HTTP)[[[if-]]]] は[[大文字・小文字不区別]]となっていますが、
将来の拡張も不区別とは明記していません (おそらく意図は不区別ですが)。
どちらの [[RFC]] も [CODE(HTTP)[[[if-]]]] で始まらない拡張の値は認めていません。

** 文脈

[50] 任意の[[応答]]で利用できると思われますが、不明です。
[[要求]]では利用できないと思われます。

[51] 実際に利用されている例があるかは不明です。

** 処理

[39] [[応答]]に [CODE(HTTP)@en[[[Safe:]]]] [[ヘッダー]]がなければ、
[CODE(HTTP)@en[[[GET]]]] や [CODE(HTTP)@en[[[HEAD]]]] の場合を除き、
[[非安全]]とみなさなければ[['''なりません''']] [SRC[>>24]]。

[40] [[利用者エージェント]]は [CODE(HTTP)@en[[[GET]]]] や [CODE(HTTP)@en[[[HEAD]]]]
の時 [CODE(HTTP)@en[[[Safe:]]]] [[ヘッダー]]を無視する[['''べきです''']] [SRC[>>24]]。

;; [41] [[RFC 7230]] で[[安全なメソッド]]が増えているので (>>12)、
>>39 と >>40 もそのように読み替えるべきと思われます。

[26] [[利用者エージェント]]は[[要求]]の[[反復]]が[[安全]]なら、
[[利用者]]に確認せずに自動的に[[反復]]して構いません [SRC[>>24]]。

[EG[
[27] 例えば次のような場合に[[利用者エージェント]]は [CODE(HTTP)@en[[[POST]]]]
[[要求]]を繰り返す必要があります [SRC[>>24]]。
[FIG(list)[
- [28] [[中間器]]の誤りで失敗した場合
- [29] [CODE(HTTP)@en[[[POST]]]] 結果の表示中に[[利用者]]が[[再読み込み]]した場合
- [30] [[履歴]]から [CODE(HTTP)@en[[[POST]]]] 結果を選んだ場合で、既に[[履歴]]バッファーに残っていない場合
]FIG]

[31] [CODE(HTTP)@en[[[POST]]]] が[[不安全]]なら再試行する前に[[利用者]]に明示的に確認する必要がありますが、
多くの[[利用者]]を混乱させますし、 [[navigation]] を遅延させてしまいます。
[[安全]]ならこの確認を省略できます。 [SRC[>>24]]
]EG]

[52] 実装例があるかは不明です。

* 歴史

** RFC

[FIG(quote)[
[FIGCAPTION[
[2] RFC 2068・2616 (HTTP/1.1) 9.1 Safe and Idempotent Methods
]FIGCAPTION]

* RFC 1945 (HTTP/1.0) 12.2; RFC 2068・2616 (HTTP/1.1) 9.1.1 Safe Methods
> [DEL[[DEL[The writers of client software]] [INS[Implementers]]]] [INS[[INS[{2616}]] Implementors]] should be aware that the software represents the user in
their interactions over the Internet, and should be careful to allow
the user to be aware of any actions they [DEL[may]] [INS[might]] take which may have an
unexpected significance to themselves or others.

実装者は、ソフトウェアがインターネット上の相互作用で利用者を表現することを意識し、
自身や他者に意図せぬ意味を持つかもしれない動作を取ろうとする時には利用者がそのことに気づけるように注意するべきです。

> In particular, the convention has been established that the GET and
HEAD methods [DEL[should never]] [INS[SHOULD NOT]] have the significance of taking an action
other than retrieval. These methods [DEL[should]] [INS[ought to]] be considered [DEL["safe."]] [INS["safe".]]
This allows user agents to represent other methods, such as POST, [INS[[INS[{2068,2616}]] PUT and DELETE,]] in a special way, so that the user is made aware of the
fact that a possibly unsafe action is being requested.

特に、 [CODE(HTTP)[[[GET]]]] 方式や [CODE(HTTP)[[[HEAD]]]]
方式が取り出し (retrieval) 以外の動作を取る意味を持つ'''べきではない'''という慣習が確立しています。
これらの方式は「安全」であると考えられるべきです。
これによって、利用者は他の方式、例えば [CODE(HTTP)[[[POST]]]]
や [CODE(HTTP)[[[PUT]]]] や [CODE(HTTP)[[[DELETE]]]]
を、特別な用途で表明することができ、
よって利用者に非安全かもしれない動作が要求されようとしていることを気づかせることができます。

> Naturally, it is not possible to ensure that the server does not
generate side-effects as a result of performing a GET request; in
fact, some dynamic resources consider that a feature. The important
distinction here is that the user did not request the side-effects,
so therefore cannot be held accountable for them.

当然、サーバーが [CODE(HTTP)[GET]] 要求を行うことで副作用を起こさないことを保証はできません。
実際、動的資源の中にはそれを機能としています。
ここでの重要な違いは、利用者は副作用を要求していないので、
従ってそれについての責任を負えないことです。

[INS[
注: 注記のない変更点は、 RFC 2068→RFC 2616 での修正。
]INS]

* RFC 2068・2616 (HTTP/1.1) 9.1.2 Idempotent Methods
→[CODE(WikiPage)[[[冪等]]]]
]FIG]

** RFC 2310

[42] [[RFC 2310]] は [CODE(HTTP)@en[[[Safe:]]]] [[ヘッダー]]を追加しました。

[44] [[RFC 4229]] は [[RFC 2310]] を出典に状態「[[実験的]]」で[[IANA登録簿]]に登録しています。

[REFS[
- [43] [CITE@en[RFC 4229 - HTTP Header Field Registrations]] ([TIME[2014-11-02 18:53:20 +09:00]] 版) <http://tools.ietf.org/html/rfc4229#section-2.1.93>
]REFS]

* 関連

[5] 類似した概念に[[冪等]]があります。[[安全なメソッド]]は、[[冪等]]です [SRC[>>6]]。

;; [17] 将来にわたってこの性質が保証されるのかは不明です。