Web技術の基本 (3) HTTPでやりとりする仕組み

# この記事の内容について
　Web系エンジニアになるための必須知識の1つである「Web技術の仕組み」について、初学者でもわかりやすいと定評のある書籍「イラスト図解式 この一冊で全部わかるWeb技術の基本」の要点を自分なりにまとめて、理解力の向上に努めていきます。
　私はまだエンジニア歴1年未満の初学者なので、間違い等があればご指摘いただけると幸いです。
# Web技術の基本 (1) 〜 (7)
[Web技術の基本(1) 〜Web技術とは〜](https://qiita.com/Nao52/items/a12402f8e21a9b9ba961)
[Web技術の基本(2) 〜Webとネットワーク技術〜](https://qiita.com/Nao52/items/9f5d7731abbec8f5f4eb)
[Web技術の基本(3) 〜HTTPでやりとりする仕組み〜](https://qiita.com/Nao52/items/e95a7094893f2332e68f)
[Web技術の基本(5) 〜Webアプリケーションの基本〜](https://qiita.com/Nao52/items/65c1a599f1ed484e6e5e)
[Web技術の基本(6) Webのセキュリティと認証](https://qiita.com/Nao52/items/326948f6195a515900fd)

# 1. HTTPメッセージ
### HTTPメッセージによる「要求」と「応答」
　HTTPでは、他のクライアント / サーバーシステム同様、クライアントであるWebブラウザが要求を送り、サーバーであるWebサーバーがその要求に対して応答を返すといった、単純なやり取りを繰り返すことで、Webサイトの閲覧を可能にしている。HTTPにおいて、WebブラウザとWebサーバーがやりとりする際に利用されるのが **「HTTPメッセージ」** と呼ばれるデータ型である。
### 2種類のHTTPメッセージ
* HTTPリクエスト・・・Webブラウザからの要求
* HTTPレスポンス・・・Webサーバーからの応答

# 2. HTTPリクエスト / HTTPレスポンス
### HTTPリクエスト
##### リクエスト行
→ Webサーバーに対してどのような処理をしてほしいかというリクエストの要求内容を記述しており、具体的には「情報を取得したい」、「情報を送信したい」といった情報をWebサーバーへ伝える。
##### メッセージヘッダー
→ Webブラウザの種類やバージョン、対応するデータ形式など付加的な情報を記述する。
##### メッセージボディ
→ Webページ内のフォーム欄などに入力したテキストデータなどをWebサーバーに送る目的で使用される。
### HTTPレスポンス
##### ステータス行
→ HTTPリクエストに対して、Webサーバーの処理の結果を伝える
##### メッセージヘッダー
→ Webサーバーの種類、送信するデータの形式など付加的な情報を記述
##### メッセージボディー
→ WebブラウザからリクエストされたHTMLなどのデータが格納される

# 3. HTTPメソッド
　HTTPリクエストを用いてWebサーバーに具体的な要求内容を伝えているのは、HTTPリクエスト内に含まれる「**HTTPメソッド**」である。
　HTTPメソッドは目的別に複数定義されているが、主に使われるのは、「**Get**」メソッドと「**Post**」メソッドである。
### 「Get」と「Post」の違い
#### 「Get」メソッド
URLにデータが組み込まれるため、送ったデータがWebブラウザの閲覧履歴に残る。
→ URLの末尾に「？」をつけ、「パラメータ=値」の形式で送信する
#### 「Post」メソッド
メッセージボディ内にデータが組み込まれるため、閲覧履歴には残らない。
→ 機密性を重視する場合や大量データを送信したい際に使用される

# 4. ステータスコード
　HTTPレスポンス内にはHTTPリクエストに対するWebサーバー内での処理結果が含まれている。それを「**ステータスコード**」という。
### ステータスコードの分類
ステータスコードは以下の5つに分類される
##### 100番台
continue : リクエスト継続中を通知する
##### 200番台
OK : リクエストが正常に受理されたことを通知する
##### 300番台
リクエストに対し、転送処理など追加の追加の処理が必要なことを通知する
##### 400番台
クライアントのエラーであることを通知する
##### 500番台
Webサーバのエラーであることを通知する

# 5. メッセージヘッダー
　HTTPリクエストとHTTPレスポンスはいずれも「**メッセージヘッダー**」を利用することで、HTTPメッセージ関する詳細な情報を送信することが可能となる。
　メッセージヘッダーは複数の「**ヘッダーフィールド**」という行から成り立っており、情報の種類によって以下の4つに分類できる。
##### 一般ヘッダーフィールド
→ リクエストとレスポンスの両方に含まれる。代表的なものとして、作成された日付を表す「Date」がある。
##### リクエストヘッダーフィールド
→ リクエストのみに含まれる。代表的なものとしてクライアントの固有情報を示す「User-Agent」がある。Webサーバーは「User-Agent」を参照して、クライアントごとに異なる処理を行うことができる。
##### レスポンスヘッダーフィールド
→ レスポンスのみに含まれる。代表的なものとして、プロダクト情報を示す「Server」などがある。「Server」が示す情報を制限することも可能である。
##### エンティティヘッダーフィールド
→ リクエストとレスポンスの両方に含まれる。一般ヘッダーがHTTPメッセージ全体に対しての付加情報を示すのに対して、メッセージボディに含まれるデータの付加情報を示す。代表的なものにデータの種類を示す「Content-Type」がある。

# 6. TCPによるデータ通信
　HTTPのデータのやりとりを行う際に、TCPが利用される。TCPはWebサイトの閲覧だけでなく、メールの送受信やファイルの転送といったデータ転送時に利用される。
　TCPはクライアントとサーバーがお互いに通信できる状況なのか確認し、「**コネクション**」と呼ばれる通信経路を確立した上でデータのやりとりを行う。
### コネクションの確立
1. クライアントからの接続要求　（SYN)
1. クライアントに対して確認応答および、サーバーからの接続要求 (SYN + ACK)
1. サーバーに対しての確認応答　(ACK)

　クラインアントからサーバーに対して、接続を要求するための**SYNパケット**と呼ばれるデータを送る。SYNパケットを受け取ったサーバーはそれに対して応答する。
　クライアントからの接続要求に対して、サーバーが確認応答(**ACKパケット**)を送信し、接続可能であることを伝える。また、クライアントに対して接続を要求するためにSYNパケットを同時に送信する。
　サーバーからの接続要求に対してクライアントはACKパケットを送信し、双方向で通信が可能であることを確認し、コネクションの確立が完了する。

# 7. HTTP/1.1のやりとり
### HTTPキープアライブ
　HTTP1.0以前ではWebブラウザからHTTPリクエストを送信するたびにTCPおけるコネクションを確立し、WebサーバーがHTTPレスポンスとしてデータを引き渡した段階でコネクションが閉じるという方式が用いられていた。
　HTTP1.1以降ではコネクションを継続して利用する方式となった。この機能を**HTTPキープアライブ**と呼ぶ。HTTP1.1以降では特に指定がない限りこの機能が利用されている。
### HTTPパイプライン
　HTTPにおけるデータのやりとりの効率化のため、HTTP1．1では**HTTPパイプライン**と呼ばれる機能がサポートされている。
　HTTPパイプラインはHTTPレスポンスを待つことなく複数のHTTPリクエストを送信することを可能としている。

# 8. HTTP/2のやりとり
### ストリームによる多重化
##### パイプライン機能 (HTTP / 1.1)
　「HTTPリクエストの順番通りにHTTPレスポンスを返さなければならない」という制約がある。そのため、ある一つのHTTPレスポンスの処理に時間がかかる場合、それ以降のHTTPレスポンスはその処理が終わるのを待つ必要があり、Webページの表示が遅くなる。
##### ストリーム (HTTP / 2)
　1つのTCPコネクション上に「**ストリーム**」と呼ばれる仮想的な通信経路を複数生成し、それぞれのストリーム内でHTTPリクエストとHTTPレスポンスのやりとりを可能とした。

# 9. HTTP/2での改良点
### バイナリ形式の利用
　より効率的にデータのよりとりをするためバイナリ形式のフォーマットを用いるようになった。データの変換処理にかかる時間やWebブラウザ、Webサーバーへの負担を軽減できる。
### ヘッダー圧縮
　HTTP/2ではヘッダー情報を圧縮することが可能となった。ヘッダー情報の中から差分だけを送るHPACKと呼ばれる圧縮方式を利用することで、データの転送量を削減できる。
### サーバープッシュ
　WebブラウザからのHTTPリクエストの内容をもとにWebサーバー側で必要なファイルを判断し、事前にWebブラウザに送信することが可能となった。

# 10. HTTPSの仕組み
　**HTTPS**とはHTTP over SSL/TLSの略で、HTTPの通信において、暗号化方式である**SSL(Secure Sockets Layer)** や**TLS(Transport Layer Security)** を利用することでWebサイトを安全に使うことができる仕組みのこと
### 安全性を確保する仕組み
##### 盗聴防止 (暗号化通信)
　万が一、通信内容を傍聴されても内容を解読させないために、データを暗号化して送ることにより、第三者からの盗聴を防ぐことができる。
##### 改ざん防止
　データの改ざん対策として、「メッセージダイジェスト」が利用される。メッセージダイジェストとは、あるデータから一意の短いデータ(ハッシュ値)を計算し、データ送受信時にハッシュ値を比較して改ざんを検知する。
##### なりすまし防止 (Webサイト運用元の確認)
　Webサーバーに「**SSL証明書**」と呼ばれる電子証明書を配置しておき、接続時に検証することで、Webサイトを運営する会社の身元を確認する。
　SSLサーバー証明書は発行を認められた「**認証局**」による運営元の認証作業を通過する必要があり、信頼できない発信元のSSLサーバー証明書が利用されている場合はWebブラウザに警告画面が表示される。

# 11. HTTPSのやりとり
### SSL/TLSハンドシェイク
HTTPSで通信を開始するには、以下の4つのフェーズのやりとりを行う必要がある。
1. 暗号化方式の決定
→ Webブラウザ、Webサーバーの両方が利用可能な暗号化形式の決定する。その他、HTTPSで利用されるSSL、TLSバージョンやメッセージダイジェストの方式など
1. 通信相手の証明
→ Webブラウザで通信しているWebサーバーが正しい相手なのか、SSLサーバー証明書により確認を行う。
1. 鍵の交換
→ データ転送に利用される「鍵」を交換する。鍵はデータを転送する際の暗号化、暗号化されたデータを復号する際にも利用される。
1. 暗号化方式の確認
→ 実際に利用する暗号化方式の最終確認作業を行う。

HTTPSにおけるこれら4つのフェーズのやりとりは、SSLあるいはTLSによって実現されるため、「**SSL/TLSハンドシェイク**」と呼ばれる。

# 12. ステートフルとステートレス
### ステートフルとステートレスの違い
##### ステートフル
　直前にやりとりをした相手など状態を、以降のやりとりでも覚えていること。多数のクライアントに対して1つのサーバーでやりとりをする場合、負担が非常に大きくなる。
##### ステートレス
　リクエスト / レスポンスの1往復のやりとりが完結された処理とみなされ、複数の処理を関連づける仕組みがないこと。HTTPでは多くの処理を素早く処理するため、ステートレスな設計が適している。

# 13. Cookie (クッキー)
　HTTPはステートレスなプロトコルであるため、状態を保持し管理する仕組みがない。そのため、状態を保持し管理する必要がある場合は**Cookie**と呼ばれるデータが用いられる。
### Cookieのやりとり
　Webサーバーへ接続してきたWebブラウザに対して、コンテンツなどと一緒にWebブラウザに保存してもらいたい情報をCookieとして送る。
　Cookieを受け取ったWebブラウザはそれを保存しておき、Webサーバーに接続する際に保存しておいたCookieを送信することで、Webサーバーは接続してきた相手を識別できる。
### メッセージヘッダーの利用
　WebサーバーはHTTPレスポンスに **「Set-Cookie」ヘッダー**を含めることでCookieを送信でき、WebブラウザはHTTPリクエストに　**「Cookie」ヘッダー**を含めることで送信できる。
### セッションCookie
　**有効期限が設定されていないCookie**は、Webブラウザが閉じられると同時に削除される。このようなCookieを「**セッションCookie**」と呼ぶ。

# 14. セッション
　WebブラウザとWebサーバーのやりとりにおいて、一連の関連性のある処理の流れを「**セッション**」と呼ぶ。
### セッションの管理
　セッション管理においてWebブラウザを識別するための情報を「**セッションID**」と呼び、セッションIDはWebサーバーで生成され、Cookieに含めてWebブラウザに送信される。
　セッションIDを受け取ったWebブラウザは、CookieにセッションIDを含めて処理を行うことでWebサーバーとのセッションを維持できる。

# 15. URI
　情報やデータといったリソースを識別するための記述方法を**URI(Uniform Resource Identifier)** と呼ぶ。
・URIのうちリソースが存在する場所を示すものを**URL(Uniform Resource Locator)**
・URIのうち場所は問わずにリソースの名前を示すものを**URN(Uniform Resorce Name)**
### リクエストURI
　HTTPリクエストの場合、URIはリクエスト行のメソッドに続いて記述され、「**リクエストURI**」とも呼ばれる。
　リクエストURIにはURIを全て含める**絶対URI形式**と、URIの一部を含める**相対URI形式**があり、通常は記述を簡略化した相対URI形式で記述される。
### パーセントエンコーディング
　URIで使用できる文字は定められており、「予約文字」と「非予約文字」が存在する。
　予約文字でも非予約文字でもない文字をURIで利用する場合は、「**パーセントエンコーディング**」と呼ばれる方法を用いてその文字を変換する必要がある。