『Real World HTTP』を読んだ

最近のホットトピックとして、『ゴミ箱の購入』が挙げられる。
ゴミ箱がなかったときと比較すると、ゴミを捨てるのが有意に楽になった。
ゴミ箱を持っていない方は、ぜひゴミ箱の購入を検討してほしい。

Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術

Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術

どんな本か

タイトルかっこいい。泣く子も黙るオライリィ。Kindle版がなかったので紙本を購入した。

本書を読むことで、最新のさまざまなウェブのトピックにキャッチアップできる基礎力が身につく本としてまとめました。

あとがきより。
著者は渋川よしきさんという現DeNAのエンジニアの方。初版が2017年6月と新しく、最近のウェッブ通信事情をさらっとなぞれそうなかんじ。

なぜ読んだか

Webに疎いことが長年のコンプレックスだった。 ちょうど最近、シャの仕事でウェッブの認証周りについて調べる必要があった。書籍はまだしもインターネッツですら枯れた情報が溢れており、また自信を持ってそれを取捨選択できないことに課題を感じた。今も昔も変わらぬ部分と、それを踏まえていまのデファクトスタンダードを知りたいと思った。 たまたまTwitterに流れてきた本書をみて、お、最近のやつやん、ええやん、ってなった。

感想など

全体

久しぶりに訳書ではない技術書を読んで、日本語の自然さと読みやすさに感動した。内容も基礎的なので、読み始めた瞬間から「やばい、読める!読めるぞ!」ってなったが、後半には案の定疲れて失速した。

いたるところでRFCが参照されているが、単にRFCのダイジェストに留まらず、歴史的背景や行間、ブラウザのサポート事情なども勘案しつつ、見識のある著者の意見も述べられている。Webの開発者にとっては、「基礎を理解していれば実務に生きるかも」というレイヤの話というより、普段の業務にあたり当然知っておくべき内容だと思った。

HTTPの変遷

そもそもHTTPの機能について知識が曖昧だった。それを理解するのに、HTTP/0.9からはじまる歴史にそって解説されていてとてもわかりやすかった。この流れで改めて歴史をたどると、枯れていった機能や技術要素はほとんどないのが印象深い。シンプルに「高速化」と「安全性」を目的に、ハードウェアその他周辺技術の進化に伴って、HTTP/2に至るまで、機能追加や再設計を経て改善が積み重なってきていることがよくわかった。

HTTPにまつわる全体の流れにフォーカスしていて、各トピックにキャッチアップできる状態を目指しているので、各機能の細かいアルゴリズムについては、参照されているRFCや、他の書籍をみたほうがよさそう。とはいえ、直近のWeb事情を綺麗に書籍でまとまっていて非常に有用だと思うので、そのへん自信がない方にはぜひおすすめしたい。

Go言語とcurl

サンプルコードはGoで書かれている。Goはいままで触ったことがなかったが、せっかくの機会なので、環境を作って写経してみるなどした。環境といってもすごく簡単で、Goのインストールと、エディタはGoglandを使ってみた。

www.jetbrains.com

コードも明瞭で実行も簡単。普段はC#を触ったり触らなかったりするマンとしては、 defer とか戸惑う。個人的にGoの流行り方はなんか不思議で、コミュニティが特に活発なわけでもなく、水面下でグイグイ勢力を伸ばしているようにみえる。触ってみると、その軽量さと高機能さでとてもバランスよくて、単に良いものだから流行るというとてもかっこいいかんじなんだと変に納得した。

curlすごい便利。Google Chromeでは開発者ツールとして「Copy as cURL」なる機能があり、ブラウザのリクエストをcurlのオプションとして再現してくれる。魔が差してスクレイピングをする機会があれば活用したい。

今後

ウェッブサービスを作っていけば否が応でも接する内容なので、日々のお仕事を通して理解を深めていきたい。
最近は週に1冊くらいは技術書を読んでいる。特に意識してがんばっているわけではない。ブログに書かない本もあるので、だいたいずっと本を読んでいる。だいたいわかってきたこととして、積読はキューではなくスタック。前々から読みたいと思っている本に全然手を付けられていない。

