# 機能設計書 1-HttpFoundation

## 概要

本ドキュメントは、Symfony HttpFoundationコンポーネントの機能設計を記述する。HttpFoundationはHTTP仕様に基づくリクエスト・レスポンスのオブジェクト指向レイヤーを提供し、PHPのスーパーグローバル変数（`$_GET`、`$_POST`、`$_SERVER`、`$_COOKIE`、`$_FILES`）を置き換える抽象化を実現する。

### 本機能の処理概要

HttpFoundationコンポーネントは、HTTP通信の入出力をオブジェクト指向で扱うための基盤コンポーネントである。PHPの標準的なスーパーグローバル変数によるHTTPリクエスト/レスポンス処理を、型安全かつテスト可能なオブジェクト指向APIで置き換える。

**業務上の目的・背景**：PHPの標準的なHTTP処理はスーパーグローバル変数に依存しており、テスタビリティが低く、型安全性も欠ける。HttpFoundationはこれらの課題を解決し、HTTPメッセージを構造化されたオブジェクトとして扱うことで、保守性の高いWebアプリケーション開発を可能にする。Symfonyフレームワーク全体の基盤として、他のすべてのHTTP関連コンポーネントがこのコンポーネントに依存する。

**機能の利用シーン**：Webアプリケーション開発において、HTTPリクエストの受信からレスポンスの送信まで、すべてのHTTP通信処理で利用される。コントローラーでのリクエストパラメータ取得、レスポンス生成、セッション管理、Cookie操作、ファイルアップロード処理など、Web開発の基本操作すべてに関わる。

**主要な処理内容**：
1. HTTPリクエストのパース（クエリパラメータ、ボディ、ヘッダー、Cookie、アップロードファイル）
2. HTTPレスポンスの構築（ステータスコード、ヘッダー、ボディコンテンツ）
3. セッション管理（開始、読み書き、フラッシュメッセージ）
4. Cookie管理（生成、読み取り、削除）
5. ファイルアップロード処理（バリデーション、移動）
6. リダイレクトレスポンス、JSONレスポンス、ストリーミングレスポンス等の特殊レスポンス生成
7. IPアドレスユーティリティ、URLサイナー、Accept-Headerパーサー等の補助機能
8. リクエストマッチング機能（パス、ホスト、メソッド、IP等の条件マッチ）

**関連システム・外部連携**：HttpKernel、Routing、Security、BrowserKitなどSymfonyの主要コンポーネントすべてがHttpFoundationに依存する。また、PSR-7ブリッジを通じてPSR-7準拠のライブラリとの相互変換が可能。

**権限による制御**：HttpFoundation自体には認証・認可機能はないが、リクエストオブジェクトの`attributes`プロパティを通じてSecurityコンポーネントと連携し、認証情報の受け渡しに利用される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | プロファイラーホーム | 補助機能 | RedirectResponseを生成してHTTPリダイレクトを実行する |
| 2 | プロファイラーパネル | 補助機能 | Requestオブジェクトからのクエリパラメータ取得とResponseの生成 |
| 3 | プロファイラー検索 | 補助機能 | Sessionへの検索条件の保存とRedirectResponseの生成 |
| 4 | プロファイラー検索バー | 補助機能 | RequestおよびSessionから検索条件の取得 |
| 8 | PHP情報表示 | 補助機能 | phpinfo()の出力をResponseとして返却 |
| 9 | Xdebug情報表示 | 補助機能 | xdebug_info()の出力をResponseとして返却 |
| 12 | Webデバッグツールバー | 補助機能 | Requestからのトークン取得・Session処理、Responseの生成 |
| 14 | リクエスト情報パネル | 補助機能 | Request/Responseオブジェクトの詳細データ（ヘッダー、クエリ、Cookie等）の表示 |
| 42 | リダイレクト | 補助機能 | RedirectResponseの生成とHTTPステータスコードの管理 |

## 機能種別

基盤ライブラリ / HTTP通信抽象化 / データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| query | array | No | GETパラメータ ($_GET相当) | InputBagによる型安全なアクセス |
| request | array | No | POSTパラメータ ($_POST相当) | InputBagによる型安全なアクセス |
| attributes | array | No | ルーティング等で設定されるカスタム属性 | ParameterBagによるアクセス |
| cookies | array | No | Cookie値 ($_COOKIE相当) | InputBagによる型安全なアクセス |
| files | array | No | アップロードファイル ($_FILES相当) | FileBagによるUploadedFile変換 |
| server | array | No | サーバー変数 ($_SERVER相当) | ServerBagによるヘッダー抽出 |
| content | string/resource | No | リクエストボディの生データ | JSON等のペイロードとしてパース可能 |

