← Back to index

2026-03-15

5ch専用ブラウザ(ChMate)対応で踏んだ落とし穴と対策

5chライクな掲示板をゼロから開発し、ChMate等の専用ブラウザ(専ブラ)で読み書きできるようにする過程で遭遇した問題と解決策をまとめる。

想定読者

参考実装

調査にあたり eddist(Rust製の5ch互換掲示板エンジン)のソースコードを繰り返し参照した。ChMateで実運用されている実績があり、「なぜこう書いているのか」自体が専ブラ互換のナレッジとして極めて有用。


1. ChMateはHTTP:80で通信する

症状

原因

ChMateは2つのHTTPクライアントを使い分けている:

機能通信方式ポート
bbsmenu取得WebView (HTTPS)443
subject.txt / DAT / bbs.cgiRaw HTTPクライアント80

VercelはHTTP:80を308でHTTPSにリダイレクトする。ChMateはこのリダイレクトに追従できない。 Vercelの設定で無効化する手段はない。

確認方法

Android端末にmitmproxyを設定し、ChMateの通信をパケットキャプチャして確定診断した。

対策


2. Set-CookieにSecure / SameSiteを付けてはいけない

症状

原因

bbs.cgiのレスポンスで Set-Cookie: edge-token=xxx; HttpOnly; Secure; SameSite=Lax を返していた。

ChMateはSecure属性が付いたCookieを保存しない。 SameSiteも同様。一般的なWebセキュリティのベストプラクティスだが、専ブラのHTTPクライアント実装と互換性がない。

確認方法

bbs.cgiに診断ログを6箇所追加し、wrangler tail でリアルタイム確認:

POST /test/bbs.cgi  (write_tokenで書き込み成功、Set-Cookie発行)
  [bbs.cgi] Setting edge-token cookie: 0e6f10f0...

POST /test/bbs.cgi  (直後の再書き込み)
  [bbs.cgi] Cookie header: (absent)    ← Cookieが送信されていない

SameSite=None; Secure に変えても同じ。属性を両方削除して初めてCookieが保存された。

対策

Set-Cookie: edge-token=xxx; HttpOnly; Max-Age=31536000; Path=/

eddistも同じ構成(Secure / SameSiteを意図的に未設定)。


3. Shift_JISエンコードで絵文字が消える

症状

原因

5chプロトコルのDATファイルはShift_JIS(CP932)エンコード。CP932の文字集合に絵文字は含まれない。

自前実装ではCP932非対応文字を全角「?」に置換していたため、情報が不可逆に消失。

eddistの方式

eddistは encoding_rs クレート(WHATWGエンコーディング仕様準拠)を使用。CP932非対応文字は自動的にHTML数値参照に変換される:

😅 → 😅

HTML数値参照はASCII文字のみで構成されるため、Shift_JISエンコードを問題なく通過する。専ブラはDAT本文をHTMLとして解釈するので、😅 は絵文字として表示される。

対策

Shift_JIS変換のフォールバック処理を変更:

// NG: 情報消失
CP932非対応文字 → 全角?

// OK: HTML数値参照で保持
CP932非対応文字 → &#コードポイント;

追加の罠: 異体字セレクタ

🕳️ のような絵文字は U+1F573(穴)+ U+FE0F(異体字セレクタ)の2文字構成。eddistの方式でも U+FE0F️ に変換され、専ブラで文字化けマークとして表示される。

U+FE0F(絵文字スタイル指示)と U+FE0E(テキストスタイル指示)は表示ヒントであり、Shift_JIS/DATの文脈では不要なので除去するのが正解。一方、U+200D(ZWJ: ゼロ幅接合子)は結合絵文字の構成要素なので除去してはいけない。

文字処理理由
U+FE0F (VS16)除去表示指示。なくても絵文字は表示される
U+FE0E (VS15)除去同上
U+200D (ZWJ)HTML数値参照で保持👨‍👩‍👧 等の結合に必要

4. 専ブラが想定するURL体系

症状

原因

専ブラは5chのURL体系に基づいてURLを自動構築する:

用途専ブラが構築するURL
板トップ/{板ID}/
スレッド閲覧/test/read.cgi/{板ID}/{スレッドキー}/
DAT取得/{板ID}/dat/{スレッドキー}.dat
過去ログ/{板ID}/kako/{下位ディレクトリ}/{スレッドキー}.dat

DAT取得は実装済みでも、それ以外のURLにルートがないと不便な動作になる。

対策

専ブラ固有フォーマットが必要なエンドポイント(DAT、subject.txt等)以外はWeb UIにフォールバックするのが保守コスト的に合理的。


まとめ: 専ブラ対応チェックリスト

eddistのソースコードは専ブラ互換性の暗黙知の宝庫。迷ったらeddistと差分比較するのが最も確実な調査手段。