[17] [[HTTP要求]]を[[受信]]して[[HTTP応答]]を作成・[[送信]]する[[プログラム]]を、
[DFN[[RUBY[[[鯖]]][サーバー]@en[server]]]]といいます。

* 仕様書

[REFS[
- [13] [CITE@en[RFC 7230 - Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing]] ([TIME[2014-06-07 01:59:35 +09:00]] 版) <https://tools.ietf.org/html/rfc7230#section-2.1>
- [20] [CITE@en[RFC 7232 - Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests]] ([TIME[2014-09-11 10:02:44 +09:00]] 版) <https://tools.ietf.org/html/rfc7232#section-5>
- [46] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-8.1>
- [51] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-8.2>
- [54] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-8.4>
- [58] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-8.5>
- [59] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-17>
- [9] [CITE@en[RFC 3875 - The Common Gateway Interface (CGI) Version 1.1]] 
-- [3] '''<http://tools.ietf.org/html/rfc3875#section-3.1>'''
-- [8] <http://tools.ietf.org/html/rfc3875#section-8.1>
- [62] [CITE@en[RFC 5849 - The OAuth 1.0 Protocol]]
([TIME[2014-12-28 14:19:21 +09:00]] 版)
<http://tools.ietf.org/html/rfc5849#section-1.1>
- [65] [CITE@en[RFC 6749 - The OAuth 2.0 Authorization Framework]] ([TIME[2014-12-15 14:15:35 +09:00]] 版) <http://tools.ietf.org/html/rfc6749#section-1.1>
- [70] [CITE@en[RFC 6749 - The OAuth 2.0 Authorization Framework]] ([TIME[2014-12-15 14:15:35 +09:00]] 版) <http://tools.ietf.org/html/rfc6749#section-10.11>
- [140] [CITE@en[RFC 6455 - The WebSocket Protocol]] ([TIME[2015-03-11 20:42:50 +09:00]] 版) <http://tools.ietf.org/html/rfc6455#section-4.2>
]REFS]

* 意味

[162] [DFN[[RUBYB[Webサーバー]@en[Web server]]]]は、
[[Web]] の[[サーバー]]です。ほとんどすべての場合、[[プロトコル]]として [[HTTP]]
を[[実装]]したもののことを指しています。

;; [163] [[Webサーバー]]と[[HTTPサーバー]]は、ほとんど同義として用いられますが、
一般的な文脈では [[Webサーバー]]、特に [[HTTP]] について扱うときのみ
[[HTTPサーバー]]と呼ぶことが多そうです。

[14] [[HTTP]] [DFN[[RUBY[[[鯖]]][サーバー]@en[server]]]]は、
[[HTTP要求]]に対して[[HTTP応答]]を[[送信]]することによってサービスを提供するため[[接続]]を[[受理]]する[[プログラム]]です。
[SRC[>>13]]

;; [19] [[鯖]]は、[[起源鯖]]であることもあれば、[[串]]や[[トンネル]]や[[関門]]のような[[中間器]]であることもあります。

[131] [[HTTP]] 視点では[[鯖]]は[[ブラックボックス]]で、どのように[[要求]]を処理して[[応答]]を生成するかは自由です。
[[鯖]]自身が直接処理しても構いません ([[起源鯖]]) し、他の[[鯖]]に処理を委ねても構いません
([[中間器]])。

[FIG(sequence)[
:C:[[クライアント]]
:S:[[鯖]]
:C -> S:[[要求]]
:#S#:何らかの処理
:S -> C:[[応答]]
]FIG]

[132] [[HTTP]] を利用する[[プロトコル]] ([[WebDAV]] や [[OAuth]] など) によっては、
[[鯖]]の構成や動作に更に制限や要件が規定されています。

[134] ある(広義の)[[鯖]]が入口にあたる[[関門]] ([RUBYB[[[逆串]]]@en[reverse proxy]]) とその先の実際の[[鯖]]で構成される場合、
後者を[RUBYB[[[アプリケーション鯖]]]@en[application server]]や[RUBYB[[[バックエンド]]]@en[backend]]と呼ぶことがあります。

[FIG(sequence)[
:C:[[クライアント]]
:P:[[逆串]]
:A:[[アプリケーション鯖]]
:C -> P:[[要求]]
:P -> A:[[要求]]
:#A#:[[アプリケーション]]固有の処理
:A -> P:[[応答]]
:P -> C:[[応答]]
]FIG]

[133] [[鯖]]が[[要求]]を処理するために他の[[プログラム]]や[[コンポーネント]]に処理を委ねることもよくあります。
[[HTTP]] 視点ではそれらも含めて[[鯖]]の一部であり、[[鯖]]内部の構成や [[API]]
は[[鯖]]が自由に決められます。そのような [[API]] の中には標準化されているものもあり
([[CGI]]、[[ISAPI]]、[[WSGI]]、[[PSGI]] など)、その場合は [[HTTP]] 処理を行う部分を[[鯖]]、
アプリケーション固有の処理を行う部分を[[スクリプト]]や[[アプリケーション]]などと呼びます。
[[ミドルウェア]]などその他の[[コンポーネント]]が組み合わさる場合もあります。

[FIG(sequence)[
:C:[[クライアント]]
:S:[[鯖]]
:A:[[アプリケーション]]
:C -> S:[[要求]]
:S -> A:呼び出し
:#A#:[[アプリケーション]]固有の処理
:A -> S:結果
:S -> C:[[応答]]
]FIG]

[FIG(quote)[
[2] 
>
:'server':
The application program that invokes the script in order to
service requests from the client.
>
:[DFN[[RUBYB[鯖]@en[server]]]]:
[[クライアント]]からの[[要求]]に対して[[サービス]]を提供するため[[スクリプト]]を呼び出す[[応用プログラム]]。

[FIGCAPTION[
[CITE@en[RFC 3875 - The Common Gateway Interface (CGI) Version 1.1]] ([TIME[2011-11-20 06:09:05 +09:00]] 版) <http://tools.ietf.org/html/rfc3875#section-1.4>
]FIGCAPTION]
]FIG]

* 処理

[45] [[HTTPサーバー]]の処理について、[[仕様書]]はある部分は順序や細かな要件を定めつつ、
別の部分は曖昧にしており、また別の部分は何も規定されていなかったりします。

[170] [[プロトコル]]としての動作に大きな影響のない事項
(例えば認証エラー [CODE[401]] と未対応メソッドのエラー [CODE[405]]
の両方に該当するとき、どちらを返すべきか) は、[[サーバー]]の判断に委ねられています。
[[相互運用性]]に関わる事項 (例えば[[内容符号化]]と[[転送符号化]]の適用順序)
は明確に定められています。

-*-*-

[173] [[HTTPサーバー]]は、[[HTTPクライアント]]との間の[[HTTP接続]]を流れるデータを、
[[HTTP接続の処理]]によって順次処理していくことが期待されます。

[21] 応答ヘッダーの受信完了の通知を受けて、[[HTTP要求]][VAR[要求]]を処理しなければなりません。

[40] 次のようにします。

