HTML要素からHTTP/2優先度を指定する Priority Hints

HTTP/2ではリクエストは並列的に行われますが、クライアントは各リクエストに優先度を設定できます。サーバはこの優先度によって、レスポンスの順番(正確にはレスポンスを返すのに使用するリソース)を、制御しています。

この優先度の設定はブラウザが自動で行っており、Webエンジニアは意識する必要はありません。例えばレンダリングを開始するのに必要なCSSなどは優先度が高く、画像などは優先度が低く設定されるのが一般的です。

しかし、Webエンジニアが明示的にHTML要素にどの優先度でリクエストするか指示したい場合でも現状は出来ません。例えば、ユーザの閲覧目的が特定の画像である場合や、特定のJavaScriptがコンテンツに重要ということもあるかもしれません。

同様にFetch APIにも同じことが言えるかと思います。

そこで、それらを可能にするためにW3CのWICGで「Priority Hints」という、仕組みの議論がされています。

まだCommunity Groupでの議論であり、仕組みが有用か?スコープは?仕組みはどのようにスべきか?などである。たたき台として、例は出てきているが、まだまだ変わる可能性は高い。

Priority Hints

Priority Hintsの仕組みを用いることで、Webデベロッパーは、HTML要素にgroup属性でcritical, fonts, functional, visual, lateを指定することで、優先度を指示できます。

HTTP/2の優先度は、具体的にはWeightとDpendencyからなる。Dependencyを用いることでリソースAをレスポンスしてから、リソースBをレスポンスするように指示できる。上記のgroupはそのまま、HTTP/2のDependencyの関係を指示できるものだと思われる。

現在、たたき台として上がっている分かりやすい例を幾つか示す。

Fetch APIに関してはスコープ内だが、まだ未定。

例1
<img src=foo group=visual>

画像が最初の表示に影響を与えるので比較的高い優先順位でロードされることを意味する。

例2
<img src=foo before=visual>

他の表示に影響を与えるリソースよりも高い優先順位で画像をロードすることを意味する(本当に重要な画像など)。

例3
<link rel=stylesheet href=foo group=late> 

最初の表示をブロックしないスタイルシートであることを意味します。

例4
<iframe src=foo group=late>

iframeとそのすべてのサブリソースの重要度を下げることを意味します。

Open questions

幾つかの課題がOpen questionsと挙げられているが
上記とは別にHTML要素間のDependencyを明示できるようにする仕組みも検討されている。

<img fetch-class="shop-branding" src="logo.png" higher-priority-than="shop-scripts" lower-priority-than="shop-item">

<script fetch-class="shop-scripts" src="lazy-loader.js">

<img fetch-class="shop-item" src="product-01.png">
<img fetch-class="shop-item" src="product-02.png">

DNS Queries over HTTPS の標準化

DNS Queries over HTTPS」の仕様の標準化が始まっている。

今までもこのテーマはIETFにおいて何度か議論になってきましたが、今回 DNS Over HTTPS (doh) WGの設立に合わせて(まだProposed)、この「DNS Queries over HTTPS」の標準化がマイルストーンとなっている。

今回の「DNS Queries over HTTPS」は、Googleの提供しているDNS over HTTPSとは全然違う仕様である点は注意が必要です。GoogleのものはクエリとレスポンスをJson形式で構造化するが、今回は比較的素のDNSクエリをHTTPSで送り合う仕様である(今後JSON形式をサポートする可能性はあります)。


このプロトコルではHTTP/2を使う必要があります(MUST)。HTTP/2を使うことで、既存のWebサーバとのコネクション上でDNSレコードをサーバプッシュで送る事も出来ます。

DNS Queries over HTTPS

背景

たとえば、接続しているネットワークが外のDNSとの通信を許可するとは限りません。

公衆Wi-Fiなどのネットワーク提供者がネットワーク内のDNSとの接続のみを許可していたり、もしくはなりすましされて、DNS通信が偽装される可能性もあります。そのようなネットワークでも安全にDNSとやり取りするために、HTTPS上でDNSクエリを送る方法が今回の「「DNS Queries over HTTPS」」という仕様になります。

HTTPリクエス

GET及びPOSTをサポートします。GETの場合はGETパラメータに、POSTの場合はHTTPボディにDNSクエリが格納されます。
www.example.comのAレコードを問い合わせる場合は

GETの場合

   :method = GET
   :scheme = https
   :authority = dnsserver.example.net
   :path = /.well-known/dns-query?  (no CR)
           content-type=application/dns-udpwireformat&  (no CR)
           body=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
   accept = application/dns-udpwireformat, application/simpledns+json

POSTの場合

   :method = POST
   :scheme = https
   :authority = dnsserver.example.net
   :path = /.well-known/dns-query
   accept = application/dns-udpwireformat, application/simpledns+json
   content-type = application/dns-udpwireformat
   content-length = 33

   <33 bytes represented by the following hex encoding>
   abcd 0100 0001 0000 0000 0000 0377 7777
   0765 7861 6d70 6c65 0363 6f6d 0000 0100
   01
  • .well-known/dns-queryにリクエストします(別のPathでも可)
  • acceptヘッダにapplication/dns-udpwireformatを設定すべきです
  • GETの場合は、bodyはBase64urlエンコードされます
  • キャッシュ出来るように、DNSクエリのDNS IDは0がセットされる

