# API設計書

## 概要

本ドキュメントは、FreeBSD ソースツリー (freebsd-src-main) に含まれる HTTP ベースの API エンドポイントを定義する。FreeBSD は OS カーネルおよびユーザーランドプログラムのソースコードであり、一般的な Web アプリケーションフレームワーク (Laravel, Django 等) とは異なり、REST API を主目的とするプロジェクトではない。

本プロジェクト内で HTTP プロトコルを通じてサービスを提供するコンポーネントは以下の 3 つである:

1. **virtual_oss httpd** -- OSS オーディオデバイスマルチプレクサの HTTP ストリーミングサーバー
2. **prometheus_sysctl_exporter** -- sysctl メトリクスを Prometheus 形式で HTTP 提供するエクスポーター
3. **ctlstat (Prometheus モード)** -- CTL (CAM Target Layer) 統計を Prometheus 形式で HTTP 提供するツール

また、HTTP クライアントライブラリとして **libfetch** が存在するが、これはサーバーサイド API ではなくクライアントライブラリ API であるため、補足として記載する。

## 共通仕様

### ベースURL

```
http://{host}:{port}/
```

各コンポーネントはそれぞれ独立したデーモンまたはプロセスとして動作し、起動時のオプションによりバインドアドレスとポートが決定される。共通のベース URL は存在しない。

### 認証方式

認証機構は実装されていない。全てのエンドポイントは認証不要でアクセス可能である。アクセス制御はファイアウォール (pf, ipfw) またはネットワークレベルで行うことを前提としている。

### 共通ヘッダー

| ヘッダー名 | 必須 | 説明 |
| --- | --- | --- |
| Content-Type | - | レスポンスで返却される (リクエストでは不要) |
| Connection | - | レスポンスで `close` が返却される |
| Range | - | virtual_oss の stream.wav エンドポイントで部分取得に使用可能 |

### 共通エラーレスポンス

| ステータスコード | 説明 |
| --- | --- |
| 404 | Not Found - 不正なパスへのリクエスト (virtual_oss) |
| 416 | Range Not Satisfiable - 不正な Range ヘッダー (virtual_oss) |
| 503 | Service Unavailable - 接続スロットが満杯 (virtual_oss) |

## API一覧

| カテゴリ | エンドポイント | メソッド | 説明 |
| --- | --- | --- | --- |
| virtual_oss ストリーミング | / | GET | インデックスページ (HTML) |
| virtual_oss ストリーミング | /index.html | GET | インデックスページ (HTML、/ と同一) |
| virtual_oss ストリーミング | /stream.wav | GET | WAV 形式オーディオストリーム |
| virtual_oss ストリーミング | /stream.m3u | GET | M3U プレイリスト |
| Prometheus メトリクス | / (prometheus_sysctl_exporter) | GET | sysctl メトリクス (Prometheus 形式) |
| Prometheus メトリクス | / (ctlstat -P) | GET | CTL 統計メトリクス (Prometheus 形式) |

## 各APIエンドポイント定義

### virtual_oss HTTP ストリーミングサーバー

virtual_oss は OSS オーディオデバイスのマルチプレクサデーモンであり、内蔵 HTTP サーバーによりライブオーディオストリーミングを提供する。`-H host -P port` オプションで HTTP サーバーが有効化される。

#### 1. インデックスページ取得

ストリーミングサービスのランディングページを返却する。HTML 形式で、ストリーム URL の案内やオーディオプレーヤーウィジェットを含む。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| エンドポイント | `GET /` または `GET /index.html` |
| 認証 | 不要 |
| 権限 | なし |

**パスパラメータ**

なし

**クエリパラメータ**

なし

**リクエストボディ**

なし

**レスポンス（成功時）**

ステータスコード: `200 OK`

```
HTTP/1.0 200 OK
Content-Type: text/html
Server: virtual_oss/1.0
Cache-Control: no-cache, no-store
Expires: Mon, 26 Jul 1997 05:00:00 GMT
```

レスポンスボディは HTML 形式で、以下の情報を含む:
- VLC による接続手順の案内
- `http://{host}:{port}/stream.m3u` へのリンク
- `<audio>` タグによる WAV ストリーム再生ウィジェット
- 現在のアクティブ接続数と空きスロット数

**レスポンス（エラー時）**

ステータスコード: `404 Not Found` (不正なパスの場合)

```
HTTP/1.0 404 Not Found
Content-Type: text/html
Server: virtual_oss/1.0
```

---

#### 2. WAV オーディオストリーム取得

ライブオーディオデータを WAV (PCM) 形式でストリーミング配信する。HTTP Range リクエストに対応しており、部分取得 (Partial Content) をサポートする。最大ストリーミング時間は 3 時間 (10,800 秒) に制限されている。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| エンドポイント | `GET /stream.wav` |
| 認証 | 不要 |
| 権限 | なし |