[FIG(steps)[
= [22] [VAR[応答]]を、[VAR[要求]]に'''要求検査'''を適用した結果に設定します。
= [24] [VAR[応答]]が [CODE[null]] でなければ、
== [23] [VAR[応答]]を送信します。
= [167] それ以外で、 [VAR[要求]]の[F[メソッド][要求メソッド]]が [CODE[CONNECT]] か [CODE[TRACE]] の場合、
== [27] [VAR[要求]]の[F[メソッド]]の操作を実行します。
= [28] それ以外の場合、
== [176] [VAR[処理器]]を、[VAR[要求]]の[F[要求対象]]に関する'''処理の選択'''の結果に設定します。
== [168] [VAR[要求]]について[VAR[処理器]]を実行します。
]FIG]

[25] ここで、'''要求検査'''とは、受信した[VAR[要求]]に対して[[サーバー]]全体の制約を検査する、
[[サーバー]]の実装や設定に依存した操作です。
[[応答]]を返すか、問題がなければ [CODE[null]] を返します。

[EG[
[174] 例えば次のような検査を行うことが期待されます。

[FIG(list)[
- [164] [[プロキシ]]でないのに異なる[[起源]]の[[要求対象]]が指定された場合に、
[CODE[421]] [[応答]]か[[HTTPリダイレクト]]を返します。
- [165] [[サーバー]]全体の[[HTTP認証]]の検査を行い、問題があれば [CODE[401]]
[[応答]]を返します。
- [166] 当該[[クライアント]]のアクセス頻度が高すぎるなら、 [CODE[429]]
[[応答]]を返します。
]FIG]

[175] [[状態符号]]の選択方法は [CODE[4xx]] を参照。
]EG]

[177] [VAR[要求]]の[F[要求対象]]に関する'''処理の選択'''は、
[VAR[要求]]の[F[要求対象]]が指すもの、つまり[[対象資源]]に基づき適切な処理を選択する[[サーバー]]の実装や設定に依存した処理です。
[[Webアプリケーション]]開発の現場では[[ルーティング][ルーティング (Webアプリケーション)]]と呼ばれることがあります。

[169] 選択された処理は、[VAR[要求]]について適切な[[応答]]を作成し、送信することが期待されます。

[36] [[HTTP]] の[[仕様書]]が想定する典型的な処理は、次のようなもののようです。

[FIG(steps)[
= [178] [VAR[応答]]を、[VAR[要求]]に'''対象資源依存の要求検査'''を適用した結果に設定します。
= [179] [VAR[応答]]が [CODE[null]] でなければ、
== [180] [VAR[応答]]を送信し、ここで停止します。
= [34] [VAR[要求]]を[[キャッシュ]]によって処理可能なら、
== [42] [VAR[要求]]に対応する[[キャッシュ項目]]を使って[[応答]]し、ここで停止します。
= [29] [[起源鯖]]で、[[対象資源]]に関する[[内容折衝]]が適用される場合、
[[内容折衝]]により返す[[表現]]を選択します。
= [32] 必要に応じて[[内容符号化]]を適用します [SRC[>>30]]。
= [37] [[実体タグ]]を決定します [SRC[>>30]]。
= [26] [[条件付き要求]]が適用される場合、
== [147] [[要求]]に事前条件が指定されていれば、
[[起源鯖]]であり[[要求メソッド]]が[[条件付き要求]]として適切である場合、
その条件を確認します [SRC[>>20, >>58]]。 ([[条件付き要求]]を参照。)
== [148] [[要求]]に事前条件が指定されていない場合で、
[[対象資源]]について非[[条件付要求]]を受け付けたくない場合、
[CODE[[[428]]]] [[応答]]を返します。
= [31] [[要求メソッド]]で指定された操作を実行します。
= [35] 必要なら[[実現値操作]]を適用します [SRC[>>30]] ([[実現値操作]]を参照)。
== [33] [[範囲要求]]なら、結果の適切な部分を [CODE(HTTP)[[[206]]]] [[応答]]として返します。
([[範囲要求]]を参照。)
]FIG]

[181] ここで、'''対象資源依存の要求検査'''とは、
受信した[VAR[要求]]に対して[[対象資源]]によって規定される制約を検査する、
[VAR[処理器]]に依存した操作です。
[[応答]]を返すか、問題がなければ [CODE[null]] を返します。

[EG[
[182] 例えば次のような検査を行うことが期待されます。

[FIG(list)[
- [183] そもそも[[対象資源]]が存在しなければ、 [CODE[404]] [[応答]]を返します。
- [184] [VAR[要求]]の[F[メソッド][要求メソッド]]が想定外なら、 [CODE[405]] [[応答]]を返します。
- [185] [VAR[要求]]に処理遂行に十分な情報が含まれないなら、 [CODE[400]]
[[応答]]を返します。
- [186] [VAR[要求]]の処理を実行するための権限が足りていないなら、 [CODE[403]]
[[応答]]や [CODE[401]] [[応答]]を返します。
]FIG]

[187] [[状態符号]]の選択方法は [CODE[4xx]] を参照。
]EG]


[39] [[応答]][VAR[応答]]の送信は、次のようにします。

[FIG(steps)[
= [44] [VAR[応答]]に対し、必要なら[[転送符号化]]を適用します [SRC[>>30]]。
= [41] [VAR[応答]]を送信します。
]FIG]

* アプリケーションサーバーAPI

[138] [[HTTPサーバー]]と[[アプリケーション]]との間の [[API]] やサーバー拡張には次のものがあります。
[FIG(short list)[
- [[HTTP]] (= [[逆串]])
- [[CGI]]
-- [[NPH]]
- [[SSI]]
- [[FastCGI]]
- [[Apacheモジュール]]
-- [[mod_perl]]
-- [[mod_ruby]]
- [[FrontPage Server Extensions]]
- [[PHP]]
- [[ASP]]
- [[JSP]]
- [[ISAPI]]
- [[WSGI]]
- [[PSGI]]
- [[Java Servlet]]
- [[P6W]]
]FIG]

[139] その他 [[HTTPサーバー]]の動作の記述に次のものが使われます。
[FIG(short list)[
- [[httpd.conf]]
- [[.htaccess]]
- [[.htpasswd]]
- [[server-side image map]]
]FIG]

* HTTP サーバーの終了

[149] [[HTTPサーバー]]を綺麗に終了させるには少し慎重さが必要です。
[[graceful]] な終了 (close, shutdown, stop, terminate / [[再起動]] restart) と呼ばれています。

@@ [[HTTP/2]] の場合、

[151] まず、新規の[[HTTP接続]]の受け付けを停止する必要があります。

[150] [[アイドル状態]]の [[HTTP接続]]があれば、これを切断する必要があります。

[159] [[応答]]送信済みで[[要求]]受信待ち中なら、
[[応用]]がこれを受信している限りにおいて、中断できません。
[[応用]]が処理し終えているか、中断するべきと判断したか、
サーバーが設定したタイムアウトに達したなら、接続を切断できます。

[152] [[応答]]を未送信なら、次に送信する[[応答]]で
[CODE[Connection: close]] を送信した方が良さそうです。