メモ

1章 HTTP/1.0のシンタックス:基本となる4つの要素

  • HTTPは「メソッドとパス」「ヘッダー」「ボディ」「ステータスコード」の4つの要素に分解できる
  • HTTPはWebブラウザとWebサーバが通信するときの手順とフォーマットをルール化したもの
  • HTTP
    • 0.9:パスをサーバに指定し、テキスト情報が書かれたページを取得してくるだけ(1999)
    • 1.0:GETなどのメソッド、HTTPバージョン、ヘッダー、ステータスコードなどが追加(1992)
  • 電子メールとの関係

    • HTTP/1.0は先行していた電子メールのフォーマット(ヘッダー+本文)を取り入れた
    • HTTPのヘッダーの例
      • リクエスト:User-Agent,Referer,Authorization
      • レスポンス:Content-Type,Cotent-Length,Content-Encoding,Date
      • 共通:X-からはじまるヘッダーはアプリケーション独自

          $ curl -v --http1.0 -H "X-Test: Hello" http://localhost:18888
          * Rebuilt URL to: http://localhost:18888/
          *   Trying ::1...
          * Connected to localhost (::1) port 18888 (#0)
          > GET / HTTP/1.0
          > Host: localhost:18888
          > User-Agent: curl/7.43.0
          > Accept: */*
          > X-Test: Hello
          > 
          * HTTP 1.0, assume close after body
          < HTTP/1.0 200 OK
          < Date: Thu, 05 Oct 2017 09:12:36 GMT
          < Content-Length: 32
          < Content-Type: text/html; charset=utf-8
        
  • ニュースグループとの関係

    • HTTP/1.0では先行していたニュースグループからメソッドとステータスコードを取り入れた
    • HTTPのメソッドの例:GET,HEAD,POST,PUT,DELETE
    • HTTPのステータスコードの例
      • 1xx系:処理中の情報の伝達
      • 2xx系:成功時のレスポンス
      • 3xx系:サーバからクライアントへの命令(リダイレクト、キャッシュの利用など)
      • 4xx系:クライアントからのリクエストのエラー
      • 5xx系:サーバー内部のエラー
  • リダイレクト
    • ステータスコード
      • 301 Moved Permanently:ドメイン移転,HTTPS化
      • 302 Found:一時メンテナンス
      • 303 See Other:ログイン後のページ遷移
      • 307 Temporary Redirect:302とは異なり、メソッド変更を許可しない
      • 308 Moved Permanently:301とは異なり、メソッド変更を許可しない
    • HTTP/1.0のRFCではリダイレクトは5回までと制限されていたが、HTTP/1.1では制限がなくなり、無限ループを検知しなければならない、とされた
    • Googleのガイドラインでは「リダイレクトは5回以下、できれば3回以下」
  • URL
    • 言葉の定義
      • URL(Uniform Resource Locators):場所からドキュメントなどのリソースを特定する手段を提供
      • URN(Uniform Resource Name):リソースに対する名前の付け方のルール
      • URI(Uniform Resource Identifier):URI+URN
    • WebではURLとURNはほぼ同義で、RFC3305で「URIが公式でURLは慣用表現」となったが、文脈に寄っていろいろ
      • URLを使う: W3C,Go,Python,Node.js
      • URIを使う: Ruby,C#
      • 両方を使う: Java
    • URLの仕様
      • スキーマ://ユーザ:パスワード@ホスト名:ポート/パス#フラグメント?クエリー
      • RFC2718でUTF-8を用いてエンコードすれば日本語も使える(最近のブラウザだとデコードして表示してくれる)
      • 仕様上の長さ制限はないが、IE(Edge)では2083文字までしか扱えないため、「だいたい2000文字」が目安
      • RFC3492で国際化ドメイン名(IDN)の表現のためのエンコーディングルール Punycode が決められた
  • ボディ
    • HTTP/0.9ではリクエストにデータは含められず、レスポンスはファイルコンテンツそのものだった
    • HTTP/1.0ではリクエストにコンテンツを含められ、レスポンスはボディとヘッダーを含む

2章 HTTP/1.0のセマンティクス:ブラウザの基本機能の裏側

  • シンプルなフォームの送信(x-www-form-urlencoded)
    • &と=でボディを構成する
    • アルファベット、数値、アスタリスク、ハイフン、ピリオド、アンダースコア以外はエスケープが必要(RFC1866)
  • フォームを使ったファイルの送信(multipart/form-data)(RFC1867)
    • 複数ファイルを送信するために、ブラウザが独自に境界文字列を付与する
  • フォームを利用したリダイレクト
    • 3xx系によるリダイレクトは、URLの文字数制限があったり、URLにデータが入ってしまう
    • 送信したいデータをhiddenでもたせ、HTMLが読み込まれたイベントでJavaScriptを使ってPOSTする
  • コンテントネゴシーエション
    • 1リクエストでサーバーとクライアント間で期待している形式や設定を共有する仕組み
    • Accept:ファイルの種類の決定(text/html,application/html+xml,application/xml;q=0.9,image/webp,*/*,q=0.8)
    • Acccept-Language:表示言語の設定。あまり使われておらず、HTMLに埋め込むケースが多い <html lang='ja'>
    • Accept-Charset:キャラクタセットの設定。全ブラウザが全キャラクタセットのエンコーダを内包しているため、送信しているブラウザはない
    • Accept-Encoding:現代の圧縮アルゴリズムなら、テキストファイルが1/10、JSONが1/20まで圧縮できる(cf.br,compress,deflate,gzip,..)
  • クッキー
    • ウェブサイトの情報をクライアントに保存する仕組み
    • 使うときの注意点
      • 確実に保存されるわけではない
      • 最大容量4キロバイト
      • secureを付与すればHTTPSで暗号化されたときのみ送信されるが、HTTPの場合は平文
    • 属性:Expires.Max-Age,Domain,Path,Secure,HttpOnly,SameSite,...
  • 認証とセッション
    • BASIC認証:ユーザ名とパスワードをbase64エンコーディング
    • Digest認証:ユーザ名とパスワードをハッシュ化
    • 最近は「フォーム認証」+「クッキーによるセッション管理」
  • プロキシ
    • HTTPなどの通信を中継し、サーバ負荷軽減やファイアウォールの役割を担う仕組み
    • プロキシは通信内容を理解して改変や代替するのに対し、ゲートウェイは通信内容をそのまま転送する
  • キャッシュ
    • すでにダウンロード済みのファイルの再ダウンロードを抑制する仕組み
    • HTTP/0.9ではコンテンツの新旧比較をしていた
    • HTTP/1.0ではExpiresヘッダーが導入された(HTTP/1.1のガイドラインでは「最大1年間」RFC2068)
    • Progma: no-cache を指定すると、キャッシュを無視してサーバリクエストを行う - ETagヘッダ:動的に変化するHTMLに対応するため、更新日時ではなくファイルのハッシュで比較する(RFC2068)
    • Cache-Controlヘッダ:柔軟なキャッシュ制御をサーバ側から支持できる(public,private,max-age=n,s-maxage,no-cche,no-store,...)
    • Varyヘッダ:同じURLでもクライアントによって返答が異なることを示す
  • リファラー
    • ユーザがどの経路からウェブサイトに到達したかをサーバが把握するために、クライアントがサーバに送信するヘッダ
    • RFC1945提案時のスペルミスのまま“Referer"となっている
    • 画像への直接リンクを防いだりCSRF対策で使われたりしていたが、ブラウザの設定で回避されうるため、いまは使われていない
    • HTTPSのウェブサイトからHTTPのウェブサイトへ遷移するときは送信しない(RFC2616)
    • Referer-Poilcyヘッダ:no-referrer,no-referrer-when-downgrade,same-origin,origin,string-origin,unsafe-url,...
  • 検索エンジン向けのコンテンツのアクセス制御
    • robots.txt:サーバのコンテンツ提供者が、クローラに対してアクセスの許可・不許可を伝えるためのプロトコル
    • サイトマップ:ウェブサイトに含まれるページ一覧とそのメタデータを提供するXMLファイル

