[103] [[HTTP]] の[DFN[[RUBYB[[[代替サービス]]]@en[alternative service]]]]は、 [[QUIC]] への切り替えなどに用いられています。

* 仕様書

[REFS[
- [10] [CITE@en[RFC 7838 - HTTP Alternative Services]] ([TIME[2016-04-17 23:25:39 +09:00]] 版) <https://tools.ietf.org/html/rfc7838>
-- [61] [CITE@en[RFC 7838 - HTTP Alternative Services]] ([TIME[2016-04-17 23:25:39 +09:00]] 版) <https://tools.ietf.org/html/rfc7838#section-3>
-- [86] [CITE@en[RFC 7838 - HTTP Alternative Services]] ([TIME[2016-04-17 23:25:39 +09:00]] 版) <https://tools.ietf.org/html/rfc7838#section-4>
-- [109] [CITE@en[RFC 7838 - HTTP Alternative Services]] ([TIME[2016-04-17 23:25:39 +09:00]] 版) <https://tools.ietf.org/html/rfc7838#section-9.4>
- [95] [CITE@en[RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)]] ([TIME[2016-04-13 23:55:13 +09:00]] 版) <https://tools.ietf.org/html/rfc7540#section-4.1>
- [107] [CITE[Hypertext Transfer Protocol (HTTP) Alt-Svc Parameter Registry]] ([TIME[2016-04-09 05:02:19 +09:00]] 版) <https://www.iana.org/assignments/http-alt-svc-parameters/http-alt-svc-parameters.xhtml>
- [118] [CITE@en[RFC 8164 - Opportunistic Security for HTTP/2]] ([TIME[2017-05-11 15:47:35 +09:00]]) <https://tools.ietf.org/html/rfc8164#section-4.3>
- [132] [CITE@en[RFC 8164 - Opportunistic Security for HTTP/2]] ([TIME[2017-05-11 15:47:35 +09:00]]) <https://tools.ietf.org/html/rfc8164#section-4.5>
]REFS]

* 代替サービス

[27] 普通 [[HTTP]] の[[資源]]へのアクセスは [[URL]] で指定された[[起源サーバー]]に接続して行いますが、
それとは異なるアクセス方法を[[起源サーバー]]が提供したい場合があり、
それを[DFN[[RUBYB[代替サービス]@en[alternative service]]]]と言っています。
より正確には、ある[[起源]]の[[資源]]群に、
本来とは異なる[[プロトコル]]、[[ホスト]]、[[ポート]]の組み合わせでアクセスできるとき、
[[起源]]の[[代替サービス]]が利用可能であるといいます [SRC[>>10]]。

[EG[
[31] [[起源サーバー]]は、[[負荷]]が大きい時や、
[[クライアント]]により近い[[サーバー]]があるときに、
他の[[サーバー]]を使うよう[[クライアント]]に求めたいことがあります。 [SRC[>>10]]
]EG]

[EG[
[28] [[起源サーバー]]は、 [[HTTP/2]] など新しいプロトコルや、
[[TLS]] など[[セキュリティー]]を向上させたプロトコルを使ったアクセスを提供したいことがあります。
[SRC[>>10]]
]EG]

[EG[
[29] [[起源サーバー]]は、運用上、例えば [[SNI]] に対応しているかどうかなどで、
[[クライアント]]群を分類したいことがあるかもしれません。 [SRC[>>10]]
]EG]

[36] [[代替サービス]]は、 ([[ALPNプロトコル名]], [[RFC 3986]] [[ホスト]],
[[RFC 3986]] [[ポート]]) の組で表します。 [SRC[>>10]]

[30] [[代替サービス]]は[[起源]]全体に適用されるものですから、
一部の[[資源]]のみに適用することはできません [SRC[>>10]]。

** 発見

[58] [[サーバー]]は、次の方法を使って[[代替サービス]]を[[広告]]できます。
[FIG(middle list)[
- [CODE[Alt-Svc:]] [[HTTPヘッダー]]
- [CODE[ALTSVC]] [[フレーム][HTTP/2フレーム]]
]FIG]

[HISTORY[
[59] 元々 [CODE(HTTP)@en[Alternate-Protocol:]] [[ヘッダー]]が使われていましたが、
例によって [[IETF]] で[[標準化]]された際に改称・非互換変更され、
[CODE[Alt-Svc:]] となりました。
]HISTORY]

[111] [[クライアント]]は、[[サーバー]]からこれらを受信したら、
その情報を保持して[[代替サービス]]として使います。