[153] [[応答]]を未送信または[[応答]]を送信中で、これを中断するべきと判断できるなら、
これを直ちに切断できます。

[154] [[応答]]を未送信または[[応答]]を送信中で、中断するべきと判断できないなら、
[[応答]]の送信を完了次第、直ちに切断する必要があります。 (次の[[要求]]が送信されてくる可能性もありますが、
無視しなければなりません。)

[155] 通常の [[HTTP]] の場合、中断するべきかどうかは[[応用]]が判断するしかありません。
基本的には中断するべきではなさそうですが、タイムアウトを設定した方が良いかもしれません。

[156] [[WebSocket]] の場合、中断するべきかどうかは[[応用]]が判断するしかありません。
それがかなわない場合は中断するべきです。 [[Closeフレーム]]
([[状態符号][WebSocket状態符号]] [CODE[1001]]) を送信して直ちに接続を閉じるべきかもしれませんし、
それもせずに切断してしまっても良いかもしれません。
中断しない場合でも、タイムアウトを設定した方が良いかもしれません。

[157] [CODE[CONNECT]] の場合、中断するべきかどうか判断する方法はないので、
直ちに接続を閉じるのが良さそうです。

[161] [[クライアント]]は、[[サーバー]]が書き込み側を閉じても直ちにそれに反応して接続を閉じないかもしれません。
通常動作中はそれを待っても良いかもしれませんが、サーバーを終了させたい時は、
[[クライアント]]が接続を閉じるのを待たずに直ちに強制切断するべきかもしれません。

[158] [[HTTP接続]]が閉じられ、それを処理する[[応用]]が完了するか、
[[応用]]を中断できる場合で中断したなら、サーバー全体を終了できます。

* HTTP サーバーの実装

[145] [[HTTPサーバー]]は沢山の実装があります。
[FIG(short list)[
- [[CERN httpd]]
- [[NCSA HTTPd]]
- [[Apache]]
- [[ATS]]
- [[IIS]]
- [[PWS]]
- [[nginx]]
- [[GWS]]
- [[AnyEvent::HTTPD]]
- [[Starman]]
- [[Starlet]]
- [[Twiggy]]
- [[Twiggy::Prefork]]
- [[h2o]]
- [[Squid]]
- [[DeleGate]]
- [[Caddy]]
- [[publicfile]]
- [[Cowboy]]
]FIG]

[188] [[Webサイトホスティングサービス]]も参照。

* WebDAV に関する要件

[47] [[WebDAV]] に従う[[資源]]に関しては、次のようにエラーの検査を行います。
[FIG(steps)[
= [48] 必要があれば、[[認証]]に関するエラーを返します [SRC[>>46]]。
= [56] [[要求]]に [[payload body]] がある場合、
== [55] [[要求メソッド]]の定義上これを無視することになっている場合、
[CODE(HTTP)[[[415]]]] [[応答]]を返します [SRC[>>54]]。
== [50] [[XML]] を指定することになっている場合、
=== [57] [[整形式]] [[XML 1.0]] [[文書]]でなければ、 [CODE(HTTP)[[[400]]]] 
を返します [SRC[>>51]]。
=== [52] [[整形式]]であっても怪しい内容を含んでいれば、
[CODE(HTTP)[[[400]]]] を返して構いません [SRC[>>51]]。
= [49] 必要があれば、その他のエラーを返します。
]FIG]

[53] [[WebDAV]] [[鯖]]は、[[XML 1.0]] と [[XML名前空間 1.0]]
に対応しなければ[['''なりません''']] [SRC[>>51]]。

[60] [[WebDAV]] [[鯖]]は、 [[WebDAV]] の [[XML文書]] ([[死特性]]以外)
の未知の[[要素]]や[[属性]]、既知ながら想定されていない場所で使われている[[要素]]や[[属性]]について、
無視して処理しなければ[['''なりません''']] [SRC[>>59]]。

[61] [[処理指令]]は無視する[['''べきです''']] [SRC[>>59]]。

* CGI に関する要件

[4] [[CGI]] に関して、[[クライアント]]からの[[要求]]を [[CGIスクリプト]]に伝達するに当たり、
[[プロトコル]]や[[トランスポート層]]の[[認証]]、[[セキュリティー]]を実装するのは[[鯖]]の責任です。
更にそれ以上のデータ型やプロトコルの変換などを行なっても構いません。 [SRC[>>3]]

[5] [[鯖]]は [[CGI]] の仕様に従って[[クライアント]]の[[要求]]を変換して
[[CGIスクリプト]]に提供しなければ[['''なりません''']]。逆に[[CGIスクリプト]]の結果を、
たとえそれが [[CGI]] の仕様に適合しなかったとしても、
関係する[[プロトコル]]に適合するよう変形する必要があります。 [SRC[>>3]]

[6] [[鯖]]が[[認証]]を適用する場合にあっては、[[要求]]がそれをすべて通過しない限り
[[CGIスクリプト]]を実行しては[['''なりません''']]。 [SRC[>>3]]

[7] また次のことについて明確にすることが推奨されています [SRC[>>8]]:
[FIG(list)[
- [10] [[path segment]] に関する制約、特に最後以外で[[空文字列]]の [[path segment]] を認めるか否か
- [11] [CODE(URI)[[[.]]]] や [CODE(URI)[[[..]]]] の扱い:
-- 禁止、普通に扱う、[[相対URL]]での扱いを踏襲する、など
- [12] [[path]] などの長さの制約
]FIG]

* OAuth 1.0 鯖 (サービス提供者)

[67] [DFN[[RUBY[鯖][サーバー]@en[server]]]]は、 [[OAuth]]
で[[認証]]された[[要求]]を受理できる能力のある[[HTTP鯖]]です [SRC[>>62]]。

[63] 元々は[DFN[[RUBYB[サービス提供者]@en[service provider]]]]ともいいました [SRC[>>62]]。

[68] [[鯖]]は、次の[[エンドポイント]]を持ちます。
[FIG(short list)[
- [[一時credentials要求]]の[[エンドポイント]]
- [[資源所有者認可]]の[[エンドポイント]]
- [[トークン要求]]の[[エンドポイント]]
]FIG]

;; [69] もちろん、その他に [[OAuth]] を利用する [[API]] の[[エンドポイント]]も持ちます。

