# 画面設計書 78-プロキシ設定

## 概要

本ドキュメントは、Jenkinsのプロキシサーバー設定画面の設計仕様を記述したものです。

### 本画面の処理概要

この画面はJenkinsが外部ネットワーク（インターネット）にアクセスする際に使用するプロキシサーバーの設定を行う画面です。プラグインのダウンロード、アップデートセンターへの接続、外部リソースの取得など、Jenkinsが外部通信を行う際のプロキシ経由接続を構成します。

**業務上の目的・背景**：企業のイントラネット環境では、セキュリティポリシーによりインターネットへの直接接続が制限され、プロキシサーバー経由でのアクセスが必須となることが一般的です。この設定画面では、プロキシサーバーのホスト名、ポート番号、認証情報、プロキシを経由しないホスト（No Proxy Host）を設定することで、Jenkinsの外部通信を適切に構成できます。

**画面へのアクセス方法**：
1. Jenkins管理画面（Manage Jenkins）から「Manage Plugins」を選択
2. プラグイン管理画面の「Advanced」タブを選択
3. または、システム設定画面からプロキシ設定セクションにアクセス
4. URLは設定によって異なる（プラグイン管理の一部として組み込み）

**主要な操作・処理内容**：
1. プロキシサーバーのホスト名（Server）を入力
2. プロキシサーバーのポート番号（Port）を入力
3. プロキシ認証用のユーザー名（User name）を入力（オプション）
4. プロキシ認証用のパスワード（Password）を入力（オプション）
5. プロキシを経由しないホストのリスト（No Proxy Host）を入力
6. 接続テスト（Validate Proxy）の実行
7. 設定の保存

**画面遷移**：
- 遷移元：
  - Jenkins管理画面（28-Jenkins管理）
  - プラグイン管理画面（37-プラグイン管理トップ）
  - セットアップウィザード（55-プロキシ設定）
- 遷移先：
  - Jenkins管理画面（設定保存後）
  - プラグイン管理画面（設定保存後）

**権限による表示制御**：
- ADMINISTER権限：設定の編集、テスト、保存が可能
- 権限なし：アクセス不可

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 49 | プロキシ設定 | 主機能 | Jenkinsのプロキシサーバー設定 |
| 64 | フォームバリデーション | API連携 | 設定値の入力検証 |

## 画面種別

設定画面（フォーム編集）

## URL/ルーティング

- 設定フォーム: プラグイン管理画面のAdvancedタブに組み込み
- バリデーションエンドポイント: `POST /descriptorByName/hudson.ProxyConfiguration/validateProxy`

## 入出力項目

| 項目名 | 入出力 | 必須 | 型 | 説明 |
|--------|--------|------|-----|------|
| name (Server) | 入出力 | はい | String | プロキシサーバーのホスト名またはIPアドレス |
| port (Port) | 入出力 | はい | Integer | プロキシサーバーのポート番号（0-65535） |
| userName (User name) | 入出力 | いいえ | String | プロキシ認証用ユーザー名 |
| secretPassword (Password) | 入出力 | いいえ | Secret | プロキシ認証用パスワード（暗号化保存） |
| noProxyHost (No Proxy Host) | 入出力 | いいえ | String | プロキシを経由しないホストのリスト（改行/カンマ区切り） |
| testUrl (Test URL) | 入力 | いいえ | String | プロキシ接続テスト用のURL |

## 表示項目

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| Server入力欄 | テキストボックス | プロキシサーバーホスト名入力フィールド |
| Port入力欄 | 数値入力 | プロキシサーバーポート番号入力フィールド（0-65535） |
| User name入力欄 | テキストボックス | プロキシ認証ユーザー名入力フィールド |
| Password入力欄 | パスワード入力 | プロキシ認証パスワード入力フィールド（マスク表示） |
| No Proxy Host入力欄 | テキストエリア | プロキシ除外ホストリスト入力フィールド |
| Test URL入力欄 | テキストボックス | 接続テスト用URL入力フィールド（詳細設定内） |
| Validate Proxyボタン | ボタン | プロキシ接続テスト実行ボタン |

## イベント仕様

### 1-プロキシ接続テスト（Validate Proxy）