**パスパラメータ**

なし

**クエリパラメータ**

なし

**リクエストヘッダー (オプション)**

| ヘッダー名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| Range | string | - | `bytes={start}-{end}` 形式。部分取得を要求する |

**リクエストボディ**

なし

**レスポンス（成功時 - 通常）**

ステータスコード: `200 OK`

```
HTTP/1.0 200 OK
Content-Type: audio/wav
Server: virtual_oss/1.0
Cache-Control: no-cache, no-store
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Connection: Close
Content-Length: {total_length}
```

レスポンスボディは WAV ヘッダー + PCM 生オーディオデータ。WAV ヘッダーには以下の情報が含まれる:
- フォーマット: PCM (audioformat = 0x01)
- チャンネル数: 設定により可変 (1 または 2)
- サンプルレート: 設定により可変
- ビット深度: 設定により可変 (8, 16, 24, 32)

**レスポンス（成功時 - Range リクエスト）**

ステータスコード: `206 Partial Content`

```
HTTP/1.1 206 Partial Content
Content-Type: audio/wav
Server: virtual_oss/1.0
Cache-Control: no-cache, no-store
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Connection: Close
Content-Range: bytes {start}-{end}/{total}
Content-Length: {delta}
```

**レスポンス（エラー時）**

ステータスコード: `416 Range Not Satisfiable`

```
HTTP/1.1 416 Range Not Satisfiable
Server: virtual_oss/1.0
```

条件: Range ヘッダーの start がサンプルサイズ境界に整列していない場合。

ステータスコード: `503 Out of Resources`

```
HTTP/1.0 503 Out of Resources
Server: virtual_oss/1.0
```

条件: 全ての接続スロットが使用中の場合。同時接続数は起動時の `-n` オプションで設定される。

---

#### 3. M3U プレイリスト取得

メディアプレーヤー (VLC 等) で使用するための M3U プレイリストファイルを返却する。RTP が設定されている場合は RTP マルチキャストアドレスを、それ以外の場合は HTTP ストリーム URL を返却する。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| エンドポイント | `GET /stream.m3u` |
| 認証 | 不要 |
| 権限 | なし |

**パスパラメータ**

なし

**クエリパラメータ**

なし

**リクエストボディ**

なし

**レスポンス（成功時）**

ステータスコード: `200 OK`

```
HTTP/1.0 200 OK
Content-Type: audio/mpegurl
Server: virtual_oss/1.0
Cache-Control: no-cache, no-store
Expires: Mon, 26 Jul 1997 05:00:00 GMT
```

レスポンスボディ (RTP 設定時):

```
rtp://239.255.0.1:{rtp_port}
```

レスポンスボディ (HTTP ストリーム時):

```
http://{host}:{port}/stream.wav
```

---

### Prometheus sysctl エクスポーター

`prometheus_sysctl_exporter` は FreeBSD の sysctl ノードの値を Prometheus スクレイプ形式で HTTP レスポンスとして出力するユーティリティである。通常 `inetd(8)` 経由で TCP ポート 9124 にバインドして使用する。`-h` オプションにより HTTP モードが有効化される。

#### 4. sysctl メトリクス取得

全ての (またはフィルタリングされた) sysctl ノードの値を Prometheus テキスト形式 (version 0.0.4) で返却する。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| エンドポイント | `GET /` (inetd 経由、TCP ポート 9124) |
| 認証 | 不要 |
| 権限 | なし (sysctl の読み取り権限に依存) |

**パスパラメータ**

なし

**クエリパラメータ**

なし (フィルタリングはコマンドライン引数 `-i` / `-e` で設定)

**リクエストボディ**

なし

**レスポンス（成功時）**

ステータスコード: `200 OK`

```
HTTP/1.1 200 OK
Connection: close
Content-Encoding: gzip (gzip モード時)
Content-Length: {length}
Content-Type: text/plain; version=0.0.4
```

レスポンスボディは Prometheus テキスト形式のメトリクスデータ:

```
# HELP sysctl_kern_openfiles Number of open files
# TYPE sysctl_kern_openfiles gauge
sysctl_kern_openfiles 1234
# HELP sysctl_kern_maxfiles Maximum number of open files
# TYPE sysctl_kern_maxfiles gauge
sysctl_kern_maxfiles 100000
```

メトリクス命名規則:
- プレフィックス: `sysctl_`
- sysctl ノード名の `.` を `_` に置換
- 集約可能なコンポーネント (デバイス名等) はラベルとして付与

コマンドラインオプション:
- `-d`: メトリクス説明を出力
- `-g`: gzip 圧縮を有効化 (Content-Encoding: gzip)
- `-h`: HTTP モード (ヘッダー付き出力)
- `-i pattern`: 正規表現に一致するメトリクスのみ出力
- `-e pattern`: 正規表現に一致するメトリクスを除外

---

