morisolog

ソフトウェア関連の技術書まとめ:新卒3年目エンジニア

【技術書 1】『Real World HTTP』を読んだ(前半)

本の内容

『Real World HTTP 第 2 版 - 歴史とコードに学ぶインターネットとウェブ技術』, 渋川よしき.

個人のメモ書き程度の記事です。🙏

本の内容を箇条書きでまとめていきます。

1 章 HTTP/1.0 の世界:基本となる 4 つの要素

  • HTTP とは Web ブラウザと Web サーバーが通信する際の手順とフォーマットをルール化したもの
    • 仕様は RFC で定義されている
  • HTTP 通信は以下の 4 つのパーツに分解できる
    • メソッドとパス
    • ヘッダー
    • ボディー
      • ヘッダーの空行から Content-Length バイト数分を読み込む
    • ステータス
  • HTTP の歴史
    • 1990 年 : HTTP/0.9
      • パスの指定とボディの受信しかできなかった
    • 1996 年 : HTTP/1.0
      • メソッド、ヘッダー、ステータス、リクエストボディ追加
    • 1997 年 : HTTP/1.1
    • 2015 年 : HTTP/2
  • HTTP の先祖
    • 電子メール
      • ヘッダーはインターネット普及以前のメールシステムに由来する
        • Authorization : 認証情報をサーバーに伝える.標準的な形式(Basic/Digest/Bearer)は RFC で定められている.
        • Content-Type : ファイルの種類。MIME タイプ(RFC6838)で記述する。text/html みたいなやつ。
        • Content-Length : ボディの長さをバイト単位で表す。圧縮されている場合は圧縮後のサイズを表す。
      • MIME タイプ
        • タイプ/サブタイプ;引数=値といった形で記述する、ファイル形式の標準。
          • タイプ : データのカテゴリ。videotext
          • サブタイプ : データの正確な種類。タイプがtextの場合はplaintext
        • タイプごとに利用可能なサブタイプが決まっている。
    • ニュースグループ
      • メソッドとステータス
  • URL
    • HTTP のために作られたが、それまでにあった FTP、メールなどにも対応した規格になっている。

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

  • HTTP/1.0 ではクライアントからのボディ(フォーム)送信、ファイル送信が可能に

    1. application/x-www-form-urlencoded

      • ブラウザは RFC1866 の変換フォーマットでボディをエンコードして送信

        decode  title=Head First PHP & MySQL&author=Michael Morrison
        RFC1866 title=Head+First+PHP+%26+MySQL&author=Michael+Morrison
        
    2. multipart/form-data

      • 1 度のリクエストで複数ファイルを送信できる
      • boundaryで区切られたファイルはメタ情報(ファイル名やファイル形式)を保持できる

        headers...
        Content-Type: multipart/form-data; boundary=------WebKitFormBoundaryX139fhEFk
        
        ------WebKitFormBoundaryX139fhEFk
        Content-Description: form-data; name="title"
        
        The Art of Community
        ------WebKitFormBoundaryX139fhEFk
        Content-Description: form-data; name="attachment-file"; filename="test.txt"
        Content-Type: text/plain
        
        hello world
        ------WebKitFormBoundaryX139fhEFk--
        
  • コンテントネゴシエーション

    • サーバーとクライアントで最適な設定を決める。使うヘッダーは 4 種類。

      Request Header Response ネゴシエーション対象
      Accept Content-Type MIME タイプ(ファイル形式)
      Accept-Language Content-Language 表示言語
      Accept-Charset Content-Type 文字コード
      Accept-Encoding Content-Encoding ボディの圧縮形式
      1. ファイルの種類

        • q は品質係数と呼ばれ、MIME タイプの優先順位を表す。0 ~ 1 の数値が指定でき、デフォルトは 1.0 となる。
        Accept: text/html,application.xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
        
      2. コンテンツの圧縮

        • 同じ記号が何度も出る JSON であれば 1/20 のサイズになる
        • クライアントが受け入れ可能な圧縮方式を指定(Accept-Encoding) => サーバーが指定された方式で圧縮(Content-Encoding)
        • Content-Length は圧縮後のサイズ
  • クッキー

    • サイトの情報をブラウザに保存する仕組み。ヘッダー上でやりとりされる。
    • やり取りの流れ
      • クライアントはサーバーから受け取ったクッキーをローカルのストレージに保存
      • 同オリジンへアクセスする場合はそのクッキーを読み出しサーバーへ送信
    • 注意点
      • 永続性が保証できない
      • 最大容量は 4 キロバイト
      • HTTP の場合は平文で送受信され漏洩の危険性
    • クッキーに寿命や制約を与える
      • Expires, Secure, HttpOnly, SameSite 属性など
    • オリジン
      • "スキーム", "ドメイン", "ポート"の 3 つの組が同じであればブラウザは同一オリジンと判定する
        • クッキーに限らず、localStorage や sessionStorage もオリジン単位で送受信を判定
    • SameSite 属性
      • Strict, Lax, None の 3 種類
      • SameSite=Strict か Lax を指定しておくと他サイトからのクロスサイトなリクエスト時にクッキーが飛んで来ないようにできる
      • デフォルトは Lax か
  • 認証とセッション

    • BASIC 認証と Digest 認証は ID/PW を毎回クライアントから送る方式
    • クッキーを使ったセッション管理がメジャー
      • フォーム等で ID/PW を送信し、認証が通ればクッキーにセッショントークンを発行。2 回目以降はクッキーを再送し認可してもらう。
  • プロキシ

    • HTTP などの通信を中継する仕組み
      • プロキシにキャッシュ機能を持たせてレスポンスを高速化したりする。外部からの攻撃から保護するファイアウォールとしての役割もある。
    • プロキシを設定するとスキームも追加されて、"http://"や"https://"から始まる URL 形式になる。<=??よくわかっていない
  • キャッシュ

    • キャッシュにはブラウザ上のキャッシュとプロキシサーバーあるいは CDN(Content Delivery Network)のキャッシュの大きく 2 種類がある。
    • Expires ヘッダー
      • Expires ヘッダーの日時が期限内であればキャッシュ=「新鮮」なので強制的にブラウザキャッシュを利用。
      • デメリットとして、期日以内に更新されたコンテンツを見ることが一切できない。
    • Etag
      • 更新日時と違い、基本的にはファイルのハッシュ値を使う。
      • サーバー側で自由に生成できるので、更新日時+ファイルサイズとかでも OK。
    • Cache-Control ヘッダー
      • キャッシュ制御をブラウザに指示できるヘッダー。
      • キーは(private,public,max-age,no-cache,no-store)
      • no-cache を指示すると、「基本的にはずっとキャッシュを使い、デプロイしたタイミングで新しいものを読み込ませたい」時に便利。キャッシュバスティング。
    • Vary
      • 同じ URL でもクライアントによって返す結果が異なることを示す
      • User-Agent や Accept-Language など、結果が変わる条件をヘッダーに記載する
    • リファラー(Referer)
      • アクセス元の URL をクライアントからサーバーに送信する。
      • Referer が送信されないよう制限することも可能。Referrer-Policy または Content-Security-Policy ヘッダーで設定する。
    • 検索エンジン(クローラー)へのアクセス制御
      1. robots.txt: クローラーにアクセスして欲しくないファイルを伝える
      2. サイトマップ: クローラーにサイトページの一覧を提供する

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