「Validate Proxy」ボタン押下時に、設定されたプロキシを使用して指定URLへの接続テストを実行します。

**処理フロー**:
1. テストURL、プロキシ設定情報をPOST送信
2. doValidateProxy()メソッドでプロキシ経由接続を試行
3. HttpClientを使用してHEADリクエストを送信
4. 接続結果をFormValidationで返却
5. 成功/失敗メッセージを画面に表示

### 2-ポート番号バリデーション

ポート番号入力時にリアルタイムでバリデーションを実行します。

**処理フロー**:
1. ポート番号の変更を検知
2. doCheckPort()メソッドでバリデーション
3. 0-65535の範囲チェック
4. 結果をFormValidationで返却

### 3-ユーザー名/パスワード警告

ユーザー名またはパスワード入力時に、非TLS接続の警告を表示します。

**処理フロー**:
1. 入力値の変更を検知
2. doCheckUserName()/doCheckSecretPassword()でチェック
3. 値が設定されている場合、非TLS警告をFormValidation.warningで返却

### 4-設定保存

設定保存時に、プロキシ設定をXMLファイルに永続化します。

**処理フロー**:
1. フォームデータを受信
2. ProxyConfigurationオブジェクトを生成/更新
3. save()メソッドでproxy.xmlに保存
4. SaveableListener.fireOnChange()で変更を通知

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 設定保存 | - | ファイル更新 | proxy.xmlに設定を保存 |

### テーブル別更新項目詳細

Jenkinsは設定をXMLファイルで管理しているため、データベーステーブルは使用しません。

#### 設定ファイル

| 操作 | ファイル | 更新内容 | 備考 |
|-----|---------|---------|------|
| 設定保存 | proxy.xml | プロキシ設定全体 | `$JENKINS_HOME/proxy.xml` |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| Server | ラベル | Server | 常時表示 |
| Port | ラベル | Port | 常時表示 |
| User name | ラベル | User name | 常時表示 |
| Password | ラベル | Password | 常時表示 |
| No Proxy Host | ラベル | No Proxy Host | 常時表示 |
| Test URL | ラベル | Test URL | 詳細設定内 |
| Validate Proxy | ボタン | Validate Proxy | 詳細設定内 |
| PortNotANumber | エラー | （ポートが数値でない） | ポート番号エラー時 |
| PortNotInRange | エラー | （ポートが範囲外） | ポート番号範囲外時 |
| NonTLSWarning | 警告 | （非TLS接続の警告） | ユーザー名/パスワード設定時 |
| TestUrlRequired | エラー | （テストURL未入力） | バリデーション時 |
| MalformedTestUrl | エラー | （不正なURL形式） | バリデーション時 |
| Success | 成功 | （接続成功） | バリデーション成功時 |
| FailedToConnect | エラー | （接続失敗） | バリデーション失敗時 |
| FailedToConnectViaProxy | エラー | （プロキシ経由接続失敗） | プロキシ経由接続失敗時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|----------|
| ADMINISTER権限なし | アクセス拒否 |
| ポート番号不正 | FormValidation.errorでエラーメッセージを表示 |
| テストURL未入力 | FormValidation.errorでエラーメッセージを表示 |
| テストURL形式不正 | FormValidation.errorでエラーメッセージを表示 |
| プロキシ接続失敗 | FormValidation.errorで接続エラーメッセージを表示 |
| 保存失敗 | IOExceptionをスロー |

## 備考

- `ProxyConfiguration`クラスは`Describable`を実装しており、Descriptorパターンで設定フォームを提供します
- パスワードは`Secret`クラスで暗号化されて保存されます
- `noProxyHost`はスペース、タブ、改行、カンマ、パイプで区切られたパターンリストとして処理されます
- ワイルドカード（`*`）を使用したパターンマッチングをサポートします
- `DEFAULT_CONNECT_TIMEOUT_MILLIS`システムプロパティで接続タイムアウトを設定可能（デフォルト20秒）
- プロキシ認証（Basic認証、NTLM認証を含む）はJavaの`Authenticator`機構を使用して実装されています

---

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

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

### 推奨読解順序

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