3章 Go言語によるHTTP/1.0クライアントの実装

  • 2章の内容をGoで書いてみる(省略)

4章 HTTP/1.1のシンタックス:高速化と安全性を求めた拡張

  • 仕様の歴史
    • RFC2068(最初のバージョン,1997)
    • RFC2616(改訂)
      • RFC2817(TLS)
      • RFC5785(URI)
      • RFC6266(Content-Desposition)
      • RFC6285(追加のステータスコード)
    • (最新版,2014)
      • RFC7230(メッセージの文法)
      • RFC7231(セマンティクスと内容)
      • RFC7232(条件付きリクエスト)
      • RFC7233(範囲指定リクエスト)
      • RFC7234(キャッシュ)
      • RFC7235(認証)
  • 通信の高速化
    • Keep-Alive
      • 連続したリクエストにおいてコネクションを再利用し、TCP/IPの通信を高速化する仕組み
      • クライアントとサーバの両方が設定を持ち、短いほうが採用される(デフォルトは、IEが60秒、FireFoxが115秒、nginxが75秒、など)
    • パイプライニング
      • 最初のリクエストが完了する前に次のリクエストを送信し、ネットワークの稼働率をあげる仕組み
  • TLS(Transport Layer Security)
    • 通信経路を暗号化するプロトコル
    • SSLは様々な脆弱性が発見されており非推奨で、実際に使われているのはほとんどがTLS
    • 要素技術:ハッシュ関数,共通鍵暗号,公開鍵暗号,デジタル署名,鍵交換(cf.DH,DHE)
    • 通信手順
      • ハンドシェイク(通信の確立):SSLサーバ証明書を利用した信頼性の保証、公開鍵暗号による共通鍵の交換、通信の開始
      • レコード(通信):共通鍵暗号による通信
      • 通信高速化:Keep-Alive,セッション再開機能(TLS 1.2),事前共有鍵(TLS 1.3),QUIC(TCPではなくUDPを使う)
    • 暗号強度
      • 共通鍵暗号方式のビット数でレベル分けされる
      • 60ビットでは小規模組織の極短期間の攻撃で、80ビットでは短期間の組織的な攻撃で解読されるとされている
      • 96ビット、112ビット、128ビットでそれぞれ10年、20年、30年の期間耐えられるとされている
      • 2017年現在、推奨となっているのは112から128ビット
    • 暗号スイート
      • TLS 1.0から1.3のバージョン間で相互交換的に使える、鍵方式や暗号化のアルゴリズムの組み合わせ
      • 暗号スイートのうち、今使っても安全なもの、互換性のために残すべきもののリストが、Mozillaのサイトにある
    • プロトコルの選択
      • ALPN(Application-Layer Protocol Negotiation)
        • 最初のハンドシェイク時にクライアントからサーバに「クライアントが利用可能なプロトコル一覧」を添付して送信する
        • サーバはそのレスポンスで、鍵交換や証明書と一緒に選択したプロトコルを送信する
        • 選択できるプロトコルはIANAで管理されている(ex. http/1.1,spty/1,turn,h2,webrtc,ftp,...)
        • RFC上は識別子をUTF-8でエンコードするとされており、日本語や絵文字が入っても問題ない
    • TLSが守るのは通信経路であってそれ以外の情報の秘匿は行わない
  • PUTメソッドとDELETEメソッドの標準化
    • HTMLのウェブフォームから送信することはできず、XMLHttpRequestを使う必要がある
  • OPTIONS、TRACE、CONNECTメソッドの追加
    • OPTIONS:サーバが受け取り可能なメソッド一覧を返す(nginxを含む多くのWebサーバでデフォルトOFF)
    • TRACE(TRACK):Content-Typeにmessage/httpを設定し200 OKで返す(XST脆弱性があり使われていない)
    • CONNECT:HTTPのプロトコル上に、他のプロトコルのパケットを流せるようにする
  • プロトコルのアップグレード
    • HTTP以外のプロトコルへのアップグレードができるようになった(ex. HTTP->TLS,HTTP->WebSocket,HTTP->HTTP/2)(RFC2817)
    • ただし、TLSへはセキュリティが守られない問題、HTTP/2ではこの機能が削除されており、現在はほぼWebSocket用
  • バーチャルホストのサポート
    • HTTP/1.0では1台のWebサーバでひとつのドメインのみを扱う前提だったが、HTTP/1.1では複数のサービスを扱えるようになった
    • Hostヘッダに、リクエストを贈りたいサーバ名を記述することが義務付けられた
  • チャンク
    • データ全体を一括で送信するのではなく小分けにして送信する方式 Trunsfer-Encoding: chunked