HTTPレスポンス

HTTPレスポンスボディにDNSレスポンスが格納されます。max-ageにDNSTTLと同じ値を格納すべきです。また、304ステータスコードやLast-Modifiedヘッダ、Etagヘッダは仕様すべきではありません。

www.example.comの問い合わせに、93.184.216.34 (TTL=128)を帰す場合は

   :status = 200
   content-type = application/dns-udpwireformat
   content-length = 64
   cache-control = max-age=128

   <64 bytes represented by the following hex encoding>
   abcd 8180 0001 0001 0000 0000 0377 7777
   0765 7861 6d70 6c65 0363 6f6d 0000 0100

   0103 7777 7707 6578 616d 706c 6503 636f
   6d00 0001 0001 0000 0080 0004 5db8 d822

セキュリティの報告先を記述する、security.txtの提案仕様

Webサイトのセキュリティリスクを発見したものの、連絡先が適切に公開されていないがために、結局報告されず脆弱性が放置されるケースがあるようだ(国内だと、IPA脆弱性関連情報の届出受付もあるが)

発見者が脆弱性等の報告を出来るような情報を、Web作成者が提供できるようにする仕様がIETFに提出されている。

この「A Method for Web Security Policies」という提案仕様では、security.txtをドメイン直下のURLに配置し、連絡先などを記述するようになっている。

security.txt

security.txtは例えば以下のとおりである

# Our security address

Contact: security@example.com
Contact: +1-201-555-0123
Contact: https://example.com/security
Encryption: https://example.com/pgp-key.txt
Disclosure: Full
  • #: コメント行
  • Contact: 連絡先。メールアドレス・電話番号・URLが記述できる
  • Encryption: 暗号化用の鍵
  • Disclosure: 問題の対応後の、受け付けた報告の開示ポリシー。Full, Partial, Noneのいずれか。

QUICにおける信頼性のないストリームの提案仕様

QUICはUDPを使用しますが、内部的にストリームという信頼性のある通信単位をもちます。ストリーム上では正しい順序での配送が保証され、パケットロスしたデータも回復されます。

そのようなQUICに対して、信頼性のないストリーム、つまりパケットロスしても回復しないようなストリームの検討を行うInternet-Draftが出ている。また、合わせてその信頼性のないストリームを用いてHTTPボディを送るための仕様も提出されている。

ぞれぞれ下記の通りである

これらによって、HTTPヘッダは確実に届けるが、HTTPボディはロスしても良いというHTTPが実現できるのは面白い点である。

現状の標準化動向としては、QUICの仕様に取り込まれるかは分からないが(個人的には険しいと思う)

面白そうなので簡単に読む

Considerations for Unreliable Streams in QUIC

信頼性のないストリームに関する考慮事項と要件について書かれている。ちなみに、この仕様はQUICのdraft-04を参照している点にも注意である。

  • コネクション確立時に、この仕様に対応していることを示すaccept_unreliable_stream_framesトランスポートパラメータを用いてネゴシーエションする
  • 信頼性のないストリームをオープンする際に'R' (RELIABLE)フラグを立てる
  • ゾンビストリームを防ぐため、ストリームのクローズ(FIN)はロスした場合は再送される
  • 信頼性のないストリームは、輻輳制御およびフロー制御をうける
  • アプリケーションは、任意の再送戦略を取れる(再送しても良い)

Unreliable Transmission Extension for HTTP/2 over QUIC

メディアなどの配信のために、HTTPボディの送信に信頼性のないQUICストリームを利用するための仕様。基本的には上記の「Unreliable Streams in QUIC」の仕組みを用いる。

  • クライアントから「Transport-Response-Reliability: unreliable」ヘッダを用いることで、レスポンスに信頼性のないストリームの利用を要求できる
  • 「Transport-Response-Reliability: unreliable-after DATE」で時間を指定することで、指定時間経過後は再送しないことも要求できる
  • HTTPヘッダに関しては信頼性のあるストリームで送信されるなければならない(draft-ietf-quic-http-04, 05に言及)

TLS record_size_limit 拡張の提案

IoTデバイスなどリソースが制限されている端末でTLS通信を行うのには課題がある。特に送られてきたレコードを復号するのにはそれを計算する十分なメモリが必要になる。

リソースが制限されている端末でも問題なく復号処理が出来るように、相手に受信したいレコードのサイズを伝えられるようにするrecord_size_limit拡張の仕様が提案されている。

仕様は「Record Size Limit Extension for Transport Layer Security」であり、MozillaのMartin Thomsonによって提案されている。この提案はすでにWGドラフトになっている。

この仕様によって、max_fragment_length 拡張は廃止される。

max_fragment_length拡張 の課題

