# proxiedFetch

`fetch` 互換のラッパーで、リクエストを Fluxlay ホストプロセス経由で送信します。`Access-Control-Allow-Origin` を返さない `network:` 宣言済み origin (Google カレンダーの ICS フィードや公開 RSS など) に対して使用します。ホストが通常の HTTP クライアントとしてアップストリームへ問い合わせるため、ブラウザの CORS は適用されません。

## インポート

```tsx
import { proxiedFetch } from "@fluxlay/react";
```

## シグネチャ

```tsx
function proxiedFetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
```

引数の形は標準の `fetch` API と同じです。返される `Response` には upstream のステータス・ボディ、および転送対象のレスポンスヘッダだけが乗ります。

## 使い方

```tsx
import { proxiedFetch } from "@fluxlay/react";

async function loadEvents(icsUrl: string) {
  const res = await proxiedFetch(icsUrl);
  if (!res.ok) throw new Error(`ICS ${res.status}`);
  return res.text();
}
```

対象 origin は `fluxlay.yaml` の `network:` で宣言する必要があります:

```yaml
# fluxlay.yaml
network:
  - origin: https://calendar.google.com
    reason: ユーザーの公開 ICS カレンダーを取得する。
```

## 用途

壁紙は隔離された `fluxlay://` origin で動作し、外向きリクエストは 2 段階のゲートで制限されます:

1. **CSP `connect-src`**: 壁紙 webview からは `fluxlay.yaml` の `network:` で宣言した origin にしか到達できない。
2. **CORS**: CSP を通っても、upstream が `Access-Control-Allow-Origin` を返さなければブラウザがレスポンスをブロックする。実運用の API には CORS を返さないもの (ICS / 静的ファイルホスト / 公開 RSS) が多い。

`proxiedFetch` は 2 番目の制約を回避します。リクエスト内容をローカル Fluxlay API (`POST /v1/network-proxy`) に POST すると、ホスト (Rust) が代行で fetch してボディを壁紙に返します。ホスト側 HTTP には CORS が適用されないので、`network:` 宣言済みの origin はすべて利用可能になります。

1 番目のゲートはそのままです — 未宣言 origin はプロキシが 403 を返すため、セキュリティモデルは直接 `fetch` と同じです。

## 標準 `fetch` との差分

- 受け付けるのは `http:` / `https:` URL のみ。`file:` / `data:` / 独自スキームは 400。
- `Cookie` / `Origin` / `Host` / `Referer` リクエストヘッダは upstream に転送されない。
- レスポンスボディは 10 MiB 上限。超過すると 502。
- ストリーミングレスポンスは非対応。upstream のボディは全てバッファされてから壁紙に返される。
- 転送するレスポンスヘッダは `Content-Type` / `Cache-Control` / `ETag` / `Last-Modified` のみ。`Set-Cookie` 等はドロップ。
- リクエストタイムアウト 30 秒、リダイレクト 5 ホップまで追従。

## 備考

- `init.headers` の `Authorization` 等は upstream にそのまま転送される。トークンが壁紙 origin のストレージに永続化されることはなく、各呼び出し時にホストを通過するだけ。
- `User-Agent` を呼び出し側で指定しない場合、自動的に `Fluxlay-Wallpaper-Proxy/<version>` が設定される。`User-Agent` 必須の API (GitHub 等) も追加設定なしで動く。
- `init.signal` の `AbortSignal` は壁紙側 fetch をキャンセルする。ホスト側のリクエストはバックグラウンドで完了まで継続する。