[42] [[起源サーバー]]も[[代替サービス]]も、
[[代替サービス]]を更新したり、消去したり、
[[新鮮寿命]]を伸ばしたりできます。 [SRC[>>10]]

** 代替サービスキャッシュ

[45] [[クライアント]]は、[[キャッシュ]]に、[[起源]]ごとの[[代替サービス]]群を保持します。

[37] [[代替サービス]]は、次の状態を持ちます。
[FIG(list members)[
: [DFN[[F[[RUBYB[[[新鮮寿命]]]@en[freshness lifetime]]]]]] :
[[秒]]単位の[[時間]] [SRC[>>10]]。
: [F[[CODE[persist]]]] :
[[代替サービス]]が[[ネットワーク設定]]を超えて有効かどうかのフラグ。
]FIG]

[44] [[クライアント]]は、[[ネットワーク設定]]が変化した時、
[CODE[persist]] フラグの値が [CODE[1]] であるものを除き、
[[代替サービス]]の情報を[[キャッシュ]]から削除する[SHOULD[べきです]]。
これは、[[代替サービス]]によって[[クライアント]]を最適なサーバーに向けていた場合に、
[[ネットワーク設定]]の変化で最適性が変化する可能性があるからです。 [SRC[>>10]]

[105] [[クライアント]]は、[[代替サービス]]から
[CODE(HTTP)[421]] [[応答]]を受信したら、
当該[[代替サービス]]の情報を[[キャッシュ]]から削除しなければ[MUST[なりません]] [SRC[>>10]]。

[110] [[起源]]ごとに[[クライアント]]が保持する情報を消去する際には、
[[代替サービス]]の[[キャッシュ]]も消去しなければ[MUST[なりません]] [SRC[>>109]]。

** 利用

[50] [[クライアント]]は、
[[代替サービス]]の情報が利用可能となったら、
それが[[新鮮]]であり、既存の[[接続][HTTP接続]]より[[セキュリティー]]的に好ましいものである限りにおいて、
当該[[起源]]のすべての[[要求]]で、その[[代替サービス]]を使う[SHOULD[べきです]]。
[[代替サービス]]を使う義務はありませんが、
[[サーバー]]の[[負荷分散]]などのために[[代替サービス]]を使っているかもしれませんから、
[[代替サービス]]を使った方が好ましいとされています。 [SRC[>>10]]

[46] しかし、[[代替サービス]]の利用は [[fingerprinting vector]] です [SRC[>>109]]。
悪意ある[[サーバー]]は、[[クライアント]]の識別のために[[代替サービス]]情報を提供するかもしれません。

[129] [[クライアント]]は、[[クッキーなどの削除の際][Clear Site Data]]に、
[[代替サービス]]の情報も消去しなければ[MUST[なりません]] [SRC[>>118]]。

;; [130] これは [[Opportunistic Security for HTTP/2]] 
の独自の規定ですが、本来[[代替サービス]]一般に適用するべきものと思われます。

[40] [[クライアント]]は、[[代替サービス]]が[[新鮮]]である間、
いつでも当該[[代替サービス]]を使うことができます。 [SRC[>>10]]

[51] [[クライアント]]は、複数の[[代替サービス]]がある場合、
自身の適切な方法でいずれかを選択できます。 [SRC[>>10]]

[52] [[プロキシ]]を使う設定の[[クライアント]]は、
[[代替サービス]]に直接接続するのではなく、
[[プロキシ]]経由で接続する[SHOULD[べきです]] [SRC[>>10]]。

[54] [[クライアント]]は、[[代替サービス]]を使うことにした場合でも、
[[代替サービス]]の[[接続][HTTP接続]]の確立を待たずに既存の[[接続][HTTP接続]]を使い続けても構いません。
しかし、[[セキュリティー]]上の理由から、[[代替サービス]]の[[接続][HTTP接続]]の確立を待った方が良いこともあります。
[SRC[>>10]]

;; [[Opportunistic HTTP/2 Security]] もこれを明示的に認めています。

[41] [[クライアント]]は、既にある[[接続][HTTP接続]]については、
[[新鮮寿命]]を過ぎてもそのまま使い続けることができます。 [SRC[>>10]]

[55] [[クライアント]]は、
[[代替サービス]]への[[接続][HTTP接続]]が失敗したり、応答しなくなったりした場合には、
[[起源サーバー]]や他の[[代替サービス]]への[[接続][HTTP接続]]にフォールバックして構いません。
[SRC[>>10]]

