# 機能設計書 49-プロキシ設定

## 概要

本ドキュメントは、JenkinsのHTTPプロキシ設定機能の設計を記載する。

### 本機能の処理概要

プロキシ設定は、Jenkinsがインターネットアクセス時に使用するHTTPプロキシサーバーの設定を管理する機能を提供する。プラグインのダウンロード、アップデートセンターへのアクセス、その他の外部通信に適用される。

**業務上の目的・背景**：企業環境では、インターネットアクセスにプロキシサーバーを経由する必要がある場合が多い。Jenkinsがプラグインの更新やセキュリティ情報の取得などで外部と通信するため、プロキシ設定が必要である。

**機能の利用シーン**：
- 企業ネットワーク内でのJenkins運用
- プラグインのインストール・更新
- アップデートセンターからのセキュリティ情報取得
- URLConnectionを使用する任意の外部通信

**主要な処理内容**：
1. プロキシサーバー設定（ホスト名、ポート）
2. プロキシ認証設定（ユーザー名、パスワード）
3. プロキシ除外ホストの設定
4. 接続テスト機能

**関連システム・外部連携**：外部HTTPサーバーとの通信全般に影響。

**権限による制御**：プロキシ設定の変更にはJenkins.ADMINISTER権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 55 | プラグインマネージャー | 関連画面 | プロキシ設定タブでの設定 |

## 機能種別

設定管理 / ネットワーク設定

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | String | Yes | プロキシサーバーのホスト名 | 空文字不可 |
| port | int | Yes | プロキシサーバーのポート番号 | 0-65535の範囲 |
| userName | String | No | プロキシ認証のユーザー名 | - |
| secretPassword | Secret | No | プロキシ認証のパスワード（暗号化） | - |
| noProxyHost | String | No | プロキシを使用しないホスト（パターン、複数指定可） | 正規表現パターン |
| testUrl | String | No | 接続テスト用URL | 有効なURL形式 |

### 入力データソース

- Web UIからのフォーム入力
- $JENKINS_HOME/proxy.xmlからのロード

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| name | String | プロキシホスト名 |
| port | int | プロキシポート番号 |
| userName | String | 認証ユーザー名 |
| secretPassword | Secret | 暗号化されたパスワード |
| noProxyHost | String | 除外ホストパターン |

### 出力先

- $JENKINS_HOME/proxy.xml（設定ファイル）
- メモリ上の設定オブジェクト

## 処理フロー

### 処理シーケンス

#### 設定の保存

```
1. フォーム送信
2. パラメータバリデーション
   └─ ポート番号の範囲チェック
3. ProxyConfigurationオブジェクト生成
4. XmlFile.write()でproxy.xmlに保存
5. SaveableListener通知
```

#### 接続テスト（doValidateProxy）

```
1. 権限チェック（Jenkins.ADMINISTER）
2. テストURLのバリデーション
3. HttpClientビルダー設定
   └─ プロキシサーバー設定
   └─ 認証設定
   └─ タイムアウト設定
4. HEADリクエスト実行
5. レスポンスステータス確認
6. FormValidation返却
```

#### URLConnection時のプロキシ適用

```
1. ProxyConfiguration.open(URL)呼び出し
2. プロキシ設定存在チェック
3. 除外ホストパターンマッチング
4. プロキシ適用（または直接接続）
5. 認証設定（必要な場合）
6. デフォルトタイムアウト設定
7. URLConnection返却
```

### フローチャート