似たように最大フラグメントサイズをネゴシエーションする拡張としてmax_fragment_length がある。しかし幾つかの課題がある

  • サイズが対象であり、クライアント・サーバ両方が送信するサイズが一緒である
  • クライアントからの提案に対して、サーバはそれより低い値を提案できない(サーバの方のリソースが制限されている場合に問題)
  • 最大レコードサイズは2^14なのにたいし、2^12までしか指定できない

record_size_limit拡張

現在、record_size_limit拡張の拡張コードはTBDになっているが、値はuint16で指定することになる。

uint16 RecordSizeLimit;

このrecord_size_limit拡張では

  • 制限は平文サイズに対して適応される(パディングなどは含まない)
  • 送信相手にのみ適応される。自信はそれ以上のサイズを送信して良い。
  • サーバが制限しようとすることもあるので、クライアント側はサイズを制限しなくてもrecord_size_limit拡張を送信スべき
  • 64以下のサイズを送っていはいけない

record_size_limit拡張によってmax_fragment_length拡張はとって代わります。record_size_limit拡張をサポートするサーバは、record_size_limit拡張とmax_fragment_length拡張がClientHello似合った場合無視しなければなりません。

W3CにおけるWeb Lifecycleの議論

W3CでWebPerf Web Performanceで、「Web Lifecycle」というトピックが議論に上っていた。(Agenda URL)

これは、iOSアプリやAndroidアプリのActivityのようなライフサイクルを、Webアプリケーションでも定義しようというものらしい。

まだ具体的な仕様は無いものの面白そうなので簡単に見てみる。ちょうざっくり

背景

  • 30%以上のユーザがタブを10以上開いており、現在表示しているタブのユーザ体験に影響を与えている
  • バックグラウンド(非表示のタブなど)の扱いについて明確なライフサイクルは存在しない(デスクトップとモバイルで扱いが異なる)
  • ライフサイクルやAPIがなく、アプリケーションが自身がどういう状態にあるか分からない(既にイベントはあるが一貫性がない)

提案

f:id:ASnoKaze:20170831231236p:plain
(スライドより)

  • LOADING: 読み込み状態
  • ACTIVE: 見えており、フォーカスがある状態
  • PASSIVE: 見えているがフォーカスはない状態 (例えばアプリケーションはゲームの停止などを行う)
  • BACKGROUNDED: 見えてない状態。例えばUI処理の停止される。
  • STOPPED: 見えてない状態。バックグラウンド実行の停止。
  • DISCARDED: メモリ再利用のためにバックグラウンドタブの廃棄。
  • TERMINATED: ユーザによってタブが閉じられた。

図の通り、BACKGROUNDEDやSTOPPEDからもタブが選択されれば再度、ACTIVEな状態に遷移する。

各状態遷移時にイベントが発火するためアプリケーション側は現在の状態を検知できるようになっている。

この状態遷移によって

  • 各状態のコールバックを用意し、アプリケーションがデータの保存やレポートを送れるようになる
  • アプリケーションはバックグラウンドで行いたい作業を宣言できる(Audio, Network Upload, Updating tab titleなど)
  • 適切なバッググラウンド処理が可能(ServiceWorkerの利用、必要なものにレンダラのリソース配分)
  • アプリケーションに依存するが、リソースの制限によってシステムによってアプリケーションを停止・終了できる

課題

まだまだ議論が始まったばかりだが、幾つかの課題が挙げられている

  • STOP遷移時のコールバック(onStop)の制限事項。ネットワーク利用の制限などどうするか
  • バックグラウンド実行時の処理・レンダリングをどうするか(WebUSB, Updating title and favicon, Notifications)
  • 同一ドメインで複数タブを開いた時に、タブを超えてデータが共有される。STOP時に壊れてしまう
  • ダイアログの表示を保存するか

ただしCurrent Workがあるようなので、Googleとしてはそういう動きがあるんだと思われる

Chrome62から、http://でのフォームに入力すると警告が出るようになる

Chrome 52(今年1月リリース)において、パスワードの入力フォームがあるとアドレスバーに警告が出るようになったのはニュースサイトでも多くとりあえげられたのでご存じの方も多いと思います。
www.itmedia.co.jp


上記内容のGoogleからのアナウンスにおいて、Chrome62(今年10月リリース予定)で対応を強めることもアナウンスされています。
security.googleblog.com


Chrome62より、http://のページで、 type="text"などの入力フォームに文字を打つとアドレスバーに警告が出るようになるもようです。

フォーム入力時の警告

Chrome Canaryでデータ入力時の警告を確認できるようになりました
f:id:ASnoKaze:20170818122057g:plain


この機能は、Chrome Canaryでchrome://flagsのより、
「Mark non-secure origins as non-secure」を「warn on http while in incognito mode or after editing forms」にすると機能するようになります。
(現状、betaだと有効にしても警告が出ないような気がします)
f:id:ASnoKaze:20170818122423p:plain


現状、文字を入力するinput typeでのみ警告が出るようで、fileやチェックボックスでは警告は出ないようです。