HTTP通信のざっくりとした流れについて調べてみた

## はじめに
こんにちは！SIerに入社して１年目の新人エンジニアです。日々の業務で当たり前のように使われている用語で「えっ、それって何？」と思ったものを調べて、自分なりにまとめていきます。

今回は「HTTP通信の流れ」について。

## 目次
- [TCP/IPモデルってそもそも何？](#tcpipモデルってそもそも何)
- [HTTP通信の基本的な流れ](#http通信の基本的な流れ)
- [カプセル化と脱カプセル化って何？](#カプセル化と脱カプセル化って何)
- [クライアント側のカプセル化](#クライアント側のカプセル化)
  - [アプリケーション層](#アプリケーション層)
  - [トランスポート層](#トランスポート層)
  - [インターネット層](#インターネット層)
  - [ネットワークインターフェース層](#ネットワークインターフェース層)
- [サーバー側の脱カプセル化](#サーバー側の脱カプセル化)
- [HTTPレスポンスの流れ](#httpレスポンスの流れ)
- [まとめ](#まとめ)
- [参考資料](#参考資料)

## TCP/IPモデルってそもそも何？
調べてみて最初に混乱したのが「OSI参照モデル」と「TCP/IPモデル」という似ているけど違う概念でした。今回はより実用的なTCP/IPモデルで説明します。

TCP/IPモデルは4つの層で構成されています

1. **ネットワークインターフェース層**（物理層＋データリンク層）：物理的な接続と、LANなどの物理ネットワーク内での通信を担当
2. **インターネット層**：異なるネットワーク間でのデータ配送を担当（IPがここで活躍）
3. **トランスポート層**：端末間のデータ転送を制御（TCPやUDPがここに属する）
4. **アプリケーション層**：ユーザーが使用するアプリケーションの通信を担当（HTTPはここ）

これらの層が連携して通信を実現しているんですね！

## HTTP通信の基本的な流れ
HTTP通信は、クライアント（例えばブラウザ）からサーバーへのリクエストと、サーバーからクライアントへのレスポンスから成り立っています。

ざっくりとした流れはこんな感じ
1. ユーザーがブラウザでURLを入力
2. ブラウザがHTTPリクエストを作成
3. リクエストデータが各層を通過して、徐々に必要な情報が追加される（**カプセル化**）
4. ネットワークを通じてサーバーにデータが届く
5. サーバー側で各層を逆に通過しながら、追加された情報が解析・除去される（**脱カプセル化**）
6. サーバーアプリケーションがリクエストを処理
7. レスポンスが同様のプロセスを逆に辿ってクライアントに戻る

## カプセル化と脱カプセル化って何？

**カプセル化**：上位層から下位層へデータが渡される際に、各層で必要なヘッダー情報が追加されていく過程
**脱カプセル化**：下位層から上位層へデータが渡される際に、各層でヘッダー情報が解析・除去されていく過程

郵便物に例えると、最初に手紙（データ）を書いて、封筒に入れて（HTTPヘッダー）、宛先を書いて（TCPヘッダー）、郵便番号を追加して（IPヘッダー）、最後に配達方法の指示を書く（イーサネットヘッダー）みたいな感じです！

## クライアント側のカプセル化
クライアントからサーバーへのHTTPリクエストが、各層でどのようにカプセル化されていくのか見ていきましょう。

### アプリケーション層
ここでは、ユーザーがブラウザでWebページを表示しようとしている場面を想像してください。

1. ユーザーが「https://example.com」と入力
2. ブラウザがHTTPリクエストを作成します：
```
GET / HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 ...
Accept: text/html,application/xhtml+xml,...
```

この時点でのデータ構造は
```
[HTTPヘッダー][HTTPデータ(空の場合もある)]
```

### トランスポート層
アプリケーション層からデータを受け取ったトランスポート層（TCP）では：

1. 宛先ポート（HTTPなら80番、HTTPSなら443番）と送信元ポートを決定
2. データの分割（必要な場合）とシーケンス番号の割り当て
3. TCPヘッダーを追加

TCPヘッダーには以下の情報が含まれます
- 送信元ポート番号（例: 51234）
- 宛先ポート番号（例: 443）
- シーケンス番号
- 確認応答番号
- コントロールフラグ（SYN, ACK, FIN など）
- ウィンドウサイズ

この時点でのデータ構造は
```
[TCPヘッダー][HTTPヘッダー][HTTPデータ]
```

### インターネット層
トランスポート層からデータを受け取ったインターネット層（IP）では

1. 送信元IPアドレスと宛先IPアドレスを決定
   - 宛先IPはDNS解決で得られたexample.comのIPアドレス
   - 送信元IPはクライアントのIPアドレス
2. IPヘッダーを追加

IPヘッダーには以下の情報が含まれます
- プロトコルバージョン（IPv4/IPv6）
- 送信元IPアドレス
- 宛先IPアドレス
- データ長
- TTL（Time To Live）

この時点でのデータ構造は
```
[IPヘッダー][TCPヘッダー][HTTPヘッダー][HTTPデータ]
```

### ネットワークインターフェース層
インターネット層からデータを受け取ったネットワークインターフェース層では

1. MACアドレス（物理アドレス）の解決（ARP）
   - 次のルーターのMACアドレスを取得
2. イーサネットフレームのヘッダーとフッターを追加

イーサネットヘッダーには以下の情報が含まれます：
- 送信元MACアドレス
- 宛先MACアドレス
- イーサタイプ（例: IPv4, IPv6, ARP）

最終的なデータ構造は
```
[イーサネットヘッダー][IPヘッダー][TCPヘッダー][HTTPヘッダー][HTTPデータ][イーサネットフッター]
```

この形でデータはクライアントから物理的なネットワークを通ってルーターへ、そしてインターネットを経由して最終的にサーバーに届きます。

## サーバー側の脱カプセル化
サーバーにデータが届くと、クライアント側と逆の流れで各層を上っていきます。

1. **ネットワークインターフェース層**：
   - イーサネットヘッダーとフッターを確認・除去
   - MACアドレスを確認（自分宛てか確認）
   - IPパケットを抽出してインターネット層へ渡す

2. **インターネット層**：
   - IPヘッダーを確認・除去
   - IPアドレスを確認（自分宛てか確認）
   - トランスポート層のデータを抽出して渡す

3. **トランスポート層**：
   - TCPヘッダーを確認・除去
   - ポート番号を確認（正しいサービス宛てか確認）
   - データを結合（分割されていた場合）
   - アプリケーション層にデータを渡す

4. **アプリケーション層**：
   - HTTPヘッダーを解析
   - リクエストを処理（Webサーバーが対応するリソースを探す）
   - レスポンスを生成

## HTTPレスポンスの流れ
レスポンスは基本的にリクエストと逆の流れをたどります：

1. サーバーアプリケーションがHTTPレスポンスを作成
2. アプリケーション層からトランスポート層へと下りながらカプセル化
3. 物理的なネットワークを通じてクライアントへ
4. クライアント側で脱カプセル化
5. ブラウザがHTTPレスポンスを処理してWebページを表示

## まとめ
HTTP通信は、一見シンプルな「リクエスト→レスポンス」の流れに見えますが、実際には複数のネットワーク層で様々な処理が行われていました。各層がそれぞれの役割を果たし、ヘッダー情報の追加（カプセル化）と解析・除去（脱カプセル化）を行うことで、インターネット上の異なるコンピュータ間での通信を実現しているようです。

## 参考資料
https://zenn.dev/itpassport/articles/03bd090fa135ba

https://www.itmanage.co.jp/column/osi-reference-model/