[REFS[
- [74] [CITE@ja[OAuth 1.0 API Reference - Google Accounts Authentication and Authorization — Google Developers]] ([TIME[2014-12-05 11:52:26 +09:00]] 版) <https://developers.google.com/accounts/docs/OAuth_ref>
- [77] [CITE[Implementing Sign in with Twitter | Twitter Developers]] ([TIME[2015-03-05 11:12:29 +09:00]] 版) <https://dev.twitter.com/web/sign-in/implementing>
- [78] [CITE[3-legged authorization | Twitter Developers]] ([TIME[2015-03-05 11:08:34 +09:00]] 版) <https://dev.twitter.com/oauth/3-legged>
- [80] [CITE[はてな OAuth - Hatena Developer Center]] ([TIME[2015-03-05 15:21:53 +09:00]] 版) <http://developer.hatena.ne.jp/ja/documents/auth/apis/oauth>
- [81] [CITE@en[OAuth Authorization Model - YDN]] ([TIME[2015-03-05 15:33:18 +09:00]] 版) <http://web.archive.org/web/20120117120610/http://developer.yahoo.com/oauth/>
- [82] [CITE@ja[OAuth1.0:OAuth1.0 - Yahoo!デベロッパーネットワーク]] ([TIME[2015-03-05 15:53:36 +09:00]] 版) <http://developer.yahoo.co.jp/other/oauth/>
- [88] [CITE[OpenPNE3 OAuth 対応アプリケーション作成ガイド]] ([TIME[2009-09-11 15:26:43 +09:00]] 版) <https://trac.openpne.jp/svn/OpenPNE3/doc/branches/develop/OAuth/ja.txt>
- [89] [CITE[apiDoc: Withings - 1.0.0]] ([TIME[2015-03-05 16:20:37 +09:00]] 版) <http://oauth.withings.com/api/doc#api-OAuth_Authentication>
- [100] [CITE[OAuth on Bitbucket - Bitbucket - Atlassian Documentation]] ([TIME[2015-03-05 18:51:40 +09:00]] 版) <https://confluence.atlassian.com/display/BITBUCKET/OAuth+on+Bitbucket>
- [102] [CITE@ja[OAuth認証方法について - GREE Developer Center]] ([TIME[2015-03-06 00:43:20 +09:00]] 版) <https://docs.developer.gree.net/ja/globaltechnicalspecs/oauth>
- [103] [CITE@ja[OAuth認証方法について(GREE Platform for Feature Phone) - GREE Developer Center]] ([TIME[2015-03-06 00:46:20 +09:00]] 版) <https://docs.developer.gree.net/ja/technicalspecs/featurephone/oauth>
- [104] [CITE[RESTful API - Smartphone App - Mobage Developers Documentation Center]] ([TIME[2015-03-06 00:51:05 +09:00]] 版) <https://docs.mobage.com/display/JPSA/REST_API_Reference_JP>
- [108] [CITE[認証と認可 — サイボウズ Live・API ドキュメント]] ([TIME[2015-01-23 16:20:44 +09:00]] 版) <https://developer.cybozulive.com/doc/current/pub/authorize.html>
- [109] [CITE@en-us[Flickr Services]] ([TIME[2015-03-06 01:25:01 +09:00]] 版) <https://www.flickr.com/services/api/auth.oauth.html>
- [112] [CITE[OAuth Authentication in the Fitbit API - API - Confluence]] ([TIME[2015-03-06 08:29:40 +09:00]] 版) <https://wiki.fitbit.com/display/API/OAuth+Authentication+in+the+Fitbit+API>
- [113] [CITE[Consumer Authentication]] ([TIME[2012-09-26 04:52:48 +09:00]] 版) <http://pic.photobucket.com/dev_help/WebHelpPublic/Content/Getting%20Started/Consumer%20Authentication.htm>
- [114] [CITE@en[OAuth1/spec.md at master · WP-API/OAuth1]] ([TIME[2015-03-06 08:42:54 +09:00]] 版) <https://github.com/WP-API/OAuth1/blob/master/docs/spec.md>
- [115] [CITE@en[OAuth 1.0 Server · OpenBankProject/OBP-API Wiki]] ([TIME[2015-03-06 08:46:04 +09:00]] 版) <https://github.com/OpenBankProject/OBP-API/wiki/OAuth-1.0-Server>
- [116] [CITE[OAuth 1.0a | Desk.com </developers>]] ([TIME[2015-02-26 08:21:13 +09:00]] 版) <http://dev.desk.com/guides/oauth/>
- [118] [CITE[AWeber Email Marketing API - API Reference - OAuth Authentication]] ([TIME[2015-03-06 08:57:06 +09:00]] 版) <https://labs.aweber.com/docs/authentication>
- [119] [CITE@en[Authenticating with the Meetup API - Meetup]] ([TIME[2015-03-06 09:01:47 +09:00]] 版) <http://www.meetup.com/meetup_api/auth/>
- [121] [CITE[Documentation – Rdio Developers]] ([TIME[2015-03-06 09:04:10 +09:00]] 版) <http://webcache.googleusercontent.com/search?q=cache:ivQuDlKnn1wJ:www.rdio.com/developers/docs/web-service/oauth/>
- [122] [CITE@en[Dropbox - Core API - endpoint reference]] ([TIME[2015-03-06 09:07:10 +09:00]] 版) <https://www.dropbox.com/developers/core/docs>
- [124] [CITE@ja[API | Tumblr]] ([TIME[2015-03-06 09:27:33 +09:00]] 版) <https://www.tumblr.com/docs/en/api/v2>
- [125] [CITE@en[認証 - Evernote Developers]] ([TIME[2015-03-06 09:30:38 +09:00]] 版) <https://dev.evernote.com/intl/jp/doc/articles/authentication.php>
- [126] [CITE@en[Technical details of UserVoice API - UserVoice Developer]] ([[UserVoice]] 著, [TIME[2015-01-24 06:02:32 +09:00]] 版) <https://developer.uservoice.com/docs/api/technical-details/>
- [127] [CITE@en[Authentication | XING Developer]] ([TIME[2015-03-06 10:00:00 +09:00]] 版) <https://dev.xing.com/docs/authentication>
- [129] [CITE@en[AUTHORIZATION Header · Medisana/vitadock-api Wiki]] ([TIME[2015-03-13 09:35:09 +09:00]] 版) <https://github.com/Medisana/vitadock-api/wiki/AUTHORIZATION-Header>
- [130] [CITE@en[Opera: Opera Link API Beta]] ([[Frank M. Palinkas, Technical Writer]] 著, [TIME[2015-03-14 20:58:39 +09:00]] 版) <http://www.opera.com/docs/apis/linkrest/#auth>
- [146] [CITE@en[Authentication — Marketplace API 2.0 documentation]] ([TIME[2015-06-24 10:24:58 +09:00]] 版) <http://firefox-marketplace-api.readthedocs.org/en/latest/topics/authentication.html>
- [171] [CITE@en[Upwork API Reference]] ([TIME[2017-03-13 18:51:45 +09:00]]) <https://developers.upwork.com/?lang=python>
]REFS]

* OAuth 2.0 鯖

[64] [[OAuth 2.0]] では[[鯖]]は[[資源鯖]]と[[認可鯖]]に分けられています。

;; それぞれの項を参照。

[66] [[資源鯖]]と[[認可鯖]]の相互作用は [[OAuth]] 仕様の範囲外とされています。
[[資源鯖]]と[[認可鯖]]は同じ[[鯖]]であっても構いません。
一つの[[認可鯖]]に複数の[[資源鯖]]が対応していても構いません。 [SRC[>>65]]

[71] [[サービス提供者]]は、[[フィッシング]]の防止のために[[資源所有者]]を啓蒙したり、
正しい [[Webサイト]]であると簡単に確認できる方法を用意したりするべきです [SRC[>>70]]。

