【ミライトデザイン社内勉強会#2】HTTPについて

## 参考

[HTTP の概要 - HTTP | MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Overview)


## プロトコルとは？

[プロトコル (protocol)とは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word11.html)

 コンピューター同士の通信をする際の手順や規格のこと。

-  HTTP（Hypertext Transfer Protocol）
    - ホームページ閲覧。パソコンとWebサーバーのデータのやり取り。
    - **HTTP は、 HTML 文書などのリソースを取り出すことを可能にするプロトコルです。**
- SSL（Secure Sockets Layer）
    - 送受信しているデータを暗号化通信のプロトコル。httpsから始まるホームページで使われます。
-  FTP（File Transfer Protocol）
    - パソコンからサーバーへファイルの転送。ホームページ作成のファイルアップロードなどで使われます。
- SMTP（Simple Mail Transfer Protocol）
    - メールを送信する取り決めのこと
- TCP/IP
    - TCP「Transmission Control Protocol」とIP「Internet Protocol」を組み合わせたもの
    - TCPは、信頼性・確実性を重視したデータ送受信。HTTP、HTTPS、POP3、SMTP、FTPなどと組み合わされて使われます。ホームページ閲覧、メール送受信、ファイル転送など。
    - データ・パケットを指定された場所まで届ける。インターネットで幅広く使われるプロトコル。
