# 機能設計書 23-url

## 概要

本ドキュメントは、Node.jsのurlモジュールの機能設計について記述する。urlモジュールは、URL文字列の解析・構築機能を提供し、レガシーURL API（url.parse）とWHATWG URL API（URL、URLSearchParams）の両方をサポートする。

### 本機能の処理概要

**業務上の目的・背景**：urlモジュールは、Webアプリケーション開発において不可欠なURL処理を提供する。HTTPリクエストのURL解析、APIエンドポイントの構築、クエリパラメータの操作など、様々なシーンで使用される。レガシーAPI（url.parse）は後方互換性のために維持されているが、新しいコードではWHATWG URL APIの使用が推奨される。

**機能の利用シーン**：
- URLを各構成要素（プロトコル、ホスト、パス、クエリ等）に分解する際
- 相対URLを絶対URLに解決する際
- クエリパラメータを解析・構築する際
- ファイルパスをfile:// URLに変換する際
- URLをHTTPリクエストオプションに変換する際
- URLパターンマッチングを行う際

**主要な処理内容**：
1. `url.parse()` - URL文字列を解析してUrlオブジェクトに分解（レガシー）
2. `url.format()` - UrlオブジェクトまたはURLオブジェクトをURL文字列に変換
3. `url.resolve()` - 相対URLを解決
4. `url.resolveObject()` - URLオブジェクト間の解決
5. `URL` - WHATWG URL APIのコンストラクタ
6. `URLSearchParams` - クエリパラメータの操作
7. `URLPattern` - URLパターンマッチング
8. `pathToFileURL()` - ファイルパスをfile:// URLに変換
9. `fileURLToPath()` - file:// URLをファイルパスに変換
10. `urlToHttpOptions()` - URLをHTTPリクエストオプションに変換
11. `domainToASCII()` / `domainToUnicode()` - ドメイン名の変換

**関連システム・外部連携**：
- internalBinding('url') - ネイティブURL処理
- internalBinding('url_pattern') - URLパターン処理
- internalBinding('encoding_binding') - Punycode変換（toASCII）

**権限による制御**：特になし。すべての機能は任意のユーザーコードから利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本モジュールはAPI機能であり、関連する画面はありません |

## 機能種別

URL解析 / URL構築 / パターンマッチング

## 入力仕様

### 入力パラメータ

#### url.parse（レガシー）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| urlString | string | Yes | 解析するURL文字列 | validateString |
| parseQueryString | boolean | No | クエリをオブジェクトにパースするか | - |
| slashesDenoteHost | boolean | No | //がホストを示すか | - |

#### url.format

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| urlObject | Object \| string \| URL | Yes | フォーマット対象 | validateObject（オブジェクトの場合） |
| options | Object | No | フォーマットオプション | validateObject |

#### url.resolve

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| from | string | Yes | ベースURL | - |
| to | string | Yes | 相対URL | - |

#### pathToFileURL

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| path | string | Yes | ファイルパス | validateString |
| options | Object | No | オプション | - |

#### URLコンストラクタ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | string | Yes | URL文字列 | - |
| base | string \| URL | No | ベースURL | - |

### 入力データソース

プログラムコードからの直接呼び出し。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| url.parse戻り値 | Url | {protocol, auth, host, hostname, port, pathname, search, query, hash, href, path, slashes} |
| url.format戻り値 | string | URL文字列 |
| url.resolve戻り値 | string | 解決されたURL文字列 |
| URLオブジェクト | URL | WHATWG URL仕様準拠のURLオブジェクト |
| pathToFileURL戻り値 | URL | file:// URL |
| fileURLToPath戻り値 | string | ファイルパス |
| urlToHttpOptions戻り値 | Object | {protocol, hostname, port, path, ...} |

### 出力先

呼び出し元への戻り値として返却。

## 処理フロー

### 処理シーケンス

```
1. URL文字列の入力
   └─ 空白トリミング、バックスラッシュ変換
2. プロトコル抽出
   └─ protocolPatternによるマッチング
3. ホスト部分の解析
   └─ auth、hostname、portの分離
4. パス部分の解析
   └─ pathname、search、hashの分離
5. 結果オブジェクトの構築
   └─ Urlオブジェクトまたはformattedの返却
```

### フローチャート