5章 HTTP/1.1のセマンティクス:広がるHTTPの用途

  • ファイルをダウンロードした後でローカルに保存
    • デフォルトではMIMEタイプをみて、例えばimage/pngであればブラウザ内に表示する
    • サーバからのレスポンスにContent-Disposionヘッダがあると、保存ダイアログを出してファイルを保存する
    • もともとはHTTPではなく電子メールの添付のためのRFC1806で定義された
  • ダウンロードの中断、再開
    • Accept-Rangesヘッダがあれば、大きなファイルの指定範囲を切り出してダウンロードできる
    • Range: bytes=1000-1999 のようにリクエストする
    • カンマ区切りで複数範囲の指定や、Range区切りごとに並列でダウンロードもできる
  • XMLHttpRequest
    • curlコマンドに相当する機能をJavaScriptから使えるようにする
    • ブラウザと違い
      • 送受信時にHTMLがリロードされない(cf. Ajax)
      • GETとPOST以外も送信できる
      • キー:値 形式のデータ以外の、プレーンテキスト、JSON、バイナリデータ、XMLなども送受信できる
      • セキュリティのため、アクセスできる情報の制限と、送信制限がある
    • Comet:XMLHttpRequestを使ったロングポーリングによりリアルタイムの双方向通信を行う
  • Geo-Location
    • クライアント自身が場所を得るには、GPSを使ったり、WifiのBSSIDを使ったりする
    • サーバがクライアントの場所を推測するには、GeoIPと呼ばれる、IPアドレスから推測する方法がある
  • X-Powered-Byヘッダ
    • RFCではないがサーバがシステム名を返すのに使用しておりデファクトスタンダードになっている
    • かつてFireFoxはこのヘッダをみて挙動を変えていたが、現在はRFC1945のHTTP/1.0で標準化されているServerヘッダをみている
  • リモートプロシージャコール(RPC)
    • 別のコンピュータにある機能を、自分のコンピュータ内であるかのように呼び出す仕組み
    • XML-RPC(RFC3529),SOAP(W3C規格),JSON-RPC(独自仕様)
  • WebDAV
    • HTTPを拡張して分散ファイルシステムとして使えるようにしたもの(HTTP/1.1には含まれない,RFC2518)
    • HTTP/1.1のPOST/GET/PUT/DELETEに加え、ファイルシステムとして機能するために、COPYとMOVEが追加されている
    • Dropbox,Google Driveなどのオンラインストレージサービスと異なり、同期型を前提としている
    • Gitでは転送プロトコルとしてSSHとHTTPSをサポートしているが、このHTTPSの中ではWebDAVを使っている
  • ウェブサイト間での共通の認証・認可プラットフォーム
    • 認証(Authentication):ログインしようとしているユーザが「何者か?」を確認する
    • 認可(Authorization):認証したユーザが誰なのかを把握した上で、与える権限を決定する
    • シングルサインオン:一度サインインしたら、全システムがすべて有効になる仕組み
    • Kerberos認証:企業内でユーザ管理をひとつにまとめ、全システムがそれを利用する仕組み(RFC1510,RFC4120)
    • SAML(Security Assersion Markup Language):Web(HTTP/SOAP)を前提としたシングルサインオンの仕組み(OASIS規格)
    • OpenID:中央集権のID管理ではなく、すでに登録されているウェブサービスのユーザ情報を使い、他のサービスにログインする仕組み
    • OpenSocial:ソーシャルネットワークの共通APIであり、認証だけでなく会員情報やその他情報をもつプラットフォームを指向
    • OAuth:認証ではなく認可の仕組み(RFC5849,RFC6749,RFC6750)
    • OpenID Connect:OAuth 2.0をベースにして、認可だけでなく認証にも使えるよう拡張したもの