[56] ただし、これは [[downgrade attack]] かもしれないので注意が必要です。
特に[[代替サービス]]への接続でプロトコルの折衝に失敗した場合には、
[[代替サービス]]への接続の失敗とみなしては[MUST[なりません]]。 [SRC[>>10]]

[EG[
[57] 例えば [CODE[h2][HTTP/2]] を使おうとしたのに [[ALPN]] で [CODE[h2][HTTP/2]]
が選べなかった場合は、フォールバックしてはなりません。
]EG]

[32] [[代替サービス]]は[[URL]]や[[起源]]に影響せず、
接続先の決定とプロトコルの選択のみに関わるものです。 [[HTTPリダイレクト]]とは異なります。
特に、
[FIG(list)[
- [33] [[service identity]] の検証では、
元の [[URL]] の[F[ホスト]]を使わなければなりません。 [SRC[>>10]]
- [47] [[SNI]] では、元の [[URL]] の[F[ホスト]]を使わなければなりません。 [SRC[>>10]]
- [34] [[HTTP]] [CODE(HTTP)@en[Host:]] には、
元の [[URL]] の[F[ホスト]]や[F[ポート]]を使わなければなりません。
[SRC[>>10]]
]FIG]

;; [35] もちろん、[[開発者コンソール]]の類には実際に使った[[代替サービス]]の情報を表示できます
[SRC[>>10]]。

[EG[
[123] [[Opportunistic HTTP/2 Security]] により [CODE(URI)@en[http:]]
[[要求]]が [[HTTPS]] で送信される場合、 [CODE[:scheme]]
の値は [CODE[http][http:]] となります。
]EG]

[53] [[代替サービス]]への[[HTTP要求]]には、 [CODE[Alt-Used:]]
[[ヘッダー]]を含めることができます [SRC[>>10]]。

;; 必須ではないようです。

[43] [[代替サービス]]は当該[[起源]]について完全に [[authoritative]]
とみなされます [SRC[>>10]]。[[代替サービス]]に関する制御はもちろん、
[[キャッシュ]]その他あらゆる面で、[[起源サーバー]]と等価に扱われるようです。

;; この点、[[プロキシ]]や[[ミラーサーバー]]とは異なります。

[38] [[クライアント]]は、[[代替サービス]]が当該[[起源]]全体の制御下にあり、妥当であることの[DFN[[RUBYB[十分な保証]@en[reasonable assurances]]]]を有しなければ[MUST[なりません]]。
ここでいう「[[十分な保証]]」は、
[[HTTPSサーバー認証]]で確立できます。[[クライアント]]は更に他の要件を加えても構いません。
[SRC[>>10]]

[EG[
[39] [[起源]]の[F[ホスト]]が [CODE[www.example.com]] のとき、
[[代替サービス]]の[F[ホスト]]が [CODE[other.example.com]] で[F[プロトコル]]が
[CODE[h2][HTTP/2]] (= [[HTTP/2]] over [[TLS]]) なら、[[証明書]]が [CODE[www.example.com]]
で有効かどうかを検証することで、
十分な保証があるとみなすことができます。しかし[F[プロトコル]]が [CODE[h2c]]
(= [[HTTP/2]] over [[TCP]]) では、同様の検査ができないので、
十分な保証が得られないと判断せざるを得ません。 [SRC[>>10]]
]EG]

[EG[
[127] [[Opportunistic HTTP/2 Security]] は[[HTTPSサーバー認証]]を
「[[十分な保証]]」としていますが、その上で追加の検査も規定しています。
]EG]

[48] [[代替サービス]]の[F[プロトコル]]が [[TLS]] を使う場合、
[[クライアント]]が [[SNI]] に対応していなければ、
その[[代替サービス]]を使っては[MUST[なりません]] [SRC[>>10]]。

;; [49] なぜか [[SNI]] を使わなければ[MUST[ならない]]とはされていませんが、
普通に考えれば、[F[ホスト]]が[[ドメイン名]]の場合、使わなければならないはずです
(そうでなければ[[Web互換]]ではありません)。[F[ホスト]]が[[IPアドレス]]なら、
[[SNI]] は使えません。

* プロトコル

[104] 次のものが[[代替サービス]]で利用されています。
[FIG(short list)[
- [CODE(HTTP)@en[Alt-Svc:]]
-- [CODE(HTTP)@en[ma=""]]
-- [CODE(HTTP)@en[persist=""]]
- [CODE(HTTP)@en[ALTSVC]]
- [CODE(HTTP)@en[Alt-Used:]]
- [CODE(HTTP)[421]]
]FIG]

