【HTTP】HTTPリクエストの流れ

### HTTP(HyperText Transfer Protocol)とは何か

コンピュータで扱えるデータの転送用プロトコルであり、RESTの重要な特徴である統一インターフェース、ステートレスサーバー、キャッシュなどをを実現している、TCP/IPをベースWEBの基盤となるプロトコル。


## 具体的な仕組み

#### クライアントとサーバー

Webはアーキテクチャスタイルに「クライアント/サーバー」を採用しており、クライアント(Webブラウザ)が情報を提供するサーバーに接続し、各種のリクエストを出してレスポンスを受け取る流れになっている。

#### リクエストとレスポンス

先述したリクエストからレスポンスまでの流れを「リクエスト/レスポンス型」のプロトコルと呼ぶ。
サーバーでの処理に時間がかかる場合でも、リクエストを出したクライアントはレスポンスが返るまで待機する。これはHTTPが同期型のプロトコルであるため。


#### クライアントで行われること

クライアントでは、以下の流れでリクエスト/レスポンスを行う

① リクエストメッセージの構築
② リクエストメッセージの送信
③ レスポンスが返るまで待機(同期型の場合)
④ レスポンスメッセージの受信
⑤ レスポンスメッセージの解析
⑥ クライアントの目的を達成するために必要な処理

最後にクライアントは、自身の目的を達成するための処理を行う。
ブラウザであれば、HTMLをレンダリングしてウィンドウに表示する処理。
検索エンジンようにデータを集めるロボットプログラムであれば、HTMLのデータの解析結果をデータベースに格納する処理。


#### サーバーで行われること

リクエストを受けたサーバーは、以下の処理を行う

① リクエストの待機
② リクエストメッセージの受信
③ リクエストメッセージの解析
④適切なアプリケーションプログラムへの処理の委譲
⑤ レスポンスメッセージの構築
⑥ レスポンスメッセージの送信


## HTTPメッセージ

リクエストメッセージとレスポンスメッセージをまとめて「HTTPメッセージ」と呼ぶ。


### HTTPメッセージの構造

#### リクエストメッセージ 
`http://example.jp:8080/search?s=test&tt#s90 `
上記に対する必要最小限のリクエストは、以下のようになる。

```
GET /search?s=test&tt HTTP/1.1
Host: example.jp:8000 
```
リクエストメッセージの1行目はリクエストラインと呼び、メソッド(GET)、リクエストURL(/search?s=test&tt)、プロトコルバージョン(HTTP/1.1)からなる。
URlフラグメント(s90)は、クライアント側で処理するのでリクエストメッセージには含めない。

リクエストURLは今回の例のようにパス以降の文字列になるか、絶対URLになる。
ただ、プロキシへのリクエストの場合は、リクエストURlに必ず絶対URLを使わなければならない。

リクエストメッセージの2行目はヘッダと呼ぶ。ヘッダはメッセージのメタデータとなる。1つのメッセージは複数のヘッダを持つことが出来る。
各ヘッダは、「名前: 値」という構成になっており、先の例では名前「Host」に値「example.jp:8000」が入っている。
8000は、ポート番号のこと。

先の例では記述しなかったが、ヘッダの後にボディが続くこともある。
ボディには、そのメッセージを表す本質的な情報が入る。

#### レスポンスメッセージ

先程の `http://example.jp:8080/search?s=test&tt#s90` へのリクエストが成功すると、サーバーは以下のようなレスポンスをクライアントに返す。

```
HTTP/1.1 200 OK
Content-Tyep: application/xhtml+xml; charset=uft-8

<html xmlns='http://www.w3.org/1999/xhtml'>
.
.
.
</html>
```

レスポンスメッセージの1行目はステータスラインと呼び、プロトコルバージョン(HTTP/1.1)、ステータスコード(200)、テキストフレーズ(OK)からなる。
ステータスコードはリクエストの結果をプログラムで処理可能な数値コードで表現する。この場合の「200」はリクエストが成功したことを示す。

2行目以降は、リクエストメッセージと同様にヘッダとなる。
この例では、Content-TyepヘッダでHTMLのMIMEメディアタイプ(application/xhtml+xml)、その文字エンコーディング方式(uft-8)を指定している。

この例ではボディにHTMLが含まれている。
ヘッダとボディは空行(ヘッダ最終行末尾のCRLFに連続するCRLF)で区切られる。
また、ボディにはテキストだけでなく、バイナリデータを入れることもできる。


### HTTPメッセージの構造を整理

1行目はスタートラインと総称される。リクエストメッセージの場合はリクエストライン、レスポンスメッセージの場合はステータスラインとなる。
ヘッダ各行の改行はCRLF、ヘッダの終了は空行で識別する。
また、ヘッダは省略することもできる。
最後は、ヘッダに続いてボディを持つことが出来る。