6章 Go言語によるHTTP1.1クライアントの実装

  • 4章、5章の内容をGoで書いてみる(省略)

7章 HTTP/2のシンタックス:プロトコルの再定義

  • HTTP/2
    • HTTP.1.1までとはデータ表現が大きく異なるが、通信アプリケーションから見れば大差はない
    • ストリームによる通信の高速化
      • HTTP/1.1まで
        • ひとつのリクエストがTCPのソケットを専有するため、2〜6本のTCP接続を確立して並列化していた
        • クローズ状態からLISTENして、クライアントからの接続リクエストがあって初めてESTABLISH状態になる
      • HTTP/2
        • 1つのTCP接続の内部に、ストリームという仮想のTCPソケットを作り、「フレーム」という単位を送受信する
        • 最初からLISTENとほぼ同じIDLE状態で、ヘッダを受け取ると即座に通信可能なOPEN状態になる
    • アプリケーション層
      • HTTP/1.1まで
        • メソッドやパス、ステータスコードなどはヘッダ組み込まれており、実装上は「ヘッダ」「ボディ」のみ
        • テキストプロトコルであり、ヘッダの終端である空行まで1バイトずつ先読みする必要があるため、高度な並列化は難しい
      • HTTP/2
        • バイナリ化され、最初にフレームサイズが入っているため、TCPソケットのレイヤでデータをフレーム単位に分割できる
    • フローコントロール
      • 通信先のウィンドウサイズ(受け取ることのできる空きバッファサイズ)を管理し、空いた分を埋めるようにデータを送る
    • サーバプッシュ
      • CSSやJavaScript、画像などのうち、優先度の高いものをあらかじめサーバからクライアントに送信し、キャッシュしておく
    • HPACKによるヘッダの圧縮
      • 静的テーブルという名前で、事前に頻出するヘッダ名と値をテーブルに持っている
      • 同一コネクション内のHTTPヘッダはインデックス化されて動的テーブルに格納される
    • SPDYとQUIC
      • SPDY:Googleが開発したHTTP代替のプロトコルで、これがほぼそのままHTTP/2になった
      • QUIC:「TCPソケット上のSPDY」と同じく、「UDPソケット上のQUIC」であり、HTTP/2と協調動作する
  • Fetch API
    • XMLHttpRequestと同様の、サーバアクセスを行う関数
    • fetch("xxx.json", {...}).then(...)) みたいな記述で、Promiseに準拠している
    • CORSモード、キャッシュ、リダイレクト、リファラのポリシーを制御できる
    • Server Worker内から利用できる
  • Server-Sent Events
    • HTTP/1.1のChunked形式を元にした、HTML5の機能のひとつ
    • CometのロングポーリングとChunkedレスポンスを組み合わせ、1リクエストに対して複数のイベントを送信する
    • Chunked形式を使っているが、HTTPの上にイベントストリームという別のテキストプロトコルを載せている
  • WebSocket
    • サーバ/クライアント間で、オーバーヘッドの小さい双方向通信を行う(RFC6455)
    • 1対1の通信なので、送信先の情報などは持たない
    • 他のHTTPベースのプロトコルと異なり、ステートフルな通信であるため、例えばロードバランシングや再接続では同一のサーバに接続する必要がある
    • HTTPより下のレイヤのTCPソケットに近い機能を提供するため、それに近いJavaScriptのAPIを提供する
  • Socket.IO
    • WebSocketをさらに使いやすくするライブラリ
    • WebSocket不能時にXMLHttpRequestによるロングポーリングでエミュレーションする機能、切断時の自動再接続など
  • WebRTC(Web Real-Time Communication)
    • ブラウザとブラウザのP2P通信
    • RFC7478でユースケースが定義されている(cf. シンプルなビデオ通話,ファイアウォール越しのビデオ通話,グローバルなビデオ通話,スクリーン共有,ファイル交換,複数人ビデオ会議,ボイスチャット付きオンラインゲーム,カスタマーセンター,IP電話端末,...)
    • ORTC(Object Real-Time Communication):WebRTCのAPIをより洗練させ、機能を追加する活動
  • HTTPウェブプッシュ
    • ウェブサイトに対するプッシュ通知機能を提供する仕組み(通信プロトコルはRFC8030,JavaScriptAPIはW3C規格)
    • 動作原理
      • ブラウザがプッシュサービスに購読を申し込む(Service Workerでpushイベントを登録する)
      • アプリケーションサーバがプッシュサービスにメッセージを投稿(プッシュサービスはいまのところブラウザごとに実装されている)
      • ブラウザがプッシュメッセージを受信