* [CODE(HTTP)@en[Alt-Svc:]] ヘッダー

** 意味

[60] [CODE(HTTP)@en[Alt-Svc:]] [[ヘッダー]]は、
[[代替サービス]]が利用可能であると[[クライアント]]に[[広告]]するものです [SRC[>>61]]。

** 構文

[63] [CODE(HTTP)@en[Alt-Svc:]] [[ヘッダー]]の値は、
[CODE[clear]] ([[小文字]]) または1つ[[以上]]の値の[[リスト][リスト (HTTP)]]です。
[SRC[>>61]]

[71] 複数の値がある場合、[[サーバー]]の[RUBYB[優先度]@en[preference]]を表しており、
最初の値が最も好ましいものです。 [SRC[>>61]]

[FIG(railroad)[
= |
== [CODE[clear]]
== =
=== 値
=== *
==== [[OWS]]
==== [CODE[,]]
==== [[OWS]]
==== 値
]FIG]

[64] 値は、[[ALPNプロトコル名]]、[CODE[=]]、[[ホスト]]および[[ポート]]の後に、
0個[[以上]]の[[引数][引数 (HTTP)]]を並べたものです。 [SRC[>>61]]

[FIG(railroad)[
= プロトコル名
= [CODE[=]]
= [[ホスト]]および[[ポート]]
= 引数群
]FIG]

[67] [[ALPNプロトコル名]]は、[[字句]]として表します。
[[字句]]で表せない[[オクテット]]および [CODE[%]] は、
[[RFC 3986]] [[パーセント符号化]]しなければ[MUST[なりません]]。
[[パーセント符号化]]には[[大文字]]を使わなければ[MUST[なりません]]。
それ以外は[[パーセント符号化]]しては[MUST[なりません]]。 [SRC[>>61]]

;; これは、単純な[[文字列]]としての[[比較]]を行うためです。 [SRC[>>61]]

;; [70] [[大文字]]と[[小文字]]は区別されます。

[65] [[ホスト]]および[[ポート]]は、[[引用文字列]]です。その値は、
[[RFC 3986]] [[ホスト]]、[CODE[:]]、[[RFC 3986]] [[ポート]]を並べたものですが、
[[ホスト]]は省略可能です。省略すると、[[起源]]の[F[ホスト]]を表します。 [SRC[>>61]]

[FIG(railroad)[
= ?
== [[ホスト]]
= [CODE[:]]
= [[ポート]]
]FIG]

;; [133] これは [[URL]] でよく見かける[[ホストとポート]]の構文とは省略できる部分が違っています。

[66] [[引数][引数 (HTTP)]]は、[[字句]]、[CODE[=]]、[[字句]]または[[引用文字列]]を並べたものです。
[[引数][引数 (HTTP)]]の前には区切りの [CODE[;]] が必要です。 [CODE[;]]
の前後には、 [[OWS]] を置けます。 [SRC[>>61]]

[FIG(railroad)[
= *
== [[OWS]]
== [CODE[;]]
== [[OWS]]
== [[字句]]
== [CODE[=]]
== |
=== [[字句]]
=== [[引用文字列]]
]FIG]

** 引数

[73] 
[FIG(short list)[
- [CODE(HTTP)@en[ma]]
- [CODE(HTTP)@en[persist]]
- [CODE(HTTP)@en[v][ALTSVC]]
]FIG]

[74] 未知の[[引数][引数 (HTTP)]]は、無視しなければ[MUST[なりません]] [SRC[>>61]]。

[75] [[引数名]]の[[大文字]]と[[小文字]]の区別の有無は不明です。

[76] 同名の[[引数][引数 (HTTP)]]が複数ある場合の扱いは不明です。

[77] [[引数][引数 (HTTP)]]の順序は意味を持たないと思われますが、明記されていません。

[108] [[IANA登録簿]]があります [SRC[>>107]]。
登録と[[適合性]]の関係は不明です。

** 文脈

[62] 任意の[[応答]]で使えます [SRC[>>61]]。
ただし [CODE(HTTP)[421]] [[応答]]では無視されます。

