
2026/08/06 3:52
Sula: Scryer Prolog で書かれた Gemini プロトコルサーバー
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
本文では、パッチ適用済みの Scryer Prolog を基盤として構築された、安全かつ軽量な Web サーバー「Sula」を紹介します。堅牢な TLS サポートと優雅なシャットダウン機能により即座に価値を提供します。より重い代替案とは異なり、Sula はシステムメモリを枯渇させることなく、ホストの
openssl(1) ツールを利用してバイナリファイルのストリーミングおよびホスト名検証を効率的に行います。そのアーキテクチャは、ネイティブのコピーストリームビルトイン機能を有効にする特定のアップストリームパッチと、暗号化用の Rust ポートに依存し、負荷下でも安定したパフォーマンスを実現します。インストールにはリポジトリのクローン実行、cargo install --path .の実行、および PATH に openssl(1) が存在するかを確認する手順が必要です。コマンドラインでオプションフラグ(バインドアドレス/ポート、ホスト名検証 [デフォルトは localhost]、コンテンツディレクトリ、証明書パス)を指定して起動できます。提供されたホスト名がサーバー証明書と一致しない場合、起動時に中止されます。シャットダウンは Ctrl+C を通じて優雅に行われ、ログ記録後にコード 0 でクリーンに終了します。コア機能には rustls を 통한 TLS、PKCS#12 識別ファイルのサポート、/etc/mime.typesからの MIME ネゴシエーション、ネイティブバイナリストリーミングが含まれます。エラー処理はハンドシェイク失敗および切断を検出してループを継続しますが、その他のエラーでは例外を再スローします。プロジェクトには config.pl、mime.pl、log.pl などのいくつかのモジュールが含まれています。今後、このプロジェクトはキー/証明書ペアのサポート、クライアント証明書、ファイルベース設定、ユーザー管理、CGI スクリプト、完全なステータスコード、レート制限、仮想ホスティング、包括的なファイルロギングといった高度な機能との統合を計画しています。.gmi コンテンツタイプを含む現代の Web トラフィックを安全に扱う低負荷ソリューションを求める開発者や企業にとって、安全性と簡素性を両立しつつ、拡張された機能を目的として現在もアクティブに開発が行われている Sula は有望な代替案です。本文
/sula/: Scryer Prolog による Gemini プロトコルサーバー
/sula/ は、Scryer Prolog で実装された Capsule サフィックスに対応するスペイン語用の Gemini プロトコルサーバーです。
要件と環境設定
Sula は修正を加えた Scryer Prolog(ブランチ
js/fixes)に依存します。このパッチ版 Scryer Prolog は、以下の機能を含んでいます:
- ストリーミング処理: プロログのヒープ上にデータを保持せず、TLS クライアントへのバイナリファイルボディを直接流せるネイティブな
ブルトイン関数を実装。$copy_stream/2 - EOF 処理修正:
のlibrary(pio)
を修正し、プロセスパイプなどのストリームが EOF で正しく終了するようにし、無限ループを防ぐ。buffer_prepare_for_n/5 - SIGINT ハンドリング:
に非ブロッキングのポリングループを追加し、socket_server_accept/4
をブロック系システムコールにトラップされるのではなく、キャッチ可能なSIGINT
例外として処理する。$interrupt_thrown - 移植性: rustls へのポート対応。
- クライアント証明:
を修正し、オプションのクライアント証明書を受け付けるようにした。tls_server_negotiate
ビルドとインストール
以下のコマンドで修正版 Scryer Prolog を構築・インストールします:
git clone https://git.sagredo.dev/scryer-prolog -b js/fixes cd scryer-prolog cargo install --path .
※ 重要: 起動時にアイデンティティ証明書の CN(共通名称)を読み込み、設定したホスト名と一致するかを
openssl(1) で確認するため、環境変数 $PATH に openssl が必ず存在している必要があります。
実行方法
sula.pl は複数のスクリプト言語に対応するポリグロットスクリプトです。起動時に $env:SWI_PROLOG_PATH ではなく PATH 上の scryer-prolog を直接検出・実行し、エントリーゴールとして sula:run/0 を呼び出します。
./sula.pl \ --addr HOST:PORT \ --hostname NAME \ --content DIR \ --certs DIR
コマンドラインオプション
すべてのオプションは順序不問です。認識できない項目は静かに無視されます。
| オプション | 意味 | デフォルト値 |
|---|---|---|
| リスニングソケットのバインドアドレスとポート | |
| 証明書の期待される CN。不一致の場合は起動時エラーで終了 | |
| サーバーするファイルのルートディレクトリ | |
| と を含むディレクトリ | なし(必須) |
サーバーの停止
Ctrl+C を押すとクリーンなシャットダウンが実行されます:
- リスニングソケットが閉じられる。
- トップレベルキャッチで「Shutting down」とログに記録される。
- プロセスはステータス 0 で終了します。
機能概要
- セキュリティ: rustls を使用した TLS および PKCS#12 アイデンティティファイル対応。
- ホスト名の検証: 起動時に
を呼出し、証明書の CN がopenssl x509
と一致するかをアサーションします(不一致の場合はエラー)。--hostname - コンテンツネゴシエーション: 拡張子に基づいて MIME タイプを決定し、
を使用します。起動時にmime/2
がパースされ読み込まれます。/etc/mime.types
ファイルには.gmi
が割り当てられます。text/gemini - 効率的なレスポンス:
- テキストレスポンスは
を使用して送信。format/3 - バイナリレスポンスは
(ファイルから TLS ソケットへ)でストリーミングされ、プロログのヒープを介したメモリ転送なしで処理されます。$copy_stream/2
- テキストレスポンスは
- エラーハンドリング:
- TLS ハンドシェイク失敗や接続切断についてはログに記録してループを継続します。
- 他のエラーはトップレベルで表面化します。
- グレースフルシャットダウン: 修正された Scryer の
を通じて、socket_server_accept/4
による丁寧な停止が可能。SIGINT
ファイル構成
各ファイルの役割は以下の通りです:
- sula.pl: ポリグロットランチャーおよびメインの sula モジュール(
、リクエストループ)。run/0 - config.pl: CLI オプションの解析(DCG)および設定アクセッサー(
,cert/1
など)。addr/1 - cert.pl: 証明書の読み込みおよびホスト名 vs. CN チェック。
- mime.pl:
のパース(DCG)および/etc/mime.types
ファクト(事実)。mime/2 - request.pl: リクエストラインリーダー。
- gemini_uri.pl: Gemini URI DCG(
)。gemini://host[:port]/path[?query] - ip.pl: IP アドレスの認識処理(Gemini ホストとして拒否されます)。
- response.pl: レスポンスステータスコードの DCG。
- log.pl: タグ付きログ出力機能
。log_msg/3 - banner.pl:
の読み込みおよび行ごとの表示(banner.txt
)。display_banner/1
今後の予定機能
以下の機能を追加する予定です:
- アイデンティティ.p12 の代わりに鍵と証明書を使用
- クライアント証明書対応
- 設定ファイルからの読み込み
- ユーザーの保存および読み込み機能
- CGI スクリプトの実行
- すべての HTTP ステータスコードへの対応
- レート制限(Rate Limiting)
- 仮想ホストリング
- ファイルロギング
- マルチスレッディングやホットリロード機能の検討