### 入力データソース

- PHPスーパーグローバル変数（`$_GET`, `$_POST`, `$_SERVER`, `$_COOKIE`, `$_FILES`）
- `php://input`ストリーム（リクエストボディ）
- `Request::createFromGlobals()`によるファクトリメソッドで自動収集

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| statusCode | int | HTTPステータスコード（100-511） |
| headers | ResponseHeaderBag | レスポンスヘッダーコレクション |
| content | string | レスポンスボディ |
| version | string | HTTPプロトコルバージョン（1.0/1.1/2.0） |
| charset | string | レスポンスの文字エンコーディング |

### 出力先

- HTTP出力（`header()`関数およびPHP出力バッファ経由）
- `Response::send()`メソッドによるヘッダー送信とコンテンツ出力

## 処理フロー

### 処理シーケンス

```
1. リクエスト生成
   └─ Request::createFromGlobals()でPHPスーパーグローバルからRequestオブジェクトを構築
2. パラメータバッグの初期化
   └─ ParameterBag, InputBag, FileBag, ServerBag, HeaderBagの各インスタンスを生成
3. リクエスト情報の解析
   └─ URI、パスインフォ、ベースURL、HTTPメソッド、コンテンツタイプ等を解析
4. コントローラーでの処理
   └─ リクエストオブジェクトからパラメータを取得し、ビジネスロジックを実行
5. レスポンス生成
   └─ Response/JsonResponse/RedirectResponse等の適切なレスポンスオブジェクトを構築
6. レスポンス送信
   └─ Response::send()でヘッダーとコンテンツをクライアントに送出
```

### フローチャート

