# 機能設計書 4-https

## 概要

本ドキュメントは、Node.jsのhttpsモジュール（HTTPSサーバー・クライアント機能）の機能設計を記載する。httpsモジュールは、TLS/SSLで暗号化されたHTTP通信を提供するコアモジュールである。

### 本機能の処理概要

httpsモジュールは、httpモジュールの機能をTLS/SSL暗号化で拡張したものである。サーバー側では証明書を使用した暗号化接続を受け付け、クライアント側ではSSL/TLS接続を確立してセキュアな通信を行う。

**業務上の目的・背景**：現代のWebアプリケーションでは、データの機密性と完全性を保護するためHTTPS通信が必須となっている。httpsモジュールは、セキュアなWebサーバーの構築、外部APIへの安全な接続、認証情報の保護などを実現するための基盤機能を提供する。

**機能の利用シーン**：
- セキュアなWebアプリケーションサーバーの構築
- 外部REST API（決済、認証等）への安全な接続
- マイクロサービス間のセキュア通信
- クライアント証明書認証
- プロキシサーバー経由のHTTPS通信（CONNECTトンネル）

**主要な処理内容**：
1. HTTPSサーバーの作成と起動（createServer, Server）
2. TLS証明書の設定と検証
3. クライアントリクエスト（request, get）
4. プロキシトンネル確立（CONNECT method）
5. TLSセッションキャッシュ
6. ALPN（Application-Layer Protocol Negotiation）対応

**関連システム・外部連携**：
- tlsモジュール（TLS/SSL暗号化）
- httpモジュール（HTTP処理）
- netモジュール（TCP接続）
- cryptoモジュール（暗号化処理）

**権限による制御**：特別な権限制御なし。ポート番号443（標準HTTPSポート）は1024未満のためOS権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 直接関連する画面なし |

## 機能種別

ネットワーク通信 / セキュア通信 / サーバー構築

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| url | string / URL | Yes（リクエスト時） | リクエスト先URL | URL形式チェック |
| options | object | No | サーバー/リクエストオプション | validateObject |
| key | string / Buffer | Yes（サーバー） | 秘密鍵 | - |
| cert | string / Buffer | Yes（サーバー） | 証明書 | - |
| ca | string / Buffer / Array | No | CA証明書 | - |
| requestListener | Function | No | リクエストハンドラ | validateFunction |
| ALPNProtocols | Array | No | ALPNプロトコル一覧 | - |

### 入力データソース

- 証明書：ファイルシステムまたは設定から読み込み
- リクエスト：アプリケーションコードからのAPI呼び出し

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| server | Server | HTTPSサーバーインスタンス |
| request | ClientRequest | クライアントリクエストインスタンス |
| response | IncomingMessage | レスポンスメッセージ |
| socket | TLSSocket | TLS暗号化ソケット |

### 出力先

- サーバー：クライアントへの暗号化HTTPレスポンス
- クライアント：イベント（'response'）またはコールバック

## 処理フロー

### 処理シーケンス（サーバー）

```
1. createServer()でServerインスタンス生成
   └─ TLS設定（証明書、ALPN等）を適用
2. tls.Server継承による暗号化レイヤー初期化
3. server.listen()でポートをバインド
4. TLSハンドシェイク
   └─ クライアントとの暗号化接続確立
5. HTTPリクエスト処理
   └─ _connectionListenerでHTTP解析
6. レスポンス送信
   └─ 暗号化されたレスポンスを返却
```

### 処理シーケンス（クライアント/プロキシ経由）

```
1. request()でClientRequest生成
2. プロキシ使用判定（kProxyConfig）
3. プロキシ経由の場合
   └─ getTunnelConfigForProxiedHttps()でトンネル設定
   └─ CONNECT リクエスト送信
   └─ 200応答でトンネル確立
   └─ TLSハンドシェイク（目的サーバーと）
4. 直接接続の場合
   └─ tls.connect()でTLS接続
5. HTTPリクエスト送信
6. レスポンス受信
```

### フローチャート

