Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RFC911Xから振り返るHTTPの仕様

shiro seike
September 24, 2022

 RFC911Xから振り返るHTTPの仕様

HTTPとPHPは切っても切れ離せない関係があります。

PHPもその周辺のミドルウェアもHTTPを正しく理解することで、さらにその力を発揮する事が出来ます。

そんなHTTPに関するRFCが2022年6月に新たに公開されました。

HTTPは実際にどのようなメッセージを送信、受信していてそのメッセージにはどのような意味が込められているのか、
PHPerにとって知っておくべきHTTP仕様をこのタイミングでRFC911*から振り返ってみましょう。

- 想定する聴講者
- HTTP仕様について興味がある方
- HTTP Messageの中身、やり取りについて知りたい方
- HTTP header による挙動変化について知りたい方

shiro seike

September 24, 2022
Tweet

More Decks by shiro seike

Other Decks in Programming

Transcript

  1. 自己紹介
 清家 史郎
 @seike460
 - ID
 - GitHub:seike460
 - Twitter:@seike460


    - Work at
 - 株式会社 Fusic (フュージック) 
 技術開発本部/技術開発第一部門 
 - チームリーダー/プリンシパルエンジニア/ 
 エバンジェリスト
 - Skill
 - PHP/Go/AWS
 - Community
 - Fukuoka.php Organizer 
 - PHPカンファレンス2018 - 2022 
 2

  2. Agenda
 3
 1. HTTPとは
 2. RFC 911*
 3. RFC 9110:

    HTTP Semantics
 4. RFC 9111: HTTP Caching
 5. RFC 9112: HTTP/1.1
 6. RFC 9113: HTTP/2
 7. RFC 9114: HTTP/3
 8. まとめ

  3. HTTP
 6
 Hypertext Transfer Protocol(HTTP)は、一般的なインターフェイス、拡張可能なセマンティクス、 
 および自己記述的なメッセージを共有する、ステートレスアプリケーションプロトコル 
 
 HTTP

    はクライアントとサーバー間の通信を目的として設計されており 
 旧来のクライアント・サーバーモデルに則っており、クライアントはサーバーに 
 リクエストを送信するためにポートを開き、サーバー側からのレスポンスが返ってくるまで待機。 
 
 HTTP ヘッダーによって、プロトコルの拡張や実験が容易になっており 、新しい機能であっても、
 クライアントとサーバーが新たなヘッダーの意味について単純な合意があれば導入可能。 
 
 HTTP はいわゆるステートレスプロトコルであり、
 サーバーは二つのリクエスト間で何もデータを保持しない。 
 参考:MDN Web Docs「HTTP」: https://developer.mozilla.org/ja/docs/Web/HTTP

  4. RFC911*
 10
 RFC 9110 - HTTP Semantics
 RFC 9111 -

    HTTP Caching
 RFC 9112 - HTTP/1.1
 RFC 9113 - HTTP/2
 RFC 9114 - HTTP/3
 RFC 9115 - An Automatic Certificate Management Environment (ACME) Profile 
 for Generating Delegated Certificates 
 RFC 9116 - A File Format to Aid in Security Vulnerability Disclosure 
 RFC 9117 - Revised Validation Procedure for BGP Flow Specifications 
 RFC 9118 - Enhanced JSON Web Token (JWT) Claim Constraints 
 for Secure Telephone Identity Revisited (STIR) Certificates 
 RFC 9119 - Multicast Considerations over IEEE 802 Wireless Media 

  5. RFC9110
 13
 RFC 9110 - HTTP Semantics
 HTTP メッセージの意味を定義づける
 


    - GETやPOSTといったHTTP Method
 - HTTPメッセージやコンテンツに関する情報を伝達する HTTP Header 
 - みんな大好き500 Internal Server Error 等のHTTP Status Code

  6. RFC9110 - 目次
 14
 - 1. Introduction
 - 2. Conformance

    
 - 3. Terminology and Core Concepts 
 - 4. Identifiers in HTTP 
 - 5. Fields
 - 6. Message Abstraction 
 - 7. Routing HTTP Messages 
 - 8. Representation Data and Metadata 
 - 9. Methods
 - 10. Message Context 
 - 11. HTTP Authentication 
 - 12. Content Negotiation 
 - 13. Conditional Requests 
 - 14. Range Requests 
 - 15. Status Codes 
 - 16. Extending HTTP 
 - 17. Security Considerations 
 - 18. IANA Considerations 
 - 19. References
 
 引用:WEB+DB PRESS Vol.123 HTTP3/入門 後藤 ゆきさんの記事より 

  7. Fields
 15
 今まで「HTTP Header」と呼んでいたHTTP Messageの
 ヘッダーセクション及びトレーラーセクションの事で
 RFC9110 - 5.1[Fields]にて説明がある。
 Field

    Namesはcase-insensitive(大文字小文字区別なし)で
 Hypertext Transfer Protocol Field Name Registryに登録する必要がある
 RFCやW3C等のリファレンスが、
 リンクとして提供されている
 
 登録はGitHub Issuesを通して
 審査が行われているようでした
 
 https://github.com/protocol-registries/http-fields 

  8. Message Abstraction
 16
 HTTPメッセージの構成は左図の様に定義されています。 
 
 
 Header Fields Header

    Fields Header Fields Contents Trailer Fields Trailer Fields Trailer Fields Header Section
 Contents
 Trailer Section
 HTTP HeaderでMessage Semanticsを変更または拡張したり、サー バーに追加のContextを提供したりする 
 Contentsの目的はMethods Semanticsで定義されます。 
 例えば、PUTの場合は「作成または置き換え」を目的としていて 
 置き換えるべきものがContents内に格納されます 
 メッセージの整合性チェック、デジタル署名、配信メトリック、 または後処理ステータス情報の提供に役立つ 
 HTTP/1.1ではASCII でエンコードされたテキスト形式で、 
 HTTP/2以降ではHTTP Framesと呼ばれるBinary形式で 
 HTTP Messageが送信されるがHTTPメッセージの構成としては同等です。 

  9. Methods
 17
 - GET
 - ターゲットとなるResourcesへ転送を要求する 
 - HEAD
 -

    サーバーがResponseにContentsを送信してはならない事を除いて、GETと同様 
 リンクのテストや、変更をチェックする為にメタデータを取得するために利用 
 - POST
 - 掲示板などにメッセージを投稿したり、ターゲットとなるResourcesに 
 データの追加を要求したりなど特定のSemanticsに従って、処理することを要求する 
 - PUT
 - ターゲットとなるResourcesの状態を作成または置き換えることを要求する 

  10. Methods
 18
 - DELETE
 - ターゲットとなるResourcesに現在の機能との関連性の削除をすることを要求する 
 - CONNECT
 -

    宛先オリジンサーバーへのトンネルを確立することを要求する 
 プロキシへのリクエストで使用することを目的としている 
 - OPTIONS
 - 利用可能な通信オプションに関する情報を要求する 
 - TRACE
 - リクエストメッセージのリモート、アプリケーションレベルのループバックを要求する 
 
 ※追加事項として、GET, HEAD, DELETEでコンテンツを含めるのを非推奨としている 
  DELETEにBodyを投げてたりする場合は注意が必要(数年前に身に覚えが… 

  11. Status Code
 19
 - Informational 1xx
 - 要求されたアクションを完了して最終的な応答を送信する前に、 
 接続ステータスまたは要求の進捗を通知するための暫定的な応答を示す

    
 - Successful 2xx
 - クライアントの要求が正常に受信、理解、受け入れられたことを示す 
 - Redirection 3xx
 - リクエストを満たすためにユーザーエージェントが 
 さらなるアクションを実行する必要があることを示す 
 - Client Error 4xx
 - クライアントがエラーしているように見えることを示す 
 - Server Error 5xx
 - サーバーが要求された方法を実行できないことを認識していることを示す 
 これらのそれぞれの定義が提供されている事と別に、 
 Status Codeが取りうる値が100 - 599で有ることを明示しています 

  12. RFC9111 - 目次
 21
 1. Introduction
 2. Overview of Cache

    Operation 
 3. Storing Responses in Caches 
 4. Constructing Responses from Caches 
 5. Field Definitions 
 6. Relationship to Applications and Other Caches 
 7. Security Considerations 
 8. IANA Considerations 
 9. References
 引用:WEB+DB PRESS Vol.123 HTTP3/入門 後藤 ゆきさんの記事より 

  13. Field Definitions
 22
 - Age
 - 応答が生成されたOrigin Serverで正常に検証されてから推定値を表す 
 max-ageよりもAgeが大きくなった場合、staleとして扱われ、逆の場合Freshとして扱われる

    
 - Cache-Control(※リクエストの場合、Responseの場合意味が異なる) 
 あくまで要求であることを意識する 
 - max-age:指定された秒数よりもAgeが少ないResponseを要求する 
 - max-stale:指定された秒数のstaleを受け入れる事を示す 
 - min-fresh:最低でも指定された秒数よりFreshなResponseを要求する 
 - no-cache:検証を成功させず、Originからの取得を要求する(スーパーリロードの際につく) 
 - no-store:キャッシュを保存してはならないことを要求する 
 - no-transform:proxyなどにContentsの変換を避ける事を要求する 
 - only-if-cached:キャッシュのResponseを期待し、違う時504(Gateway Timeout)を要求する 

  14. Field Definitions
 23
 - Cache-Control(※レスポンスの場合、前述のリクエストと同じディレクティブは省略してます) 
 - private:共有キャッシュがレスポンスを保存してはならない(ブラウザキャッシュ) 
 -

    public :共有キャッシュにレスポンスを保存してよい(CDN等のキャッシュ) 
 - Expires
 - 期限切れを表し、時刻を設定することでその時刻以降は無効なキャッシュで有ることを示す 
 - Pragma
 - HTTP/1.0時代のディレクティブであるため、現在は非推奨 
 - Warning
 - 追加情報を示すディレクティブであったが、浸透しないため廃止された 

  15. RFC 9112: HTTP/1.1 - 目次
 25
 RFC 9112: HTTP/1.1
 1.

    Introduction
 2. Message
 3. Request Line
 4. Status Line
 5. Field Syntax
 6. Message Body
 7. Transfer Codings
 8. Handling Incomplete Messages
 9. Connection Management
 10. Enclosing Messages as Data
 11. Security Considerations
 12. IANA Considerations
 13. References
 
 引用:WEB+DB PRESS Vol.123 HTTP3/入門 後藤 ゆきさんの記事より 

  16. Request Line Status Line
 26
 $ curl -v --http1.1 http://httpbin.org/get 


    
 * Trying 34.227.213.82:80... 
 * Connected to httpbin.org (34.227.213.82) port 80 (#0) 
 > GET /get HTTP/1.1 
 > Host: httpbin.org
 > User-Agent: curl/7.79.1 
 > Accept: */*
 >
 * Mark bundle as not supporting multiuse 
 < HTTP/1.1 200 OK 
 < Date: Fri, 19 Aug 2022 15:43:37 GMT 
 < Content-Type: application/json 
 < Content-Length: 253 
 < Connection: keep-alive 
 〜省略〜

  17. HTTPリクエストの構成要素
 27
 ▪リクエストライン
 GET … HTTP メソッド。クライアントが実行したい操作を定義する GET や POST等

    
 /hoge … リソースのパス 
 HTTP/1.1 … HTTP プロトコルのバージョン 
 > GET /hoge HTTP/1.1 
 
 ▪リクエストヘッダー 
 サーバーに追加の情報を与える任意のHTTPヘッダー 
 > Host: httpbin.org
 > User-Agent: curl/7.79.1 
 > Accept: */*
 
 ▪空行
 >
 ▪メッセージボディ
 POST等の場合はリクエスト内にボディが挿入されることがある。 

  18. Message Body
 28
 - Transfer-Encoding
 - Request側は理解できる圧縮形式を送付[accept-encoding: gzip, deflate, br]

    
 - Response側は[Transfer-Encoding: gzip, chunked]の様に 
 accept-encodingに合わせた形式でHeader Fieldsにてやり取りしながら返答 
 - Content-Length、Message Body Length 
 - Encodingに応じた長さを返答する 

  19. RFC 9113: HTTP/2 - 目次
 32
 1. Introduction
 2. HTTP/2

    Protocol Overview 
 3. Starting HTTP/2 
 4. HTTP Frames
 5. Streams and Multiplexing 
 6. Frame Definitions 
 7. Error Codes
 8. Expressing HTTP Semantics in HTTP/2 
 9. HTTP/2 Connections 
 10. Security Considerations 
 11. IANA Considerations 
 12. References
 引用:WEB+DB PRESS Vol.123 HTTP3/入門 後藤 ゆきさんの記事より 

  20. HTTP Frames & Streams
 34
 Head of Line Blockingの対策として、HTTP FramesとStreamsがあります


    HTTPメッセージを複数のFrameに分割してバイナリ形式で送受信します。
 Frame毎にリクエストとレスポンスが紐付いてやり取り出来るので、
 一つの大きなファイルへのリクエストに他のリクエストが待たされるという事がなくなり ました。

  21. RFC 7541 HPACK: Header Compression for HTTP/2
 35
 更に高速化する仕組みとしてHeaderを 


    Index番号で判断し、通信量を節約して高速化する 
 HPACKという仕組みがあります。 
 詳細は省きますが静的テーブルとして 
 インデックス番号を決めておいて番号を送信し、 
 通信量を減らす事が出来ます。 
 
 (動的テーブルもありますがここでは省きます 

  22. HTTP2(TCP)の課題
 36
 引用:HTTP/2: What no one is telling you:Hooman Beheshti


    TCPは送信したパケットを
 順番通りに処理する必要がある
 
 パケットロスが発生した場合、
 再度送信してもらう必要があり
 パケットの順番が入れ替わった時、
 もとの順番に戻す必要がある
 
 FastlyのHooman Beheshti氏によると
 シミュレーションにて
 ランダムパケットロスを2%を入れた時、
 HTTP1よりも遅くなる事がわかった

  23. RFC 9114: HTTP/3 - 目次
 38
 1. Introduction
 2. HTTP/3

    Protocol Overview 
 3. Connection Setup and Management 
 4. Expressing HTTP Semantics in HTTP/3 
 5. Connection Closure 
 6. Stream Mapping and Usage 
 7. HTTP Framing Layer 
 8. Error Handling
 9. Extensions to HTTP/3 
 10. Security Considerations 
 11. IANA Considerations 
 12. References
 引用:WEB+DB PRESS Vol.123 HTTP3/入門 後藤 ゆきさんの記事より 

  24. Google QUIC
 39
 QUICはTCPと同じトランスポートプロトコル
 UDPベースのHTTPプロトコルで
 TLS1.3が組み込まれておりHTTPSが利用される事が前提
 TCPのようなデータの整合性を担保し、TLS1.3を利用した 
 アプリケーションプロトコルレイヤの暗号化も行える 


    
 GoogleがChromeに実験的に組み込んだプロトコルで、 
 Google QUICをIETFにて議論され、IETFのワーキンググループ単位で 
 標準化が進められました。 
 
 HPACKはQPACKという新しい仕組みで置き直されていています。 
 RFC 9204 QPACK: Field Compression for HTTP/3 

  25. RFC 9114: HTTP/3
 41
 HTTP 3はQUICによりUDPベースでStream通信が出来るため、
 TCPの様にパケットロスが発生した場合でも
 それぞれのStream単位で処理を進める事が出来る
 
 その他にもConnectionIDにより、移動中Wifiネットワークから


    4G回線等に切り替わり時のIPアドレスが変更された際の通信の継続性対策や
 0-RTT及び1-RTTによる暗号化接続の高速化など
 様々な仕組みが追加されており改善が期待されています。

  26. まとめ
 Point 2
 HTTP1.1:今までのHTTPを支えてきた技術で、KeepAliveによりConnectionを保っていた 
 43
 HTTPを利用したアプリケーションの構築を行うにあたりRFC9110、RFC9111は是非見て欲しい
 Point 1
 


    HTTP2:HTTP Frame & Streamにより、TCPの中での性能向上が図られた
 Point 3
 Point 4
 HTTP3:QUICによるUDP通信により、さらなる性能向上が期待される

  27. 参考文献
 46
 ▪RFC Trans
 https://tex2e.github.io/rfc-translater/html/index.html
 
 ▪WEB+DB PRESS Vol.123
 ▪GitHub

    - flano-yuki/http3-note: My HTTP/3 Note
 HTTP/3入門 後藤 ゆきさん(GitHub:flanoyuki Twitter:@flano_yuki)

  28. telnetによるHTTPリクエスト
 49
 $ telnet www.httpbin.org 80
 Trying 3.94.154.124...
 Connected to

    www.httpbin.org.
 Escape character is '^]'.
 GET /get HTTP/1.1 ★実際に入力
 Host: httpbin.org ★実際に入力
 
 HTTP/1.1 200 OK
 Date: Wed, 17 Aug 2022 14:25:15 GMT
 Content-Type: application/json
 Content-Length: 197
 Connection: keep-alive
 Server: gunicorn/19.9.0
 Access-Control-Allow-Origin: *
 Access-Control-Allow-Credentials: true
 
 {
 "args": {},
 "headers": {
 "Host": "httpbin.org",
 "X-Amzn-Trace-Id": "Root=1-62fcfa4b-11ed483b37e7ba455a897f3a"
 },
 "origin": "125.56.55.69",
 "url": "http://httpbin.org/get"
 }
 telnetを利用しhttpbin.orgの 
 80番ポートに接続(HTTP標準ポート) 
 
 接続するHTTP Method (GET) 
 接続するURI (/get) 
 接続するHTTP Version(HTTP/1.1) 
 
 Host リクエストヘッダー(httpbin.org) 

  29. curlによるHTTPリクエスト
 50
 $ curl -v --http1.1 http://httpbin.org/get 
 
 *

    Trying 34.227.213.82:80... 
 * Connected to httpbin.org (34.227.213.82) port 80 (#0) 
 > GET /get HTTP/1.1 
 > Host: httpbin.org
 > User-Agent: curl/7.79.1 
 > Accept: */*
 >
 * Mark bundle as not supporting multiuse 
 < HTTP/1.1 200 OK 
 < Date: Fri, 19 Aug 2022 15:43:37 GMT 
 < Content-Type: application/json 
 < Content-Length: 253 
 < Connection: keep-alive 
 〜省略〜

  30. 一般的なHTTPリクエストヘッダー
 53
 Accept: "*/*"
 クライアントが理解できるコンテンツタイプを MIME タイプで伝える
 
 Accept-Encoding: "gzip,

    deflate, br"
 コンテンツのエンコーディング、圧縮アルゴリズムのどれをクライアントが理解することができるかを示します。
 Apacheのmod_deflate等が利用
 gzip:Lempel-Ziv coding (LZ77) と32ビット CRC を用いた圧縮形式
 deflate:zlib 構造体と deflate 圧縮アルゴリズムを用いた圧縮形式
 br:Brotli アルゴリズムを用いた圧縮形式
 
 Accept-Language: "ja,en-US;q=0.9,en;q=0.8"
 クライアントがどの言語を理解できるか、どの種類のロケールが推奨されるかを示す
 
 Cache-Control: "max-age=0"
 キャッシュをコントロールするヘッダーで、 no-storeをつけることでキャッシュをさせなくしたり、
 有効期限を設定したりします。

  31. 拡張HTTPリクエストヘッダー
 54
 Sec-Fetch-Dest: "document", 
 Sec-Fetch-Mode: "navigate", 
 Sec-Fetch-Site: "none",

    
 Sec-Fetch-User: "?1", 
 フェッチメタデータリクエストヘッダー 
 リクエストの発信元のコンテキストに関する追加情報を提供する HTTP リクエストヘッダー 
 リクエストがどこから来たのかという追加情報をサーバーに提供し、悪意のあるリクエストを無視できるようになる 
 
 Sec-Ch-Ua: "" Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97"" 
 Sec-Ch-Ua-Mobile: "?0", 
 Sec-Ch-Ua-Platform: ""macOS"", 
 User-Agent Client Hints 
 ユーザーエージェント(UA)クライアントヒントヘッダにより、サーバーはユーザーエージェント(ブラウザ)、 
 オペレーティングシステム、デバイスに応じて応答を変化させることができる。 
 
 X-Amzn-Trace-Id: "Root=1-61eb64b7-24bc07aa6d8b197a203a12a9" 
 AWSが付与するTrace情報 
 Application Load Balancerが付与するIDで、リクエストの行方を追うために利用する 

  32. POST リクエスト
 55
 $ curl -v -X POST --http1.1 http://httpbin.org/post

    
 * Trying 54.147.68.244:80... 
 * Connected to httpbin.org (54.147.68.244) port 80 (#0) 
 > POST /post HTTP/1.1 
 > Host: httpbin.org
 > User-Agent: curl/7.79.1 
 > Accept: */*
 >
 * Mark bundle as not supporting multiuse 
 < HTTP/1.1 200 OK 
 < Date: Fri, 19 Aug 2022 15:55:10 GMT 
 < Content-Type: application/json 
 < Content-Length: 317 
 〜省略〜

  33. POST Bodyの送信
 56
 $ curl -v -H "Content-Type: application/json" -d

    '{"hoge":"fuga"}' --http1.1 --trace-ascii - http://httpbin.org/post 
 Warning: --trace-ascii overrides an earlier trace/verbose option 
 == Info: Trying 34.227.213.82:80... 
 == Info: Connected to httpbin.org (34.227.213.82) port 80 (#0) 
 => Send header, 132 bytes (0x84) 
 0000: POST /post HTTP/1.1 
 0015: Host: httpbin.org 
 0028: User-Agent: curl/7.79.1 
 0041: Accept: */* 
 004e: Content-Type: application/json 
 006e: Content-Length: 15 
 0082:
 => Send data, 15 bytes (0xf) 
 0000: {"hoge":"fuga"} 
 == Info: Mark bundle as not supporting multiuse 
 〜省略〜