Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a8f4824
hcl形式による実用的なコンフィグシステム
sanbungi Feb 22, 2026
5d77163
hclの設定を読み込み、実際にルーティングを行う
sanbungi Feb 22, 2026
4c90e04
routeタイプ rawに対応し、固定のメッセージ返却に対応、ただしerror_response関数に依存しており、任意の番号のレスポンス…
sanbungi Feb 22, 2026
7588898
リバースプロキシを実装
sanbungi Feb 24, 2026
d135b88
configリダイレクトを追加
sanbungi Feb 24, 2026
1d883d6
printをicに置き換え、logger.debugも一旦整理
sanbungi Feb 24, 2026
4a0e009
リクエストにリモートのIPアドレス要素を追加
sanbungi Feb 24, 2026
68feec3
各ルーターブロックのip制限に対応
sanbungi Feb 24, 2026
12c59b1
エラーページのHTMLを返せるように関数を用意
sanbungi Feb 24, 2026
99d89db
response_xxx系関数をresponse_any関数に置き換え
sanbungi Feb 24, 2026
4dccbc5
format
sanbungi Feb 24, 2026
fd2fa27
関数の構造変更に対応し、response_any関数に置き換え
sanbungi Feb 25, 2026
6cb900a
単体テストに合わせて軽微な修正
sanbungi Feb 25, 2026
86ccd53
テストケース側の呼び出しの修正
sanbungi Feb 25, 2026
11ab35f
ステータスコードのリストを拡充し、モジュール化
sanbungi Feb 25, 2026
67218a4
存在しない番号の場合の動作を修正
sanbungi Feb 25, 2026
86ec746
build_responseの返り値が1つ増えていたためfallしていた
sanbungi Feb 25, 2026
011a79a
呼び出しミスを修正、単体テスト呼び出し変更対応完了
sanbungi Feb 25, 2026
dfab7ca
xfail解除
sanbungi Feb 25, 2026
d70daa9
実験用ディレクトリから移動、コメント整理
sanbungi Feb 25, 2026
cf475ac
簡易的なドキュメントを追加
sanbungi Feb 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,130 @@ uv run pytest .
- 正常なレスポンス生成

途中で失敗すれば即座に500エラーを返す。


# 設定ファイル解説(仮)

MyHTTPServerは、HCL (HashiCorp Configuration Language) を採用した設定ファイル(`config.hcl`)を使用します。設定は **Global > Server > Route** の3層構造で記述します。

## 1. 階層構造

| スコープ | 記述数 | 役割 |
| --- | --- | --- |
| **`global`** | 1つのみ | プロセス全体の動作(スレッド、ログ、共通タイムアウト) |
| **`server`** | 複数可 | バーチャルホストの設定(ドメイン、ポート、TLS、共通ヘッダー) |
| **`route`** | 複数可 | パスごとの挙動(静的配信、プロキシ、リダイレクト、制限) |

---

## 2. Global ブロック

サーバー全体の設定を定義します。

```hcl
global {
worker_processes = 4 # ワーカースレッド数
max_connections = 1024 # 最大同時接続数
timeout = "30s" # 通信タイムアウト

logging {
level = "info" # debug, info, warn, error
output = "stdout" # パスまたは stdout
format = "json" # json または text
}
}

```

---

## 3. Server ブロック

特定のホスト名やポートに対する設定を定義します。

### 基本設定

| パラメータ | 型 | 説明 |
| --- | --- | --- |
| `host` | string | 待ち受けるホスト名(ドメイン) |
| `port` | int | 待ち受けるポート番号 |
| `root` | string | ドキュメントルートのパス |

### サブブロック

* **`tls`**: HTTPS有効化時に `enabled`, `cert`, `key` を指定。
* **`headers`**: `add` (map), `remove` (list) を使用してレスポンスヘッダーを操作。

---

## 4. Route ブロック

URLパスごとの挙動を定義します。**最長一致(Longest Match)**の原則で適用されます。

### Route Type 一覧

| type | 必須ブロック | 用途 |
| --- | --- | --- |
| **`static`** | なし | `root`配下の静的ファイル配信 |
| **`proxy`** | `backend` | リバースプロキシ(`upstream`への転送) |
| **`raw`** | `respond` | 固定ステータスコードとボディの返却 |
| **`redirect`** | `redirect` | 指定URLへのHTTPリダイレクト |

### 設定例

```hcl
# 静的配信 + アクセス制限
route "/admin" {
type = "static"
security {
ip_allow = ["192.168.1.0/24"]
deny_all = true
}
}

# リバースプロキシ
route "/api" {
type = "proxy"
backend {
upstream = "http://localhost:9000"
timeout = "30s"
}
}

# 固定レスポンス (メンテナンス等)
route "/health" {
type = "raw"
respond {
status = 200
body = "OK"
}
}

# リダイレクト
route "/old-path" {
type = "redirect"
redirect {
url = "/new-path"
code = 301
}
}

```

---

## 5. 共通オプション

`route` 内で利用可能な補助設定です。

### security ブロック

* `ip_allow`: 許可するIP/CIDRのリスト。
* `deny_all`: trueの場合、リスト外からのアクセスを403で拒否。

### headers ブロック

* `add` / `set`: ヘッダーの追加・上書き。 `{ "Key" = "Value" }` 形式。
* `remove`: 削除するヘッダー名のリスト。

---
84 changes: 84 additions & 0 deletions config/example.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
global {
worker_processes = 4
max_connections = 1024
timeout_keepalive = "65s"
timeout = "30s"

logging {
level = "info"
output = "/var/log/myhttpd/access.log"
format = "json" # json or text
}
}

server "main-server" {
host = "example.com"
port = 80
root = "./html"

tls {
enabled = true
cert = "/etc/certs/example.com.crt"
key = "/etc/certs/example.com.key"
min_version = "TLS1.2"
}

headers {
add = {
"X-Frame-Options" = "DENY"
}
remove = ["Server", "X-Powered-By"]
}

route "/" {
type = "static"
index = ["index.html", "index.htm"]

# ブラウザキャッシュ設定
headers {
set = { "Cache-Control" = "public, max-age=3600" }
}
}

route "/admin" {
type = "static"

# IP制限などのブロックが見やすい
security {
ip_allow = ["192.168.10.0/24"]
deny_all = true
}
}

route "/config" {
type = "raw"

# 実際にはファイルが存在しても、攻撃者に存在を悟らせないため404を返す
respond {
status = 404
body = "Not Found"
}
}

route "/v1" {
type = "proxy"

backend {
upstream = "http://localhost:9000"
timeout = "30s"

# プロキシ時にヘッダーを書き換える
headers {
set = { "X-Real-IP" = "$remote_addr" }
}
}
}
route "/old" {
type = "redirect"

redirect {
url = "/hello.html"
code = 302
}
}
}
Loading