- UDP（User Datagram Protocol）
    - [インターネット用語1分解説～UDPとは～ \- JPNIC](https://www.nic.ad.jp/ja/basics/terms/udp.html)
    
    > インターネットで標準的に使われているプロトコルの一種で、 「User Datagram Protocol」の略です。 インターネット・プロトコル(IP)を使ったネットワークにおいて、 アプリケーション同士が最小限の仕組みでデータを送受信できるように考案された、 シンプルなプロトコルです。 OSI参照モデル*1におけるトランスポート層のプロトコル

## OSI参照モデル

[OSI参照モデル - Wikipedia](https://ja.wikipedia.org/wiki/OSI%E5%8F%82%E7%85%A7%E3%83%A2%E3%83%87%E3%83%AB)
[OSI参照モデルまとめ \- Qiita](https://qiita.com/tatsuya4150/items/474b60beed0c04d5d999#%E3%83%AC%E3%82%A4%E3%83%A4%E3%83%BC7%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E5%B1%A4)

- 層を分けてカプセル化することができる
- 第1,2,3,4層　あたりはルーターとかがやってくれる
- アプリケーション開発者が触っているのは第5,6,7あたり
- HTTPやFTP等の通信サービス。は第７層のプロトコル

## Hypertextとは？

- 関連付けされている文書
- HTML
    - リンクで相互の関連付けをする

## Proxyサーバーとは
[プロキシ (proxy)とは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word1752.html)

- 通信を中継してくれるサーバーのこと
- クライアントからリクエストを受け取って、サーバーに送信する
    - サーバーはクライアントを知らない
- 子供フィルターとかもプロキシサーバーで行っている

- 透過的
    - HTTPリクエストには変更を加えない。
- 透過的出ない
    - サーバーを通過する前に何らかの形でリクエストを変更する

### リバースプロキシとは
[リバースプロキシ - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%AA%E3%83%90%E3%83%BC%E3%82%B9%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7)

[リバースプロキシ (reverse proxy)とは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word1755.html)

- HTTPサーバーで受け取って、リバースプロシキを利用して別のポートへ飛ばしたりしてた
- リバースなので標準の使い方と別
    - たくさんのクライアントからプロキシで受け取って1つのサーバーに飛ばすのが標準の使いたか
        - クライアント: サーバー = n : 1
    - 1つのリクエストを複数のサーバーに飛ばすのがリバースプロキシ
        - クライアント: サーバー = 1 : n
- 負荷の分散や、セキュリティに利用

### リバースプロキシとプロキシの違い

[リバースプロキシとは？仕組みをわかりやすく解説 \| カゴヤのサーバー研究室](https://www.kagoya.jp/howto/network/reverse-proxy/)

> <img width="706" alt="スクリーンショット 2020-05-21 11.57.05.png (61.2 kB)" src="https://img.esa.io/uploads/production/attachments/14942/2020/05/21/76977/8c8650b9-f6d8-4d24-98b4-b3a4b07f6113.png">

## ユーザーエージェント
- ブラウザ
- Android, IOS
    - Retrofit、Alamofire

- ユーザーの代わりのリクエストを送ってくれるもの全て

### ブラウザの役割
https://developer.mozilla.org/ja/docs/Web/HTTP/Overview#Client_the_user-agent
> ウェブページは、ハイパーテキスト文書です。これは表示されているテキストの一部が新たなウェブページの取り込みを (通常、マウスのクリックによって) 発生させるリンクであり、ユーザーがユーザーエージェントを導いてウェブ内を移動できるということです。ブラウザーはこれらの導きを HTTP リクエストに変換して、さらにユーザーへ明確なレスポンスを返すために HTTP レスポンスを解釈します。

## ウェブサーバー

- 冗長化
    - 複数のサーバーを同じIPアドレスで接続でき、自動で振り分けてくれる
    - 中のコードは同じなので、負荷を分散できる

## HTTPの基本方針

- HTTP はシンプル
    - HTTP/2 で HTTP メッセージをフレームにカプセル化することにより複雑さが増しましたが、 HTTP は全体的にシンプルで人間が読めるように設計されています。
- HTTP は拡張可能
    - CookieはHTTPの標準ヘッダーを拡張した機能
- HTTP はステートレスであるがセッションレスではない
    - 状態を持たない
    - 他のリクエストに影響を受けない
    - Cookieを使用することによって、ステートフルなセッションが実現できる。
        - Cookieはブラウザが保持している
            - 保存要領4096byt
        - CookieにsessionIdが保存されている
- HTTPとコネクション
    - HTTPはTCPに依存している
        - TCPは信頼性があり、UDPには信頼性がない
            - UDPはゲームの通信に使われてたりする
    - クライアントとサーバーが HTTP で通信するには TCP コネクションの確立が必要
    - TCPでは通信の最初に3ウェイハンドシェイクという通信を行う
        - UDPではTCPのように3ウェイハンドシェイクを行わず、コネクション管理も行いません。このため、速くデータを送信出来、サーバー側の負荷も軽くて済みます。
    - HTTP/1.0ではリクエスト/レスポンスのペアでコネクションを開いていたので効率が悪かったが、HTTP/2ではひとつのコネクションで複数のメッセージをやりとりできるようになったので効率が向上した
    - [ネットワーク入門サイト - TCP・UDP](https://beginners-network.com/tcp_udp.html)

## HTTPが制御できること

### キャッシュ

- 提供されたリソースの複製を保存して、要求されたときに背後でその複製を提供する技術です。
- ブラウザキャッシュ：一度アクセスしたサイトのデータ（画像やHTMLなど）をブラウザで一時的に保管しておく仕組み
    - キャッシュがないと毎回サーバーにアクセスする必要がある。
- 共有キャッシュ：複数のユーザーによって再使用されるレスポンスを保存するキャッシュです。

#### HTTPキャッシュの対象
- GETのレスポンスのみキャッシュされる

> [HTTP キャッシュ - HTTP | MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Caching)
<img width="910" alt="image.png (102.0 kB)" src="https://img.esa.io/uploads/production/attachments/14942/2020/06/04/76977/454279c3-aea4-412a-9467-a8c0017578b1.png">


### オリジン制約の緩和

- 同一のオリジンのページだけが、ウェブページの情報すべてにアクセスできる。
    - セキュリティー保護のため
- HTTPヘッダーの設定によって同一のオリジン以外のページも利用できる。

- [同一オリジンポリシー - ウェブセキュリティ | MDN](https://developer.mozilla.org/ja/docs/Web/Security/Same-origin_policy#:~:text=%E5%90%8C%E4%B8%80%E3%82%AA%E3%83%AA%E3%82%B8%E3%83%B3%E3%83%9D%E3%83%AA%E3%82%B7%E3%83%BC%E3%81%A8%E3%81%AF,%E3%81%AB%E5%88%B6%E9%99%90%E3%81%99%E3%82%8B%E3%82%82%E3%81%AE%E3%81%A7%E3%81%99%E3%80%82)

-  [CORS (Cross-Origin Resource Sharing) ってなに？](https://aloerina01.github.io/blog/2016-10-13-1)
> オリジンとは
オリジン ＝ スキーム、ホスト、ポートの組み合わせ
(※スキームによって微妙に違うこともある)
> `http://www.exsample.com:80/index.html`のURLを例にすると
> スキーム ＝ `http://`
ホスト ＝ `www.exsample.com`
ポート ＝ `80` (ポート番号「80」は省略可なので普段見かけることは少ない)

### 認証

 > 基本的な認証は HTTP が提供しており、 WWW-Authenticate などのヘッダーを使用するか、 HTTP Cookie を使用した特別なセッションを設定するかします。

### プロキシとトンネリング
[プロキシサーバーとトンネリング - HTTP | MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Proxy_servers_and_tunneling)

- プロキシ
    - 上記でも記載されている。proxyサーバー。

- トンネリング
>トンネリングはデータをカプセル化することによって、パブリックネットワークを介してプライベートネットワークデータおよびプロトコル情報を送信します。

    - [トンネリング (tunneling)とは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word12036.html)

### セッション

- HTTP Cookie を使用して、リクエストとサーバーのセッションを関連付けて状態をもつ

## HTTP のフロー

クライアントがサーバー (最終目的地のサーバーまたは中間のプロキシ) と通信したいとき、クライアントは以下の段階を踏みます。

- TCP コネクションを開く
    - リクエスト/レスポンスの通信をするためにコネクションを開く
- HTTP メッセージを送信する
    - リクエストを受け取ってレスポンスが帰ってくる

> ```
GET / HTTP/1.1
Host: developer.mozilla.org
Accept-Language: fr
```

- サーバーから送信されたレスポンスを読み取る
    - サーバーから帰って来るのは全て文字列。
    - ブラウザが読み込んで整形してくれる。


> ```
HTTP/1.1 200 OK
Date: Sat, 09 Oct 2010 14:28:02 GMT
Server: Apache
Last-Modified: Tue, 01 Dec 2009 20:18:22 GMT
ETag: "51142bc1-7449-479b075b2891b"
Accept-Ranges: bytes
Content-Length: 29769
Content-Type: text/html

> <!DOCTYPE html... (ここに、リクエストした 29769 バイトのウェブページがある)
```


## HTTPメッセージ

- 文字を送信して、文字を受け取っているだけ。

### リクエスト

> <img width="693" alt="image.png (59.8 kB)" src="https://img.esa.io/uploads/production/attachments/14942/2020/06/04/76977/a8f4d7e4-b5f6-4252-84c4-935bcc08974b.png">

- メソッド
    - GET、POST、DELETEなど
- パス
- HTTPプロトコルのバージョン
- ヘッダー
- 空行
    - 空行でヘッダーとボディを分けてる
- POSTなども場合はボディもある

[HTTPリクエストとは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word1841.html)

> <img width="213" alt="image.png (8.2 kB)" src="https://img.esa.io/uploads/production/attachments/14942/2020/06/04/76977/296d039d-52fa-4907-810f-fc381a34e40a.png">




### レスポンス

> <img width="758" alt="image.png (176.2 kB)" src="https://img.esa.io/uploads/production/attachments/14942/2020/06/04/76977/d9c4ec38-e9fa-41e5-b969-6817eb9d8d22.png">

- 準拠する HTTP プロトコルのバージョン。
- ステータスコード。リクエストが成功したか否か、およびその理由を示します。
- ステータスメッセージ。ステータスコードの簡単な説明ですが、権威はありません。
- リクエストと同様の HTTP ヘッダー。
- (省略可) リソースを含む本文。

## 質問
#### ファイルのダウンロードとかはどうやってる？

- Content-Typeでファイルかどうかを判定している。
- やりとりできるのは文字列だけ。

#### HTTP2.0ってあんまり実際に見たことないけど普及してるの？
- まだあんまり普及はしてないかも？
- [HTTP/2 - Wikipedia](https://ja.wikipedia.org/wiki/HTTP/2)