8章 HTTP/2のセマンティクス:新しいユースケース

  • レスポンシブデザイン
    • クライアントの画面サイズ、レイアウトに合わせて適切な表現をする
    • スマートフォンのブラウザは、スクリーンの解像度に対して一回り小さい論理解像度のディスプレイが接続されていると認識する
    • ブラウザの論理解像度をCSSピクセル、論理解像度と物理解像度の比率をピクセルデバイスレシオと呼ぶ
  • セマンティックウェブ
    • 表面的な「文書」ではなく、「意味」を扱えるようにして、ウェブの可能性を広げようという運動
    • ページに含まれる情報を分析し、情報の集約や探索を人手を介さずに行えるようにする
    • RDF(Resource Description Framework):URIで識別されるエンティティ間の関係性を記述する(主語、述語、目的語)
    • ダブリンコア:メタデータ記述のボキャブラリー集(RFC5013)
      • 電子書籍のOpen eBook(OEB)規格に含まれる、ファイルのリストや書籍情報を格納したOpen eBook Package Format(OPF)で利用されている
    • RSS(RDF Site Summary):ウェブサイトの更新履歴のサマリーに関するボキャブラリー
    • マイクロフォーマット:RDFとは異なり、HTMLのタグとクラスを使い表現する
      • 一時期もてはやされたが、CSSのクラス名衝突でレイアウトが崩れるなど問題あり、現在ではschema.orgのデータフォーマットが推奨されている
    • マイクロデータ:HTMLに埋め込み可能なセマンティックの表現形式(W3C定義) - ボキャブラリーはマイクロフォーマットよりもかなり少ない(ex. Event,Organization,Person,Product,...)
    • RDFの逆襲:RDFそのものは広く使われなかったが、様々な派生フォーマットを生み出した(ex. RDF/XML,Turtle,JSON-LD,RDFa,...)
      • GoogleはJSON-LDを推奨しており、今後利用が見込まれる
  • オープングラフプロトコル
    • 検索エンジンではなく主にソーシャルネットワークで使われるメタデータ(Facebookが開発) ogp.me
    • Twitterカードは、オープングラフプロトコルをベースにTwitter用の情報を追加したもの
    • AMP(Accelerated Mobile Pages)
    • 主に静的なウェブサイトでモバイルの高速化をする仕組み
    • 高速化の仕組み
      • ページの構成を固定化:ルールで決められているサブセット、もしくは特別な代替記法のみをつかう制約を設ける
      • CDN対応:クローラがAMPをに意識すると、その内容をすべてCDNにコピーする
      • タグの最適化:コンテンツをサーバ側に引き取るときにタグを書き換える(仕様外,Googleの独自実装)
  • HTTPライブストリーミング(HLS)による動画のストリーミング再生
    • Appleが2009年に提唱した動画ストリーミング再生の仕組み - モバイル向けのSafari、Chromeと、デスクトップのSafari、Edgeでサポートされており、モバイルではデファクトスタンダード
    • メリット:特殊なプロトコルではなくHTTPを利用しているため、通常と同じWebサーバが使え、CDNも使える
    • デメリット:ストリーミングを名乗っているが実体はプログレッシブダウンロードであり、遅延が発生する
  • MPEG-DASH(Dynamic Adaptive Streaming over HTTP)による動画のストリーミング再生
    • HTTPを使い、動的に適切なビットレートでストリーミングを行う方式 github.com/Dash-Industory-Forum/dash.js
    • 「HTTPを使ったプログレッシブダウンロードで動画再生」という点でHLSと同じだが、ブラウザ自身がプロトコルを解釈するのではなく、データの解析をJavaScriptで行い、JavaScriptから扱うAPIを介して再生する