```mermaid
flowchart TD
    A[URL入力] --> B{入力タイプ}
    B -->|文字列| C[url.parse処理]
    B -->|URL/Url| D[url.format処理]
    C --> E[プロトコル抽出]
    E --> F[ホスト解析]
    F --> G[パス解析]
    G --> H[Urlオブジェクト生成]
    D --> I[各部品を結合]
    I --> J[URL文字列生成]
    H --> K[結果返却]
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | DEP0169警告 | url.parse()使用時に非推奨警告を発行 | node_modules外からの呼び出し時 |
| BR-002 | ホスト名最大長 | ホスト名は255文字まで | ホスト名解析時 |
| BR-003 | 禁止文字 | ホスト名に特定の文字を禁止 | forbiddenHostChars参照 |
| BR-004 | IDNA変換 | 非ASCII文字を含むドメイン名をPunycode変換 | toASCII使用 |
| BR-005 | IPv6対応 | []で囲まれたホスト名はIPv6として処理 | isIpv6Hostname判定 |

### 計算ロジック

#### Url.prototype.parse（177-506行目）
1. 空白文字のトリミングとバックスラッシュの変換
2. simplePathPatternによる高速パスマッチング
3. プロトコルの抽出とホスト解析
4. authの分離とホスト名のIDNA変換
5. パス、クエリ、ハッシュの分離

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

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

本モジュールはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ERR_INVALID_URL | TypeError | 無効なURL | 正しいURL形式を使用 |
| ERR_INVALID_ARG_VALUE | TypeError | 無効なポート番号 | 有効なポート番号を指定 |
| ERR_INVALID_ARG_TYPE | TypeError | 引数の型が不正 | 正しい型の引数を渡す |

### リトライ仕様

リトライ処理は行わない。

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

トランザクション処理は行わない。

## パフォーマンス要件

- simplePathPatternによる高速パス解析（256-276行目）
- 必要な場合のみquerystring.parseを実行

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

- url.parse()はCVEが発行されない旨の警告を表示（DEP0169）
- 禁止ホスト文字によるスプーフィング防止（173-175行目）
- IDNA変換後の空ホスト名チェック（ERR_INVALID_URL）
- ホスト名最大長制限（255文字）

## 備考

- url.parse()は非推奨（DEP0169）、WHATWG URL APIの使用を推奨
- URLPatternはinternalBinding('url_pattern')から提供
- fileURLToPathBufferはBufferとしてパスを返却する変種

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | url.js | `lib/url.js` | Urlコンストラクタ（77-90行目） |

**読解のコツ**: Urlオブジェクトの各プロパティ（protocol, slashes, auth, host, port, hostname, hash, search, query, pathname, path, href）の意味を理解する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | url.js | `lib/url.js` | module.exports（1025-1045行目） |

**主要処理フロー**:
1. **1025-1031行目**: レガシーAPI（Url, parse, resolve, resolveObject, format）
2. **1033-1036行目**: WHATWG API（URL, URLPattern, URLSearchParams）
3. **1037-1039行目**: ドメイン変換関数
4. **1041-1044行目**: パス変換関数

#### Step 3: url.parse実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | url.js | `lib/url.js` | urlParse関数（134-151行目） |
| 3-2 | url.js | `lib/url.js` | Url.prototype.parse（177-506行目） |

**主要処理フロー**:
- **134-144行目**: 非推奨警告の発行（DEP0169）
- **189-232行目**: 空白トリミングとバックスラッシュ変換
- **256-276行目**: simplePathPatternによる高速パス
- **278-285行目**: プロトコル抽出
- **319-441行目**: ホスト解析とauth分離
- **452-490行目**: search、query、hashの処理

#### Step 4: url.format実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | url.js | `lib/url.js` | urlFormat関数（575-615行目） |
| 4-2 | url.js | `lib/url.js` | Url.prototype.format（634-718行目） |

**主要処理フロー**:
- **575-612行目**: 入力タイプの判定と処理分岐
- **634-703行目**: 各URL部品の結合処理
- **689-703行目**: slashedProtocolの処理

#### Step 5: WHATWG URL APIを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | internal/url.js | `lib/internal/url.js` | URL/URLSearchParamsの実装 |

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

```
lib/url.js
    │
    ├─ urlParse() [134-151行目]
    │      └─ Url.prototype.parse() [177-506行目]
    │              ├─ simplePathPattern処理 [256-276行目]
    │              ├─ getHostname() [508-527行目]
    │              ├─ autoEscapeStr() [550-572行目]
    │              └─ parseHost() [1003-1014行目]
    │
    ├─ urlFormat() [575-615行目]
    │      ├─ Url.prototype.format() [634-718行目]
    │      └─ bindingUrl.format() [611行目]
    │
    ├─ urlResolve() [720-722行目]
    │      └─ Url.prototype.resolve() [724-726行目]
    │              └─ Url.prototype.resolveObject() [733-1001行目]
    │
    └─ internal/url.js
           ├─ URL (WHATWG)
           ├─ URLSearchParams
           ├─ domainToASCII
           ├─ domainToUnicode
           ├─ pathToFileURL
           ├─ fileURLToPath
           └─ urlToHttpOptions
```

### データフロー図

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

URL文字列 ───▶ url.parse ───▶ Urlオブジェクト
Urlオブジェクト ───▶ url.format ───▶ URL文字列
base, relative ───▶ url.resolve ───▶ 解決済みURL
ファイルパス ───▶ pathToFileURL ───▶ file:// URL
file:// URL ───▶ fileURLToPath ───▶ ファイルパス
ドメイン名 ───▶ domainToASCII ───▶ Punycode
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| url.js | `lib/url.js` | ソース | メインモジュール |
| internal/url.js | `lib/internal/url.js` | ソース | WHATWG URL API実装 |
| querystring.js | `lib/querystring.js` | ソース | クエリ文字列処理 |
| internal/querystring.js | `lib/internal/querystring.js` | ソース | encodeStr関数 |
| internal/validators.js | `lib/internal/validators.js` | ソース | バリデーション関数 |