[REFS[
- [72] [CITE@ja[Using OAuth 2.0 to Access Google APIs - Google Accounts Authentication and Authorization — Google Developers]] ([TIME[2014-11-22 05:37:53 +09:00]] 版) <https://developers.google.com/accounts/docs/OAuth2>
- [73] [CITE@ja[Using OAuth 2.0 for Login (early version) - Google Accounts Authentication and Authorization — Google Developers]] ([TIME[2014-10-24 09:43:45 +09:00]] 版) <https://developers.google.com/accounts/docs/OAuth2LoginV1>
- [99] [CITE@en[OAuth | GitHub API]] ([TIME[2015-03-05 18:02:01 +09:00]] 版) <https://developer.github.com/v3/oauth/>
- [75] [CITE@en[OAuth 2.0 in Azure AD]] ([TIME[2015-03-05 10:30:09 +09:00]] 版) <https://msdn.microsoft.com/en-us/library/azure/dn645545.aspx>
- [76] [CITE@en[Errors from Secured Resources]] ([TIME[2015-03-05 10:50:36 +09:00]] 版) <https://msdn.microsoft.com/en-us/library/azure/dn645539.aspx>
- [83] [CITE@ja[Yahoo! ID連携:Yahoo! ID連携 - Yahoo!デベロッパーネットワーク]] ([TIME[2015-03-05 15:54:27 +09:00]] 版) <http://developer.yahoo.co.jp/yconnect/>
-- [85] [CITE@ja[Yahoo! ID連携:iOS/Androidへの導入(OSを選択する) - Yahoo!デベロッパーネットワーク]] ([TIME[2015-03-05 15:56:41 +09:00]] 版) <http://developer.yahoo.co.jp/yconnect/client_app/>
-- [84] [CITE@ja[Yahoo! ID連携:SDKを利用しない場合 - Yahoo!デベロッパーネットワーク]] ([TIME[2015-03-05 15:55:51 +09:00]] 版) <http://developer.yahoo.co.jp/yconnect/server_app/explicit/>
- [79] [CITE[1. OAuth認証 - ヤマレコ Web API]] ([TIME[2015-02-25 16:41:06 +09:00]] 版) <https://sites.google.com/site/apiforyamareco/api/oauth>
- [86] [CITE@en-US[Web API Authorization Guide - Spotify Developer]] ([TIME[2015-03-05 15:59:09 +09:00]] 版) <https://developer.spotify.com/web-api/authorization-guide/>
- [87] [CITE@en[OAuth | Slack]] ([[Slack]] 著, [TIME[2015-03-05 16:04:09 +09:00]] 版) <https://api.slack.com/docs/oauth>
- [90] [CITE@en[OAuth2 · reddit/reddit Wiki]] ([TIME[2015-03-05 16:27:05 +09:00]] 版) <https://github.com/reddit/reddit/wiki/OAuth2>
- [91] [CITE@ja[• Instagram Developer Documentation]] ([TIME[2015-03-05 16:42:50 +09:00]] 版) <https://instagram.com/developer/authentication/>
- [92] [CITE[Understanding Authentication]] ([TIME[2015-02-28 04:30:54 +09:00]] 版) <https://www.salesforce.com/us/developer/docs/api_rest/Content/intro_understanding_authentication.htm>
- [93] [CITE@en[SurveyMonkey - Guide OAuth]] ([TIME[2015-03-05 17:23:37 +09:00]] 版) <https://developer.surveymonkey.com/mashery/guide_oauth>
- [94] [CITE[Connecting]] ([TIME[2015-03-05 17:39:49 +09:00]] 版) <https://developer.foursquare.com/overview/auth>
- [95] [CITE@en-US[OAuth 2.0 Authentication | Viadeo API]] ([TIME[2015-03-05 17:50:17 +09:00]] 版) <http://dev.viadeo.com/documentation/authentication/oauth-authentication/>
- [96] [CITE@en[Authenticating with OAuth 2.0 | LinkedIn Developer Network]] ([TIME[2015-03-05 17:56:22 +09:00]] 版) <https://developer.linkedin.com/docs/oauth2>
- [98] [CITE@ja[Add Facebook Login to Your App]] ([TIME[2015-03-05 18:02:07 +09:00]] 版) <https://developers.facebook.com/docs/facebook-login/v2.2>
-- [97] [CITE@ja[Login Dialog]] ([TIME[2015-03-05 18:01:31 +09:00]] 版) <https://developers.facebook.com/docs/reference/dialogs/oauth>
- [101] [CITE@ja[ユーザ認可について << mixi Developer Center (ミクシィ デベロッパーセンター)]] ([TIME[2015-01-09 16:40:43 +09:00]] 版) <http://developer.mixi.co.jp/appli/ns/pc/api_auth/>
- [105] [CITE[RESTful API - Smartphone App - Mobage Developers Documentation Center]] ([TIME[2015-03-06 00:51:05 +09:00]] 版) <https://docs.mobage.com/display/JPSA/REST_API_Reference_JP>
- [106] [CITE[Bitly API Documentation]] ([TIME[2014-11-01 00:33:47 +09:00]] 版) <http://dev.bitly.com/authentication.html>
- [107] [CITE[docomo Developer support API 共通リファレンス 第 2.0.4 版]] ([TIME[2015-03-02 17:25:25 +09:00]] 版) <https://devsite-pro.s3.amazonaws.com/contents_file/API_common_reference_latest.pdf>
- [110] [CITE@en[OAuth | Heroku Dev Center]] ([TIME[2015-03-06 08:02:41 +09:00]] 版) <https://devcenter.heroku.com/articles/oauth>
- [111] [CITE[Login with Amazon
Developer Guide for Websites]] ([TIME[2015-01-20 08:36:09 +09:00]] 版) <https://images-na.ssl-images-amazon.com/images/G/01/lwa/dev/docs/website-developer-guide._TTH_.pdf>
- [117] [CITE[Yahoo OAuth 2.0 Guide - Yahoo Developer Network]] ([TIME[2015-03-06 08:50:28 +09:00]] 版) <https://developer.yahoo.com/oauth2/guide/>
- [120] [CITE@en[Authenticating with the Meetup API - Meetup]] ([TIME[2015-03-06 09:01:47 +09:00]] 版) <http://www.meetup.com/meetup_api/auth/>
- [123] [CITE@en[Dropbox - Core API - endpoint reference]] ([TIME[2015-03-06 09:07:10 +09:00]] 版) <https://www.dropbox.com/developers/core/docs>
- [128] [CITE@en[gitlabhq/oauth2.md at master · gitlabhq/gitlabhq]] ([TIME[2015-03-06 10:46:37 +09:00]] 版) <https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/oauth2.md>
- [135] [CITE[楽天ウェブサービス(RAKUTEN WEBSERVICE)]] ([TIME[2015-03-24 23:58:21 +09:00]] 版) <http://webservice.rakuten.co.jp/document/oauth>
- [136] [CITE[HTTP API - Reference - SoundCloud Developers]] ([TIME[2015-03-29 18:44:37 +09:00]] 版) <https://developers.soundcloud.com/docs/api/reference#connect>
- [137] [CITE@en[Authentication | feedly Cloud API]] ([TIME[2015-01-23 08:10:58 +09:00]] 版) <https://developer.feedly.com/v3/auth/>
]REFS]