```mermaid
flowchart TD
    A[HTTPリクエスト受信] --> B[Request::createFromGlobals]
    B --> C[ParameterBag群の初期化]
    C --> D[URI/メソッド/ヘッダー解析]
    D --> E{コントローラー処理}
    E --> F[Response生成]
    F --> G{レスポンス種別}
    G -->|通常| H[Response]
    G -->|JSON| I[JsonResponse]
    G -->|リダイレクト| J[RedirectResponse]
    G -->|ファイル| K[BinaryFileResponse]
    G -->|ストリーム| L[StreamedResponse]
    H --> M[Response::send]
    I --> M
    J --> M
    K --> M
    L --> M
    M --> N[ヘッダー送信 + コンテンツ出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 信頼プロキシ制御 | X-Forwarded-*ヘッダーは信頼済みプロキシからのリクエストのみ解釈する | リバースプロキシ環境 |
| BR-02 | HTTPメソッドオーバーライド | `_method`パラメータまたはX-HTTP-Method-Overrideヘッダーによるメソッド上書きはPOSTリクエストのみ許可 | enableHttpMethodParameterOverride()が有効時 |
| BR-03 | セッションID再生成 | セッション固定攻撃防止のため、認証時にセッションIDを再生成する | Session::migrate()呼び出し時 |
| BR-04 | ファイルアップロード検証 | アップロードファイルはPHP内部のis_uploaded_file()チェックを通過したもののみ受け入れる | UploadedFile::move()実行時 |

### 計算ロジック

特になし（HTTP通信の抽象化が主目的のため、複雑な計算ロジックは含まない）。

## データベース操作仕様

### 操作別データベース影響一覧

HttpFoundationコンポーネント自体はデータベース操作を行わない。セッションストレージとしてPDOを利用する場合はSessionHandlerにて間接的にDBアクセスが行われるが、これはPHP標準のSessionHandlerInterfaceを通じた処理である。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | BadRequestException | 不正なリクエストパラメータ（型不一致等） | InputBagが自動検出し例外をスロー |
| - | ConflictingHeadersException | X-Forwarded-ForとForwardedヘッダーの矛盾 | 信頼プロキシ設定の見直し |
| - | SuspiciousOperationException | 不正なホスト名等のセキュリティ上疑わしい操作 | リクエスト元の検証 |
| - | SessionNotFoundException | セッションが設定されていない状態でのアクセス | リクエストにセッションを事前設定 |
| - | JsonException | 不正なJSONペイロード | リクエストボディのJSON形式を確認 |

### リトライ仕様

HTTPFoundationはリトライ機能を持たない（上位のHttpClientコンポーネントが担当）。

## トランザクション仕様

HTTPFoundationはトランザクション管理を行わない。

## パフォーマンス要件

- Requestオブジェクトの生成は軽量であり、通常1ms未満で完了する
- セッション処理はストレージバックエンドの性能に依存する
- opcache.preloadによるシンボル事前読み込みに対応（class_exists呼び出し）

## セキュリティ考慮事項

- **信頼プロキシ設定**: `Request::setTrustedProxies()`で信頼するプロキシIPとヘッダーを明示的に設定する必要がある。未設定のままX-Forwarded-*ヘッダーを信頼するとIPスプーフィングが可能
- **InputBagの型安全性**: 文字列パラメータへのアクセス時に`InputBag`が型チェックを行い、配列注入攻撃を防止
- **セッション固定攻撃防止**: `Session::migrate()`によるセッションID再生成
- **ファイルアップロード検証**: `UploadedFile::isValid()`によるPHPアップロードメカニズムの検証
- **ホスト名検証**: `Request::setTrustedHosts()`による許可ホスト名のパターン制限

## 備考

- Symfony 8.1-DEV時点のコードに基づく
- PHP 8.1以上が必要（型付きプロパティ、enum等を使用）
- PSR-7との相互変換はPsrHttpMessageBridgeコンポーネントが提供

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、HTTPメッセージを構成するパラメータバッグ群の構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ParameterBag.php | `src/Symfony/Component/HttpFoundation/ParameterBag.php` | 基本的なキー/バリュー格納の仕組み。all(), get(), set(), has()等の基本メソッド |
| 1-2 | InputBag.php | `src/Symfony/Component/HttpFoundation/InputBag.php` | ParameterBagを継承し、型安全なアクセスを提供。getString(), getInt()等 |
| 1-3 | HeaderBag.php | `src/Symfony/Component/HttpFoundation/HeaderBag.php` | HTTPヘッダー専用のバッグ。大文字小文字を区別しないキーアクセス |
| 1-4 | FileBag.php | `src/Symfony/Component/HttpFoundation/FileBag.php` | $_FILESをUploadedFileオブジェクトに変換するバッグ |
| 1-5 | ServerBag.php | `src/Symfony/Component/HttpFoundation/ServerBag.php` | $_SERVERからHTTPヘッダーを抽出するバッグ |

**読解のコツ**: ParameterBagが基底クラスであり、InputBag, HeaderBag, FileBag, ServerBagがそれぞれ特化した振る舞いを追加している継承関係を意識すること。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Request.php | `src/Symfony/Component/HttpFoundation/Request.php` | HTTPリクエストの中心クラス。1800行超の大規模クラス |

**主要処理フロー**:
1. **44-65行目**: HTTPメソッド定数の定義（METHOD_GET, METHOD_POST等）
2. **70-89行目**: 信頼プロキシ設定用の静的プロパティ
3. **94行目**: `$attributes`プロパティ（ParameterBag型）- ルーティング結果等のカスタム属性
4. **100行目**: `$request`プロパティ - POSTパラメータ（InputBag）

#### Step 3: レスポンスクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Response.php | `src/Symfony/Component/HttpFoundation/Response.php` | HTTPレスポンスの中心クラス |

**主要処理フロー**:
- **24-86行目**: HTTPステータスコード定数の定義（HTTP_OK=200, HTTP_NOT_FOUND=404等）
- **91-100行目**: Cache-Controlディレクティブの定義

#### Step 4: 特殊レスポンスクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | JsonResponse.php | `src/Symfony/Component/HttpFoundation/JsonResponse.php` | JSON形式のレスポンスを生成 |
| 4-2 | RedirectResponse.php | `src/Symfony/Component/HttpFoundation/RedirectResponse.php` | HTTPリダイレクトレスポンス |
| 4-3 | BinaryFileResponse.php | `src/Symfony/Component/HttpFoundation/BinaryFileResponse.php` | ファイルダウンロードレスポンス |
| 4-4 | StreamedResponse.php | `src/Symfony/Component/HttpFoundation/StreamedResponse.php` | ストリーミングレスポンス |
| 4-5 | StreamedJsonResponse.php | `src/Symfony/Component/HttpFoundation/StreamedJsonResponse.php` | ストリーミングJSONレスポンス |

#### Step 5: セッション管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Session/Session.php | `src/Symfony/Component/HttpFoundation/Session/Session.php` | セッション管理の中心クラス。SessionStorageInterface, AttributeBag, FlashBagの協調 |

**主要処理フロー**:
- **43-55行目**: コンストラクタ。NativeSessionStorage、AttributeBag、FlashBagの初期化
- **57-59行目**: start()メソッドでセッション開始をストレージに委譲

### プログラム呼び出し階層図

```
Request::createFromGlobals()
    |
    +-- new Request($query, $request, $attributes, $cookies, $files, $server, $content)
    |       |
    |       +-- new InputBag($query)         ... $this->query
    |       +-- new InputBag($request)       ... $this->request
    |       +-- new ParameterBag($attributes)... $this->attributes
    |       +-- new InputBag($cookies)       ... $this->cookies
    |       +-- new FileBag($files)          ... $this->files
    |       +-- new ServerBag($server)       ... $this->server
    |       +-- new HeaderBag()              ... $this->headers
    |
    +-- Request::getPathInfo()
    +-- Request::getMethod()
    +-- Request::getClientIps()
            |
            +-- IpUtils::checkIp()