```mermaid
flowchart TD
    A[https.request] --> B{プロキシ使用?}
    B -->|Yes| C[CONNECT送信]
    C --> D{200応答?}
    D -->|Yes| E[トンネル確立]
    D -->|No| F[ERR_PROXY_TUNNEL]
    E --> G[TLSハンドシェイク]
    B -->|No| G
    G --> H[HTTPリクエスト送信]
    H --> I[レスポンス受信]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | デフォルトALPN | ['http/1.1']をデフォルトALPNとして設定 | ALPNProtocols未指定時 |
| BR-002 | セッションキャッシュ | maxCachedSessions（デフォルト100）でTLSセッションをキャッシュ | Agent使用時 |
| BR-003 | プロキシトンネル | HTTPS接続はCONNECTメソッドでトンネル確立 | プロキシ経由時 |
| BR-004 | 証明書検証 | rejectUnauthorizedでサーバー証明書を検証 | クライアント接続時 |

### 計算ロジック

- maxCachedSessions: デフォルト100セッション
- defaultPort: 443

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

本モジュールはデータベースを直接操作しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ERR_PROXY_TUNNEL | プロキシエラー | トンネル確立失敗 | プロキシ設定を確認 |
| UNABLE_TO_VERIFY_LEAF_SIGNATURE | TLSエラー | 証明書検証失敗 | CA証明書を確認 |
| CERT_HAS_EXPIRED | TLSエラー | 証明書期限切れ | 証明書を更新 |
| DEPTH_ZERO_SELF_SIGNED_CERT | TLSエラー | 自己署名証明書 | CA設定またはrejectUnauthorized |

### リトライ仕様

アプリケーション層でのリトライ実装が必要。

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

HTTPはステートレスプロトコル。TLSセッション再開によるハンドシェイク高速化をサポート。

## パフォーマンス要件

- TLSセッションキャッシュによるハンドシェイクオーバーヘッド削減
- Keep-Alive接続の再利用
- ALPN事前ネゴシエーション

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

- 最新のTLSバージョン使用推奨（TLSv1.2以上）
- 弱い暗号スイートの無効化
- 証明書の適切な検証（rejectUnauthorized: true）
- HSTS対応
- 証明書透明性（CT）対応検討

## 備考

- HTTP/2はhttp2モジュールのcreateSecureServer使用
- Let's Encrypt等の無料証明書の利用が一般的

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | https.js | `lib/https.js` | Server, Agentクラスの継承関係 |

**読解のコツ**: httpsのServerはtls.Serverを継承し、AgentはHttpAgentを継承している。この継承関係を理解することが重要。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | https.js | `lib/https.js` | 公開API定義 |

**主要処理フロー**:
1. **75-115行目**: Server関数 - TLS設定とHTTPサーバー初期化
2. **117-118行目**: プロトタイプ継承設定
3. **147-149行目**: createServer()関数
4. **160-211行目**: getTunnelConfigForProxiedHttps() - プロキシトンネル設定
5. **213-321行目**: establishTunnel() - トンネル確立処理
6. **326-432行目**: createConnection() - TLS接続生成
7. **452-469行目**: Agent関数 - HTTPSエージェント
8. **612-630行目**: request()関数

#### Step 3: プロキシトンネル処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | https.js | `lib/https.js` | CONNECT処理の実装 |

**主要処理フロー（establishTunnel）**:
- **217-225行目**: read()関数 - プロキシ応答読み取り
- **243-290行目**: onProxyData() - 200応答検証とトンネル確立
- **278-288行目**: TLSハンドシェイク開始

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

```
https.createServer(opts, requestListener)
    │
    └─ new Server(opts, requestListener)
           │
           ├─ storeHTTPOptions(opts)        // HTTP設定保存
           │
           ├─ tls.Server.call(this, ...)    // TLSサーバー初期化
           │      └─ 証明書、ALPN設定
           │
           └─ this.addListener('request', requestListener)

https.request(options)
    │
    └─ new ClientRequest(options)
           │
           ├─ Agent.createConnection()
           │      │
           │      ├─ getTunnelConfigForProxiedHttps()  // プロキシ判定
           │      │
           │      └─ プロキシ経由
           │             ├─ net.connect() / tls.connect()  // プロキシ接続
           │             └─ establishTunnel()
           │                    ├─ CONNECT送信
           │                    ├─ 200応答待機
           │                    └─ tls.connect()  // 目的サーバーへTLS
           │
           └─ 直接接続
                  └─ tls.connect()
```

### データフロー図

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

証明書(key,cert) ───▶  tls.Server初期化   ───▶  TLSサーバー
                           │
ALPNProtocols   ───▶  ALPN設定           ───▶  プロトコルネゴシエーション
                           │
HTTPリクエスト  ───▶  _connectionListener ───▶  req, res
                           │
                      ハンドラ実行        ───▶  暗号化レスポンス

[クライアント]

オプション      ───▶  プロキシ判定
                           │
                      ┌────┴────┐
                      │         │
                プロキシ経由  直接接続
                      │         │
                 CONNECT ───▶ TLS接続 ───▶  暗号化リクエスト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| https.js | `lib/https.js` | ソース | 公開API定義（メイン） |
| tls.js | `lib/tls.js` | ソース | TLS/SSL基盤 |
| _http_agent.js | `lib/_http_agent.js` | ソース | HttpAgent基底クラス |
| _http_client.js | `lib/_http_client.js` | ソース | ClientRequest実装 |
| _http_server.js | `lib/_http_server.js` | ソース | HTTPサーバー基盤 |
| internal/http.js | `lib/internal/http.js` | ソース | プロキシ設定ユーティリティ |