* WebSocket サーバー

[142] [[TCP]] や [[TCP]] over [[TLS]] によって[[ポート]]を [[listen]] し、
[[WebSocketクライアント]]からの接続を待つものを [[WebSocketサーバー]]といいます。

[141] [[WebSocket]] の[[サーバー]]側の処理は、[[負荷分散器]]や[[逆プロキシ]]などで分担して行うこともあります。
その場合、[[TCP接続]]の終端を行う部分から[[要求]]を処理して[[応答]]するものまですべて含めて、
[DFN[[RUBYB[[[サーバー]]]@en[server]]]]といいます。 [SRC[>>140]]

[143] [[WebSocketサーバー]]は、次のような処理を実装する必要があります。

[FIG(list short)[
- [[WebSocket handshake]]
- [[WebSocketメッセージ受信]]
- [[WebSocketメッセージ送信]]
- [[[CODE[Ping]]フレーム]]送信
- [[[CODE[Pong]]フレーム]]送信
- [[WebSocket closing handshake]]
]FIG]

* 歴史

[FIG(quote)[
[FIGCAPTION[
[1] [[HTTP]] ([[RFC1945]] 1.2, [[RFC2068]] 1.3, [[RFC2616]] 1.3)
]FIGCAPTION]

>
:server: An application program that accepts connections in order to
service requests by sending back responses. Any given program may be capable of being both a client and a server; our use of these terms refers only to the role being performed by the program for a particular connection, rather than to the program's capabilities in general.  Likewise, any server may act as an origin server, proxy, gateway, or tunnel, switching behavior based on the nature of each request.
>
:サーバー: [[応答]]を送り返すことで[[要求]]を service するために[[接続]]を受け入れる応用プログラム。
任意のプログラムが[[クライアント]]と[[サーバー]]のどちらにもなることができます。これらの用語を使用するときには、一般的なそのプログラムの能力ではなく、特定の接続についてのプログラムの施す役割にのみ言及します。同様に、サーバーは各要求の性質による動作の切り替えで[[起源サーバー]]、[[串]]、[[関門]]あるいは[[トンネル]]として動作するかもしれません。
]FIG]

[REFS[
- [30] [CITE@en[RFC 3229 - Delta encoding in HTTP]] ([TIME[2014-10-26 21:15:25 +09:00]] 版) <https://tools.ietf.org/html/rfc3229#section-4>
]REFS]

