Skip to content
fandhe-backend
GitHub

プラグイン設定 API リファレンス

1. 目的と位置づけ

  • 本ページは fandhe-backend の各プラグイン(crates/plugin-*)の feature 名・登録方法・Config 型・既定値・注意点を一覧化するリファレンスである
  • 一次情報源は各クレートの rustdoc(crates/plugin-*/src/lib.rs ほかの doc comment・doc test)であり、本ページは横断比較と契約の要約を担う
  • 登録先 Server の全体像は サーバ API、配線パターンの設計判断は docs/design/plugin-boundary.md(<https://github.com/Fandhe-AI/fandhe-backend/blob/main/docs/design/plugin-boundary.md>)を参照
  • curl 例を含む使い方の詳細は feature 構成別サンプル を参照し、本ページでは重複させない

全プラグイン対応早見表

プラグインfeature 名登録メソッド配線パターン種別
plugin-websocketwebsocketServer::websocket(WebSocketConfig)Upgrade 型(UpgradeHandler 拡張点)
plugin-graphqlgraphqlServer::graphql(GraphQlConfig)パスインターセプト型
plugin-openapiopenapiServer::openapi() / Server::openapi_with(OpenApiDoc)設定登録型(静的サービング)
plugin-corscorsServer::cors(CorsConfig)(+ Router::options_fallback 配線)レスポンス後処理型(finalize_response シーム)
plugin-compressioncompressionServer::compression(CompressionConfig)レスポンス後処理型(CORS の後に逐次適用)
plugin-staticstaticServer::static_files(StaticFilesConfig)パスインターセプト型 + spawn_blocking 変種
plugin-tracingtracingServer::tracing(TracingConfig)Middleware 型(Middleware 拡張点)
plugin-webrtc-proxywebrtc-proxyServer::webrtc_proxy(ProxyConfig)パスインターセプト型(別プロセス委譲)
plugin-webrtcwebrtcServer::webrtc(WebRtcConfig)パスインターセプト型(in-process)
plugin-hub-wiringなし(依存逆転型)Server::gate(TenantGate::new(config))Gate 型(RequestGate 拡張点)
  • feature はすべて fandhe-backend-core の Cargo feature(hub-wiring を除く)。無効時は依存・コード・バイナリ増がゼロになる(pay-for-what-you-use)
  • いずれも登録時のみ動作する opt-in。feature 有効でも未登録ならフォールスルーし、既定挙動を変えない

2. プラグイン別リファレンス

2.1 plugin-websocket(websocket)

RFC 6455 ハンドシェイク検証・101 応答・tokio-tungstenite へのフレーミング委譲。

項目内容
Config 型WebSocketConfig(Default 実装あり)
builder メソッドwith_path / with_max_message_size / with_max_frame_size / with_idle_timeout / without_idle_timeout / with_handler / with_close_grace / with_outbound_capacity / with_ping_interval / without_ping_interval / with_handshake_check / without_handshake_check
既定値path = "/ws"、max_message_size = 1 MiB、max_frame_size = 256 KiB、idle_timeout = Some(60 秒)、close_grace = 10 秒、outbound_capacity = 8、ping_interval = None(Ping keepalive は無効)
メッセージハンドラwith_handler(impl WsMessageHandler) で差し替え。既定は EchoHandler(後方互換)
ハンドラの戻り値型 BoxFutureWsMessageHandler::on_message / on_message_with_ctx の戻り値型 BoxFuture<'a, T>(実体は Pin<Box<dyn Future<Output = T> + Send + 'a>>)はクレートルートで再公開されており、fandhe_backend_plugin_websocket::BoxFuture(コア経由では fandhe_backend_core::plugin_websocket::BoxFuture)として参照できる。futures_util::future::BoxFuture と完全に同一の型(別の型ではない)なので、futures-util を直接の依存に加えなくてもハンドラを実装でき、既存の futures_util::future::BoxFuture で書いたハンドラも無変更で動作する(非破壊追加、v0.4.2)
接続コンテキストWsMessageHandler::on_message_with_ctx(provided、既定は既存の on_message へ委譲)で WsConnContext(conn_id() / sender() / param() / params() / peer_addr() / host() / origin() / user_agent() / query())を参照可能。WsOpenContext(on_open 引数)にも同じ peer_addr()/host()/origin()/user_agent()/query()/conn_id() があり、同一接続では常に同じ値になる(docs/design/ws-connection-context-and-close.md 参照)
接続元アドレスWsOpenContext::peer_addr() / WsConnContext::peer_addr()(両方に対応)で接続元の実 peer address(Option<std::net::SocketAddr>)を参照可能。コア経由(Server::bind/BoundServer::run_until 等の実ソケット経路)では Some、tokio::io::duplex 等の非ソケット経路・peer_addr を渡さない旧 API handle_upgrade(5 引数)からの呼び出しでは常に None(GateContext::peer_addr と同型のフェイルクローズ契約)。Debug 出力には含まれない(docs/design/ws-connection-context-and-close.md 参照)
主要リクエストヘッダ・queryWsOpenContext/WsConnContext いずれも host() / origin() / user_agent() / query() で Host/Origin/User-Agent ヘッダ(大文字小文字無視・重複時は先頭値)と query 文字列(RequestHead::query と同一の非デコード契約)を参照可能。許可リスト方式で固定 5 項目(上記 peer_addr を含む)のみを保持し、任意ヘッダを取得する汎用アクセサは無い。ヘッダ値は 1024 バイト・query は 2048 バイトが上限で、超過時は切り詰めず None(フェイルクローズ、部分一致バイパス防止)。クライアントの申告値(peer_addr を除く)であり認可判定の唯一の根拠にしないこと。Debug 出力には含まれない(docs/design/ws-connection-context-and-close.md 参照)
終了理由handler::CloseReason / handler::FailureKind(いずれも #[non_exhaustive])でセッションの終了経路を種別化。WsMessageHandler::on_close(&self, ctx: &WsConnContext, reason: CloseReason)(既定 no-op)で on_open が呼ばれた接続についてのみ終了経路を問わずちょうど 1 回通知される(ハンドシェイク検証失敗・101 送出前キャンセルでは呼ばれない、on_open と対称のフェイルクローズ契約。docs/design/ws-connection-context-and-close.md 4 節参照)。CloseReason::PongTimeout は Ping keepalive の Pong 期限切れによる切断を表す(下記参照)
サーバー起点 Ping keepaliveWebSocketConfig::with_ping_interval(interval, pong_timeout) で有効化(既定は無効、interval/pong_timeout に Duration::ZERO は PingIntervalError で構築時に拒否)。interval ごとにサーバーから Message::Ping を送出し、送出時点から pong_timeout 以内にクライアントの Pong が届かなければ CloseReason::PongTimeout で切断する(idle_timeout とは独立した死活監視で、サーバー起点 push を受けているだけの受信専用クライアントにも効く。Ping の送出自体は idle_timeout をリセットしない、Pong の受信は他の全フレーム種別と同じく idle_timeout もリセットする、既存挙動)。期限切れは受信待ちで読めるフレームがなくなった時点で判定し、それまでに届いているフレームは先に読んで処理する(Pong を返さない対向も、フレームが途切れず届いている間は切断しない)。1 回の送出(Ping・Reply・outbound push 等)がその開始時刻から pong_timeout を超えてブロックした場合も同じ PongTimeout で終了する。without_ping_interval() で明示的に無効へ戻す
送信ハンドル(切断待ち)WsSender::closed().await で切断まで待つ(受信側 Receiver drop 時に完了。cancel-safe)、WsSender::is_closed() で同期判定(send の Err が正の判定基準、こちらは参考値)。close() 呼び出し後、または受信側 drop 後のいずれか早い方で true になる(clone 間で同じ時点を観測。close() 確定時点も対象)
サーバー起点の CloseWsSender::close(code, reason) で on_message の外(on_open 等から spawn したタスク)からも任意タイミングで Close ハンドシェイクを開始できる。呼び出し前に send が Ok を返した push は Close より前に送出される(順序保証)。close() を呼んだら、要求の観測から close_grace 以内に Close ハンドシェイクを終えるか接続を打ち切る(close_grace 超過・世代キャンセル・idle timeout・送出失敗で打ち切られた場合は残りの push と Close を送らない)。code は RFC 6455 7.4 節・IANA 登録に基づき 1000..=1003・1007..=1009・1011..=1014・3000..=4999 のみ許可(1010 はクライアント専用のため拒否)、reason は 123 バイト以内でなければ WsCloseError(InvalidCode/ReasonTooLong/Closed、#[non_exhaustive])を返す。close 後の send/2 回目以降の close は Err になる。終了理由は CloseReason::SenderClose(docs/design/ws-connection-context-and-close.md 参照)
送信キュー容量・非ブロッキング送信WebSocketConfig::with_outbound_capacity(n) で WsSender の送信キュー容量を指定(既定 8、上限 MAX_OUTBOUND_CAPACITY = 4096。0・上限超は OutboundCapacityError)。WsSender::try_send(msg) は send と異なり待たず、満杯(WsTrySendError::Full(msg))とセッション終了・close 確定済み(WsTrySendError::Closed(msg))を区別して即座に返す(送れなかった WsMessage を保持し再試行・破棄を選べる)。順序保証・push の消化契約は send と同一
ハンドシェイクの受理判定フックWebSocketConfig::with_handshake_check(check)(既定は無効・後方互換、without_handshake_check() で解除)。check: WsHandshakeCheck(Fn(&WsHandshakeContext<'_>) -> Result<(), Response> への blanket impl あり、クロージャ登録可)は RFC 6455 検証を通過した要求について 101 応答の送出前に一度だけ同期で評価される。WsHandshakeContext から {name} パスパラメータ(param/params)・リクエストヘッダ(header/head)・接続元アドレス(peer_addr)を参照できる。Err(response) を返すと(1xx/2xx・304・0..=99/600 以上のステータスは 400 Bad Request へ正規化した上で)response を送出し upgrade しない(conn_id・WsSender の生成、on_open/on_close はいずれも呼ばれない)。戻り値は拒否時も Ok(())(WsError に専用 variant は追加しない、docs/design/ws-connection-context-and-close.md 16 節参照)
  • 型エイリアス: fandhe_backend_plugin_websocket::BoxFuture<'a, T> は futures_util::future::BoxFuture と同一の型。利用者は futures-util を直接依存に加えずに on_message 等の戻り値型を書ける
  • 注意: 受信メッセージ/フレームが max_message_size / max_frame_size を超えた場合は、Close フレーム(close code 1009 Message Too Big)を送出してから閉じる。frame 上限超過では送信途中の巨大 payload により Close が RST で失われないよう、生ストリームの半閉鎖 + 有界な読み捨て(無通信 2 秒の打ち切りと、トリクラー対策の総上限 3 秒または close_grace 残り期限の短い方)を行う。戻り値は従来どおり Err(WsError::Protocol(Capacity))
  • 注意: ハンドラが WsOutcome::Close を返すと送信キューを封鎖し、キュー済み push を Close より先に送出する(以後の send は Err。flush と Close は全体で close_grace が上限で、超過・世代キャンセル・送出失敗では残りと Close を送らない)。ハンドラが Err を返した場合も、封鎖してから close_grace を上限に排出して終了し、封鎖前に確定した WsSender::close があれば on_close の理由は SenderClose になる。WsOutcome::Reply 後の排出は容量回までに制限される
  • 注意: サイズ上限はメモリ枯渇 DoS 対策。アイドルタイムアウトは既定で有効(fail-safe)であり、無効化は without_idle_timeout の明示操作でのみ可能
  • 注意: close_grace(with_close_grace)はコアの世代キャンセル(最終 graceful shutdown・rebind 世代 drain)発火時の Close ハンドシェイク猶予。fandhe_backend_plugin_websocket::handle_upgrade の第 5 引数(キャンセル Future)が発火すると close code 1001 Going Away を送出し、close_grace を上限にクライアント応答を有界に待つ(v0.3.0 での BREAKING CHANGE)。接続元アドレスを渡したい呼び出し元は、同じ 5 引数 + peer_addr(6 番目)を取る handle_upgrade_with_peer_addr を使う(既存 handle_upgrade は peer_addr: None で本関数へ委譲する後方互換の薄いラッパー)。WsMessageHandler::on_message / on_message_with_ctx が返す Future は任意の await 点で drop されうる契約(docs/design/ws-cancellation-propagation.md)
  • 注意: WsConnId はサーバー側の単調カウンタ発行(unsafe 不使用・クライアント入力から独立)でプロセス内一意。値は推測可能なため認可トークン・セッション秘密として使ってはならない(識別子であって資格情報ではない)
  • 注意: on_message_with_ctx(on_message にも適用)実行中も WsSender::send の送信キュー(設定された容量、既定 8)を cancel(最優先)→ (ハンドラ完了 | outbound 到着) の順で消化するため、ハンドラ内(ctx.sender() 経由)から容量を超える回数 send(...).await してもデッドロックしない。排出ステップ開始時点で既に到着済みの push は、cancel・送出失敗・close 要求後の close_grace 超過で打ち切られない限り、そのハンドラが返す WsOutcome::Reply/Close より先に送出される(それ以外の push との相対順序は不定)。詳細契約は crates/plugin-websocket/src/session.rs モジュール doc「ハンドラ実行中の送信キュー消化」節・docs/design/ ws-connection-context-and-close.md 6 節を参照
  • 注意(デッドロック): WsSender::closed() を on_message / on_message_with_ctx の実装内でインライン await してはならない。ハンドラ実行中はセッションループがクライアントの受信ストリームを読まないため、受信側 Receiver はハンドラが返るまで drop されず自己デッドロックになる(世代キャンセル発火時のみ解除される)。on_open 等から tokio::spawn した別タスクでのみ使うこと
  • 注意(idle_timeout と Ping keepalive の併用。設計判断は docs/design/ws-connection-context-and-close.md 14 節参照): idle_timeout はクライアントからのフレーム受信でのみリセットされ、WsSender::send/try_send による push・with_ping_interval によるサーバー起点 Ping 送出では延長されない。push だけを受けている受信専用クライアントも死活監視したい場合は with_ping_interval を併用し、interval + pong_timeout を idle_timeout より小さく設定することを推奨する(例: 既定 60 秒に対し with_ping_interval(30s, 10s))。Pong の受信は他の全フレーム種別と同じく idle_timeout もリセットするため、生存クライアントは Ping への Pong で切断されず、Pong を返さない対向は idle_timeout より先に CloseReason::PongTimeout で切断される(早い方のタイマーが勝つ契約)。逆に interval を idle_timeout 以上にすると、最初の Ping が送られる前に idle_timeout が発火してしまう誤設定になるため避ける。検証は crates/plugin-websocket/tests/idle_keepalive_e2e.rs

2.2 plugin-graphql(graphql)

POST /graphql(GRAPHQL_PATH 定数)のパスインターセプト。async-graphql による実クエリ実行。

項目内容
Config 型GraphQlConfig
構築GraphQlConfig::new(executor)(executor: Executor + Clone + Send + Sync + 'static。async_graphql::Schema が満たす)
既定値なし(スキーマ必須。深さ・複雑度制限の既定値も提供しない)
  • 注意: クエリ深さ・複雑度制限(Schema::limit_depth / limit_complexity)と introspection 無効化(Schema::disable_introspection)はスキーマ登録者の責務
  • 不正な body は 400 + 固定エラー body(リクエスト由来の値を一切エコーしない)。未登録時は feature 有効でもフォールスルー

2.3 plugin-openapi(openapi)

GET /openapi.json / GET /openapi.yaml の静的サービング(明示登録時のみ)。

項目内容
登録(組み込みスキーマ)Server::openapi()(ApiDoc 由来の埋め込み OPENAPI_JSON / OPENAPI_YAML を配信)
登録(独自スキーマ)Server::openapi_with(OpenApiDoc)
Config 型OpenApiDoc
構築OpenApiDoc::from_json(json)(構築時 JSON 検証、Result<_, OpenApiDocError>)+ with_yaml(yaml)(任意)
  • 注意: openapi() と openapi_with() は排他ではなく後勝ち(最後に呼んだ方の登録が残る)。YAML 変換依存は開発用 gen-cli feature に閉じ、サーバ経路には現れない

2.4 plugin-cors(cors)

実リクエスト応答への CORS ヘッダ付与(レスポンス後処理型)+ プリフライト応答関数の 2 点構成。外部依存ゼロ。

項目内容
Config 型CorsConfig(CorsConfig::builder() 経由でのみ構築)
builder メソッドallow_origin(完全一致・複数回可) / allow_any_origin / allow_methods / allow_headers / allow_credentials / max_age / expose_headers / build
既定値オリジン空リスト(何も許可しない)、methods = None(プリフライトは対象パスの実登録メソッドを反映)、credentials 無効、max_age なし
構築時検証build() は Result<CorsConfig, CorsConfigError>。allow_any_origin() と allow_credentials(true) の併用は AnyOriginWithCredentials で拒否(トークン窃取経路を型レベルで排除)
プリフライトpreflight_response を利用者が Router::options_fallback へ直接配線する(is_preflight で判定可能)。配線例は feature 構成別サンプル
  • 注意: オリジン照合はバイト完全一致でありワイルドカード部分一致はない。ヘッダ付与に失敗した場合は当該ヘッダを付与しない側へ倒す(フェイルクローズ)

2.5 plugin-compression(compression)

条件充足レスポンスの gzip 圧縮(レスポンス後処理型の第 2 インスタンス、CORS の後に逐次適用)。外部依存は flate2(純 Rust の rust_backend)のみ。

項目内容
Config 型CompressionConfig(CompressionConfig::builder() 経由)
builder メソッドmin_size / compressible_types(丸ごと差し替え) / add_compressible_type / build(失敗しない)
既定値min_size = 1024 バイト、圧縮対象 Content-Type は text/(プレフィックス)・application/json・application/javascript・application/xml・application/xhtml+xml・image/svg+xml
圧縮判定ステータス・Content-Type・body サイズ・Accept-Encoding(q 値解釈込み)をすべて満たす場合のみ圧縮。解釈不能・条件未充足は無圧縮のまま返す(フェイルセーフ)
  • 注意: gzip のみ(br はスコープ外)。秘密情報とリクエスト反映値を同一圧縮 body に同居させると BREACH 類似の情報漏洩リスクがある(rustdoc に明記)

2.6 plugin-static(static)

GET の静的ファイル配信(パスインターセプト型 + spawn_blocking 変種)。外部依存ゼロ(fandhe-backend-http + tokio の rt feature のみ)。

項目内容
Config 型StaticFilesConfig(StaticFilesConfig::builder(mount, root) 経由でのみ構築)
builder メソッドmax_file_bytes / mime(ext, content_type)(内蔵 MIME テーブルより優先する拡張マッピング) / build
既定値max_file_bytes = DEFAULT_MAX_FILE_BYTES(8 MiB。1 リクエストあたりのメモリ使用上限そのもの)。mime 未登録時は内蔵テーブル(.webmanifest 等を含む)+ 既定 application/octet-stream
構築時検証build() は Result<_, StaticConfigError>。mount の形式不正(InvalidMount)・root の canonicalize 失敗(RootNotAccessible)・非ディレクトリ(RootNotADirectory)・mime マッピングの拡張子/Content-Type 不正(InvalidMimeMapping、CR/LF 等のヘッダインジェクション対策込み)を起動前に検出
  • 注意: 二層防御(I/O 前の字句検証 + canonicalize 後の root 配下検証)でパストラバーサル・シンボリックリンク脱出を拒否。先頭ドットセグメント(.env・.git/config 等)も配信拒否。未検出・検証失敗・サイズ超過は一律 404(存在秘匿)

2.7 plugin-tracing(tracing)

サンプリング付きトレーシング(Middleware 型の第 1 号)。決定的カウンタ方式 + 非同期・バッファ済み I/O。

項目内容
Config 型TracingConfig(公開フィールド sample_interval: NonZeroU64 / exclude_paths: Vec<String>)
構築・builderTracingConfig::default() / TracingConfig::new(sample_interval) / exclude_path(path)(チェーン可能)
既定値sample_interval = 100(100 リクエストに 1 回記録)、exclude_paths 空
出力初期化init_tracing(TracingOutput) -> WorkerGuard(tracing-appender の non_blocking writer。WorkerGuard は drop までログをフラッシュし続けるため保持必須)
  • 注意: exclude_paths はクエリ除去後パスとの完全一致のみ(プレフィックス・glob 非対応。ログ抑制範囲の意図しない拡大を防ぐ安全側の設計)。除外パスはサンプラーのカウンタも消費しない

2.8 plugin-webrtc-proxy(webrtc-proxy)

WebRTC シグナリングの別プロセス切り出し型プロキシ。POST /rtc/offer(OFFER_PATH 定数)を upstream へ委譲する。攻撃表面をプロセス境界で分離でき、MVP 推奨。

項目内容
Config 型ProxyConfig
構築・builderProxyConfig::new(upstream_addr) + with_upstream_path / with_connect_timeout / with_request_timeout / with_max_offer_bytes / with_max_answer_bytes
既定値upstream_path = "/rtc/offer"、connect_timeout = 3 秒、request_timeout = 5 秒、max_offer_bytes = max_answer_bytes = 64 KiB
  • 注意: offer / answer 双方向にサイズ上限を持つ(upstream 応答の肥大もフェイルクローズで遮断)。webrtc feature と同時有効時は webrtc-proxy が優先評価される

2.9 plugin-webrtc(webrtc)

in-process WebRTC(webrtc-rs 直接依存)。POST /rtc/offer を同一プロセス内で処理する。

項目内容
Config 型WebRtcConfig
構築・builderWebRtcConfig::new() + with_max_offer_bytes / with_max_peer_connections / with_signaling_timeout(getter: max_offer_bytes / max_peer_connections / signaling_timeout)
既定値max_offer_bytes = 64 KiB、max_peer_connections = 64、signaling_timeout = 10 秒
drain APIclose_active_peers(&config, per_close_timeout) / drain_for_shutdown(&config, per_close_timeout)(drain モジュール)
  • 注意: webrtc-rs の依存ツリーが大きく攻撃表面が広いため、クレート境界で完全分離されている。まず plugin-webrtc-proxy の採用を検討すること
  • 注意: close_active_peers / drain_for_shutdown はいずれも WebRtcConfig::registry 上のアクティブな RTCPeerConnection を 1 接続あたり per_close_timeout の有界タイムアウトで並行に明示 close する。drain_for_shutdown のみ WebRtcConfig::begin_terminal_drain で以降の新規登録を拒否するフェイルクローズ判定を伴う(close_active_peers は rebind 用途を想定し新規登録は拒否しない)。コアの SessionDrain(webrtc feature ゲート、独立シーム)が最終 graceful shutdown・rebind の両経路から自動でこれらを呼ぶため、通常は利用側が直接呼ぶ必要はない(docs/design/ws-cancellation-propagation.md 10 節を参照)

2.10 plugin-hub-wiring(feature なし・依存逆転型)

hub 共通配線(JWT RS256 / JWKS / テナント境界強制・同意ゲート・outbox・監査)。他プラグインと異なりコア側 feature を持たず、利用側サービスが本クレートを依存に追加してコアの RequestGate 拡張点へ登録する(プラグイン → コアの一方向依存)。

項目内容
登録Server::gate(TenantGate::new(TenantGateConfig::from_jwks_json(jwks_json)?))
TenantGateRequestGate 実装。Bearer JWT の RS256 検証とテナント境界強制を同期・I/O なしで行う
TenantGateConfignew(SharedJwks) / from_jwks_json(&str) で構築。authenticator() で Authenticator(検証結果キャッシュ。ゲート通過時に温まり、ハンドラ側の再検証で RS256 署名検証を再実行しない)を取得
SharedJwks再起動なしの鍵ローテーション対応 JWKS 保持(snapshot / set)。JWKS の HTTP 取得・自動リフレッシュは利用側の責務
ConsentStore / OutboxStoreゲート通過後にハンドラ層から呼ぶストレージ抽象 trait。同梱はテスト用インメモリ実装(InMemoryConsentStore / InMemoryOutboxStore)のみで、DB 実装は利用側が提供
AuditSink越境アクセス監査ログの出力先 trait(MemoryAuditSink 同梱)。外部応答は正当な 404 と越境 404 で完全同一のまま、監査ログのみで区別する
  • 注意: 検証失敗はキャッシュしない(キャッシュ汚染防止)。各型の詳細契約は rustdoc(crates/plugin-hub-wiring/src/{gate,auth,jwks,consent,outbox,audit}.rs)を参照

3. 契約・不変条件(横断)

  • opt-in 契約: すべてのプラグインは feature 有効化 + Server::xxx(...) 登録の 2 段階が揃って初めて動作する。未登録時のリクエスト挙動は feature 無効時と同一
  • 構築時検証(フェイルクローズ): 不正設定は実行時ではなく構築時に Result で拒否する(CorsConfigError / StaticConfigError / OpenApiDocError)。実行時に初めて失敗する経路を作らない
  • DoS 上限内蔵: サイズ・接続数・タイムアウトの上限は既定で有効。無効化・緩和は明示操作のみ
  • レスポンス後処理の適用順: finalize_response シームで CORS → compression の順に逐次適用される

4. セキュリティ観点

プラグイン主な観点
websocketメッセージ / フレームサイズ上限・アイドルタイムアウト既定有効(メモリ枯渇・接続占有 DoS 対策)
graphql深さ・複雑度制限と introspection 無効化は登録者責務(既定値を提供しないことを明示)。エラー応答にリクエスト由来値を含めない
corsAny オリジン + credentials の最悪構成を構築時拒否。オリジンはバイト完全一致のみ
compressionBREACH 類似リスク(秘密 + 反映値の同居 body)を rustdoc に明記。判定不能は無圧縮側へ倒す
static二層防御によるパストラバーサル・シンボリックリンク脱出拒否、機密ファイル(先頭ドット)遮断、一律 404 による存在秘匿
tracing除外は完全一致のみ(可観測性の穴の拡大防止)。ログに機密を出さない運用前提
webrtc / webrtc-proxyペイロードサイズ・接続数・タイムアウト上限。攻撃表面の観点で proxy 型を推奨
hub-wiringRS256 + JWKS・鍵ローテーション・検証失敗の非キャッシュ・越境アクセスのフェイルクローズ遮断と監査

5. スコープ外・関連ドキュメント

  • スコープ外: 各プラグインのプロトコル仕様詳細(RFC 6455 / GraphQL over HTTP / SDP 等)、curl での動作確認手順(feature 構成別サンプル)、hub-wiring の JWT / JWKS / outbox の詳細契約(rustdoc)、TLS 終端・multipart(v1 スコープ外。docs/design/v1-scope-tls-multipart.md)
  • Server 本体の設定(接続数・body 上限・タイムアウト・graceful shutdown): サーバ API、graceful shutdown ガイド
  • ルーティングとの接続(options_fallback / パスインターセプトの前提): ルーティング API
  • 拡張点の契約(Middleware / UpgradeHandler / RequestGate): 拡張 API、拡張点ガイド
  • 配線パターンの設計判断・境界検証: docs/design/plugin-boundary.md(<https://github.com/Fandhe-AI/fandhe-backend/blob/main/docs/design/plugin-boundary.md>)
  • 入門: Getting Started、チュートリアル