```
スタートライン
ヘッダ

ボディ​
```

## HTTPのステートレス性

ステートレス性とは、「サーバーがクライアントのアプリケーション状態を保存しない」制約のこと。
要するに、サーバーが前のやり取りを覚えていない。
HTTPはステートレスなプロトコルとして設計されている。

前のやりとりのことを、クライアントの「アプリケーション状態」と呼び、別名「セッション状態」とも呼ぶ。システムにログインしてからログアウトするまでの一連の動作を「セッション」と呼ぶが、この一連の操作の間の状態はアプリケーション状態のことなので、アプリケーション状態やセッション状態はほぼ同じ意味になる。
ステートレスの逆で、前のやり取りをサーバーが覚えていることを「ステートフル」と呼ぶ。


### ステートフルの欠点

サーバーがクライアントのアプリケーション状態を覚えることは、クライアントの数が増えるに従って難しくなっていく。
一つのサーバーが同時に相手をできるクライアントの数には上限があり、例えば、100台までのクライアントを処理できるサーバーの場合、101台以上のクライアントを処理するためには2台以上のサーバーが必要になる。
不特定多数のクライアントを相手にする場合はクライアントごとに接続するサーバーを特定できないため、複数のサーバー間でアプリケーションを同期して、どのサーバーでも同じアプリケーション状態を扱えるようにしなければいけない。2台のサーバー間でアプリケーション状態を同期できていたとしても、3台...4台...10台...100台... と増えていくと、データを同期するオーバーヘッドが無視できなくなる。
このように、ステートフルなアーキテクチャでは、クライアントの数が増えた場合にスケールアウトさせにくくなる欠点がある。


### ステートレスの利点

ステートフルの欠点を解決するのがステートレスなアーキテクチャ。
ステートレスでは、クライアントがリクエストメッセージに必要な情報を全て含めており、そのようなメッセージを「自己記述的メッセージ」という。
ステートレスなアーキテクチャでは、サーバーがクライアントのアプリケーション状態を覚える代わりに、全てのリクエストを自己記述的メッセージで送信する。
ステートレスなサーバーはアプリケーション状態を覚える必要がなく、新しく来るリクエストの処理に集中できるため、サーバー側のシステムは単純になる。
この性質を利用すると、処理に必要な情報は全てリクエストに含まれているため、クライアントが増えたらサーバーを増設するだけでよく、どのサーバーにリクエストを送っても構わないので、システムをスケールさせることは簡単になる。

ステートレスの欠点としては、以下がパフィーマンスを落とす要因になることがある。
・送信するデータ量が多くなる
・認証などのサーバーに負荷がかかる処理を繰り返す
・ネットワークトラブルが起きたときにそのリクエストが処理されたかどう
　かがわからない

***

### 用語

#### ハイパーテキスト 
複数の文書を相互に関連付け、結び付ける仕組み
HTML、XMLなどを指す

#### プロトコル 
コンピューター同士の通信をする際の手順や規格のこと

#### REST(REpresentational State Transfer) 〜
分散システムにおいて、複数のソフトウェアを連携させるのに適した設計原則の一つ

#### コンピュータで扱えるデータ 〜
ハイパーテキスト、静止画、音声、動画、javaScriptプログラム、PDF など

#### TCP/IP 
インターネットで標準的に用いられる通信プロトコル

#### アーキテクチャスタイル 
システムのアーキテクチャを決定する際の規約となるもの

#### アーキテクチャ 
コンピュータシステムの理論的構造

#### 同期型プロトコル 
リクエストした通りにレスポンスが返ってくる(順番が同期している)

#### メタデータ 
データについてのデータのこと

#### 絶対URL 
httpまたはhttpsから始まるURL

#### プロキシ 
内部ネットワークからインターネット接続を行う際、高速なアクセスや安全な通信などを確保するための中継サーバー

#### MIME(Multipurpose Internet Mail Extensions) 
インターネットの電子メールの規格を拡張して、さまざまな形式を扱えるようにした規格のこと

#### 文字エンコーディング方式 
文字コードを対応づける方式。
データを一定の規則に従って、目的に応じた情報に変換すること。変換された情報を符号（エンコード）、変換することを符号化（エンコーディング）と呼び、符号を元のデータへ戻すことを復号（デコード)と呼ぶ。

#### CRLF(Carrige Return / Line Feed) 
テキストデータの中で改行を指示する特殊な文字コードの組み合わせ

#### バイナリデータ 
コンピュータで扱える全てのデータのこと

#### オーバーヘッド 
送りたいデータや信号そのものとは別に付加的に必要となる制御用のデータなどのことや、それを処理、伝送するために余計にかかる負荷や時間のこと

#### スケールアウト 
システムを構成するサーバーの台数を増やすことで、システムの処理能力を高めること