[FIG(quote)[
[FIGCAPTION[
[38] RFC 3229 (差分符号化) 4 The HTTP message-generation sequence
]FIGCAPTION]

> HTTP/1.1 supports a number of different transformations on the body of a value:

[[HTTP/1.1]] は値の本体についての数々の異なる変形に対応しています。

>
:Content-coding:
According to the specification, "Content coding
values indicate an encoding transformation that has
been or can be applied to an entity.  Content codings
are primarily used to allow a document to be
compressed or otherwise usefully transformed without
losing the identity of its underlying media type and
without loss of information.  Frequently, the entity
is stored in coded form, transmitted directly, and
only decoded by the recipient."  Content-codings are
normally end-to-end transformations; i.e., once
applied at the sender, they are not removed except at
the ultimate recipient.  An intermediate server may
apply a content-coding, in appropriate circumstances.

:内容符号化:仕様書によれば、「内容符号化値は[[実体]]に適用されている、またはすることのできる符号化変形を示します。内容符号化は主として中の[[媒体型]]の同一性を失ったり情報を損失したりすることなしに、文書を圧縮したり、その他有用に変形することを認めるために使用します。よく、実体は符号化形で蓄積され、直接転送され、[[受信者]]によってのみ復号されます」。
内容符号化は通常[[末端対末端]]変形です。すなわち、ひとたび[[送信者]]のところで適用したら、最後の受信者以外では取り除きません。中間[[鯖]]は適切な場面においては内容符号化を適用しても構いません。

>
:Transfer-coding:
According to the specification, "Transfer coding
values are used to indicate an encoding
transformation that has been, can be, or may need to
be applied to an entity-body in order to ensure "safe
transport" through the network.  This differs from a
content coding in that the transfer coding is a
property of the message, not of the original entity."
Transfer-codings are explicitly hop-by-hop
transformations (although, as an optimization, an
intermediate proxy may store the transfer-coded
version of a message if this behavior is not
inconsistent with its externally visible function.)

:転送符号化:仕様書によれば、「転送符号化値はネットワークを通じた『安全な転送』を確保するために  [CODE(ABNF)[[[entity-body]]]] に適用されている、または適用することのできる、または適用する必要があるかもしれない符号化変形を示すために使用します。これは内容符号化とは異なり、転送符号化はメッセージの特性であってもとの[[実体]]の特性ではありません」。
転送符号化は陽に[[ホップ毎]]変形です (が、最適化として、中間[[串]]はその振る舞いが外部から可視の関数と不整合でなければ、メッセージの転送符号化版を蓄積しても構いません)。

>
:Ranges:
An HTTP client, using the Range header, may request
that the server return one or more subranges of the
instance, rather than the entire instance value.
HTTP/1.1 only supports byte-ranges, although there is
some possibility that future extensions will allow
for other kinds of range-specifiers (such as chapters of a document).

:範囲:HTTP [[クライアント]]は、 [CODE(HTTP)[[[Range]]]]
頭を使用して、[[鯖]]に実現値の全体ではなく、実現値の部分範囲を一つ以上返すように要求することができます。
HTTP/1.1 は[[バイト]]範囲のみに対応していますが、
将来の拡張が他の種類の範囲指定子を (この文書の後の章のように)
認める余地があります。

> A client signals its willingness to receive a content-coding by
sending an "Accept-Encoding" header, listing the set of content-codings that it understands.  It may optionally include information
about which content-codings it prefers.  If a server uses any non-identity content-coding(s), it includes a "Content-Encoding" header
field in the response, listing these content-codings in their order of application.

クライアントは内容符号化を受信する意志を [CODE(HTTP)[[[Accept-Encoding]]]]
頭に自分の理解する内容符号化の集合を列挙することによって通知します。
クライアントは任意でどの内容符号化を好むかについての情報を含めることもできます。[[鯖]]が非[[同一]]内容符号化(群)を使用する場合は、応答で
[CODE(HTTP)[[[Content-Encoding]]]] 頭欄を使用して、
内容符号化を適用した順に列挙します。

> RFC 2068 [9] did not include an analogous mechanism for negotiating
the use of transfer-codings, although it does include an analogous
"Transfer-Encoding" header for marking the response.  A new "TE"
header has since been added to HTTP/1.1 [10], analogous to the
"Accept-Encoding" header.

[[RFC 2068]] は同様に転送符号化の使用について応答に印をつける [CODE(HTTP)[[[Transfer-Encoding]]]]
頭を含んでいましたが、折衝のための相当する仕組みは含んでいませんでした。
その後 [CODE(HTTP)[Accept-Encoding]] 頭欄に相当する新しい [CODE(HTTP)[[[TE]]]]
頭が HTTP/1.1 に追加されています。

> In this document, we add new, optional message headers to support the
use of instance manipulations.  A client signals its willingness to
receive an instance-manipulation by sending an "A-IM" header (short
for "Accept-Instance-Manipulation", which is far too long to spell
out), analogous to the "Accept-Encoding" header.  Similarly, a server
lists the set of instance-manipulations it has applied using an "IM" header.

この文書では、[[実現値操作]]の使用に対応するための新しい任意のメッセージ頭を追加します。
クライアントは、実現値操作を受信する意志を
[CODE(HTTP)[[[A-IM]]]] 頭 ([CODE[Accept-Instance-Manipulation]] では綴るのが長すぎるので、その省略)
を送信することによって通知できます。同様に、[[鯖]]は
[CODE(HTTP)[[[IM]]]] 頭を使用して適用している実現値操作の集合を列挙します。

> One must understand the relationship between these transformations in
order to see how delta encoding applies to HTTP responses.

差分符号化が HTTP 応答にどう適用されるのかを見るためにはこれらの変形の関係を理解しなければなりません。

> Conceptually, the various transformations are applied in the
following sequence:

概念的には、種々の変形は次の順序で適用します。

>
= 1. Upon receiving a GET request, the server uses the URI in the
request to identify the requested resource.
= 2. Optionally, it uses information from the request (and perhaps
additional information) to select a variant of that resource.
= 3. At this point, the server may apply a non-identity content-coding to the instance, or one might have been inherent in its
generation.  This also results in a Content-Encoding header.
= 4. The result of the first three steps, at the time when the
request is processed, is an instance.  The instance includes a
body (possibly empty) and possibly some instance headers.  The
entity tag, if any, is assigned at this point.  That is, an
entity tag is associated with an instance, NOT an entity.
= 5. The server may then apply an instance-manipulation.  For
example, if the request included a Range header, the server may
optionally produce a range response, consisting of the original
set of headers, a Content-Range header, and the appropriate
range(s) from the (possibly encoded) body.  Delta encodings are
instance-manipulations, and are computed at this stage.
= 6. The result of the fifth step becomes the entity, consisting of
entity headers and an entity body.
= 7. The server may then apply a non-identity transfer-coding; on-the-fly compression could be done in this step.  If so, a
Transfer-Encoding header is added to the message.
= 8. The results of the seventh step is the message, consisting of a
message body (the transfer-coded version of the entity body),
the entity headers, and additional response and general headers.

= [CODE(HTTP)[[[GET]]]] 要求の受信に際して、[[鯖]]は要求された[[資源]]の識別のために[[要求]]中の [[URI]] を使用する。
= 任意で、要求からの情報 (とおそらく追加情報) をその資源の[[変体]]の選択のために使用する。
= この時点で、鯖は非[[同一]]内容符号化を[[実現値]]に適用してもよいし、そもそも生成の時から適用されているかもしれない。これは [CODE(HTTP)[[[Content-Encoding]]]] 頭欄に反映する。
= 要求が処理される時点で、最初の三段階の結果は[[実現値]]である。
実現値は本体 (空のこともある。) と場合によってはいくつかの実現値頭を含む。
[[実体札]]は、あれば、この時点で割り当てる。つまり、
実体札は実現値に関連付けられるのであり、[[実体]]に関連付けられるのでは'''ない'''。
= 鯖はそれから[[実現値操作]]を適用してもよい。
例えば、要求が [CODE(HTTP)[[[Range]]]] 頭を含むなら、
鯖は任意選択でもとの頭の集合と [CODE(HTTP)[[[Content-Range]]]]
頭と (符号化されているかもしれない) 本体からの適切な範囲(群)を含んだ範囲応答を生産してもよい。[[差分符号化]]は実現値操作であり、この段階で計算する。
= 五番目の段階の結果は実体となり、実体頭と[[実体本体]]を含む。
= 鯖はそれから非同一転送符号化を適用してもよい。
その場での圧縮はこの段階で行うことができる。その場合、
[CODE(HTTP)[[[Transfer-Encoding]]]] 頭がメッセージに加えられる。
= 七番目の段階の結果はメッセージであり、[[メッセージ本体]]
(実体本体の転送符号化版) と実体頭と追加の応答頭および一般頭を含む。

> Note: Section 14.13 of the HTTP/1.1 specification [10] says "The
Content-Length entity-header field indicates the size of the
entity-body."  In other words, Content-Length measures the length
of an entity, not of an instance or of a variant.  For example, if
the message is a delta encoding, Content-Length gives the length
of the delta encoding, not the length of the current instance.

注意: HTTP/1.1 仕様書の 14.13 節は「[CODE(HTTP)[[[Content-Length]]]]
[[実体頭欄]]は [CODE(ABNF)[[[entity-body]]]] の寸法を示します」
と述べています。言い換えれば、 [CODE(HTTP)[Content-Length]]
は[[実現値]]や[[変体]]の長さではなく、[[実体]]の長さを測ります。
例えば、メッセージが[[差分符号化]]されているなら、
[CODE(HTTP)[Content-Length]] は現在実現値の長さではなく、
差分符号化の長さを与えます。

> Diagrammatically, the sequence is:

図にすると次のようになります。

>
[PRE[
       datatype        operation leading to next datatype
       ========        ==================================
       resource
                   |   choose acceptable variant, if needed
                   v
       variant
                   |   apply content-coding, if any
                   v
                   |   compute/assign entity tag
                   v
       instance
                   |   apply instance manipulation, if any
                   v      (delta encoding, range selection, etc.)
       entity-body
                   |   apply transfer-coding, if any
                   v
       message-body
]PRE]

[PRE[
       データ型        次のデータ型への演算
       ========        ==================================
       資源
                   |   必要なら、受入れ可能変体を選択
                   v
       変体
                   |   あれば、内容符号化を適用
                   v
                   |   実体札を計算・割当て
                   v
       実現値
                   |   あれば、実現値操作を適用
                   v      (差分符号化、範囲選択、その他)
       実体本体
                   |   あれば、転送符号化を適用
                   v
       メッセージ本体
]PRE]

> This formalization of the HTTP message generation sequence has not
previously been described.  However, it is clear that Range selection
needs to be done after the entity tag has been assigned and after any
content-coding has been applied, and before any transfer-coding is
applied.  Therefore, this formalization is fully consistent with
previous practice and specification.

この HTTP メッセージ生成列はこれまで記述されていませんでした。
しかし、 [CODE(HTTP)[Range]] 選択を実体札を割当てた後で内容符号化を適用した後で転送符号化は適用する前に行う必要があることは明らかです。
従って、この公式かは完全に従来の慣習および仕様と整合します。

* 4.1 Relationship between deltas and ranges

> If both Ranges and delta encodings are forms of instance
manipulation, which should be applied first?  This depends on how the
Range is being used.

[CODE(HTTP)[[[Range]]]] と差分符号化の両方が実現値操作を形成する時は、
どちらを先に適用するべきでしょうか。
これはどう [CODE(HTTP)[Range]] を使用するのかによります。

> Ranges are used for two main purposes, at the discretion of the
requesting client:

[CODE(HTTP)[Range]] は要求する[[クライアント]]の裁量により、
二つの目的で使用されます。

>
- 1. to complete a partial response after a premature termination of
a message transmission.
- 2. to obtain just selected sections of an instance.

- メッセージ転送の早すぎる終端の後に部分応答を完了するため
- [[実現値]]の選択した節をただ得るため

> In the first use of Range, it would have to be applied after any
delta encoding, since the intended use is to recover an intact copy
of the delta-encoded instance.  In the second use of Range, it would
have to be applied before any delta encoding, because otherwise the
offsets specified in the Range request would be meaningless (the
client generally cannot know how a server's delta encoding maps
instance byte offsets to entity byte offsets).

最初の [CODE(HTTP)[Range]] の用法では、
意図した使用法が差分符号化実現値の完全な複製の回復のためですから、
差分符号化の後に適用しなければならないでしょう。
二番目の [CODE(HTTP)[Range]] の用法では、
差分符号化の前に適用しなければ [CODE(HTTP)[Range]]
要求での位置指定は意味が無い物となるでしょう
(クライアントは通常鯖の差分符号化が実現値のバイト位置を実体のバイト位置にどう写像するかを知ることができません)。

> Therefore, we need a mechanism to allow the client to specify the
order in which two or more instance-manipulations should be applied.
This is easily provided as part of the specification of the "A-IM"
header (see section 10.5.3), where we require that the server apply
instance-manipulations in the order that they are listed in the "A-IM" header.  We also include a "range" literal in the set of
registered instance-manipulations, to allow the client to specify (by
its ordering with respect to other instance-manipulations) whether
range selection is done before or after delta encoding.

従って、クライアントが二つ以上の実現値操作をどの順番で適用するかを指定するための仕組みが必要です。
これは [CODE(HTTP)[[[A-IM]]]] 頭の指定の位置部として簡単に提供します。
鯖は実現値操作を [CODE(HTTP)[A-IM]] 頭に列挙された順序で適用する必要があります。また、実現値操作の登録集合に [CODE(HTTP)[[[range]]]]
表記も含めることで、クライアントが (他の実現値操作との順序により)
差分符号化の前後いずれに範囲選択を行うのかを指定することができます。

> We also need a mechanism for the server to indicate in which order
two or more instance-manipulations have been applied; this is part of
the specification of the "IM" header (see section 10.5.2), where we
follow the same practice used for the "Content-Encoding" header:  the
"IM" header lists the instance-manipulations in the order that were
applied (including, perhaps, the special "range" literal).

また、鯖がどの順序で二つ以上の実現値操作を適用しているのかを示す仕組みも必要です。これは [CODE(HTTP)[[[IM]]]] 頭の指定の一部とし、
[CODE(HTTP)[[[Content-Encoding]]]] 頭で使用しているのと同じ方法を使います。
[CODE(HTTP)[IM]] 頭は実現値操作を適用した順に
(おそらく特別な [CODE(HTTP)[range]] 表記も含めて) 列挙します。

> A similar issue arises when Ranges are combined with compression.  If
the client is using a Range to complete a partial response after a
premature termination of a compressed message, then the Range would
have to be applied after the compression.  This is feasible in
unmodified HTTP/1.1, because the compression can be done as a
content-coding.  However, if the client is using a Range to obtain
selected sections of an instance, it would normally be able to
specify offsets only in terms of the uncompressed variant.  If the
selected portion was large enough to warrant compression, the client
could request a compressed transfer-coding, but this is a hop-by-hop
transformation and is not the most efficient approach (especially if
an HTTP/1.0 proxy is in the path).

同様の問題が [CODE(HTTP)[Range]] を圧縮と組み合わせる時にも起こります。
クライアントが圧縮メッセージの早すぎる終端の後に部分応答を完了するために
[CODE(HTTP)[Range]] を使用するとき、 [CODE(HTTP)[Range]]
は圧縮の後に適用しなければなりません。これは、
圧縮が内容符号化として行われるのですから無修正の HTTP/1.1
で可能です。しかし、クライアントが実現値の選択した節を得るために
[CODE(HTTP)[Range]] を使用するなら、通常は非圧縮変体においてのみ位置を指定することができます。選択された部分が圧縮する根拠として十分な大きさなら、
クライアントは圧縮転送符号化を要求することができるのですが、
これはホップ毎転送であり、 (特に経路上に HTTP/1.0 串があると)
もっとも効率的なほうほうではありません。

> We can resolve this issue by supporting the use of compression as an
instance-manipulation (as well as as a content-coding or transfer-coding), and by using the new mechanism that allows the client to
specify that the compression instance-manipulation is done after the
Range instance-manipulation.

この問題は、 (内容符号化としてや転送符号化としてと同様に)
実現値操作として圧縮を使用することに対応し、
クライアントが [CODE(HTTP)[Range]] 実現値操作を行った後に圧縮実現値操作を行うように指定できるようにする新しい機構を用いることで解決できます。

> This also allows the client to control whether compression is done
before or after delta encoding, since some simple differencing
algorithms (such as the UNIX "diff" command) require post-compression
of their output to yield the best results.

これは、 ([[UNIX]] [KBD[[[diff]]]] 命令のような) 単純差異算法は最善の結果を得るために出力を後から圧縮することが必要ですので、
クライアントが差分符号化の前後いずれで圧縮を行うのかを制御することも認めます。
]FIG]