[72] [[HTTP/2]] でも使えますが、 [CODE[ALTSVC]] [[フレーム][HTTP/2フレーム]]を使う[SHOULD[べきです]]
[SRC[>>61]]。
なお本[[ヘッダー]]の値の部分は、 [CODE[ALTSVC]] [[フレーム][HTTP/2フレーム]]の[[Alt-Svc欄値]][[欄]]の値としても用いられます。

[131] [[サーバー]]全体に適用されるものですから、
[[利用者コンテンツ]]が設定できないようにする[SHOULD[べきです]] [SRC[>>132]]。

** [CODE[clear]]

[68] [CODE[clear]] は、[[代替サービス]]をすべて無効化することを表します。
[SRC[>>61]]

[69] 同じ[[応答]]に他の[[代替サービス]]が含まれる場合 (これは[[非妥当]]ですが、
あり得ます。)、それもまた無効化されます。 [SRC[>>61]]

** [CODE(HTTP)@en[ma]] 引数

[78] [CODE[Alt-Svc]] により記述された[[代替サービス]]の[F[新鮮寿命]]は、
[[メッセージ]]の[[生成]]から24時間です [SRC[>>61]]。
[CODE[ma]] [[引数]]の指定がある場合は、[[生成]]からその[[秒]]数です [SRC[>>61]]。

[79] [CODE(HTTP)@en[ma]] [[引数]]の値は、[[デルタ秒]]です [SRC[>>61]]。

;; [80] [[応答]]自体の[F[新鮮寿命]]とは関係しません。従って[[応答]]が[[腐敗]]したかどうかに関わらず、
[[代替サービス]]はその[F[新鮮寿命]]まで有効です。

** [CODE(HTTP)@en[persist]] 引数

[83] [CODE(HTTP)@en[persist]] [[引数]]の値 [CODE[1]] は、
[[ネットワーク設定]]が変更された後でも[[代替サービス]]が有効であろうとの[[ヒント]]を表します。
[SRC[>>61]]

[84] この指定がなければ、[[代替サービス]]は、
[[ネットワーク設定]]が変更された時に消去されるべきです。 [SRC[>>61]]

[85] 他の値は指定されても無視しなければ[MUST[なりません]] [SRC[>>61]]。

** [CODE(HTTP)@en[v][ALTSVC]] 引数

[113] [[Google]] は [[QUIC]] 対応に当たり [CODE(HTTP)@en[v][ALTSVC]]
[[引数]]を使っています。

** 処理

[106] [CODE(HTTP)[421]] [[応答]]では、無視しなければ[MUST[なりません]] [SRC[>>10]]。

[81] [CODE(HTTP)@en[Alt-Svc:]] [[ヘッダー]]を受信したら、
当該[[起源]]の既存のすべての[[代替サービス]]を無効化します [SRC[>>61]]。

;; [82] 明記されていませんが、同じ[[応答]]で複数の[[代替サービス]]が指定されていれば、
それらは同時に有効になると思われます。

* [CODE[ALTSVC]] フレーム (HTTP/2)

[87] [CODE[ALTSVC]] [[フレーム][HTTP/2フレーム]]は、
[[クライアント]]に[[代替サービス]]を[[広告]]するものです。

** 意味

[89] [[ストリーム識別子]]が [N[0]] ''以外''なら、
当該[[ストリーム]]の[[起源]]に関連付けられた[[代替サービス]]を表します [SRC[>>86]]。

[90] [[ストリーム識別子]]が [N[0]] なら、
[[起源]]欄の[[起源]]に関連付けられた[[代替サービス]]を表します [SRC[>>86]]。

** 構文

[92] [[フレーム型]]は、 [N[10]] ([N[0xA]]) です [SRC[>>86]]。

[94] [[フラグ]]はありません [SRC[>>86]]。 0 でなければ[MUST[なりません]] [SRC[>>95]]。
[[受信者]]は無視しなければ[MUST[なりません]] [SRC[>>95]]。

[FIG(packet)[
:width:8

= 1 0
= 1 0
= 1 0
= 1 0
= 1 0
= 1 0
= 1 0
= 1 0
]FIG]

[93] [[payload]] は、次の[[欄]]で構成されます。
[FIG(list members)[
: [DFN[[RUBYB[起源長]@en[Origin-Len]]]] :
[[起源][ALTSVC]]欄の長さを、[[オクテット]]数の[[符号無し16ビット整数]]で表したものです。 [SRC[>>86]]
: [DFN[[RUBYB[起源]@en[Origin]]]] :
[[代替サービス]]の適用対象の[[起源]]の[[ASCII直列化]]です。 [SRC[>>86]]
: [DFN[[RUBYB[Alt-Svc欄値]@en[Alt-Svc-Field-Value]]]] :
[CODE(HTTP)@en[Alt-Svc:]] [[ヘッダー]]の値相当の[[オクテット列]]です。
本欄の長さは、 [[payload]] のうち[[起源長]]と[[起源][ALTSVC]]を除外した長さです。 [SRC[>>86]]
]FIG]