Response::send()
    |
    +-- Response::sendHeaders()
    |       +-- header() PHP関数
    +-- Response::sendContent()
            +-- echo $this->content
```

### データフロー図

```
[入力]                        [処理]                              [出力]

$_GET/$_POST/$_SERVER  --->  Request::createFromGlobals()  --->  Request オブジェクト
$_COOKIE/$_FILES             ParameterBag群の初期化               (query, request, attributes,
php://input                  URI/メソッド/ヘッダー解析             cookies, files, server, headers)

Request オブジェクト    --->  コントローラー処理             --->  Response オブジェクト
                             ビジネスロジック実行                  (statusCode, headers, content)

Response オブジェクト   --->  Response::send()               --->  HTTPレスポンス出力
                             sendHeaders() + sendContent()        (ヘッダー + ボディ)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Request.php | `src/Symfony/Component/HttpFoundation/Request.php` | ソース | HTTPリクエスト表現の中心クラス |
| Response.php | `src/Symfony/Component/HttpFoundation/Response.php` | ソース | HTTPレスポンス表現の中心クラス |
| ParameterBag.php | `src/Symfony/Component/HttpFoundation/ParameterBag.php` | ソース | キー/バリュー格納の基底クラス |
| InputBag.php | `src/Symfony/Component/HttpFoundation/InputBag.php` | ソース | 型安全なパラメータバッグ |
| HeaderBag.php | `src/Symfony/Component/HttpFoundation/HeaderBag.php` | ソース | HTTPヘッダー管理 |
| ResponseHeaderBag.php | `src/Symfony/Component/HttpFoundation/ResponseHeaderBag.php` | ソース | レスポンスヘッダー管理（Cookie含む） |
| FileBag.php | `src/Symfony/Component/HttpFoundation/FileBag.php` | ソース | アップロードファイル管理 |
| ServerBag.php | `src/Symfony/Component/HttpFoundation/ServerBag.php` | ソース | サーバー変数管理 |
| Cookie.php | `src/Symfony/Component/HttpFoundation/Cookie.php` | ソース | Cookieオブジェクト |
| JsonResponse.php | `src/Symfony/Component/HttpFoundation/JsonResponse.php` | ソース | JSONレスポンス |
| RedirectResponse.php | `src/Symfony/Component/HttpFoundation/RedirectResponse.php` | ソース | リダイレクトレスポンス |
| BinaryFileResponse.php | `src/Symfony/Component/HttpFoundation/BinaryFileResponse.php` | ソース | バイナリファイルレスポンス |
| StreamedResponse.php | `src/Symfony/Component/HttpFoundation/StreamedResponse.php` | ソース | ストリーミングレスポンス |
| StreamedJsonResponse.php | `src/Symfony/Component/HttpFoundation/StreamedJsonResponse.php` | ソース | ストリーミングJSONレスポンス |
| EventStreamResponse.php | `src/Symfony/Component/HttpFoundation/EventStreamResponse.php` | ソース | Server-Sent Eventsレスポンス |
| ServerEvent.php | `src/Symfony/Component/HttpFoundation/ServerEvent.php` | ソース | SSEイベントオブジェクト |
| Session/Session.php | `src/Symfony/Component/HttpFoundation/Session/Session.php` | ソース | セッション管理 |
| RequestStack.php | `src/Symfony/Component/HttpFoundation/RequestStack.php` | ソース | リクエストスタック管理 |
| IpUtils.php | `src/Symfony/Component/HttpFoundation/IpUtils.php` | ソース | IPアドレスユーティリティ |
| UriSigner.php | `src/Symfony/Component/HttpFoundation/UriSigner.php` | ソース | URL署名ユーティリティ |
| UrlHelper.php | `src/Symfony/Component/HttpFoundation/UrlHelper.php` | ソース | URL生成ヘルパー |
| AcceptHeader.php | `src/Symfony/Component/HttpFoundation/AcceptHeader.php` | ソース | Accept-Headerパーサー |
| HeaderUtils.php | `src/Symfony/Component/HttpFoundation/HeaderUtils.php` | ソース | ヘッダーユーティリティ |
| ChainRequestMatcher.php | `src/Symfony/Component/HttpFoundation/ChainRequestMatcher.php` | ソース | リクエストマッチャーチェーン |