* 関連

[15] 多くの場合、[[鯖]]は[[起源鯖]]として機能します。

[16] [[鯖]]に対して、[[要求]]を送信するものを[[クライアント]]といいます。

[18] [[鯖]]は、[[要求]]に関しては[[受信者]]、[[応答]]に関しては[[送信者]]となります。

[189] 
[[無料のWebサーバー]]

* メモ

[144] [CITE@ja[2015年Webサーバアーキテクチャ序論 - ゆううきブログ]]
([[y_uuki]] 著, [TIME[2015-05-28 16:29:29 +09:00]] 版)
<http://yuuki.hatenablog.com/entry/2015-webserver-architecture>

[160] [CITE@en[net/http: add built-in graceful shutdown support to Server · Issue #4674 · golang/go]]
([TIME[2016-10-22 23:31:38 +09:00]])
<https://github.com/golang/go/issues/4674>

[FIG(quote)[
[FIGCAPTION[
[43] [CITE@en[Web Annotation Protocol]]
([TIME[2017-02-24 02:14:26 +09:00]])
<https://w3c.github.io/web-annotation/protocol/wd/#dfn-resource>
]FIGCAPTION]

> Web Server
> A program that accepts connections in order to service HTTP requests by sending HTTP responses.

]FIG]

[172] サーバーによって (エンドポイントによって) は処理に時間がかかって応答の末尾まで返し終わるのに非常に時間がかかることがあります。
クライアントは十分長い時間待つ必要がありますが、短いタイムアウトを設定していて変更不能なものもあります。