HTTP/1.0 で登場するリクエストのパターンを Go 言語で実装する

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

  • 通信の高速化
    • Keep-Alive がデフォルトで有効に
      • Keep-Alive とはハンドシェイクの回数を減らすことで TCP/IP レイヤーでの通信回数を減らす仕組み
      • HTTP レイヤーだと、2 回目以降の通信で高速化
      • クライアントとサーバーどちらかのタイムアウト時間になるまで有効
  • TLS による暗号化通信のサポート
    • TLS は通信の安全を守るための仕組み
      1. 中間者に通信を傍受されたり
      2. 中間者に通信内容を改ざんされたり
      3. 中間者にクライアントと偽ってリクエストを送られたりしない仕組みを提供
    • TLS の通信手順1
      1. C: SSL サーバー証明書の安全性を確認
      2. C: 共通鍵を作成し、証明書内の公開鍵で暗号化
      3. S: 秘密鍵で復号
      4. C/S: 共通鍵で通信内容を暗号化
  • 新メソッドの追加
    • PUT と DELETE が必須のメソッドとなった
    • OPTION, TRACE, CONNECT メソッドが追加
  • プロトコルのアップグレード
  • 名前を使ったバーチャルホストのサポート

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

  • ファイルのダウンロード
    • ブラウザが MIME タイプをもとに基本インライン表示。表示できない MIME タイプはダウンロード。
    • Content-Dispositionヘッダーに attachment を指定すると、ダウンロードを強制できる。
  • ダウンロードの中断・再開
    • Accept-Rangesヘッダーで範囲指定ダウンロードの可否を教えてあげる。
    • 範囲指定ダウンロードを行うときは、Rangesヘッダーに範囲を指定する。
    • 圧縮している場合は圧縮後のバイナリファイルに範囲指定する。
  • XMLHttpRequest
    • HTTP 通信を JavaScript から使えるようにする
  • Geo-Location
    • クライアントの承認が必要だが位置情報の正確性が高い Geolocation API
      • W3C で規格化され、ほとんどのブラウザが対応
    • クライアントの承認が必要ない GeoIP
  • X-Powered-by
    • システム名(Apache, nginx など)を返すのに使われてきた。現在はServerヘッダーの方が主流。
  • リモートプロシージャコール(RPC)
    • 「クライアント − サーバー」型の通信プロトコルで、サーバー上で実装されている関数(Procedure、プロシージャ)をクライアントからの呼び出しに応じて実行する技術
    • XML-RPCSOAP, JSON-RPC などがある
    • 最近では gRPC が人気
  • WebDAV
  • ウェブサイト間で共通の認証・認可プラットフォーム
    • シングルサインオン
      • 各システム間のアカウント管理をバラバラに行わず、一度サインインしたら、全システムが全て有効になるような仕組み
      • Kerberos 認証, SAML, OpenID, OpenSocial, OAuth, OpenID Connect など
    • OAuth2
      • 他サービスへ権限を移譲する認可の仕組み
    • OpenId Connect3
      • OAuth2.0 をベースに、認可だけでなく認証も行えるように拡張した仕組み
      • 今後のデファクトスタンダードになっていく可能性
    • JWT (JSON Web Token)

  1. 本にある図(p.119)がわかりやすい。

  2. 仕様書の日本語訳 https://www.openid.or.jp/document/

  3. この@TakahikoKawasaki さんの記事が分かりやすかった。https://qiita.com/TakahikoKawasaki/items/498ca08bbfcc341691fe