[FIG(packet)[
:width:32

= 16 起源長
= 16... 起源
= 32... Alt-Svc欄値
]FIG]

** 文脈

[102] [[サーバー]]が[[クライアント]]に送ることができます。

[101] [CODE[ALTSVC]] と [CODE(HTTP)@en[Alt-Svc:]] の混用は、
結果が予測困難となるので、好ましくありません。 [SRC[>>86]]

** 処理

[88] [CODE[ALTSVC]] に対応しない[[エンドポイント][HTTP/2エンドポイント]]は、
無視します [SRC[>>86]]。

[96] [[サーバー]]は、受信しても無視しなければ[MUST[なりません]] [SRC[>>86]]。

[97] [[ストリーム識別子]]が [N[0]] で、
[[起源][ALTSVC]]が空なら、無視しなければ[MUST[なりません]] [SRC[>>86]]。

[98] [[ストリーム識別子]]が [N[0]] ''以外''で、
[[起源][ALTSVC]]が空でなければ、無視しなければ[MUST[なりません]] [SRC[>>86]]。

[91] [[クライアント]]は、示された[[起源]]が現在の[[接続][HTTP接続]]において
[[authoritative]] でないと判断するなら、
当該[[代替サービス]]を無視しなければ[MUST[なりません]] [SRC[>>86]]。

[125] [[起源][ALTSVC]]欄の値が正しい [[ASCII直列化]]でない場合にどう処理するべきなのかは明らかではありません。
[[authoritative]] でないと判断して無視するのが適切でしょうか。

[100] [CODE[ALTSVC]] の受信は、意味的には、
[CODE(HTTP)@en[Alt-Svc:]] [[ヘッダー]]の受信と等価です [SRC[>>86]]。

[99] [CODE[ALTSVC]] [[フレーム][HTTP/2フレーム]]は[[ホップ毎]]に処理されるものですから、
[[中間器]]は[[転送]]しては[MUST[なりません]]。
ただし、受信した [CODE[ALTSVC]] をもとに新たに [CODE[ALTSVC]]
を送信することは構いません。 [SRC[>>86]]

* 用法

** QUIC

[112] [[Chrome]] は、 [[QUIC]] 対応のために[[代替サービス]]を使っています。

[115] [[代替サービス]]として[[ALPNプロトコル名]] [CODE[quic]]
を指定することで、 [[QUIC]] を使うための接続先を指定できます。

;; [116] [[HTTP/1]] と [[SPDY]]/[[HTTP/2]] との使い分けはどちらも [[TLS]] over [[TCP]]
ベースなので [[TLS]] [[ALPN]] で可能でしたが、 [[QUIC]] は [[TCP]] すら使わないので、
一旦従来の [[HTTP/1]] または [[HTTP/2]] で接続してから、
利用可能であることを[[代替サービス]]として明示する必要があります。

;; [117] [[Google]] 以外が [[QUIC]] を実装するのかどうか、実装するとしたらいつになるのかは、
現時点では不透明です。

** 日和見暗号化

[128] [[Opportunistic HTTP/2 Security]] では、
本来[[素のHTTP]]を使う [CODE(URI)@en[http:]] [[URL]]
へのアクセスであっても、 [[HTTPS]] を使って接続できることを[[代替サービス]]として示すことができます。

[114] [[Firefox]] が実装しています。

;; [119] 本来の [[HTTPS]] ほど安全ではない中途半端な解法であるにも関わらず
[[HTTPS]] への移行を阻害するおそれがあるとしてあまり支持されていません。
[[Mozilla]] 以外は実装しないとみられています。

** プッシュサービス

[SEE[ [[プッシュサービス]] ]]

** その他

[120] [[RFC]] は任意の[[プロトコル]]の組み合わせで利用できると汎用的に規定しています。

[121] 特に、[[負荷分散]]など[[サーバー]]の判断で他の[[サーバー]]にアクセスさせたいときに使えることを主要な用途の1つに挙げています。
しかし、[[クライアント]]が対応しているかもしていないかもしれない本手法が既存の手法に対して特に優位といえる点があるかどうかは謎です。

