Skip to content

trueno の仕様の考え方

README(英語)は設置手順と API の使い方を書いている。ここでは「なぜそういう形か」を日本語で短くまとめる。

前提:CGI しか無い場所で動かす

対象は、Apache の CGI が唯一の実行手段で、常駐プロセスも pip も無い共用レンタルサーバ。そこで成り立つように、次を守る。

  • Python 3.6 の標準ライブラリだけ。cgi モジュールにも依存しない(3.13 で消えたため)
  • DB を持たない。状態はすべて files/ 配下のファイルとその mtime
  • 配信は Apache の静的配信。CGI が動くのは書き込み系と一覧だけ

URL が寿命を語る

アップロード時に保存期間(bucket)を選ぶ。1h / 1d / 1w は cron が mtime で掃除し、keep は掃除しない。

bucket URL の形 ID
1h 1d 1w /<bucket>/<id>.<ext> 4 文字(base62)
keep /<id>.<ext> 6 文字

URL を見れば「いつまであるか」が分かる。短い方が長生き、という逆転はわざとで、恒久的なものだけが短い特権的な URL を得る。4 文字 ID は衝突時に再試行し、O_EXCL で原子的に作る。

sidecar で DB の代わりにする

一覧や削除に要る情報(元のファイル名・コメント・削除キー・時刻)は、ファイルの隣の <id>.<ext>.meta(JSON)に置く。

  • Apache は .meta を配信しない(.htaccess で拒否)
  • 削除キーは sha256 のハッシュだけを保存する。.meta が漏れても鍵は漏れない
  • 本体と .meta は同じ mtime なので、cron は両方を同時に掃除する。孤児を探す処理は要らない
  • sidecar の無い古いファイルは、ID をそのまま名前として一覧に出る
  • 一覧は ID をリンクにし、元のファイル名を添える。元の名前が _ だけ(_.jpg 等)なら隠したい意図と見て出さない

認可は 2 段

  1. bearer token:~/.trueno-key に 1 行 1 トークン。トークンごとに使える bucket を絞れる(no-keep、buckets:1h,1d)。削除はどのトークンでも可(運営者の権限)
  2. 匿名:運営者が bucket を列挙したときだけ、トークン無しの upload を受ける。keep を匿名に開けることは想定していない。削除は upload 時に自分で決めた削除キーで行う

既定は 1 だけ。2 は「昔ながらの、誰でも置けるアプロダ」を再現したいときに開ける。

エンドポイント

役割 状態
POST /upload 保存。time / comment / delete_key 書き込み
GET /list 一覧。files/ を走査して .meta を合流、新しい順、ページ送り 読み取り
POST /delete 削除キー or bearer で本体と .meta を消す 書き込み
GET /info 上限値・拡張子・匿名で開いている bucket 読み取り
GET /<...> 本体。Apache の静的配信 —

一覧は公開。URL が既に公開されている以上、一覧に新しい秘密は無い。

サムネイル

画像一覧は専用ページ(thumbs.html)。サーバで縮小版は作らない(CGI ホストに画像ライブラリは無い)。ブラウザが元画像を読み込んで縮めて表示する。古いファイルにもそのまま効く。

作らないもの

captcha、IP 制限、ダウンロード数、アカウント。ダウンロード数を数えるには配信を CGI 経由にする必要があり、「配信は静的」の前提が崩れる。

設置の形

docroot をそのまま置く。設定は make.local の数行で、make deploy が公開 URL・サイト名・匿名 bucket を各ファイルに焼き込む。.htaccess の SetEnv を無視するホストがあるため、環境変数に頼らない。

Created 2026-10-07 by lamutara · Updated 2026-10-07 by lamutara · 6 revisions