```mermaid
flowchart TD
    A[URLConnection要求] --> B{プロキシ設定あり?}
    B -->|No| C[直接接続]
    B -->|Yes| D[createProxy()呼び出し]
    D --> E{除外ホストにマッチ?}
    E -->|Yes| C
    E -->|No| F[プロキシ経由接続]
    F --> G{認証設定あり?}
    G -->|Yes| H[Authenticator設定]
    G -->|No| I[タイムアウト設定]
    H --> I
    C --> I
    I --> J[URLConnection返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-49-01 | 除外ホストパターン | noProxyHostはスペース/タブ/改行/カンマ/パイプで区切り | 除外ホスト設定時 |
| BR-49-02 | ワイルドカード | 除外ホストパターンで「*」はワイルドカードとして機能 | 除外ホスト設定時 |
| BR-49-03 | デフォルトタイムアウト | 接続タイムアウトはデフォルト20秒 | 全URLConnection |
| BR-49-04 | パスワード暗号化 | パスワードはSecret型で暗号化保存 | 認証設定時 |
| BR-49-05 | HTTPS認証キャッシュ | 最初のHTTPSアクセス前にHTTP接続で認証キャッシュをシード | プロキシ認証時 |

### 計算ロジック

#### 除外ホストパターンマッチング
```
1. noProxyHostを区切り文字で分割
2. 各パターンの「.」を「\\.」にエスケープ
3. 各パターンの「*」を「.*」に変換
4. 正規表現としてホスト名とマッチング
```

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

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

| 操作 | 対象ファイル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 保存 | $JENKINS_HOME/proxy.xml | WRITE | プロキシ設定の永続化 |
| ロード | $JENKINS_HOME/proxy.xml | READ | 起動時の設定読み込み |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| FormException | ポート番号エラー | ポートが0-65535範囲外 | 有効なポート番号を指定 |
| FormException | テストURL必須 | 接続テストでURLが未指定 | テストURLを指定 |
| IOException | 接続エラー | プロキシ経由の接続に失敗 | プロキシ設定とネットワークを確認 |

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

XMLファイルへの保存は原子的ではないが、XmlFileクラスが一時ファイルを経由したアトミック書き込みを実装。

## パフォーマンス要件

- 接続テスト: タイムアウト20秒（デフォルト）
- プロキシ判定: 1ミリ秒以内

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

- プロキシパスワードはSecret型で暗号化保存
- 接続テスト実行にはJenkins.ADMINISTER権限が必要
- プロキシ認証情報がTLS以外で送信される場合の警告表示

## 備考

- デフォルトタイムアウトはシステムプロパティで変更可能
- newHttpClient()/newHttpClientBuilder()でモダンなHttpClientを使用可能
- java.net.Authenticatorを使用したプロキシ認証をサポート

---

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

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

### 推奨読解順序

#### Step 1: ProxyConfiguration基盤を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ProxyConfiguration.java | `core/src/main/java/hudson/ProxyConfiguration.java` | プロキシ設定の主要クラス |

**主要処理フロー（ProxyConfiguration）**:
- **100行目**: DEFAULT_CONNECT_TIMEOUT_MILLIS（デフォルト20秒）
- **102-117行目**: フィールド定義（name, port, userName, secretPassword, noProxyHost）
- **133-155行目**: コンストラクタ（設定値の初期化）
- **157-168行目**: newAuthenticator() - プロキシ認証のAuthenticator生成
- **213-233行目**: getNoProxyHostPatterns() - 除外ホストパターンの取得
- **235-237行目**: isExcluded() - 除外ホスト判定
- **268-277行目**: createProxy() - Proxyオブジェクト生成
- **280-285行目**: save() - 設定の永続化
- **310-336行目**: open(URL) - プロキシ適用URLConnection取得
- **367-368行目**: newHttpClient() - モダンHttpClient生成
- **389-408行目**: newHttpClientBuilder() - HttpClient.Builder生成
- **422-428行目**: newHttpRequestBuilder() - HttpRequest.Builder生成
- **515-641行目**: DescriptorImpl - 設定画面とバリデーション

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

```
外部通信要求
    │
    ├─ ProxyConfiguration.open(URL)
    │      ├─ get() - ProxyConfiguration取得
    │      ├─ createProxy(host) - Proxy生成
    │      │      └─ isExcluded(host) - 除外判定
    │      ├─ URL.openConnection(proxy)
    │      └─ Authenticator.setDefault() - 認証設定
    │
    └─ ProxyConfiguration.newHttpClient()
           └─ newHttpClientBuilder()
                  ├─ proxy(JenkinsProxySelector)
                  ├─ authenticator()
                  └─ connectTimeout()

設定画面
    │
    └─ DescriptorImpl
           ├─ doCheckPort() - ポート番号バリデーション
           ├─ doCheckUserName() - ユーザー名警告
           ├─ doCheckSecretPassword() - パスワード警告
           └─ doValidateProxy() - 接続テスト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ProxyConfiguration.java | `core/src/main/java/hudson/ProxyConfiguration.java` | ソース | プロキシ設定主要クラス |
| ProxyConfigurationManager.java | `core/src/main/java/hudson/ProxyConfigurationManager.java` | ソース | プロキシ設定管理 |
| URLConnectionDecorator.java | `core/src/main/java/hudson/URLConnectionDecorator.java` | ソース | URLConnectionカスタマイズ |
| UserAgentURLConnectionDecorator.java | `core/src/main/java/jenkins/UserAgentURLConnectionDecorator.java` | ソース | User-Agent設定 |