### ctlstat Prometheus エクスポーター

`ctlstat` は CAM Target Layer (CTL) の I/O 統計を表示するユーティリティであり、`-P` オプションにより Prometheus 形式の HTTP レスポンスを出力する。`inetd(8)` 経由での使用を想定している。

#### 5. CTL 統計メトリクス取得

CTL (iSCSI ターゲット等) の LUN およびポートの I/O 統計を Prometheus テキスト形式で返却する。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| エンドポイント | `GET /` (inetd 経由) |
| 認証 | 不要 |
| 権限 | なし (/dev/cam/ctl へのアクセス権に依存) |

**パスパラメータ**

なし

**クエリパラメータ**

なし

**リクエストボディ**

なし

**レスポンス（成功時）**

ステータスコード: `200 OK`

```
HTTP/1.1 200 OK
Connection: close
Content-Type: text/plain; version=0.0.4
```

レスポンスボディは Prometheus テキスト形式の CTL 統計データ (LUN 統計およびポート統計)。

---

## 補足: libfetch HTTP クライアントライブラリ API

libfetch はサーバーサイド HTTP API ではなく、HTTP/HTTPS/FTP クライアントとして機能する C ライブラリである。pkg(8) や fetch(1) 等のツールが内部で使用している。主要な関数を以下に列挙する。

### HTTP 関連関数

| 関数名 | シグネチャ | 説明 |
| --- | --- | --- |
| `fetchXGetHTTP` | `FILE *fetchXGetHTTP(struct url *, struct url_stat *, const char *)` | HTTP GET でファイル取得 (メタデータ付き) |
| `fetchGetHTTP` | `FILE *fetchGetHTTP(struct url *, const char *)` | HTTP GET でファイル取得 |
| `fetchPutHTTP` | `FILE *fetchPutHTTP(struct url *, const char *)` | HTTP PUT でファイルアップロード |
| `fetchStatHTTP` | `int fetchStatHTTP(struct url *, struct url_stat *, const char *)` | HTTP HEAD でメタデータ取得 |
| `fetchListHTTP` | `struct url_ent *fetchListHTTP(struct url *, const char *)` | ディレクトリ一覧取得 |
| `fetchReqHTTP` | `FILE *fetchReqHTTP(struct url *, const char *, const char *, const char *, const char *)` | 任意の HTTP メソッドでリクエスト |

### 汎用関数

| 関数名 | シグネチャ | 説明 |
| --- | --- | --- |
| `fetchGetURL` | `FILE *fetchGetURL(const char *, const char *)` | URL 文字列からスキームを自動判定して取得 |
| `fetchPutURL` | `FILE *fetchPutURL(const char *, const char *)` | URL 文字列からスキームを自動判定してアップロード |
| `fetchStatURL` | `int fetchStatURL(const char *, struct url_stat *, const char *)` | URL 文字列からメタデータ取得 |
| `fetchParseURL` | `struct url *fetchParseURL(const char *)` | URL 文字列をパースして struct url に変換 |
| `fetchFreeURL` | `void fetchFreeURL(struct url *)` | パースされた URL 構造体を解放 |

### エラーコード

| コード | 定数名 | 説明 |
| --- | --- | --- |
| 1 | FETCH_ABORT | 操作中断 |
| 2 | FETCH_AUTH | 認証エラー |
| 3 | FETCH_DOWN | サービス利用不可 |
| 7 | FETCH_MEMORY | メモリ不足 |
| 8 | FETCH_MOVED | リダイレクト |
| 9 | FETCH_NETWORK | ネットワークエラー |
| 10 | FETCH_OK | 成功 |
| 11 | FETCH_PROTO | プロトコルエラー |
| 13 | FETCH_SERVER | サーバーエラー |
| 15 | FETCH_TIMEOUT | タイムアウト |
| 18 | FETCH_URL | URL パースエラー |

## 備考

- FreeBSD はオペレーティングシステムのソースコードであり、一般的な Web アプリケーションのような REST API は主目的ではない。本ドキュメントで記載した HTTP エンドポイントは、特定のユーティリティが提供する付加的な機能である。
- virtual_oss の HTTP サーバーは簡易的な実装であり、HTTP/1.0 および HTTP/1.1 の一部機能のみをサポートする。
- prometheus_sysctl_exporter と ctlstat の Prometheus モードは `inetd(8)` 経由での運用を前提としており、スタンドアロンの HTTP サーバーとしては動作しない。
- `tools/tools/netrate/httpd/httpd.c` にベンチマーク用の簡易 HTTP サーバーが存在するが、これはネットワーク性能測定ツールであり、実運用を目的とした API ではないため本ドキュメントの対象外とした。
- `contrib/` ディレクトリ配下の HTTP 関連コード (OpenSSL の http_server 等) はサードパーティのコントリビューションであり、FreeBSD プロジェクト固有の API ではないため対象外とした。