[122] 理論上は [[HTTP/1]] から [[HTTP/2]] への切り替えなど他の手法が既に確立している場面でも本手法を利用できますが、
その必要はなさそうですし、実装が新たにそうした形で対応することもないかもしれません。

[124] いずれにせよ、 [[RFC]] は一般的な事項の規定しか含んでいませんから、
より詳細を定めた個別の[[仕様書]]が出版されない限り、
[[相互運用性]]に問題があり、実質的には使うことはできない状態です。

* 歴史

** [CODE(HTTP)@en[Alternate-Protocol:]] ヘッダー

[1] [CITE[SPDY Protocol - Draft 2 - The Chromium Projects]]
( ([TIME[2013-10-19 15:06:10 +09:00]] 版))
<http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft2#TOC-Server-Advertisement-of-SPDY-through-the-HTTP-Alternate-Protocol-header>

[2] [CITE[Re: Add QUIC to Alternate-Protocol support. (issue 12156005) - Google グループ]]
( ([TIME[2013-10-20 06:22:12 +09:00]] 版))
<https://groups.google.com/a/chromium.org/forum/#!topic/chromium-reviews/NhzeGXtLCOA>

[3] [CITE[Actually enable Alternate-Protocol support for QUIC. (issue 17410014) - Google グループ]]
( ([TIME[2013-10-20 06:22:43 +09:00]] 版))
<https://groups.google.com/a/chromium.org/forum/#!topic/chromium-reviews/y2RjueIsQbM>

[4] 
>
[PRE(HTTP code)[
HTTP/1.1 304 Not Modified
X-GData-User-Country: JP
Date: Sun, 20 Oct 2013 06:20:16 GMT
Server: GSE
Alternate-Protocol: 80:quic

]PRE]

[5] [CITE[SPDY Protocol - Draft 2 - The Chromium Projects]]
( ([TIME[2014-11-01 00:36:56 +09:00]] 版))
<http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft2#TOC-Server-Advertisement-of-SPDY-through-the-HTTP-Alternate-Protocol-header>

[6] 
[PRE(HTTP example code)[
Alternate-Protocol: 80:quic,p=0.01
]PRE]


[FIG(quote)[
[FIGCAPTION[
[7] [CITE[QUIC FAQ - The Chromium Projects]]
([TIME[2016-04-16 07:05:17 +09:00]] 版)
<https://www.chromium.org/quic/quic-faq>
]FIGCAPTION]

> How do I aim Chrome at the test server?
> If you have an HTTP server, you'll need it to emit a response header that looks like:
> Alternate-Protocol: quic:<QUIC server port>

]FIG]

[8] [CITE[Issue 1720163002: When Alt-Svc header processing is enabled, do not process Alternate-Protocol - Code Review]]
([TIME[2016-04-18 00:42:12 +09:00]] 版)
<https://codereview.chromium.org/1720163002/>

[9] [CITE@en[698362 – Decide what to do regarding Alternate-Protocol vs redirects]]
([TIME[2016-04-18 17:03:45 +09:00]] 版)
<https://bugzilla.mozilla.org/show_bug.cgi?id=698362>

** [CODE(HTTP)@en[Alt-Svc:]] ヘッダー

[16] [CITE@en[HTTP Alternative Services]]
( ([TIME[2014-07-24 13:19:57 +09:00]] 版))
<https://httpwg.github.io/http-extensions/alt-svc.html>

[17] [CITE@en[Certificate verification bypass through the HTTP/2 Alt-Svc header — Mozilla]]
([TIME[2015-04-04 05:00:27 +09:00]] 版)
<https://www.mozilla.org/en-US/security/advisories/mfsa2015-44/>

[18] [CITE[Bits Up!: Opportunistic Encryption For Firefox]]
([TIME[2015-04-06 16:35:05 +09:00]] 版)
<http://bitsup.blogspot.jp/2015/03/opportunistic-encryption-for-firefox.html>

[19] [CITE[Mozilla Dials Back on Firefox Opportunistic Encryption]]
([TIME[2015-06-18 11:58:10 +09:00]] 版)
<http://www.eweek.com/security/mozilla-dials-back-on-firefox-opportunistic-encryption.html>

[20] [CITE@en[Certificate verification bypass through the HTTP/2 Alt-Svc header — Mozilla]]
([TIME[2015-04-04 05:00:27 +09:00]] 版)
<https://www.mozilla.org/en-US/security/advisories/mfsa2015-44/>