9章 Go言語によるHTTP2、HTML5のプロトコル実装

  • 7章、8章の内容をGoで書いてみる(省略)

10章 セキュリティ:ブラウザを守るHTTPの機能

  • クロスサイトスクリプティング(XSS)
    • ユーザ入力でスクリプトが埋め込まれて実行される
    • すべての攻撃の起点となりうるため、もっとも危険
    • 対策
      • 出力直前にきれいにする(エスケープする)
      • クッキーを保護するためhttpOnly属性を付与する
      • X-XSS-Protectionヘッダ:インラインのスクリプトタグなど、明らかに怪しいパターンを検出する
      • Content-Securityヘッダ:ウェブサイトで使える機能を細かくON/OFFできる(ex. base-uri,child-src,img-src,script-src,...)
    • Mixed Content
      • HTTPとHTTPSが混在するコンテンツ
      • Content-Security-Policy: upgrade-insecure-request
    • クロスオリジンリソースシェアリング(CORS)
      • クライアントからサーバにアクセスする直前までの権限確認プロトコル
      • ドメインをまたいだリソースにXMLHttpRequestやFetch APIでアクセスする
  • 中間者攻撃
    • プロキシサーバが通信を中継するときに通信内容を抜きとられることで情報が漏洩する
    • 対策
      • HTTPS(TLS)を利用する
      • HSTS(Http Strict Transport Security):サーバ側から「今後接続するときはHTTPSで接続してほしい」と伝達する仕組み
        • Strict Stransport-Security: max-age=31536000;includeSubDomains
        • 初回接続時はHTTPになってしまう問題に対し、Google Chromeでは、HTTPSで接続するべきウェブサイトのリストを集めている
        • 中間車が持つ証明書が承認されてしまうと合法的にHTTPS通信をジャックできてしまう
      • HTTP公開鍵ピンニング
        • 初回アクセスで公開鍵のリストを送ってもらい、2回目以降のアクセスではサーバが送ってきた証明書の公開鍵と比較して、不正な変更がないか検証する
  • セッションハイジャッキング
    • ウェブサービスのセッショントークンを盗み出しウェブサイトにログインする攻撃
    • 対策
      • HTTPS化
      • Set-Cookie: httpOnly, secure
  • クロスサイトリクエストフォージェリ(CSRF)
    • 本人の意図しないサーバリクエストを送らせる攻撃
    • 対策
      • CSRF対策トークン:隠しフィールドにトークンを埋め込み、POSTを受け取るサーバで検証する
      • SameSite属性:リクエストを送信する前のページが同一サイトにない限りはクッキーを送信しなくなる
  • クリックジャッキング
    • IFRAMEを利用して悪意のあるページを重ねたりして、意図しない操作をさせる攻撃
    • 対策
      • X-Frame-Optionsヘッダ:ページがIFRAME内で利用されることを拒否できる
  • リスト型アカウントハッキング
    • 脆弱なWebサーバが不正侵入を受けてId/Passwordが流出した際、同じId/Passwordを流用しているユーザのセキュリティが無効になる
    • 対策
      • 二段階認証(RFC6238)
      • Geo-Location
      • 時間あたりのアクセス制御