まず、プロキシ設定の管理に使用されるクラス構造を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ProxyConfiguration.java | `core/src/main/java/hudson/ProxyConfiguration.java` | プロキシ設定のメインクラス。name、port、userName、secretPassword、noProxyHostフィールドを持つ |

**読解のコツ**: `ProxyConfiguration`は`Describable`を実装しており、設定フォームの表示と保存を担当します。`@DataBoundConstructor`と`@DataBoundSetter`でフォームデータのバインディングを行います。

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

リクエスト処理の起点を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ProxyConfiguration.java | `core/src/main/java/hudson/ProxyConfiguration.java` | DescriptorImpl内部クラスでバリデーションメソッドを提供 |

**主要処理フロー**:
1. **95-96行目**: name、portフィールド定義
2. **108-109行目**: userName、noProxyHostフィールド定義
3. **125-127行目**: secretPasswordフィールド定義
4. **133-156行目**: コンストラクタで各フィールドを初期化
5. **280-285行目**: save()メソッドで永続化
6. **514-641行目**: DescriptorImplでバリデーションメソッド

#### Step 3: ビューテンプレートを理解する

画面の実際のレンダリング処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | config.jelly | `core/src/main/resources/hudson/ProxyConfiguration/config.jelly` | Jellyテンプレートによる設定フォーム |

**主要処理フロー**:
- **23行目**: readOnlyMode判定（ADMINISTER権限チェック）
- **24-25行目**: Server入力フィールド
- **27-28行目**: Port入力フィールド（min=0、max=65535）
- **30-31行目**: User name入力フィールド
- **33-34行目**: Password入力フィールド
- **36-37行目**: No Proxy Host入力フィールド
- **40-46行目**: Advanced設定（Test URL、Validate Proxyボタン）

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

```
プラグイン管理画面 / システム設定画面
    │
    └─ ProxyConfiguration (Describable)
           │
           ├─ config.jelly (設定フォーム)
           │      │
           │      ├─ f:entry (Server)
           │      ├─ f:entry (Port)
           │      ├─ f:entry (User name)
           │      ├─ f:entry (Password)
           │      ├─ f:entry (No Proxy Host)
           │      │
           │      └─ f:advanced
           │             ├─ f:entry (Test URL)
           │             └─ f:validateButton (Validate Proxy)
           │
           └─ DescriptorImpl
                  │
                  ├─ doCheckPort()
                  ├─ doCheckUserName()
                  ├─ doCheckSecretPassword()
                  └─ doValidateProxy()
                         │
                         └─ HttpClient.send()
                                │
                                └─ テスト結果返却

設定保存
    │
    └─ ProxyConfiguration.save()
           │
           └─ XmlFile.write() → proxy.xml
```

### データフロー図

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

フォーム入力 ───▶ ProxyConfiguration        ───▶ 設定フォーム表示
                   │
                   ├─ バリデーション
                   │      │
                   │      ├─ doCheckPort()
                   │      ├─ doCheckUserName()
                   │      └─ doCheckSecretPassword()
                   │
                   └─ FormValidation返却

Validate Proxy ───▶ doValidateProxy()      ───▶ テスト結果表示
                   │
                   ├─ HttpClient構築
                   │      │
                   │      ├─ ProxySelector設定
                   │      └─ Authenticator設定
                   │
                   └─ HEAD リクエスト送信
                          │
                          └─ ステータスコード確認

設定保存 ───▶ ProxyConfiguration.save() ───▶ proxy.xml更新
                   │
                   └─ SaveableListener通知
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ProxyConfiguration.java | `core/src/main/java/hudson/ProxyConfiguration.java` | ソース | プロキシ設定のメインクラス |
| config.jelly | `core/src/main/resources/hudson/ProxyConfiguration/config.jelly` | テンプレート | プロキシ設定フォームのJellyテンプレート |
| Messages.properties | `core/src/main/resources/hudson/Messages.properties` | リソース | メッセージリソース |
| proxy.xml | `$JENKINS_HOME/proxy.xml` | 設定 | プロキシ設定の永続化ファイル |
| Secret.java | `core/src/main/java/hudson/util/Secret.java` | ソース | パスワード暗号化クラス |