[21] [CITE@en[draft-ietf-httpbis-alt-svc-07 - HTTP Alternative Services]]
([TIME[2015-05-21 10:26:13 +09:00]] 版)
<https://tools.ietf.org/html/draft-ietf-httpbis-alt-svc-07>

[22] [CITE@en[1003448 – http/2 alt-svc support]]
([TIME[2015-06-18 11:59:58 +09:00]] 版)
<https://bugzilla.mozilla.org/show_bug.cgi?id=1003448>

[23] [CITE@en[1113790 – pref change to true for network.http.altsvc.enabled and altsvc.oe]]
([TIME[2015-06-18 12:00:13 +09:00]] 版)
<https://bugzilla.mozilla.org/show_bug.cgi?id=1113790>

[24] [CITE@en[HTTP Alternative Services]]
([TIME[2015-05-30 15:33:33 +09:00]] 版)
<http://http2.github.io/http2-spec/alt-svc.html>

[25] [CITE[Issue 438263 - chromium - Update HTTP/2 AltSvc frame wire format - An open-source project to help move the web forward. - Google Project Hosting]]
([TIME[2015-06-18 12:04:09 +09:00]] 版)
<https://code.google.com/p/chromium/issues/detail?id=438263>

[11] [CITE[Issue 392575 - chromium - Implement the Alt-Svc spec - An open-source project to help move the web forward. - Google Project Hosting]]
([TIME[2015-06-18 12:04:58 +09:00]] 版)
<https://code.google.com/p/chromium/issues/detail?id=392575>

[12] [CITE@en[Issue 585876 - chromium - QUIC connections to "remote" Alt-Svcs should use the origin hostname in the SNI field - Monorail]]
([TIME[2016-04-18 00:10:27 +09:00]] 版)
<https://bugs.chromium.org/p/chromium/issues/detail?id=585876>

[13] [CITE[Issue 1720163002: When Alt-Svc header processing is enabled, do not process Alternate-Protocol - Code Review]]
([TIME[2016-04-18 00:42:21 +09:00]] 版)
<https://codereview.chromium.org/1720163002/>

[FIG(quote)[
[FIGCAPTION[
[14] [CITE@ja[YouTube]]
([TIME[2016-04-18 00:49:55 +09:00]] 版)
<https://www.youtube.com/>
]FIGCAPTION]

> alt-svc:quic=":443"; ma=2592000; v="32,31,30,29,28,27,26,25"
> alternate-protocol:443:quic

]FIG]


[FIG(quote)[
[FIGCAPTION[
[15] [CITE@ja[Google]]
([TIME[2016-04-18 00:50:55 +09:00]] 版)
<https://www.google.co.jp/>
]FIGCAPTION]

> alt-svc:quic=":443"; ma=2592000; v="32,31,30,29,28,27,26,25"
> alternate-protocol:443:quic

]FIG]

[26] [CITE@en[Implement ALT-SVC · Issue #535 · nghttp2/nghttp2]]
([TIME[2016-04-18 17:19:51 +09:00]] 版)
<https://github.com/nghttp2/nghttp2/issues/535>

[126] [CITE@en-US[mozilla-central: changeset 313435:7078c20114e2]]
([TIME[2017-05-11 15:56:57 +09:00]])
<https://hg.mozilla.org/mozilla-central/rev/7078c20114e2>

[134] [[YouTube]] [TIME[2020-03-25T01:38:39.700Z]]

[PRE(HTTP code)[
Alt-Svc: quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,h3-T050=":443"; ma=2592000
]PRE]


[135] [CITE@en[draft-bishop-httpbis-sni-altsvc-02 - The "SNI" Alt-Svc Parameter]]
([TIME[2020-11-08T14:13:40.000Z]], [TIME[2020-11-18T10:00:07.075Z]])
<https://tools.ietf.org/html/draft-bishop-httpbis-sni-altsvc-02>

[136] [[Google]] [TIME[2020-11-30T03:05:54.200Z]]

>
[PRE(HTTP code)[
Alt-Svc: h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
]PRE]

[138] [[Google]] [TIME[2021-04-30T02:25:31.900Z]]

>
[PRE(HTTP code)[
Alt-Svc: h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
]PRE]


[137] [CITE@en[HTTP/2 | 2020 | The Web Almanac by HTTP Archive]]
([TIME[2021-04-24T09:26:30.000Z]])
<https://almanac.httparchive.org/en/2020/http2#alternative-services>