diff --git a/package.json b/package.json index 8be5873..46d7ceb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mcp-play", - "version": "0.2.10", + "version": "0.2.11", "description": "A simple Node.js application to play with the Model Context Protocol.", "main": "src/server.ts", "type": "module", diff --git a/reference-docs/VERSION b/reference-docs/VERSION index 13dead7..d3b5ba4 100644 --- a/reference-docs/VERSION +++ b/reference-docs/VERSION @@ -1 +1 @@ -0.2.10 +0.2.11 diff --git a/reference-docs/cdn-apps-rust.md b/reference-docs/cdn-apps-rust.md index bdad5fe..42303a5 100644 --- a/reference-docs/cdn-apps-rust.md +++ b/reference-docs/cdn-apps-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> # FastEdge Rust SDK — CDN Apps (Proxy-Wasm) @@ -46,7 +46,7 @@ proxy-wasm = "0.2" log = "0.4" ``` -**Tier 2 — CDN app with FastEdge host services** (KV, secrets, dictionary): +**Tier 2 — CDN app with FastEdge host services** (KV, cache, secrets, dictionary): ```toml [package] @@ -195,12 +195,12 @@ impl HttpContext for HelloWorld { ## Lifecycle Callbacks -| Callback | Phase | Description | -| ----------------------------------------------------------------- | ---------------- | --------------------------------------------------- | -| `on_http_request_headers(num_headers: usize, end_of_stream: bool) -> Action` | Request headers | Inspect or modify request headers before forwarding | -| `on_http_request_body(body_size: usize, end_of_stream: bool) -> Action` | Request body | Inspect or modify request body before forwarding | -| `on_http_response_headers(num_headers: usize, end_of_stream: bool) -> Action` | Response headers | Inspect or modify response headers from origin | -| `on_http_response_body(body_size: usize, end_of_stream: bool) -> Action` | Response body | Inspect or modify response body from origin | +| Callback | Phase | Description | +| ----------------------------------------------------------------------------------------------- | ---------------- | --------------------------------------------------- | +| `on_http_request_headers(num_headers: usize, end_of_stream: bool) -> Action` | Request headers | Inspect or modify request headers before forwarding | +| `on_http_request_body(body_size: usize, end_of_stream: bool) -> Action` | Request body | Inspect or modify request body before forwarding | +| `on_http_response_headers(num_headers: usize, end_of_stream: bool) -> Action` | Response headers | Inspect or modify response headers from origin | +| `on_http_response_body(body_size: usize, end_of_stream: bool) -> Action` | Response body | Inspect or modify response body from origin | All callbacks have default no-op implementations. Override only the phases your app needs to process. @@ -508,6 +508,91 @@ impl HttpContext for RateLimitFilter { } ``` +### Cache (`fastedge::proxywasm::cache`) + +Provides ephemeral cache storage, implemented by the host. Unlike `key_value::Store`, cache operations are not scoped to a named store or handle — every function is a free function keyed directly, and every entry is scoped to the calling application. + +```rust,ignore +pub fn get(key: &str) -> Result>, Error> +pub fn set(key: &str, value: &[u8], ttl_ms: Option) -> Result<(), Error> +pub fn delete(key: &str) -> Result<(), Error> +pub fn exists(key: &str) -> Result +pub fn incr(key: &str, delta: i64) -> Result +pub fn expire(key: &str, ttl_ms: u64) -> Result +pub fn purge() -> Result +pub fn purge_prefix(prefix: &str) -> Result +``` + +| Function | Return Type | Description | +| ---------------------------------------------------- | -------------------------------- | ---------------------------------------------------------------------------- | +| `get(key: &str)` | `Result>, Error>` | Get the value for a key; `None` if the key does not exist | +| `set(key: &str, value: &[u8], ttl_ms: Option)` | `Result<(), Error>` | Set a value with an optional expiry; `None` means no expiry | +| `delete(key: &str)` | `Result<(), Error>` | Delete a key; a no-op if the key does not exist | +| `exists(key: &str)` | `Result` | Test whether a key exists | +| `incr(key: &str, delta: i64)` | `Result` | Atomically increment (or decrement) an integer value; returns the new value | +| `expire(key: &str, ttl_ms: u64)` | `Result` | Set or update a key's expiry; `false` if the key does not exist | +| `purge()` | `Result` | Delete all cache entries owned by the calling application | +| `purge_prefix(prefix: &str)` | `Result` | Delete all cache entries whose key begins with `prefix` | + +`purge()` and `purge_prefix()` both return the number of keys that were deleted. + +#### `Error` + +```rust,ignore +pub enum Error { + AccessDenied, + InternalError, + Other(String), +} +``` + +| Variant | Description | +| --------------- | ----------------------------------------------------------- | +| `AccessDenied` | The application does not have access to the specified cache | +| `InternalError` | An unexpected internal error occurred | +| `Other(String)` | An implementation-specific error (e.g., I/O failure) | + +#### Example — cache a computed value in the response headers phase + +```rust,no_run +use fastedge::proxywasm::cache; +use proxy_wasm::traits::*; +use proxy_wasm::types::*; + +proxy_wasm::main! {{ + proxy_wasm::set_log_level(LogLevel::Trace); + proxy_wasm::set_root_context(|_| -> Box { Box::new(CacheRoot) }); +}} + +struct CacheRoot; +impl Context for CacheRoot {} +impl RootContext for CacheRoot { + fn get_type(&self) -> Option { Some(ContextType::HttpContext) } + fn create_http_context(&self, _: u32) -> Option> { + Some(Box::new(CacheFilter)) + } +} + +struct CacheFilter; +impl Context for CacheFilter {} + +impl HttpContext for CacheFilter { + fn on_http_response_headers(&mut self, _: usize, _: bool) -> Action { + match cache::get("key-3338664") { + Ok(Some(_cached)) => { + // reuse the cached value + } + Ok(None) => { + // store the value for 5 minutes + let _ = cache::set("key-3338664", b"value", Some(300_000)); + } + Err(_) => {} + } + Action::Continue + } +} +``` + ### Secret Management (`fastedge::proxywasm::secret`) Provides access to encrypted secrets stored in the FastEdge platform. @@ -733,16 +818,17 @@ The `log` crate macros (`info!`, `warn!`, `error!`, etc.) work when `proxy_wasm: ## API Comparison: HTTP vs CDN -| Service | HTTP Apps (Component Model) | CDN Apps (ProxyWasm) | -| ------------- | ------------------------------------------------------------------- | -------------------------------------------------------- | -| Key-Value | `fastedge::key_value::Store` | `fastedge::proxywasm::key_value::Store` | -| Secrets | `fastedge::secret::get` | `fastedge::proxywasm::secret::get` | -| Dictionary | `fastedge::dictionary::get` | `fastedge::proxywasm::dictionary::get` | -| Diagnostics | `fastedge::utils::set_user_diag` | `fastedge::proxywasm::utils::set_user_diag` | -| Error types | Typed `Error` enums | `u32` status codes (secret) or typed `Error` (key_value) | -| Cargo feature | None required | `features = ["proxywasm"]` | -| Build target | `wasm32-wasip1` (basic) / `wasm32-wasip2` (wstd) | `wasm32-wasip1` | -| Handler | `#[wstd::http_server]` (recommended) / `#[fastedge::http]` (basic) | `proxy_wasm::main!` + traits | +| Service | HTTP Apps (Component Model) | CDN Apps (ProxyWasm) | +| ------------- | ------------------------------------------------------------------- | ----------------------------------------------------------------- | +| Key-Value | `fastedge::key_value::Store` | `fastedge::proxywasm::key_value::Store` | +| Cache | `fastedge::cache` | `fastedge::proxywasm::cache` | +| Secrets | `fastedge::secret::get` | `fastedge::proxywasm::secret::get` | +| Dictionary | `fastedge::dictionary::get` | `fastedge::proxywasm::dictionary::get` | +| Diagnostics | `fastedge::utils::set_user_diag` | `fastedge::proxywasm::utils::set_user_diag` | +| Error types | Typed `Error` enums | `u32` status codes (secret) or typed `Error` (key_value, cache) | +| Cargo feature | None required | `features = ["proxywasm"]` | +| Build target | `wasm32-wasip1` (basic) / `wasm32-wasip2` (wstd) | `wasm32-wasip1` | +| Handler | `#[wstd::http_server]` (recommended) / `#[fastedge::http]` (basic) | `proxy_wasm::main!` + traits | ## See Also diff --git a/reference-docs/cdn-examples-ab-testing-as.md b/reference-docs/cdn-examples-ab-testing-as.md index c74421a..c70feb6 100644 --- a/reference-docs/cdn-examples-ab-testing-as.md +++ b/reference-docs/cdn-examples-ab-testing-as.md @@ -3,8 +3,8 @@ sources: - id: proxy-wasm-sdk-as ref: master - commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 - updated: 2026-08-20 + commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 + updated: 2026-09-22 --> # A/B Testing — AssemblyScript (CDN) diff --git a/reference-docs/cdn-examples-ab-testing-rust.md b/reference-docs/cdn-examples-ab-testing-rust.md index a8e55fb..9d90a98 100644 --- a/reference-docs/cdn-examples-ab-testing-rust.md +++ b/reference-docs/cdn-examples-ab-testing-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-api-key-as.md b/reference-docs/cdn-examples-api-key-as.md index 4807ec3..9a743b6 100644 --- a/reference-docs/cdn-examples-api-key-as.md +++ b/reference-docs/cdn-examples-api-key-as.md @@ -3,8 +3,8 @@ sources: - id: proxy-wasm-sdk-as ref: master - commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 - updated: 2026-08-20 + commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-api-key-rust.md b/reference-docs/cdn-examples-api-key-rust.md index 5aeb1a4..a001d60 100644 --- a/reference-docs/cdn-examples-api-key-rust.md +++ b/reference-docs/cdn-examples-api-key-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> # API Key Validation — CDN (Rust) @@ -159,120 +159,3 @@ return Action::Pause; - Host services reference — secrets API (`fastedge::proxywasm::secret`) and other CDN host services - CDN apps reference — proxy-wasm app structure, `RootContext`/`HttpContext` setup, `Action` enum, and request property encodings - SDK API reference — Rust CDN SDK traits and types - -## Source Material - -### FILE: examples/cdn/api_key/src/lib.rs - -```rust -/* -* Copyright 2025 G-Core Innovations SARL -*/ -/* -Example CDN app demonstrating API key validation. - -Validates requests using an X-API-Key header checked against a stored -secret. Simpler alternative to JWT when token expiry and claims are -not needed. - -Required configuration: - - Secret: API_KEY -*/ - -use fastedge::proxywasm::secret; -use proxy_wasm::traits::*; -use proxy_wasm::types::*; - -proxy_wasm::main! {{ - proxy_wasm::set_log_level(LogLevel::Info); - proxy_wasm::set_root_context(|_| -> Box { Box::new(ApiKeyRoot) }); -}} - -struct ApiKeyRoot; - -impl Context for ApiKeyRoot {} - -impl RootContext for ApiKeyRoot { - fn get_type(&self) -> Option { - Some(ContextType::HttpContext) - } - - fn create_http_context(&self, _: u32) -> Option> { - Some(Box::new(ApiKeyContext)) - } -} - -struct ApiKeyContext; - -impl Context for ApiKeyContext {} - -impl HttpContext for ApiKeyContext { - fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action { - let expected_key = match secret::get("API_KEY") { - Ok(Some(bytes)) => match String::from_utf8(bytes) { - Ok(s) if !s.is_empty() => s, - _ => { - self.send_http_response(500, vec![], Some(b"App misconfigured")); - return Action::Pause; - } - }, - _ => { - self.send_http_response(500, vec![], Some(b"App misconfigured")); - return Action::Pause; - } - }; - - let provided_key = match self.get_http_request_header("X-API-Key") { - Some(k) if !k.is_empty() => k, - _ => { - self.send_http_response( - 401, - vec![("WWW-Authenticate", "API-Key")], - Some(b"Missing X-API-Key header"), - ); - return Action::Pause; - } - }; - - if provided_key != expected_key { - println!("API key validation failed"); - self.send_http_response(403, vec![], Some(b"Invalid API key")); - return Action::Pause; - } - - // Strip the API key header before forwarding to upstream - self.set_http_request_header("X-API-Key", None); - - println!("API key validated successfully"); - Action::Continue - } -} -``` - -### FILE: examples/cdn/api_key/Cargo.toml - -```toml -[workspace] - -[package] -name = "api_key" -version = "0.1.0" -edition = "2024" - -[lib] -crate-type = ["cdylib"] - -[dependencies] -proxy-wasm = "0.2" -fastedge = { version = "0.4", features = ["proxywasm"] } -``` - -### FILE: examples/cdn/api_key/README.md - -``` -[← Back to examples](../../README.md) - -# API Key (CDN) - -Validates requests using an `X-API-Key` header checked against a stored secret. Returns 401 if missing, 403 if invalid, and strips the header before forwarding to upstream. -``` diff --git a/reference-docs/cdn-examples-auth-jwt-as.md b/reference-docs/cdn-examples-auth-jwt-as.md index 8495978..68adc80 100644 --- a/reference-docs/cdn-examples-auth-jwt-as.md +++ b/reference-docs/cdn-examples-auth-jwt-as.md @@ -3,8 +3,8 @@ sources: - id: proxy-wasm-sdk-as ref: master - commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 - updated: 2026-08-20 + commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 + updated: 2026-09-22 --> --- capabilities: diff --git a/reference-docs/cdn-examples-auth-jwt-rust.md b/reference-docs/cdn-examples-auth-jwt-rust.md index 047c4eb..d906398 100644 --- a/reference-docs/cdn-examples-auth-jwt-rust.md +++ b/reference-docs/cdn-examples-auth-jwt-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-body-as.md b/reference-docs/cdn-examples-body-as.md index d98a1dc..f558a45 100644 --- a/reference-docs/cdn-examples-body-as.md +++ b/reference-docs/cdn-examples-body-as.md @@ -3,8 +3,8 @@ sources: - id: proxy-wasm-sdk-as ref: master - commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 - updated: 2026-08-20 + commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-body-rust.md b/reference-docs/cdn-examples-body-rust.md index 78eaab7..889ecbb 100644 --- a/reference-docs/cdn-examples-body-rust.md +++ b/reference-docs/cdn-examples-body-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-cache-control-as.md b/reference-docs/cdn-examples-cache-control-as.md index 41bcabf..ee2e585 100644 --- a/reference-docs/cdn-examples-cache-control-as.md +++ b/reference-docs/cdn-examples-cache-control-as.md @@ -3,8 +3,8 @@ sources: - id: proxy-wasm-sdk-as ref: master - commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 - updated: 2026-08-20 + commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-cache-control-rust.md b/reference-docs/cdn-examples-cache-control-rust.md index e0bb9aa..cbbf346 100644 --- a/reference-docs/cdn-examples-cache-control-rust.md +++ b/reference-docs/cdn-examples-cache-control-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-cache-rust.md b/reference-docs/cdn-examples-cache-rust.md new file mode 100644 index 0000000..8a65925 --- /dev/null +++ b/reference-docs/cdn-examples-cache-rust.md @@ -0,0 +1,237 @@ + + +# CDN Cache — Rust Example + +## Overview + +CDN app demonstrating cache operations via the proxy-wasm ABI. All operations are scoped to the calling application and addressed by key alone — there are no named stores or handles (unlike the KV store). + +Operations are dispatched via query parameters on the incoming request. Responses are always JSON. Errors return HTTP 500 with `{"error": ""}`. + +## App Type + +- **Interface**: proxy-wasm (`fastedge::proxywasm::cache`) +- **App type**: CDN +- **Language**: Rust + +## Request Interface + +All operations are specified via query parameters. The `action` parameter selects the operation; `action=get` is the default when omitted. + +| Query string | Operation | +|---|---| +| `?action=get&key=` | Read a cached value. `response` is `null` when the key is absent. | +| `?action=set&key=&value=[&ttl=]` | Store a value. Omitting `ttl` stores with no expiry. | +| `?action=delete&key=` | Delete a key. No-op when the key is absent. | +| `?action=exists&key=` | Test key membership. | +| `?action=incr&key=&delta=` | Atomic increment. `delta` may be negative. A missing key starts at `0`. | +| `?action=expire&key=&ttl=` | Set or update a key's TTL. `response` is `false` when the key is absent. | +| `?action=purge` | Delete every key owned by this app. Returns count of deleted keys. | +| `?action=purgePrefix&prefix=` | Delete app-owned keys starting with `prefix`. Returns count deleted. | + +## API Reference + +All functions are in `fastedge::proxywasm::cache`. + +### `cache::get` + +```rust +pub fn get(key: &str) -> Result>, _> +``` + +Retrieve cached bytes by key. + +- **Parameters**: `key` — cache key string +- **Returns**: `Ok(Some(Vec))` if the key exists, `Ok(None)` if absent, `Err` on failure + +**JSON response shape:** +```json +{ "action": "get", "key": "", "response": "" } +{ "action": "get", "key": "", "response": null } +``` + +--- + +### `cache::set` + +```rust +pub fn set(key: &str, value: &[u8], ttl_ms: Option) -> Result<(), _> +``` + +Store bytes under a key with an optional TTL. + +- **Parameters**: + - `key` — cache key string + - `value` — byte slice to store + - `ttl_ms` — TTL in milliseconds; `None` means no expiry +- **Returns**: `Ok(())` on success, `Err` on failure +- **Constraint**: `ttl_ms` must be a positive integer when provided; invalid values produce an error response + +**JSON response shape:** +```json +{ "action": "set", "key": "", "value": "", "ttlMs": |null, "response": true } +``` + +--- + +### `cache::delete` + +```rust +pub fn delete(key: &str) -> Result<(), _> +``` + +Remove a key from the cache. No-op if the key does not exist. + +- **Parameters**: `key` — cache key string +- **Returns**: `Ok(())` on success, `Err` on failure + +**JSON response shape:** +```json +{ "action": "delete", "key": "", "response": true } +``` + +--- + +### `cache::exists` + +```rust +pub fn exists(key: &str) -> Result +``` + +Test whether a key is present in the cache. + +- **Parameters**: `key` — cache key string +- **Returns**: `Ok(true)` if present, `Ok(false)` if absent, `Err` on failure + +**JSON response shape:** +```json +{ "action": "exists", "key": "", "response": true|false } +``` + +--- + +### `cache::incr` + +```rust +pub fn incr(key: &str, delta: i64) -> Result +``` + +Atomically increment (or decrement) a cached counter. If the key does not exist, it is treated as `0` before applying the delta. + +- **Parameters**: + - `key` — cache key string + - `delta` — signed 64-bit integer; may be negative for decrements +- **Returns**: `Ok(new_value)` — the value after increment, `Err` on failure + +**JSON response shape:** +```json +{ "action": "incr", "key": "", "delta": , "response": } +``` + +--- + +### `cache::expire` + +```rust +pub fn expire(key: &str, ttl_ms: u64) -> Result +``` + +Set or update the TTL on an existing key. + +- **Parameters**: + - `key` — cache key string + - `ttl_ms` — TTL in milliseconds; must be a positive integer +- **Returns**: `Ok(true)` if the key existed and was updated, `Ok(false)` if the key was absent, `Err` on failure + +**JSON response shape:** +```json +{ "action": "expire", "key": "", "ttlMs": , "response": true|false } +``` + +--- + +### `cache::purge` + +```rust +pub fn purge() -> Result +``` + +Delete all keys owned by the calling application. + +- **Parameters**: none +- **Returns**: `Ok(count)` — number of keys deleted, `Err` on failure + +**JSON response shape:** +```json +{ "action": "purge", "response": } +``` + +--- + +### `cache::purge_prefix` + +```rust +pub fn purge_prefix(prefix: &str) -> Result +``` + +Delete all app-owned keys whose names start with the given prefix. + +- **Parameters**: `prefix` — key prefix string +- **Returns**: `Ok(count)` — number of keys deleted, `Err` on failure + +**JSON response shape:** +```json +{ "action": "purgePrefix", "prefix": "", "response": } +``` + +--- + +## Error Handling + +- All errors return HTTP 500 with body `{"error": ""}`. +- Missing required query parameters produce descriptive error messages, e.g. `"Missing required param 'key' for 'get' action"`. +- Invalid parameter values (e.g. non-integer `ttl`, non-integer `delta`) produce descriptive parse error messages. +- Unknown `action` values produce an error listing all supported actions. + +## Dependencies + +```toml +proxy-wasm = "0.2" +fastedge = { path = "...", features = ["proxywasm"] } +querystring = "1.1" +serde_json = "1" +``` + +## Build + +```sh +cargo build --release +# Output: target/wasm32-wasip1/release/cache.wasm +``` + +## Lifecycle Notes + +- The app uses the proxy-wasm `RootContext` + `HttpContext` pattern. +- Logic executes in `on_http_response_body` (waits for `end_of_stream`). +- `on_http_response_headers` strips `content-length`, sets `content-type: application/json`, and sets `transfer-encoding: chunked` before body processing. +- Query string is read from `request.query` via `get_property`. + +## Key Constraints + +- Cache operations are scoped to the calling application — keys from one app are not accessible to another. +- There are no named stores or handles; the key is the sole address. +- `ttl` values are always in **milliseconds**. +- `delta` for `incr` is a signed 64-bit integer (`i64`); a missing key is treated as `0`. + +## See Also + +- fastedge-sdk-rust CDN key_value example (named KV store with handles, contrast to this cache API) +- fastedge-sdk-rust CDN examples overview +- proxy-wasm `HttpContext` and `RootContext` trait documentation diff --git a/reference-docs/cdn-examples-convert-image-rust.md b/reference-docs/cdn-examples-convert-image-rust.md index cf31db4..9f4fdd9 100644 --- a/reference-docs/cdn-examples-convert-image-rust.md +++ b/reference-docs/cdn-examples-convert-image-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> # CDN Example: Convert Image (Rust) @@ -202,300 +202,3 @@ Transformation is skipped (returning `Action::Continue` without modifying the re - FastEdge CDN app platform overview - FastEdge SDK Rust reference - FastEdge error codes reference - -## Source Material - -### FILE: examples/cdn/convert_image/src/lib.rs - -```rust -use image::*; -use proxy_wasm::traits::*; -use proxy_wasm::types::*; -use std::{env, env::VarError, io::Cursor, str::from_utf8}; - -proxy_wasm::main! {{ - proxy_wasm::set_log_level(LogLevel::Trace); - proxy_wasm::set_root_context(|_| -> Box { Box::new(ConvertImageRoot) }); -}} - -struct ConvertImageRoot; - -impl Context for ConvertImageRoot {} - -impl RootContext for ConvertImageRoot { - fn get_type(&self) -> Option { - Some(ContextType::HttpContext) - } - - fn create_http_context(&self, _: u32) -> Option> { - Some(Box::new(ConvertImageContext)) - } -} - -struct ConvertImageContext; - -impl Context for ConvertImageContext {} - -impl HttpContext for ConvertImageContext { - fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action { - // this header is used to select correct image version from cache - self.add_http_request_header("Image-Format", "original"); - - // get extension - let path = self.get_property(vec!["request.path"]).map(|v| String::from_utf8(v).unwrap_or_default()).unwrap_or_default(); - println!("request.path={path:?}"); - let raw_ext = self.get_property(vec!["request.extension"]); - println!("request.extension={raw_ext:?}"); - let Some(ext) = raw_ext else { - println!("No extension in request path, not transforming"); - return Action::Continue; - }; - let Ok(ext) = from_utf8(&ext) else { - println!("Invalid UTF-8 in request extension, not transforming"); - return Action::Continue; - }; - if ext.is_empty() { - println!("No extension in request path, not transforming"); - return Action::Continue; - } - - // FORMATS_TO_TRANSFORM contains list of file extensions to transfor - // note that jpg and jpeg are different extensions - let Ok(image_list) = str_param("FORMATS_TO_TRANSFORM") else { - println!("FORMATS_TO_TRANSFORM param is not set, not transforming"); - return Action::Continue; - }; - if !image_list.split(',').any(|entry| entry == ext) { - println!( - "extension {} is not in the list of formats to transform: {}, not transforming", - ext, image_list - ); - return Action::Continue; - } - - // requests from User agents that match substrings in the IGNORED_UA_LIST param are not transformed - let Some(ua) = self.get_http_request_header("User-Agent") else { - println!("User-Agent header is not set, not transforming"); - return Action::Continue; - }; - if ua.is_empty() { - println!("User-Agent header is not set, not transforming"); - return Action::Continue; - } - if let Ok(ua_to_ignore) = str_param("IGNORED_UA_LIST") { - if ua_to_ignore.split(",").any(|entry| ua.contains(entry)) { - println!("User-Agent is in ignore list, not transforming"); - return Action::Continue; - } - } - - // indicator for on_response_headers and for cache key - self.set_http_request_header("Image-Format", Some("image/avif")); - - Action::Continue - } - - fn on_http_response_headers(&mut self, _: usize, _: bool) -> Action { - // only process 200 responses - if let Some(status) = self.rsp_status() { - if status != 200 { - println!( - "Response status is {} instead of expected 200, not transforming", - status - ); - return Action::Continue; - } - } else { - println!("Response status is not set, not transforming"); - return Action::Continue; - } - - // if "Image-Format" request header is not set, don't convert the image - let Some(content_type) = self.get_http_request_header("Image-Format") else { - return Action::Continue; - }; - // instruct cache to vary by this header so "original" and "image/avif" are cached separately - self.add_http_response_header("Vary", "Image-Format"); - - if content_type == "original" { - return Action::Continue; - }; - - // image to be transformed, set headers accordingly - self.set_http_response_header("Content-Length", None); - self.set_http_response_header("Transfer-Encoding", Some("Chunked")); - self.set_http_response_header("Content-Type", Some(content_type.as_str())); - - // indicate to on_http_response_body that transformation is needed - self.set_property(vec!["response.content-type"], Some(content_type.as_bytes())); - - Action::Continue - } - - fn on_http_response_body(&mut self, body_size: usize, end_of_stream: bool) -> Action { - if !end_of_stream { - // wait till we get complete body - return Action::Pause; - } - - let Some(content_type) = self.get_property(vec!["response.content-type"]) else { - return Action::Continue; - }; - - let Ok(content_type) = from_utf8(&content_type) else { - // should never happen - println!("Invalid UTF-8 in Content-Type"); - self.send_http_response(500, vec![], None); - return Action::Pause; - }; - - if content_type != "image/avif" { - // should never happen - println!( - "Content-Type {} is not supported, not transforming", - content_type - ); - return Action::Continue; - } - - if let Some(body_bytes) = self.get_http_response_body(0, body_size) { - let buf = body_bytes.as_bytes(); - let img = match load_from_memory(buf) { - Ok(i) => i, - Err(e) => { - println!("cannot load image to memory {}, not converting", e); - return Action::Continue; - } - }; - - let mut out = Vec::new(); - let mut c = Cursor::new(&mut out); - let res = img.write_with_encoder(codecs::avif::AvifEncoder::new_with_speed_quality( - &mut c, - u8_param("AVIF_SPEED", 1, 10, 5), - u8_param("AVIF_QUALITY", 1, 100, 70), - )); - - match res { - Ok(_) => { - println!( - "{} bytes -> {} bytes {}", - body_size, - out.len(), - content_type - ); - self.set_http_response_body(0, body_size, &out) - } - Err(e) => println!("cannot store transformed image {}", e), - } - } else { - println!("No response body to transform"); - } - - Action::Continue - } -} - -impl ConvertImageContext { - fn rsp_status(&mut self) -> Option { - if let Some(status) = self.get_property(vec!["response.status"]) { - if status.len() != 2 { - println!("HTTP status property is not 2 bytes"); - return None; - } - return Some(u16::from_be_bytes([status[0], status[1]])); - } - None - } -} - -fn str_param(name: &str) -> Result { - let val = env::var(name)?; - if val.is_empty() { - return Err(VarError::NotPresent); - } - - Ok(val) -} - -fn u8_param(name: &str, min: u8, max: u8, default: u8) -> u8 { - let Ok(val) = env::var(name) else { - println!("Param {} is not set, using default value {}", name, default); - return default; - }; - if val.is_empty() { - println!("Param {} is not set, using default value {}", name, default); - return default; - } - - let val = match val.parse() { - Err(_) => { - println!( - "Param {} is not a valid number, using default value {}", - name, default - ); - return default; - } - Ok(v) => v, - }; - if val < min { - println!( - "Param {} is below minimum {}, using default value {}", - name, min, default - ); - return default; - } - if val > max { - println!( - "Param {} is above maximum {}, using default value {}", - name, max, default - ); - return default; - } - - val -} -``` - - -### FILE: examples/cdn/convert_image/Cargo.toml - -```toml -[workspace] - -[package] -name = "convert_image" -version = "0.1.0" -edition = "2024" - -[lib] -crate-type = ["cdylib"] - -[dependencies] -proxy-wasm = "0.2" -image = "0.25" -``` - - -### FILE: examples/cdn/convert_image/README.md - -``` -[← Back to examples](../../README.md) - -# Convert Image (CDN) - -Converts images to AVIF format on the fly using the proxy-wasm ABI. Only transforms requests matching configured file extensions and skips specified user agents. - -## Configuration - -- Environment variable: `FORMATS_TO_TRANSFORM` — comma-separated list of file extensions to convert (e.g. `jpg,jpeg,png`) -- Environment variable: `IGNORED_UA_LIST` — (optional) comma-separated list of User-Agent substrings to skip -- Environment variable: `AVIF_SPEED` — (optional) AVIF encoding speed, 1-10 (default: 5) -- Environment variable: `AVIF_QUALITY` — (optional) AVIF encoding quality, 1-100 (default: 70) - -## How it works - -1. **on_request_headers** — checks file extension and User-Agent, sets `Image-Format` header for cache variation -2. **on_response_headers** — sets response headers for AVIF content type on 200 responses -3. **on_response_body** — decodes the original image and re-encodes it as AVIF -``` diff --git a/reference-docs/cdn-examples-cors-as.md b/reference-docs/cdn-examples-cors-as.md index 090a82c..a514711 100644 --- a/reference-docs/cdn-examples-cors-as.md +++ b/reference-docs/cdn-examples-cors-as.md @@ -3,8 +3,8 @@ sources: - id: proxy-wasm-sdk-as ref: master - commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 - updated: 2026-08-20 + commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 + updated: 2026-09-22 --> # CORS — AssemblyScript (CDN) diff --git a/reference-docs/cdn-examples-cors-rust.md b/reference-docs/cdn-examples-cors-rust.md index 0412a56..29d4f68 100644 --- a/reference-docs/cdn-examples-cors-rust.md +++ b/reference-docs/cdn-examples-cors-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-custom-error-pages-as.md b/reference-docs/cdn-examples-custom-error-pages-as.md index bf58305..ce71e32 100644 --- a/reference-docs/cdn-examples-custom-error-pages-as.md +++ b/reference-docs/cdn-examples-custom-error-pages-as.md @@ -3,8 +3,8 @@ sources: - id: proxy-wasm-sdk-as ref: master - commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 - updated: 2026-08-20 + commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 + updated: 2026-09-22 --> --- @@ -292,241 +292,3 @@ export * from "@gcoredev/proxy-wasm-sdk-as/assembly/proxy"; - CDN app platform overview - host-services-rust reference (for Rust equivalent patterns) - best-practices reference (response body buffering, hook sequencing) - -## Source Material - -### FILE: examples/customErrorPages/assembly/index.ts - -```ts -export * from "@gcoredev/proxy-wasm-sdk-as/assembly/proxy"; -import { - Context, - FilterDataStatusValues, - FilterHeadersStatusValues, - get_property, - log, - LogLevelValues, - registerRootContext, - RootContext, - set_buffer_bytes, - BufferTypeValues, - stream_context, -} from "@gcoredev/proxy-wasm-sdk-as/assembly"; -import { setLogLevel } from "@gcoredev/proxy-wasm-sdk-as/assembly/fastedge"; - -class ErrorPagesRoot extends RootContext { - createContext(context_id: u32): Context { - setLogLevel(LogLevelValues.info); - return new ErrorPagesContext(context_id, this); - } -} - -class ErrorPagesContext extends Context { - constructor(context_id: u32, root_context: ErrorPagesRoot) { - super(context_id, root_context); - } - - onResponseHeaders(a: u32, end_of_stream: bool): FilterHeadersStatusValues { - const statusBuf = get_property("response.status"); - if (statusBuf.byteLength < 2) { - return FilterHeadersStatusValues.Continue; - } - - const bytes = Uint8Array.wrap(statusBuf); - const code: u32 = (u32(bytes[0]) << 8) | u32(bytes[1]); - - if (code >= 400 && code < 600) { - stream_context.headers.response.replace("Content-Type", "text/html"); - stream_context.headers.response.remove("Content-Length"); - stream_context.headers.response.replace("Transfer-Encoding", "Chunked"); - - log(LogLevelValues.info, "Error response detected: " + code.toString()); - } - - return FilterHeadersStatusValues.Continue; - } - - onResponseBody( - body_buffer_length: usize, - end_of_stream: bool, - ): FilterDataStatusValues { - // Read response status from property (no instance state between hooks) - const statusBuf = get_property("response.status"); - if (statusBuf.byteLength < 2) { - return FilterDataStatusValues.Continue; - } - - const bytes = Uint8Array.wrap(statusBuf); - const code: u32 = (u32(bytes[0]) << 8) | u32(bytes[1]); - - if (code < 400 || code >= 600) { - return FilterDataStatusValues.Continue; - } - - if (!end_of_stream) { - return FilterDataStatusValues.StopIterationAndBuffer; - } - const title = this.getErrorTitle(code); - const description = this.getErrorDescription(code); - const category = code >= 500 ? "Server Error" : "Client Error"; - - const html = - '' + - '' + - "" + - code.toString() + - " — " + - title + - "" + - "
" + - "

" + - code.toString() + - "

" + - "

" + - title + - "

" + - "

" + - description + - "

" + - "

" + - category + - "

" + - "
"; - - const body = String.UTF8.encode(html); - // Replace the entire original body — pass body_buffer_length as the length - // to replace, not body.byteLength. Otherwise any original bytes beyond the - // new body's length survive at the tail of the response. - set_buffer_bytes( - BufferTypeValues.HttpResponseBody, - 0, - body_buffer_length as u32, - body, - ); - - return FilterDataStatusValues.Continue; - } - - private getErrorTitle(code: u32): string { - if (code == 400) return "Bad Request"; - if (code == 401) return "Unauthorized"; - if (code == 403) return "Forbidden"; - if (code == 404) return "Not Found"; - if (code == 405) return "Method Not Allowed"; - if (code == 408) return "Request Timeout"; - if (code == 429) return "Too Many Requests"; - if (code == 500) return "Internal Server Error"; - if (code == 502) return "Bad Gateway"; - if (code == 503) return "Service Unavailable"; - if (code == 504) return "Gateway Timeout"; - if (code >= 500) return "Server Error"; - return "Error"; - } - - private getErrorDescription(code: u32): string { - if (code == 400) - return "The server could not understand the request due to invalid syntax."; - if (code == 401) - return "You need to authenticate to access this resource."; - if (code == 403) - return "You do not have permission to access this resource."; - if (code == 404) - return "The requested page could not be found. It may have been moved or deleted."; - if (code == 405) - return "The request method is not supported for this resource."; - if (code == 408) - return "The server timed out waiting for the request."; - if (code == 429) - return "You have sent too many requests. Please try again later."; - if (code == 500) - return "The server encountered an unexpected condition that prevented it from fulfilling the request."; - if (code == 502) - return "The server received an invalid response from the upstream server."; - if (code == 503) - return "The server is temporarily unavailable. Please try again later."; - if (code == 504) - return "The server did not receive a timely response from the upstream server."; - if (code >= 500) - return "The server encountered an error processing your request."; - return "An error occurred processing your request."; - } -} - -registerRootContext((context_id: u32) => { - return new ErrorPagesRoot(context_id); -}, "customErrorPages"); -``` - - -### FILE: examples/customErrorPages/package.json - -```json -{ - "name": "fastedge-as-example-custom-error-pages", - "version": "1.0.0", - "description": "FastEdge AssemblyScript example: Custom Error Pages — replace 4xx/5xx responses with branded HTML", - "scripts": { - "asbuild:debug": "asc assembly/index.ts --target debug", - "asbuild:release": "asc assembly/index.ts --target release", - "asbuild": "npm run asbuild:debug && npm run asbuild:release" - }, - "dependencies": { - "@gcoredev/proxy-wasm-sdk-as": "^1.2.3" - }, - "devDependencies": { - "@assemblyscript/wasi-shim": "^0.1.0", - "assemblyscript": "^0.28.9" - } -} -``` - - -### FILE: examples/customErrorPages/README.md - -``` -[← Back to examples](../README.md) - -# Custom Error Pages - -This application intercepts 4xx and 5xx error responses and replaces them with clean, branded HTML error pages. - -## What it does - -In `onResponseHeaders`, the app reads the `response.status` property. If it is in the 400-599 range, it sets the `Content-Type` to `text/html` and prepares for body replacement. - -In `onResponseBody`, the app buffers the full response, then replaces the body with a styled HTML page containing: - -- The numeric status code -- A human-readable error title (e.g. "Not Found", "Bad Gateway") -- A description explaining what went wrong -- An error category label ("Client Error" or "Server Error") - -Covers all common HTTP error codes (400, 401, 403, 404, 405, 408, 429, 500, 502, 503, 504) with specific messages and falls back to generic messages for other codes. - -## Build - -```sh -pnpm install -pnpm run asbuild -``` - -Build output: - -| File | Description | -|------|-------------| -| `build/customErrorPages.wasm` | Optimised release binary — upload this to FastEdge | -| `build/customErrorPages-debug.wasm` | Debug binary with source maps | - -## Deploy - -Upload `build/customErrorPages.wasm` to the FastEdge portal and attach it to your CDN application. No environment variables or secrets are required. -``` diff --git a/reference-docs/cdn-examples-custom-error-pages-rust.md b/reference-docs/cdn-examples-custom-error-pages-rust.md index ee84089..ff9f3c3 100644 --- a/reference-docs/cdn-examples-custom-error-pages-rust.md +++ b/reference-docs/cdn-examples-custom-error-pages-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> ## Custom Error Pages — CDN (Rust) diff --git a/reference-docs/cdn-examples-custom-rust.md b/reference-docs/cdn-examples-custom-rust.md index d049948..c999103 100644 --- a/reference-docs/cdn-examples-custom-rust.md +++ b/reference-docs/cdn-examples-custom-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-env-secrets-as.md b/reference-docs/cdn-examples-env-secrets-as.md index 2039ea1..cee8f25 100644 --- a/reference-docs/cdn-examples-env-secrets-as.md +++ b/reference-docs/cdn-examples-env-secrets-as.md @@ -3,8 +3,8 @@ sources: - id: proxy-wasm-sdk-as ref: master - commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 - updated: 2026-08-20 + commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 + updated: 2026-09-22 --> --- type: example diff --git a/reference-docs/cdn-examples-env-secrets-rust.md b/reference-docs/cdn-examples-env-secrets-rust.md index 0239461..82ec81d 100644 --- a/reference-docs/cdn-examples-env-secrets-rust.md +++ b/reference-docs/cdn-examples-env-secrets-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- type: example diff --git a/reference-docs/cdn-examples-geo-redirect-as.md b/reference-docs/cdn-examples-geo-redirect-as.md index 03f0c0b..849560f 100644 --- a/reference-docs/cdn-examples-geo-redirect-as.md +++ b/reference-docs/cdn-examples-geo-redirect-as.md @@ -3,8 +3,8 @@ sources: - id: proxy-wasm-sdk-as ref: master - commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 - updated: 2026-08-20 + commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-geo-redirect-rust.md b/reference-docs/cdn-examples-geo-redirect-rust.md index 2d22742..854c725 100644 --- a/reference-docs/cdn-examples-geo-redirect-rust.md +++ b/reference-docs/cdn-examples-geo-redirect-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-geoblock-as.md b/reference-docs/cdn-examples-geoblock-as.md index 462ec1f..0a9923a 100644 --- a/reference-docs/cdn-examples-geoblock-as.md +++ b/reference-docs/cdn-examples-geoblock-as.md @@ -3,8 +3,8 @@ sources: - id: proxy-wasm-sdk-as ref: master - commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 - updated: 2026-08-20 + commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-geoblock-rust.md b/reference-docs/cdn-examples-geoblock-rust.md index bc7fabe..f7db849 100644 --- a/reference-docs/cdn-examples-geoblock-rust.md +++ b/reference-docs/cdn-examples-geoblock-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-headers-as.md b/reference-docs/cdn-examples-headers-as.md index 981cd2f..7a52ea5 100644 --- a/reference-docs/cdn-examples-headers-as.md +++ b/reference-docs/cdn-examples-headers-as.md @@ -3,8 +3,8 @@ sources: - id: proxy-wasm-sdk-as ref: master - commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 - updated: 2026-08-20 + commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 + updated: 2026-09-22 --> --- @@ -66,14 +66,14 @@ registerRootContext((context_id: u32) => { All header operations are accessed via `stream_context.headers.request` or `stream_context.headers.response`. -| Method | Signature | Description | -| ------------------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -| `get(name)` | `(name: string) => string` | Returns the value of the named header, or empty string if not present | -| `add(name, value)` | `(name: string, value: string) => void` | Adds a header; multiple calls with the same name produce multiple values | -| `replace(name, value)` | `(name: string, value: string) => void` | Upserts the header value — creates the header if it does not exist (see Known Issues) | -| `remove(name)` | `(name: string) => void` | Removes the header (see Known Issues) | -| `get_headers()` | `() => Headers` (alias: `HeaderPair[]`) | Returns all headers as an array of `{ key: ArrayBuffer, value: ArrayBuffer }` | -| `set_headers(headers)` | `(headers: Headers) => void` | Replaces the full header collection | +| Method | Signature | Description | +| -------------------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `get(name)` | `(name: string) => string` | Returns the value of the named header, or empty string if not present | +| `add(name, value)` | `(name: string, value: string) => void` | Adds a header; multiple calls with the same name produce multiple values | +| `replace(name, value)` | `(name: string, value: string) => void` | Upserts the header value — creates the header if it does not exist (see Known Issues) | +| `remove(name)` | `(name: string) => void` | Removes the header (see Known Issues) | +| `get_headers()` | `() => Headers` (alias: `HeaderPair[]`) | Returns all headers as an array of `{ key: ArrayBuffer, value: ArrayBuffer }` | +| `set_headers(headers)` | `(headers: Headers) => void` | Replaces the full header collection | ### `Headers` / `HeaderPair` type diff --git a/reference-docs/cdn-examples-headers-rust.md b/reference-docs/cdn-examples-headers-rust.md index bbfc088..473091a 100644 --- a/reference-docs/cdn-examples-headers-rust.md +++ b/reference-docs/cdn-examples-headers-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-http-call-as.md b/reference-docs/cdn-examples-http-call-as.md index bc289c7..95ba36c 100644 --- a/reference-docs/cdn-examples-http-call-as.md +++ b/reference-docs/cdn-examples-http-call-as.md @@ -3,8 +3,8 @@ sources: - id: proxy-wasm-sdk-as ref: master - commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 - updated: 2026-08-20 + commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 + updated: 2026-09-22 --> ## Overview @@ -321,202 +321,3 @@ Dependencies (from `package.json`): - SDK API reference — full lifecycle hook signatures, `RootContext` and `Context` base class APIs, all enum values (`WasmResultValues`, `FilterHeadersStatusValues`, `BufferTypeValues`, `LogLevelValues`) - Platform overview — FastEdge CDN execution model, context lifecycle, how the runtime re-enters hooks after async callbacks - Best practices — timeout tuning, upstream cluster naming, error response patterns - -## Source Material - -### FILE: examples/httpCall/assembly/index.ts - -```ts -export * from "@gcoredev/proxy-wasm-sdk-as/assembly/proxy"; // this exports the required functions for the proxy to interact with us. -import { - BaseContext, - BufferTypeValues, - Context, - FilterHeadersStatusValues, - get_buffer_bytes, - HeaderPair, - log, - LogLevelValues, - makeHeaderPair, - registerRootContext, - RootContext, - send_http_response, - stream_context, - WasmResultValues, -} from "@gcoredev/proxy-wasm-sdk-as/assembly"; -import { setLogLevel } from "@gcoredev/proxy-wasm-sdk-as/assembly/fastedge"; - -const INTERNAL_SERVER_ERROR: u32 = 500; - -function handleHttpCallResponse( - ctx: BaseContext, - hdrs: u32, - bodySize: usize, - trls: u32, -): void { - if (hdrs == 0) { - log(LogLevelValues.error, "HTTP call failed — no response received"); - return; - } - - const userAgent = stream_context.headers.http_callback.get("user-agent"); - if (userAgent !== "") { - log(LogLevelValues.info, "User-Agent: " + userAgent); - } - - if (bodySize > 0) { - const bodyBytes = get_buffer_bytes( - BufferTypeValues.HttpCallResponseBody, - 0, - bodySize as u32, - ); - const bodyStr = String.UTF8.decode(bodyBytes); - log( - LogLevelValues.info, - "Response body (" + bodySize.toString() + " bytes): " + bodyStr, - ); - } else { - log(LogLevelValues.info, "Response body: empty"); - } -} - -class HttpCallRoot extends RootContext { - createContext(context_id: u32): Context { - setLogLevel(LogLevelValues.info); - return new HttpCallContext(context_id, this); - } -} - -class HttpCallContext extends Context { - httpCallDispatched: bool = false; - - constructor(context_id: u32, root_context: HttpCallRoot) { - super(context_id, root_context); - } - - onRequestHeaders(a: u32, end_of_stream: bool): FilterHeadersStatusValues { - // FastEdge re-invokes this hook after the httpCall response is processed. - // The latch gates re-dispatch so the second invocation returns Continue - // instead of firing another HTTP call. See SDK docs → Outbound HTTP. - if (this.httpCallDispatched) { - log( - LogLevelValues.info, - "HTTP call response received, resuming request.", - ); - return FilterHeadersStatusValues.Continue; - } - - log(LogLevelValues.info, "onRequestHeaders >> dispatching HTTP call"); - - const headers = new Array(); - headers.push(makeHeaderPair(":scheme", "https")); - headers.push(makeHeaderPair(":authority", "httpbin.org")); - headers.push(makeHeaderPair(":path", "/ip")); - headers.push(makeHeaderPair(":method", "GET")); - headers.push(makeHeaderPair("User-Agent", "fastedge")); - - // 3000ms accommodates cold DNS + variable network conditions; tune per upstream in production. - const result = (this.root_context as HttpCallRoot).httpCall( - "httpbin.org", - headers, - new ArrayBuffer(0), - new Array(), - 3000, - this, - handleHttpCallResponse, - ); - - if (result != WasmResultValues.Ok) { - log( - LogLevelValues.error, - "Failed to dispatch HTTP call: " + result.toString(), - ); - send_http_response( - INTERNAL_SERVER_ERROR, - "internal server error", - String.UTF8.encode("Failed to dispatch HTTP call"), - [], - ); - return FilterHeadersStatusValues.StopIteration; - } - - this.httpCallDispatched = true; - log(LogLevelValues.info, "HTTP call dispatched, pausing request"); - - return FilterHeadersStatusValues.StopIteration; - } -} - -registerRootContext((context_id: u32) => { - return new HttpCallRoot(context_id); -}, "httpCall"); -``` - -### FILE: examples/httpCall/package.json - -```json -{ - "name": "fastedge-as-example-http-call", - "version": "1.0.0", - "description": "FastEdge AssemblyScript example: HTTP Call — async HTTP dispatch with callback", - "scripts": { - "asbuild:debug": "asc assembly/index.ts --target debug", - "asbuild:release": "asc assembly/index.ts --target release", - "asbuild": "npm run asbuild:debug && npm run asbuild:release" - }, - "dependencies": { - "@gcoredev/proxy-wasm-sdk-as": "^1.2.3" - }, - "devDependencies": { - "@assemblyscript/wasi-shim": "^0.1.0", - "assemblyscript": "^0.28.9" - } -} -``` - -### FILE: examples/httpCall/README.md - -``` -[← Back to examples](../README.md) - -# HTTP Call - -This application makes an asynchronous HTTP call to an external service using the proxy-wasm HTTP dispatch API. - -## What it does - -In `onRequestHeaders`, the app dispatches an outbound HTTP GET request to `httpbin.org/ip` and pauses the hook (`StopIteration`) until the response arrives. Dispatch is latched on an instance field so the second invocation of the hook (after the response is processed) returns `Continue` instead of dispatching again. - -Inside the response callback passed to `httpCall`: - -1. Checks whether the call succeeded (a `headers` value of `0` indicates failure — timeout, DNS error, etc.). -2. Reads and logs the `User-Agent` response header via `stream_context.headers.http_callback`. -3. Reads and logs the response body via `get_buffer_bytes(BufferTypeValues.HttpCallResponseBody, ...)`. - -If the dispatch itself fails (e.g. invalid arguments), the app returns a `500` error to the client. - -## Key concepts - -- **`httpCall()`** on `RootContext` dispatches an async HTTP request. It accepts a cluster (host), headers, body, trailers, a timeout in milliseconds, the originating context, and a callback. -- **FastEdge resume model.** Returning `FilterHeadersStatusValues.StopIteration` pauses the hook. The runtime processes the HTTP response, invokes the callback, then **re-invokes `onRequestHeaders` on the same `Context` instance**. The `httpCallDispatched` latch gates re-dispatch so the hook returns `Continue` the second time. This differs from canonical proxy-wasm — calling `continueRequest()` is not required (and has no effect on FastEdge). -- **`stream_context.headers.http_callback`** provides access to the HTTP call response headers inside the callback. The SDK sets the effective context before the callback fires, so these lookups resolve against the originating request. -- **`get_buffer_bytes(BufferTypeValues.HttpCallResponseBody, ...)`** reads the response body inside the callback. - -## Build - -```sh -pnpm install -pnpm run asbuild -``` - -Build output: - -| File | Description | -|------|-------------| -| `build/httpCall.wasm` | Optimised release binary — upload this to FastEdge | -| `build/httpCall-debug.wasm` | Debug binary with source maps | - -## Deploy - -Upload `build/httpCall.wasm` to the FastEdge portal and attach it to your CDN application. No environment variables or secrets are required. -``` diff --git a/reference-docs/cdn-examples-http-call-rust.md b/reference-docs/cdn-examples-http-call-rust.md index 35d0930..2cefbe5 100644 --- a/reference-docs/cdn-examples-http-call-rust.md +++ b/reference-docs/cdn-examples-http-call-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> # HTTP Call — CDN (Rust) @@ -285,6 +285,7 @@ impl Context for HttpHeaders { println!( "Received http call response with token id: {token_id}, num_headers: {num_headers}" ); + // If num_headers is 0, then the HTTP call failed. if num_headers != 0 { let headers = self.get_http_call_response_headers(); let headers_str = headers @@ -294,7 +295,7 @@ impl Context for HttpHeaders { .join(","); println!("Response headers: [{}]", headers_str); - self.state = 1; + self.state = 1; // Set state to 1 to indicate that the HTTP call response was received successfully. self.resume_http_request(); } else { diff --git a/reference-docs/cdn-examples-kv-store-as.md b/reference-docs/cdn-examples-kv-store-as.md index 0a8fd7b..8b35bae 100644 --- a/reference-docs/cdn-examples-kv-store-as.md +++ b/reference-docs/cdn-examples-kv-store-as.md @@ -3,8 +3,8 @@ sources: - id: proxy-wasm-sdk-as ref: master - commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 - updated: 2026-08-20 + commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-kv-store-rust.md b/reference-docs/cdn-examples-kv-store-rust.md index 56aad05..620ee62 100644 --- a/reference-docs/cdn-examples-kv-store-rust.md +++ b/reference-docs/cdn-examples-kv-store-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- @@ -64,7 +64,7 @@ serde_json = "1" ### Proxy-wasm lifecycle hooks - **`on_http_response_headers`** — set response `content-type` and remove `content-length` before replacing the body -- **`on_http_response_body`** — read request query parameters via `get_property(vec!["request", "query"])`, open the store, dispatch to operations, and replace the body via `set_http_response_body` +- **`on_http_response_body`** — read request query parameters via `get_property(vec!["request.query"])`, open the store, dispatch to operations, and replace the body via `set_http_response_body` Query parameters are only available in `on_http_response_body` via `get_property` because request data is accessible throughout the response phase. @@ -151,7 +151,7 @@ match store.zrange_by_score("leaderboard", 0.0, 100.0) { ```rust let query = self - .get_property(vec!["request", "query"]) + .get_property(vec!["request.query"]) .and_then(|bytes| String::from_utf8(bytes).ok()) .unwrap_or_default(); @@ -189,7 +189,7 @@ The complete example supports these query parameter combinations: fn send_error(&self, msg: &str, body_size: usize) { println!("{}", msg); self.set_property( - vec!["response", "status"], + vec!["response.status"], Some(b"500"), ); let error_body = serde_json::json!({"error": msg}).to_string(); @@ -228,7 +228,9 @@ Sorted set entries shape: `[{"value": "", "score": }, ...]` - **`Store::open` takes a platform-configured name** — the store name must match a KV store resource attached to the app in the FastEdge platform. Passing an unknown name returns `Err`. - **`content-length` must be removed before body replacement** — when replacing the response body, always remove `content-length` in `on_http_response_headers` (set to `None`). Note: on the FastEdge CDN platform, passing `None` sets the header to an empty string rather than truly removing it; set `transfer-encoding: chunked` as a workaround. - **`on_http_response_body` must wait for end of stream** — return `Action::Pause` until `end_of_stream` is `true` before reading query parameters or replacing the body. -- **`query` property is available in the response phase** — `get_property(vec!["request", "query"])` works in `on_http_response_body` because request metadata is accessible throughout the response lifecycle. +- **`get_property` uses dot-notation path** — the correct call is `get_property(vec!["request.query"])` (a single dot-separated string), not `get_property(vec!["request", "query"])` (two separate path segments). The source uses `vec!["request.query"]`. +- **`query` property is available in the response phase** — `get_property(vec!["request.query"])` works in `on_http_response_body` because request metadata is accessible throughout the response lifecycle. +- **`set_property` uses dot-notation path** — the correct call is `set_property(vec!["response.status"], Some(b"500"))` (a single dot-separated string). - **Error type is a typed `Error` enum** (not a raw `u32` as with secrets). Match on the `Err(e)` variant and format with `format!("{}", e)` for human-readable messages. - **`store` query parameter is always required** — the example reads `store` from query params and passes it to `Store::open`. An absent `store` param returns a 500 error before any store operations are attempted. - **Empty query string is rejected** — if no query parameters are provided at all, the app returns a 500 error with the message `"App must be called with query parameters"`. @@ -240,3 +242,363 @@ Sorted set entries shape: `[{"value": "", "score": }, ...]` - Host services reference — full KV store, secrets, and dictionary API documentation for CDN (proxy-wasm) apps - CDN apps reference — proxy-wasm lifecycle hooks, request properties, header and body manipulation patterns - SDK reference (Rust) — `fastedge` crate modules, feature flags, and component model vs. proxy-wasm differences + +## Source Material + +### FILE: examples/cdn/key_value/src/lib.rs + +```rust +/* +* Copyright 2025 G-Core Innovations SARL +*/ +/* +Example CDN app demonstrating KV Store operations via the proxy-wasm interface. + +Supports all KV Store operations via query parameters: + ?store=&action=get&key= + ?store=&action=scan&match= + ?store=&action=zrange&key=&min=&max= + ?store=&action=zscan&key=&match= + ?store=&action=bfExists&key=&item= + +Defaults to action=get if not specified. +*/ + +use fastedge::proxywasm::key_value::Store; +use proxy_wasm::traits::*; +use proxy_wasm::types::*; +use serde_json::json; +use std::collections::HashMap; + +proxy_wasm::main! {{ + proxy_wasm::set_log_level(LogLevel::Info); + proxy_wasm::set_root_context(|_| -> Box { Box::new(KvStoreRoot) }); +}} + +struct KvStoreRoot; + +impl Context for KvStoreRoot {} + +impl RootContext for KvStoreRoot { + fn get_type(&self) -> Option { + Some(ContextType::HttpContext) + } + + fn create_http_context(&self, _: u32) -> Option> { + Some(Box::new(KvStoreContext)) + } +} + +struct KvStoreContext; + +impl Context for KvStoreContext {} + +impl HttpContext for KvStoreContext { + fn on_http_response_headers(&mut self, _: usize, _: bool) -> Action { + // Remove content-length since we replace the body + self.set_http_response_header("content-length", None); + self.set_http_response_header("content-type", Some("application/json")); + self.set_http_response_header("transfer-encoding", Some("chunked")); + Action::Continue + } + + fn on_http_response_body(&mut self, body_size: usize, end_of_stream: bool) -> Action { + if !end_of_stream { + return Action::Pause; + } + + let query = self + .get_property(vec!["request.query"]) + .and_then(|bytes| String::from_utf8(bytes).ok()) + .unwrap_or_default(); + + if query.is_empty() { + self.send_error("App must be called with query parameters", body_size); + return Action::Continue; + } + + let params: HashMap<&str, &str> = querystring::querify(&query).into_iter().collect(); + + let Some(store_name) = params.get("store") else { + self.send_error("Missing required param 'store'", body_size); + return Action::Continue; + }; + + let action = params.get("action").copied().unwrap_or("get"); + + let store = match Store::open(store_name) { + Ok(s) => s, + Err(e) => { + self.send_error(&format!("Failed to open KvStore '{}': {}", store_name, e), body_size); + return Action::Continue; + } + }; + + let result = match action { + "get" => self.handle_get(&store, ¶ms), + "scan" => self.handle_scan(&store, ¶ms), + "zrange" => self.handle_zrange(&store, ¶ms), + "zscan" => self.handle_zscan(&store, ¶ms), + "bfExists" => self.handle_bf_exists(&store, ¶ms), + _ => Err(format!( + "Invalid action '{}'. Supported: get, scan, zrange, zscan, bfExists", + action + )), + }; + + let body = match result { + Ok(json) => json, + Err(msg) => { + self.send_error(&msg, body_size); + return Action::Continue; + } + }; + + self.set_http_response_body(0, body_size, body.as_bytes()); + + Action::Continue + } +} + +impl KvStoreContext { + fn handle_get(&self, store: &Store, params: &HashMap<&str, &str>) -> Result { + let key = *params.get("key").ok_or("Missing required param 'key' for 'get' action")?; + match store.get(key) { + Ok(Some(value)) => { + let value_str = String::from_utf8_lossy(&value); + Ok(json!({ + "store": params.get("store").unwrap_or(&""), + "action": "get", + "key": key, + "response": value_str.as_ref() + }).to_string()) + } + Ok(None) => Ok(json!({ + "store": params.get("store").unwrap_or(&""), + "action": "get", + "key": key, + "response": null + }).to_string()), + Err(e) => Err(format!("KV get error: {}", e)), + } + } + + fn handle_scan(&self, store: &Store, params: &HashMap<&str, &str>) -> Result { + let pattern = *params.get("match").ok_or("Missing required param 'match' for 'scan' action")?; + match store.scan(pattern) { + Ok(keys) => Ok(json!({ + "store": params.get("store").unwrap_or(&""), + "action": "scan", + "match": pattern, + "response": keys + }).to_string()), + Err(e) => Err(format!("KV scan error: {}", e)), + } + } + + fn handle_zrange(&self, store: &Store, params: &HashMap<&str, &str>) -> Result { + let key = *params.get("key").ok_or("Missing required param 'key' for 'zrange' action")?; + let min: f64 = params + .get("min") + .ok_or("Missing required param 'min' for 'zrange' action")? + .parse() + .map_err(|_| "Invalid 'min' value: must be a number".to_string())?; + let max: f64 = params + .get("max") + .ok_or("Missing required param 'max' for 'zrange' action")? + .parse() + .map_err(|_| "Invalid 'max' value: must be a number".to_string())?; + + match store.zrange_by_score(key, min, max) { + Ok(entries) => { + let entries_json: Vec = entries + .iter() + .map(|(value, score)| { + let value_str = String::from_utf8_lossy(value); + json!({"value": value_str.as_ref(), "score": score}) + }) + .collect(); + Ok(json!({ + "store": params.get("store").unwrap_or(&""), + "action": "zrange", + "key": key, + "min": min, + "max": max, + "response": entries_json + }).to_string()) + } + Err(e) => Err(format!("KV zrange error: {}", e)), + } + } + + fn handle_zscan(&self, store: &Store, params: &HashMap<&str, &str>) -> Result { + let key = *params.get("key").ok_or("Missing required param 'key' for 'zscan' action")?; + let pattern = *params.get("match").ok_or("Missing required param 'match' for 'zscan' action")?; + + match store.zscan(key, pattern) { + Ok(entries) => { + let entries_json: Vec = entries + .iter() + .map(|(value, score)| { + let value_str = String::from_utf8_lossy(value); + json!({"value": value_str.as_ref(), "score": score}) + }) + .collect(); + Ok(json!({ + "store": params.get("store").unwrap_or(&""), + "action": "zscan", + "key": key, + "match": pattern, + "response": entries_json + }).to_string()) + } + Err(e) => Err(format!("KV zscan error: {}", e)), + } + } + + fn handle_bf_exists(&self, store: &Store, params: &HashMap<&str, &str>) -> Result { + let key = *params.get("key").ok_or("Missing required param 'key' for 'bfExists' action")?; + let item = *params.get("item").ok_or("Missing required param 'item' for 'bfExists' action")?; + + match store.bf_exists(key, item) { + Ok(exists) => Ok(json!({ + "store": params.get("store").unwrap_or(&""), + "action": "bfExists", + "key": key, + "item": item, + "response": exists + }).to_string()), + Err(e) => Err(format!("KV bfExists error: {}", e)), + } + } + + fn send_error(&self, msg: &str, body_size: usize) { + println!("{}", msg); + self.set_property( + vec!["response.status"], + Some(b"500"), + ); + let error_body = json!({"error": msg}).to_string(); + self.set_http_response_body(0, body_size, error_body.as_bytes()); + } +} +``` + + +### FILE: examples/cdn/key_value/Cargo.toml + +```toml +[workspace] + +[package] +name = "key_value" +version = "0.1.0" +edition = "2024" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +proxy-wasm = "0.2" +fastedge = { version = "0.4", features = ["proxywasm"] } +querystring = "1.1" +serde_json = "1" +``` + + +### FILE: examples/cdn/key_value/README.md + +``` +[← Back to examples](../../README.md) + +# Key Value (CDN) + +This example shows how to read and write data from a FastEdge KV store from a CDN app. +It intercepts the HTTP response, reads the request query string, and executes a KV operation against a named store. + +## What it does + +The app supports the following actions: + +- `get` — fetch one key +- `scan` — list keys matching a pattern +- `zrange` — read sorted-set entries by score range +- `zscan` — list sorted-set entries matching a pattern +- `bfExists` — check whether a Bloom filter contains an item + +The request must include at least: + +- `store=` — KV store name +- `action=` — optional, defaults to `get` + +For each action, the app validates required parameters and returns a JSON response body. + +## Supported query examples + +### Get a key + +```text +?store=my_store&action=get&key=user:42 +``` + +### List keys by pattern + +```text +?store=my_store&action=scan&match=user:* +``` + +### Read a sorted set by score range + +```text +?store=my_store&action=zrange&key=leaderboard&min=0&max=100 +``` + +### Search sorted-set members by pattern + +```text +?store=my_store&action=zscan&key=leaderboard&match=user:* +``` + +### Check a Bloom filter item + +```text +?store=my_store&action=bfExists&key=visitors&item=alice@example.com +``` + +## Build + +```sh +cargo build --release +# Output: target/wasm32-wasip1/release/key_value.wasm +``` + +This example is a CDN app, so it targets `wasm32-wasip1`. + +## Response format + +The app replaces the response body with JSON and sets `content-type: application/json`. +A successful response looks like this: + +```json +{ + "store": "my_store", + "action": "get", + "key": "user:42", + "response": "Alice" +} +``` + +If a required parameter is missing or the KV operation fails, the app responds with an error payload: + +```json +{ + "error": "Missing required param 'key' for 'get' action" +} +``` + +## Notes + +- The app requires query parameters to run. +- If `action` is omitted, it defaults to `get`. +- The code uses `fastedge::proxywasm::key_value::Store` and `proxy_wasm` lifecycle hooks to operate on the KV store. +``` diff --git a/reference-docs/cdn-examples-large-dictionary-as.md b/reference-docs/cdn-examples-large-dictionary-as.md index d1779cc..fe756b2 100644 --- a/reference-docs/cdn-examples-large-dictionary-as.md +++ b/reference-docs/cdn-examples-large-dictionary-as.md @@ -3,8 +3,8 @@ sources: - id: proxy-wasm-sdk-as ref: master - commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 - updated: 2026-08-20 + commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 + updated: 2026-09-22 --> # Large Dictionary — AssemblyScript (CDN) @@ -136,3 +136,129 @@ Upload `build/largeDictionary.wasm` to the FastEdge portal and attach it to your - `getEnv` — standard WASI environment variable access (under 64 KB) - proxy-wasm-sdk-as SDK reference — full list of imports from `@gcoredev/proxy-wasm-sdk-as/assembly` and `@gcoredev/proxy-wasm-sdk-as/assembly/fastedge` - FastEdge CDN app examples (other concepts) — additional CDN app patterns in the fastedge-docs reference + +## Source Material + +### FILE: examples/largeDictionary/assembly/index.ts + +```ts +export * from "@gcoredev/proxy-wasm-sdk-as/assembly/proxy"; +import { + Context, + FilterHeadersStatusValues, + log, + LogLevelValues, + registerRootContext, + RootContext, + stream_context, +} from "@gcoredev/proxy-wasm-sdk-as/assembly"; +import { + getDictionary, + setLogLevel, +} from "@gcoredev/proxy-wasm-sdk-as/assembly/fastedge"; + +class LargeDictionaryRoot extends RootContext { + createContext(context_id: u32): Context { + setLogLevel(LogLevelValues.info); + return new LargeDictionaryContext(context_id, this); + } +} + +class LargeDictionaryContext extends Context { + constructor(context_id: u32, root_context: LargeDictionaryRoot) { + super(context_id, root_context); + } + + onRequestHeaders(a: u32, end_of_stream: bool): FilterHeadersStatusValues { + // Use getDictionary for environment variables that may exceed 64KB. + // For normal-sized env vars (< 64KB), use getEnv instead. + const config = getDictionary("LARGE_CONFIG"); + + const size = config.length; + log(LogLevelValues.info, "LARGE_CONFIG size: " + size.toString() + " bytes"); + + stream_context.headers.request.add("x-config-size", size.toString()); + + return FilterHeadersStatusValues.Continue; + } +} + +registerRootContext((context_id: u32) => { + return new LargeDictionaryRoot(context_id); +}, "largeDictionary"); +``` + + +### FILE: examples/largeDictionary/package.json + +```json +{ + "name": "fastedge-as-example-large-dictionary", + "version": "1.0.0", + "description": "FastEdge AssemblyScript example: Large Dictionary — read env vars exceeding the 64KB WASI limit", + "scripts": { + "asbuild:debug": "asc assembly/index.ts --target debug", + "asbuild:release": "asc assembly/index.ts --target release", + "asbuild": "npm run asbuild:debug && npm run asbuild:release" + }, + "dependencies": { + "@gcoredev/proxy-wasm-sdk-as": "^1.2.3" + }, + "devDependencies": { + "@assemblyscript/wasi-shim": "^0.1.0", + "assemblyscript": "^0.28.9" + } +} +``` + + +### FILE: examples/largeDictionary/README.md + +``` +[← Back to examples](../README.md) + +# Large Dictionary + +This application demonstrates how to read large environment variables (> 64 KB) using the proxy-wasm dictionary API. + +## When to use `getDictionary` vs `getEnv` + +| Function | Use when | +|----------|----------| +| `getEnv(name)` | Variable value is under 64 KB (most cases) | +| `getDictionary(name)` | Variable value may exceed the 64 KB WASI env var size limit | + +The WASI environment variable interface has a **64 KB size limit** per variable. If your app needs to read larger values (e.g. large JSON configs, PEM certificates, policy documents), use `getDictionary` which calls `proxy_dictionary_get` and bypasses this limit. + +For all other environment variable access, prefer `getEnv` as it uses the standard WASI environment interface. + +## What it does + +In `onRequestHeaders`, the app reads the `LARGE_CONFIG` environment variable using `getDictionary`, logs its size, and adds it as an `x-config-size` request header for the upstream to see. + +## Configuration + +Set the following on your FastEdge application: + +| Name | Type | Description | +|------|------|-------------| +| `LARGE_CONFIG` | Environment variable | A large configuration payload (e.g. JSON, PEM certificate) | + +## Build + +```sh +pnpm install +pnpm run asbuild +``` + +Build output: + +| File | Description | +|------|-------------| +| `build/largeDictionary.wasm` | Optimised release binary — upload this to FastEdge | +| `build/largeDictionary-debug.wasm` | Debug binary with source maps | + +## Deploy + +Upload `build/largeDictionary.wasm` to the FastEdge portal and attach it to your CDN application. Configure the `LARGE_CONFIG` environment variable in the application settings. +``` diff --git a/reference-docs/cdn-examples-large-dictionary-rust.md b/reference-docs/cdn-examples-large-dictionary-rust.md index 48de0d0..e59c0c0 100644 --- a/reference-docs/cdn-examples-large-dictionary-rust.md +++ b/reference-docs/cdn-examples-large-dictionary-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-log-time-as.md b/reference-docs/cdn-examples-log-time-as.md index c6fc860..1338661 100644 --- a/reference-docs/cdn-examples-log-time-as.md +++ b/reference-docs/cdn-examples-log-time-as.md @@ -3,8 +3,8 @@ sources: - id: proxy-wasm-sdk-as ref: master - commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 - updated: 2026-08-20 + commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-log-time-rust.md b/reference-docs/cdn-examples-log-time-rust.md index c4b7b5c..ab71c4c 100644 --- a/reference-docs/cdn-examples-log-time-rust.md +++ b/reference-docs/cdn-examples-log-time-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-md2html-rust.md b/reference-docs/cdn-examples-md2html-rust.md index 0ebd4e7..bf9ce12 100644 --- a/reference-docs/cdn-examples-md2html-rust.md +++ b/reference-docs/cdn-examples-md2html-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/cdn-examples-properties-as.md b/reference-docs/cdn-examples-properties-as.md index 137fe6c..94c40a9 100644 --- a/reference-docs/cdn-examples-properties-as.md +++ b/reference-docs/cdn-examples-properties-as.md @@ -3,8 +3,8 @@ sources: - id: proxy-wasm-sdk-as ref: master - commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 - updated: 2026-08-20 + commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 + updated: 2026-09-22 --> # CDN Runtime Properties — AssemblyScript diff --git a/reference-docs/cdn-examples-properties-rust.md b/reference-docs/cdn-examples-properties-rust.md index 364c99f..ec5f2e9 100644 --- a/reference-docs/cdn-examples-properties-rust.md +++ b/reference-docs/cdn-examples-properties-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/docs-index.json b/reference-docs/docs-index.json index 21ddf3e..5cfcbf2 100644 --- a/reference-docs/docs-index.json +++ b/reference-docs/docs-index.json @@ -1,16 +1,16 @@ { "schema_version": "1.0.0", - "generated_at": "2026-09-09T13:28:16.173Z", + "generated_at": "2026-09-24T09:24:50.621Z", "source": { "repo": "fastedge-plugin", - "commit": "99dc55a", + "commit": "503a8fc", "pipeline": "sync-reference-docs" }, "topics": [ { "id": "cdn-apps-rust", "title": "FastEdge Rust SDK — CDN Apps (Proxy-Wasm)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn-apps-rust.md", "skill": "fastedge-docs", "category": "reference", @@ -29,9 +29,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "sdk", "cdn", @@ -41,7 +41,7 @@ "building", "filters" ], - "content_sha256": "55cf970e41b7f8c4bce161ef5272413f4f155ed90b01d90510d5f21dce23930e", + "content_sha256": "6a79f809ecedc76ed7617ab078604096a5933da07a44a2059849f2042a42910a", "sections": [ { "id": "cdn-apps-rust#introduction", @@ -58,9 +58,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "rust", "sdk", @@ -150,9 +150,9 @@ "0.2", "log", "0.4", + "cache", "secrets", - "dictionary", - "depend" + "dictionary" ] }, { @@ -245,7 +245,7 @@ "callback", "phase", "description", - "-----------------------------------------------------------------", + "-----------------------------------------------------------------------------------------------", "----------------", "---------------------------------------------------", "on_http_request_headers", @@ -256,11 +256,7 @@ "action", "request", "headers", - "inspect", - "modify", - "forwarding", - "on_http_request_body", - "body_size" + "inspect" ] }, { @@ -431,7 +427,7 @@ "level": 2, "anchor": "host-services-for-cdn-apps", "line_start": 423, - "line_end": 733, + "line_end": 818, "keywords": [ "host", "services", @@ -477,8 +473,8 @@ "heading": "API Comparison: HTTP vs CDN", "level": 2, "anchor": "api-comparison-http-vs-cdn", - "line_start": 734, - "line_end": 746, + "line_start": 819, + "line_end": 832, "keywords": [ "api", "comparison", @@ -491,12 +487,11 @@ "proxywasm", "-------------", "-------------------------------------------------------------------", - "--------------------------------------------------------", + "-----------------------------------------------------------------", "key-value", "fastedge", "key_value", - "store", - "secrets" + "store" ] }, { @@ -504,8 +499,8 @@ "heading": "See Also", "level": 2, "anchor": "see-also", - "line_start": 747, - "line_end": 751, + "line_start": 833, + "line_end": 837, "keywords": [ "see", "sdk", @@ -533,7 +528,7 @@ { "id": "cdn-examples-ab-testing-as", "title": "A/B Testing — AssemblyScript (CDN)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-ab-testing-as.md", "skill": "fastedge-docs", "category": "examples", @@ -555,9 +550,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "testing", "cookie-based", "traffic", @@ -567,7 +562,7 @@ "requests", "different" ], - "content_sha256": "a8a65c5b6a1c0cfb93650966caa7539474e92037e1a305816ef0944e3e09a1fc", + "content_sha256": "271da479486db22cd96d1891a8b2e5755921af0d4fd4c733df1732ef35e67684", "sections": [ { "id": "cdn-examples-ab-testing-as#introduction", @@ -584,9 +579,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "testing", "assemblyscript", "cdn", @@ -1001,7 +996,7 @@ { "id": "cdn-examples-ab-testing-rust", "title": "A/B Testing — CDN App Example (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-ab-testing-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -1023,9 +1018,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -1035,7 +1030,7 @@ "ab-testing", "traffic-splitting" ], - "content_sha256": "02a0716c80b4d8908f4996e26cf4a36904a49faf5c7a78d99d5abacf7512e387", + "content_sha256": "8c9d6d203917852f4ca811313b5c30779ba0b4d523dab6f7597099f4675c2e4f", "sections": [ { "id": "cdn-examples-ab-testing-rust#introduction", @@ -1052,9 +1047,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -1657,7 +1652,7 @@ { "id": "cdn-examples-api-key-as", "title": "CDN Example: API Key Authentication (AssemblyScript)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-api-key-as.md", "skill": "fastedge-docs", "category": "examples", @@ -1679,9 +1674,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -1691,7 +1686,7 @@ "api-key-auth", "header-validation" ], - "content_sha256": "d47decc23a11899c2cdd3360355fb8c5e9db6fb48d6b2ca5c90bee4cc5c8ae2b", + "content_sha256": "44acbfa72b450892ad45f4e360dd734b0a451a6df664428a2925e1419a6f8a6e", "sections": [ { "id": "cdn-examples-api-key-as#introduction", @@ -1708,9 +1703,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -2071,7 +2066,7 @@ { "id": "cdn-examples-api-key-rust", "title": "API Key Validation — CDN (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-api-key-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -2093,9 +2088,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "api", "key", "validation", @@ -2105,7 +2100,7 @@ "requests", "against" ], - "content_sha256": "55118b7b2a0e68b75f57892ee0ea64dae4e5bffc4354ecf2941ae41658040b8e", + "content_sha256": "6c28a1664d639ebeb12397dea7294bdd293848795b65c88c2f5aab81e2bee614", "sections": [ { "id": "cdn-examples-api-key-rust#introduction", @@ -2122,9 +2117,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "api", "key", "validation", @@ -2369,63 +2364,13 @@ "traits", "types" ] - }, - { - "id": "cdn-examples-api-key-rust#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 163, - "line_end": 279, - "keywords": [ - "source", - "material", - "file", - "examples", - "cdn", - "api_key", - "src", - "lib.rs", - "rust", - "copyright", - "2025", - "g-core", - "innovations", - "sarl", - "example", - "app", - "demonstrating", - "api", - "key", - "validation.", - "validates", - "requests", - "using", - "x-api-key", - "header", - "checked", - "against", - "stored", - "secret.", - "simpler", - "alternative", - "jwt", - "token", - "expiry", - "claims", - "needed.", - "required", - "configuration", - "secret", - "use" - ] } ] }, { "id": "cdn-examples-auth-jwt-as", "title": "JWT Validation — CDN App (AssemblyScript)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 --> --- capabilities: - jwt-auth - request-header-inspection - secret-access - http-response type: example app_type: cdn languages: - assemblyscrip", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 --> --- capabilities: - jwt-auth - request-header-inspection - secret-access - http-response type: example app_type: cdn languages: - assemblyscrip", "path": "reference/fastedge-docs/cdn/examples-auth-jwt-as.md", "skill": "fastedge-docs", "category": "examples", @@ -2449,9 +2394,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "jwt-auth", @@ -2462,7 +2407,7 @@ "example", "app_type" ], - "content_sha256": "b1fb0a577490fc4af605c215e8ece9ba673631e87fe3755435cda8df374760f4", + "content_sha256": "7defe19d2cd21c1429dbf522d5fe31e212ec1f4880b241375b44f179c2add564", "sections": [ { "id": "cdn-examples-auth-jwt-as#introduction", @@ -2479,9 +2424,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "jwt-auth", @@ -2927,7 +2872,7 @@ { "id": "cdn-examples-auth-jwt-rust", "title": "JWT Authentication — CDN App (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-auth-jwt-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -2949,9 +2894,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -2961,7 +2906,7 @@ "auth", "jwt" ], - "content_sha256": "fab044cd88079e758ffa7433aa100275b9466d2b19457fe94f40539fca11ec06", + "content_sha256": "d154eba097a174823554d450040d60276c5d185a7c0875e5214ceb2ded34f624", "sections": [ { "id": "cdn-examples-auth-jwt-rust#introduction", @@ -2978,9 +2923,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -3483,7 +3428,7 @@ { "id": "cdn-examples-body-as", "title": "Body Manipulation — AssemblyScript (CDN)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-body-as.md", "skill": "fastedge-docs", "category": "examples", @@ -3505,9 +3450,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "title", "body", @@ -3517,7 +3462,7 @@ "app_type", "languages" ], - "content_sha256": "94226f2f7783dd5978e697ebea97008427e93dbddfd4b033a8c05d74268e9a34", + "content_sha256": "cf0366213848652a381fe943b6a887700b4a939b885f9bb54dc3c6232f8b6ab0", "sections": [ { "id": "cdn-examples-body-as#introduction", @@ -3534,9 +3479,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "title", "body", @@ -3969,7 +3914,7 @@ { "id": "cdn-examples-body-rust", "title": "CDN Body Inspection and Modification — Rust", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-body-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -3991,9 +3936,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -4003,7 +3948,7 @@ "body-inspection", "body-modification" ], - "content_sha256": "8ae1b1e52a1c6d5700b08e8892ae6cda7aad01471796e76d73ec79dcf32e297b", + "content_sha256": "dd9c88154cf902f53948cceb8f2653719e2fed5373b2dd3ab3c80ba7efca05e8", "sections": [ { "id": "cdn-examples-body-rust#introduction", @@ -4020,9 +3965,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -4425,7 +4370,7 @@ { "id": "cdn-examples-cache-control-as", "title": "Cache Control — AssemblyScript (CDN)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-cache-control-as.md", "skill": "fastedge-docs", "category": "examples", @@ -4449,9 +4394,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -4461,7 +4406,7 @@ "cache-control", "response-headers" ], - "content_sha256": "3b3e6161bccadfc2c7ed913237cf413f6147239e7386715b566aa6893587902d", + "content_sha256": "0a153a37be4f5636fac31f8469be52c9af84394259760e897788b7654ba00fb9", "sections": [ { "id": "cdn-examples-cache-control-as#introduction", @@ -4478,9 +4423,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -5055,7 +5000,7 @@ { "id": "cdn-examples-cache-control-rust", "title": "Cache Control — CDN App Example (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-cache-control-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -5077,9 +5022,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -5089,7 +5034,7 @@ "cache-control", "content-type-aware-caching" ], - "content_sha256": "b0fabdfa84d4803e073c0d36e6b51424537f4051ef1a9e6ba50b56a4e184e169", + "content_sha256": "4c8bfcc4519e20ce422726bb54b90f80816615eb4f5d26cc74cc14a067da4903", "sections": [ { "id": "cdn-examples-cache-control-rust#introduction", @@ -5106,9 +5051,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -5638,10 +5583,416 @@ } ] }, + { + "id": "cdn-examples-cache-rust", + "title": "CDN Cache — Rust Example", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", + "path": "reference/fastedge-docs/cdn/examples-cache-rust.md", + "skill": "fastedge-docs", + "category": "examples", + "app_types": [ + "cdn" + ], + "languages": [ + "rust" + ], + "tags": [ + "examples", + "fastedge-docs", + "cdn", + "rust", + "auto-updated", + "true", + "sources", + "fastedge-sdk-rust", + "ref", + "main", + "commit", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", + "updated", + "2026-09-22", + "cache", + "example", + "overview", + "app", + "demonstrating", + "operations" + ], + "content_sha256": "4c6cf165f6d058b5f6d401c04abf933162f423e82a02a2b81d3a9f1ada41c285", + "sections": [ + { + "id": "cdn-examples-cache-rust#introduction", + "heading": "Introduction", + "level": 1, + "anchor": "introduction", + "line_start": 1, + "line_end": 11, + "keywords": [ + "auto-updated", + "true", + "sources", + "fastedge-sdk-rust", + "ref", + "main", + "commit", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", + "updated", + "2026-09-22", + "cdn", + "cache", + "rust", + "example" + ] + }, + { + "id": "cdn-examples-cache-rust#overview", + "heading": "Overview", + "level": 2, + "anchor": "overview", + "line_start": 12, + "line_end": 17, + "keywords": [ + "overview", + "cdn", + "app", + "demonstrating", + "cache", + "operations", + "via", + "proxy-wasm", + "abi.", + "scoped", + "calling", + "application", + "addressed", + "key", + "alone", + "there", + "named", + "stores", + "handles", + "unlike", + "store", + "dispatched", + "query", + "parameters", + "incoming", + "request.", + "responses", + "always", + "json.", + "errors", + "return", + "http", + "500", + "error", + "message" + ] + }, + { + "id": "cdn-examples-cache-rust#app-type", + "heading": "App Type", + "level": 2, + "anchor": "app-type", + "line_start": 18, + "line_end": 23, + "keywords": [ + "app", + "type", + "interface", + "proxy-wasm", + "fastedge", + "proxywasm", + "cache", + "cdn", + "language", + "rust" + ] + }, + { + "id": "cdn-examples-cache-rust#request-interface", + "heading": "Request Interface", + "level": 2, + "anchor": "request-interface", + "line_start": 24, + "line_end": 38, + "keywords": [ + "request", + "interface", + "operations", + "specified", + "via", + "query", + "parameters.", + "action", + "parameter", + "selects", + "operation", + "get", + "default", + "omitted.", + "string", + "---", + "key", + "read", + "cached", + "value.", + "response", + "null", + "absent.", + "set", + "value", + "ttl", + "store", + "omitting", + "stores", + "expiry.", + "delete", + "key.", + "no-op", + "exists" + ] + }, + { + "id": "cdn-examples-cache-rust#api-reference", + "heading": "API Reference", + "level": 2, + "anchor": "api-reference", + "line_start": 39, + "line_end": 195, + "keywords": [ + "api", + "reference", + "functions", + "fastedge", + "proxywasm", + "cache", + "get", + "rust", + "pub", + "key", + "str", + "result", + "option", + "vec", + "retrieve", + "cached", + "bytes", + "key.", + "parameters", + "string", + "returns", + "exists", + "none", + "absent", + "err", + "failure", + "json", + "response", + "shape", + "action", + "value", + "null", + "---", + "set" + ] + }, + { + "id": "cdn-examples-cache-rust#error-handling", + "heading": "Error Handling", + "level": 2, + "anchor": "error-handling", + "line_start": 196, + "line_end": 202, + "keywords": [ + "error", + "handling", + "errors", + "return", + "http", + "500", + "body", + "message", + "missing", + "required", + "query", + "parameters", + "produce", + "descriptive", + "messages", + "e.g.", + "param", + "key", + "get", + "action", + "invalid", + "parameter", + "values", + "non-integer", + "ttl", + "delta", + "parse", + "messages.", + "unknown", + "listing", + "supported", + "actions." + ] + }, + { + "id": "cdn-examples-cache-rust#dependencies", + "heading": "Dependencies", + "level": 2, + "anchor": "dependencies", + "line_start": 203, + "line_end": 211, + "keywords": [ + "dependencies", + "toml", + "proxy-wasm", + "0.2", + "fastedge", + "path", + "...", + "features", + "proxywasm", + "querystring", + "1.1", + "serde_json" + ] + }, + { + "id": "cdn-examples-cache-rust#build", + "heading": "Build", + "level": 2, + "anchor": "build", + "line_start": 212, + "line_end": 218, + "keywords": [ + "build", + "cargo", + "--release", + "output", + "target", + "wasm32-wasip1", + "release", + "cache.wasm" + ] + }, + { + "id": "cdn-examples-cache-rust#lifecycle-notes", + "heading": "Lifecycle Notes", + "level": 2, + "anchor": "lifecycle-notes", + "line_start": 219, + "line_end": 225, + "keywords": [ + "lifecycle", + "notes", + "app", + "uses", + "proxy-wasm", + "rootcontext", + "httpcontext", + "pattern.", + "logic", + "executes", + "on_http_response_body", + "waits", + "end_of_stream", + "on_http_response_headers", + "strips", + "content-length", + "sets", + "content-type", + "application", + "json", + "transfer-encoding", + "chunked", + "body", + "processing.", + "query", + "string", + "read", + "request.query", + "via", + "get_property" + ] + }, + { + "id": "cdn-examples-cache-rust#key-constraints", + "heading": "Key Constraints", + "level": 2, + "anchor": "key-constraints", + "line_start": 226, + "line_end": 232, + "keywords": [ + "key", + "constraints", + "cache", + "operations", + "scoped", + "calling", + "application", + "keys", + "one", + "app", + "accessible", + "another.", + "there", + "named", + "stores", + "handles", + "sole", + "address.", + "ttl", + "values", + "always", + "milliseconds", + "delta", + "incr", + "signed", + "64-bit", + "integer", + "i64", + "missing", + "treated" + ] + }, + { + "id": "cdn-examples-cache-rust#see-also", + "heading": "See Also", + "level": 2, + "anchor": "see-also", + "line_start": 233, + "line_end": 238, + "keywords": [ + "see", + "fastedge-sdk-rust", + "cdn", + "key_value", + "example", + "named", + "store", + "handles", + "contrast", + "cache", + "api", + "examples", + "overview", + "proxy-wasm", + "httpcontext", + "rootcontext", + "trait", + "documentation" + ] + } + ] + }, { "id": "cdn-examples-convert-image-rust", "title": "CDN Example: Convert Image (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-convert-image-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -5663,9 +6014,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "example", "convert", "image", @@ -5675,7 +6026,7 @@ "avif", "format" ], - "content_sha256": "a13f67a53c9fe7aea572cc4340f710693d326f6f3b9570a1e7428e88b43da733", + "content_sha256": "c9e876d444727919f19871887b51f11a25b8653ddc28e5f19f241a707cadd786", "sections": [ { "id": "cdn-examples-convert-image-rust#introduction", @@ -5692,9 +6043,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "cdn", "example", "convert", @@ -6159,129 +6510,13 @@ "error", "codes" ] - }, - { - "id": "cdn-examples-convert-image-rust#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 206, - "line_end": 488, - "keywords": [ - "source", - "material", - "file", - "examples", - "cdn", - "convert_image", - "src", - "lib.rs", - "rust", - "use", - "image", - "proxy_wasm", - "traits", - "types", - "std", - "env", - "varerror", - "cursor", - "str", - "from_utf8", - "main", - "set_log_level", - "loglevel", - "trace", - "set_root_context", - "box", - "dyn", - "rootcontext", - "new", - "convertimageroot", - "struct", - "impl", - "context", - "get_type", - "self" - ] - }, - { - "id": "cdn-examples-convert-image-rust#configuration", - "heading": "Configuration", - "level": 2, - "anchor": "configuration", - "line_start": 489, - "line_end": 495, - "keywords": [ - "configuration", - "environment", - "variable", - "formats_to_transform", - "comma-separated", - "list", - "file", - "extensions", - "convert", - "e.g.", - "jpg", - "jpeg", - "png", - "ignored_ua_list", - "optional", - "user-agent", - "substrings", - "skip", - "avif_speed", - "avif", - "encoding", - "speed", - "1-10", - "default", - "avif_quality", - "quality", - "1-100" - ] - }, - { - "id": "cdn-examples-convert-image-rust#how-it-works", - "heading": "How it works", - "level": 2, - "anchor": "how-it-works", - "line_start": 496, - "line_end": 502, - "keywords": [ - "works", - "on_request_headers", - "checks", - "file", - "extension", - "user-agent", - "sets", - "image-format", - "header", - "cache", - "variation", - "on_response_headers", - "response", - "headers", - "avif", - "content", - "type", - "200", - "responses", - "on_response_body", - "decodes", - "original", - "image", - "re-encodes" - ] } ] }, { "id": "cdn-examples-cors-as", "title": "CORS — AssemblyScript (CDN)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-cors-as.md", "skill": "fastedge-docs", "category": "examples", @@ -6303,9 +6538,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "cors", "response-header", "injection", @@ -6315,7 +6550,7 @@ "proxy-wasm", "sdk." ], - "content_sha256": "dcfb3c1c7467c4e745a43d3b8821e1ef8725789583876c7d2ffafd9955cc8efa", + "content_sha256": "204de98ec6e870b35f9cdd8f9b2a9d9b23c1e7152db0ee88fa8b62aaf3a5d02b", "sections": [ { "id": "cdn-examples-cors-as#introduction", @@ -6332,9 +6567,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "cors", "assemblyscript", "cdn", @@ -6903,7 +7138,7 @@ { "id": "cdn-examples-cors-rust", "title": "CORS — CDN App Example (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-cors-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -6925,9 +7160,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -6937,7 +7172,7 @@ "cors", "preflight" ], - "content_sha256": "0fb3e333f7c0f3374c1253af8febc8847afb1ee90ffeabcc90ca5cdd75762c5b", + "content_sha256": "02601a51af83f28ad9b82be9607ee55878e53af965ee28d0033dc33ac25c8fac", "sections": [ { "id": "cdn-examples-cors-rust#introduction", @@ -6954,9 +7189,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -7457,7 +7692,7 @@ { "id": "cdn-examples-custom-error-pages-as", "title": "Custom Error Pages — AssemblyScript (CDN)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-custom-error-pages-as.md", "skill": "fastedge-docs", "category": "examples", @@ -7479,9 +7714,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -7491,7 +7726,7 @@ "response-headers", "response-body" ], - "content_sha256": "d27efa1750b8e49c981eadabe5896041d527217f351a1935fb6b5da2ba740ce0", + "content_sha256": "db4273297015e84837b705d18e071b4684410000b7bc9fcf363fe82c1c58ea15", "sections": [ { "id": "cdn-examples-custom-error-pages-as#introduction", @@ -7508,9 +7743,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -7940,155 +8175,125 @@ "hook", "sequencing" ] - }, + } + ] + }, + { + "id": "cdn-examples-custom-error-pages-rust", + "title": "cdn-examples-custom-error-pages-rust", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", + "path": "reference/fastedge-docs/cdn/examples-custom-error-pages-rust.md", + "skill": "fastedge-docs", + "category": "examples", + "app_types": [ + "cdn" + ], + "languages": [ + "rust" + ], + "tags": [ + "examples", + "fastedge-docs", + "cdn", + "rust", + "auto-updated", + "true", + "sources", + "fastedge-sdk-rust", + "ref", + "main", + "commit", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", + "updated", + "2026-09-22", + "custom", + "error", + "pages", + "overview", + "intercepts", + "4xx", + "5xx", + "http" + ], + "content_sha256": "efad33874c535871854509dd840e49c337a0b3f8a7971d0743d6d1eebff0826d", + "sections": [ { - "id": "cdn-examples-custom-error-pages-as#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 296, - "line_end": 501, + "id": "cdn-examples-custom-error-pages-rust#introduction", + "heading": "Introduction", + "level": 1, + "anchor": "introduction", + "line_start": 1, + "line_end": 9, "keywords": [ - "source", - "material", - "file", - "examples", - "customerrorpages", - "assembly", - "index.ts", - "export", - "gcoredev", - "proxy-wasm-sdk-as", - "proxy", - "import", - "context", - "filterdatastatusvalues", - "filterheadersstatusvalues", - "get_property", - "log", - "loglevelvalues", - "registerrootcontext", - "rootcontext", - "set_buffer_bytes", - "buffertypevalues", - "stream_context", - "setloglevel", - "fastedge", - "class", - "errorpagesroot" + "auto-updated", + "true", + "sources", + "fastedge-sdk-rust", + "ref", + "main", + "commit", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", + "updated", + "2026-09-22" ] }, { - "id": "cdn-examples-custom-error-pages-as#what-it-does", - "heading": "What it does", + "id": "cdn-examples-custom-error-pages-rust#custom-error-pages-—-cdn-rust", + "heading": "Custom Error Pages — CDN (Rust)", "level": 2, - "anchor": "what-it-does", - "line_start": 502, - "line_end": 514, + "anchor": "custom-error-pages-—-cdn-rust", + "line_start": 10, + "line_end": 297, "keywords": [ - "onresponseheaders", - "app", - "reads", - "response.status", - "property.", - "400-599", - "range", - "sets", - "content-type", - "text", - "html", - "prepares", - "body", - "replacement.", - "onresponsebody", - "buffers", - "full", - "response", + "custom", + "error", + "pages", + "cdn", + "rust", + "overview", + "intercepts", + "4xx", + "5xx", + "http", + "responses", + "edge", "replaces", + "their", + "bodies", + "branded", + "html", + "rendered", + "via", + "handlebars", + "templates.", + "use", + "pattern", + "you", + "consistent", "styled", - "page", - "containing", - "numeric", - "status", - "code", - "human-readable", - "error", - "title", - "e.g.", - "found", - "bad", - "gateway", - "description", - "explaining", - "went", - "wrong", - "category", - "label", - "client", - "server" - ] - }, - { - "id": "cdn-examples-custom-error-pages-as#build", - "heading": "Build", - "level": 2, - "anchor": "build", - "line_start": 515, - "line_end": 528, - "keywords": [ - "build", - "pnpm", - "install", - "run", - "asbuild", - "output", - "file", - "description", - "------", - "-------------", - "customerrorpages.wasm", - "optimised", - "release", - "binary", - "upload", - "fastedge", - "customerrorpages-debug.wasm", - "debug", - "source", - "maps" - ] - }, - { - "id": "cdn-examples-custom-error-pages-as#deploy", - "heading": "Deploy", - "level": 2, - "anchor": "deploy", - "line_start": 529, - "line_end": 533, - "keywords": [ - "deploy", - "upload", + "served", + "regardless", + "origin", + "returns.", "build", - "customerrorpages.wasm", - "fastedge", - "portal", - "attach", - "your", - "cdn", - "application.", - "environment", - "variables", - "secrets", - "required." + "script", + "build.rs", + "runs", + "compile", + "time", + "embed", + "images", + "messages", + "public" ] } ] }, { - "id": "cdn-examples-custom-error-pages-rust", - "title": "cdn-examples-custom-error-pages-rust", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", - "path": "reference/fastedge-docs/cdn/examples-custom-error-pages-rust.md", + "id": "cdn-examples-custom-rust", + "title": "CDN Example: Custom — Rust", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", + "path": "reference/fastedge-docs/cdn/examples-custom-rust.md", "skill": "fastedge-docs", "category": "examples", "app_types": [ @@ -8109,120 +8314,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", - "custom", - "error", - "pages", - "overview", - "intercepts", - "4xx", - "5xx", - "http" - ], - "content_sha256": "6ca59f2c7881b6cfa873c1aa90ca38a3135eeee3546ba894a62801be63e0266e", - "sections": [ - { - "id": "cdn-examples-custom-error-pages-rust#introduction", - "heading": "Introduction", - "level": 1, - "anchor": "introduction", - "line_start": 1, - "line_end": 9, - "keywords": [ - "auto-updated", - "true", - "sources", - "fastedge-sdk-rust", - "ref", - "main", - "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", - "updated", - "2026-08-20" - ] - }, - { - "id": "cdn-examples-custom-error-pages-rust#custom-error-pages-—-cdn-rust", - "heading": "Custom Error Pages — CDN (Rust)", - "level": 2, - "anchor": "custom-error-pages-—-cdn-rust", - "line_start": 10, - "line_end": 297, - "keywords": [ - "custom", - "error", - "pages", - "cdn", - "rust", - "overview", - "intercepts", - "4xx", - "5xx", - "http", - "responses", - "edge", - "replaces", - "their", - "bodies", - "branded", - "html", - "rendered", - "via", - "handlebars", - "templates.", - "use", - "pattern", - "you", - "consistent", - "styled", - "served", - "regardless", - "origin", - "returns.", - "build", - "script", - "build.rs", - "runs", - "compile", - "time", - "embed", - "images", - "messages", - "public" - ] - } - ] - }, - { - "id": "cdn-examples-custom-rust", - "title": "CDN Example: Custom — Rust", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", - "path": "reference/fastedge-docs/cdn/examples-custom-rust.md", - "skill": "fastedge-docs", - "category": "examples", - "app_types": [ - "cdn" - ], - "languages": [ - "rust" - ], - "tags": [ - "examples", - "fastedge-docs", - "cdn", - "rust", - "auto-updated", - "true", - "sources", - "fastedge-sdk-rust", - "ref", - "main", - "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", - "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -8232,7 +8326,7 @@ "request-headers", "synthetic-response" ], - "content_sha256": "a73e35e2bec26a8caef88e750c20eec94b8a4e22bd45622922f8ab9f586d554a", + "content_sha256": "05c5008d51ac8a9fe2b0b76d6b1d52a5b3c964d3a4e07c1227591206ce8c70b0", "sections": [ { "id": "cdn-examples-custom-rust#introduction", @@ -8249,9 +8343,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -8639,7 +8733,7 @@ { "id": "cdn-examples-env-secrets-as", "title": "Environment Variables and Secrets — CDN (AssemblyScript)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 --> --- type: example app_type: cdn languages: [as] capabilities: [env-vars, secrets] ---", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 --> --- type: example app_type: cdn languages: [as] capabilities: [env-vars, secrets] ---", "path": "reference/fastedge-docs/cdn/examples-env-secrets-as.md", "skill": "fastedge-docs", "category": "examples", @@ -8661,9 +8755,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -8674,7 +8768,7 @@ "secrets", "environment" ], - "content_sha256": "0c73ed18f10ce8d8e06a88f54b4d3f23ac0b67968d5c25e974066c47408cfacb", + "content_sha256": "3c64cf405e55a27101a1b957168091583141e9c42e286db01b35cc3770d77601", "sections": [ { "id": "cdn-examples-env-secrets-as#introduction", @@ -8691,9 +8785,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -9110,7 +9204,7 @@ { "id": "cdn-examples-env-secrets-rust", "title": "Environment Variables and Secrets — CDN (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 --> --- type: example app_type: cdn languages: [rust] capabilities: [env-vars, secrets] ---", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 --> --- type: example app_type: cdn languages: [rust] capabilities: [env-vars, secrets] ---", "path": "reference/fastedge-docs/cdn/examples-env-secrets-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -9132,9 +9226,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -9144,7 +9238,7 @@ "env-vars", "secrets" ], - "content_sha256": "c649f355de98cfbff02eb0209ff30aec29948b20dda1e664b62b81a49e8a518a", + "content_sha256": "6a8766856d5c193566c9b8cdc05b6e635c040c503595795b5a2f9207b948cab2", "sections": [ { "id": "cdn-examples-env-secrets-rust#introduction", @@ -9161,9 +9255,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -9566,7 +9660,7 @@ { "id": "cdn-examples-geo-redirect-as", "title": "Geo Redirect — CDN (AssemblyScript)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-geo-redirect-as.md", "skill": "fastedge-docs", "category": "examples", @@ -9588,9 +9682,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -9600,7 +9694,7 @@ "geo-routing", "header-manipulation" ], - "content_sha256": "77bc8d7bb75d5073d55729d167f95732aae1c14e0d2cc8f5dbd17a584fe83bdf", + "content_sha256": "bfd821f4dcef5d6f8a06638c0f353365ad97cccd76619f27e6b5fc8ad6e1d48a", "sections": [ { "id": "cdn-examples-geo-redirect-as#introduction", @@ -9617,9 +9711,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -10191,7 +10285,7 @@ { "id": "cdn-examples-geo-redirect-rust", "title": "Geo Redirect — CDN (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-geo-redirect-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -10213,9 +10307,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -10225,7 +10319,7 @@ "geo-routing", "origin-rewrite" ], - "content_sha256": "e261c562cb83f75dba70f28b364fbf919b2f5013ba58235119ad284f266ad0d9", + "content_sha256": "a4ba8ac9ed821f5617d6bda76cfbd9d6d0d37c5b5b30e9206a0b2e15b713e730", "sections": [ { "id": "cdn-examples-geo-redirect-rust#introduction", @@ -10242,9 +10336,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -10747,7 +10841,7 @@ { "id": "cdn-examples-geoblock-as", "title": "Geoblock — CDN App Example (AssemblyScript)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-geoblock-as.md", "skill": "fastedge-docs", "category": "examples", @@ -10769,9 +10863,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -10781,7 +10875,7 @@ "geoblock", "geo-filtering" ], - "content_sha256": "84af0ea22b79918d77cf3d4bfb495acc76a3246c5535c41b1555f7052fcc183d", + "content_sha256": "763b705d33e44d10af681bf94505be744a28c35e28877e80f0b077006f56f37d", "sections": [ { "id": "cdn-examples-geoblock-as#introduction", @@ -10798,9 +10892,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -11276,7 +11370,7 @@ { "id": "cdn-examples-geoblock-rust", "title": "Geoblock — CDN App Example (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-geoblock-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -11298,9 +11392,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -11310,7 +11404,7 @@ "geoblock", "geo-filtering" ], - "content_sha256": "a7c062df70dea7d93851c4767e7e29ebd0ea6f820171bab1417c892702ee748e", + "content_sha256": "c88ed2e2cb497f3a3cac9866b08afcc3e2abd09c7f09fa25422cede185b2368c", "sections": [ { "id": "cdn-examples-geoblock-rust#introduction", @@ -11327,9 +11421,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -11806,7 +11900,7 @@ { "id": "cdn-examples-headers-as", "title": "CDN Headers Manipulation — AssemblyScript", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-headers-as.md", "skill": "fastedge-docs", "category": "examples", @@ -11830,9 +11924,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -11842,7 +11936,7 @@ "headers", "request-headers" ], - "content_sha256": "caec0cba8cdcb98575ff941504f05fe0ce60d9be18d75841452201ad7f996683", + "content_sha256": "eb268cb0cde0417bb082dbadb140da4f26f837195f2c6d93a907bc1643fc243e", "sections": [ { "id": "cdn-examples-headers-as#introduction", @@ -11859,9 +11953,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -11999,9 +12093,11 @@ "method", "signature", "description", - "-------------------", - "-----------------------------------------------", - "--------------------------------------------------------------------------------------------------------" + "--------------------------", + "---------------------------------------", + "-----------------------------------------------------------------------------------------------------", + "get", + "nam" ] }, { @@ -12439,7 +12535,7 @@ { "id": "cdn-examples-headers-rust", "title": "Headers — CDN (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-headers-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -12461,9 +12557,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -12473,7 +12569,7 @@ "headers", "request-headers" ], - "content_sha256": "26db929462e18b733d0d8ff6392d1a509520adb603ee47545516c24043493a11", + "content_sha256": "bf7f55f6e1a3e672e73e99857adf01eae6f05e539dcd246c132da96a418bbe7e", "sections": [ { "id": "cdn-examples-headers-rust#introduction", @@ -12490,9 +12586,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -12837,8 +12933,8 @@ }, { "id": "cdn-examples-http-call-as", - "title": "HTTP Call", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "title": "cdn-examples-http-call-as", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-http-call-as.md", "skill": "fastedge-docs", "category": "examples", @@ -12862,9 +12958,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "overview", "httpcall", "dispatches", @@ -12875,7 +12971,7 @@ "fastedge", "proxy-wasm" ], - "content_sha256": "86bdde87724666835a6a0c4dd7190437c0ea08fb8715e577c65cd2486a0b11c0", + "content_sha256": "5fd3877e09d4896bd6c69ed4c0cb9cc56dc6cd0d8fadb01c02391285f4b8bce6", "sections": [ { "id": "cdn-examples-http-call-as#introduction", @@ -12892,9 +12988,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20" + "2026-09-22" ] }, { @@ -13166,209 +13262,13 @@ "response", "patterns" ] - }, - { - "id": "cdn-examples-http-call-as#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 325, - "line_end": 485, - "keywords": [ - "source", - "material", - "file", - "examples", - "httpcall", - "assembly", - "index.ts", - "export", - "gcoredev", - "proxy-wasm-sdk-as", - "proxy", - "exports", - "required", - "functions", - "interact", - "us.", - "import", - "basecontext", - "buffertypevalues", - "context", - "filterheadersstatusvalues", - "get_buffer_bytes", - "headerpair", - "log", - "loglevelvalues", - "makeheaderpair", - "registerrootcontext", - "rootcontext", - "send_http_response", - "stream_context", - "wasmresultvalues", - "proxy-wasm-sdk-a" - ] - }, - { - "id": "cdn-examples-http-call-as#what-it-does", - "heading": "What it does", - "level": 2, - "anchor": "what-it-does", - "line_start": 486, - "line_end": 497, - "keywords": [ - "onrequestheaders", - "app", - "dispatches", - "outbound", - "http", - "get", - "request", - "httpbin.org", - "pauses", - "hook", - "stopiteration", - "until", - "response", - "arrives.", - "dispatch", - "latched", - "instance", - "field", - "second", - "invocation", - "processed", - "returns", - "continue", - "instead", - "dispatching", - "again.", - "inside", - "callback", - "passed", - "httpcall", - "checks", - "whether", - "call", - "succeeded", - "headers", - "value", - "indicates", - "failure", - "timeout", - "dns" - ] - }, - { - "id": "cdn-examples-http-call-as#key-concepts", - "heading": "Key concepts", - "level": 2, - "anchor": "key-concepts", - "line_start": 498, - "line_end": 504, - "keywords": [ - "key", - "concepts", - "httpcall", - "rootcontext", - "dispatches", - "async", - "http", - "request.", - "accepts", - "cluster", - "host", - "headers", - "body", - "trailers", - "timeout", - "milliseconds", - "originating", - "context", - "callback.", - "fastedge", - "resume", - "model.", - "returning", - "filterheadersstatusvalues.stopiteration", - "pauses", - "hook.", - "runtime", - "processes", - "response", - "invokes", - "callback", - "re-invokes", - "onrequestheaders", - "same", - "instance", - "httpcalldispatched", - "latch", - "gates", - "re-dispatch", - "hoo" - ] - }, - { - "id": "cdn-examples-http-call-as#build", - "heading": "Build", - "level": 2, - "anchor": "build", - "line_start": 505, - "line_end": 518, - "keywords": [ - "build", - "pnpm", - "install", - "run", - "asbuild", - "output", - "file", - "description", - "------", - "-------------", - "httpcall.wasm", - "optimised", - "release", - "binary", - "upload", - "fastedge", - "httpcall-debug.wasm", - "debug", - "source", - "maps" - ] - }, - { - "id": "cdn-examples-http-call-as#deploy", - "heading": "Deploy", - "level": 2, - "anchor": "deploy", - "line_start": 519, - "line_end": 523, - "keywords": [ - "deploy", - "upload", - "build", - "httpcall.wasm", - "fastedge", - "portal", - "attach", - "your", - "cdn", - "application.", - "environment", - "variables", - "secrets", - "required." - ] } ] }, { "id": "cdn-examples-http-call-rust", "title": "HTTP Call — CDN (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-http-call-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -13390,9 +13290,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "http", "call", "makes", @@ -13402,7 +13302,7 @@ "services", "timeout" ], - "content_sha256": "d1e86eef023d89dc75f57a3863c60f70ab78a1b7f854f40563265c4f403fcb2b", + "content_sha256": "5e665b5b4838fd593db0ee7e992ade82f31afd9c62cf39aa13075f9ffdf2b6ee", "sections": [ { "id": "cdn-examples-http-call-rust#introduction", @@ -13419,9 +13319,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "http", "call", "cdn", @@ -13823,7 +13723,7 @@ "level": 2, "anchor": "complete-example", "line_start": 247, - "line_end": 359, + "line_end": 360, "keywords": [ "complete", "example", @@ -13863,8 +13763,8 @@ "heading": "Gotchas", "level": 2, "anchor": "gotchas", - "line_start": 360, - "line_end": 371, + "line_start": 361, + "line_end": 372, "keywords": [ "gotchas", "action", @@ -13913,8 +13813,8 @@ "heading": "See Also", "level": 2, "anchor": "see-also", - "line_start": 372, - "line_end": 378, + "line_start": 373, + "line_end": 379, "keywords": [ "see", "proxy-wasm", @@ -13941,7 +13841,7 @@ { "id": "cdn-examples-kv-store-as", "title": "KV Store — AssemblyScript CDN Example", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-kv-store-as.md", "skill": "fastedge-docs", "category": "examples", @@ -13965,9 +13865,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -13977,7 +13877,7 @@ "kv-store", "sorted-sets" ], - "content_sha256": "7c82be09762a859504b8de768a520016b4dd63da93c478964e74af2344eb76b3", + "content_sha256": "bfdb069b5c22829eb076f681740fba8b7d13263e17108b9905e3e513a3ae7350", "sections": [ { "id": "cdn-examples-kv-store-as#introduction", @@ -13994,9 +13894,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -14615,7 +14515,7 @@ { "id": "cdn-examples-kv-store-rust", "title": "KV Store — CDN (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-kv-store-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -14637,9 +14537,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "kv-store", @@ -14650,7 +14550,7 @@ "example", "app_type" ], - "content_sha256": "d382cf1a71b92057d477f9447f2538d3008c8abd3f00d3c51323f300c086227a", + "content_sha256": "23c7f8c100db8a05f960e1382c3a9933d52661da3f5ad5a253cfd75e1d720c90", "sections": [ { "id": "cdn-examples-kv-store-rust#introduction", @@ -14667,9 +14567,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "kv-store", @@ -14826,7 +14726,7 @@ "level": 2, "anchor": "gotchas", "line_start": 223, - "line_end": 237, + "line_end": 239, "keywords": [ "gotchas", "get", @@ -14875,8 +14775,8 @@ "heading": "Related", "level": 2, "anchor": "related", - "line_start": 238, - "line_end": 243, + "line_start": 240, + "line_end": 245, "keywords": [ "related", "host", @@ -14911,13 +14811,250 @@ "vs.", "differences" ] + }, + { + "id": "cdn-examples-kv-store-rust#source-material", + "heading": "Source Material", + "level": 2, + "anchor": "source-material", + "line_start": 246, + "line_end": 518, + "keywords": [ + "source", + "material", + "file", + "examples", + "cdn", + "key_value", + "src", + "lib.rs", + "rust", + "copyright", + "2025", + "g-core", + "innovations", + "sarl", + "example", + "app", + "demonstrating", + "store", + "operations", + "via", + "proxy-wasm", + "interface.", + "supports", + "query", + "parameters", + "name", + "action", + "get", + "key", + "scan", + "match", + "pattern", + "zrange", + "min", + "f64", + "max", + "zscan", + "bfexists", + "ite" + ] + }, + { + "id": "cdn-examples-kv-store-rust#what-it-does", + "heading": "What it does", + "level": 2, + "anchor": "what-it-does", + "line_start": 519, + "line_end": 535, + "keywords": [ + "app", + "supports", + "following", + "actions", + "get", + "fetch", + "one", + "key", + "scan", + "list", + "keys", + "matching", + "pattern", + "zrange", + "read", + "sorted-set", + "entries", + "score", + "range", + "zscan", + "bfexists", + "check", + "whether", + "bloom", + "filter", + "contains", + "item", + "request", + "include", + "least", + "store", + "name", + "action", + "operation", + "optional", + "defaults", + "validates", + "required", + "parameters", + "returns" + ] + }, + { + "id": "cdn-examples-kv-store-rust#supported-query-examples", + "heading": "Supported query examples", + "level": 2, + "anchor": "supported-query-examples", + "line_start": 536, + "line_end": 567, + "keywords": [ + "supported", + "query", + "examples", + "get", + "key", + "text", + "store", + "my_store", + "action", + "user", + "list", + "keys", + "pattern", + "scan", + "match", + "read", + "sorted", + "set", + "score", + "range", + "zrange", + "leaderboard", + "min", + "max", + "100", + "search", + "sorted-set", + "members", + "zscan", + "check", + "bloom", + "filter", + "item", + "bfexists", + "visitors", + "alice", + "examp" + ] + }, + { + "id": "cdn-examples-kv-store-rust#build", + "heading": "Build", + "level": 2, + "anchor": "build", + "line_start": 568, + "line_end": 576, + "keywords": [ + "build", + "cargo", + "--release", + "output", + "target", + "wasm32-wasip1", + "release", + "key_value.wasm", + "example", + "cdn", + "app", + "targets" + ] + }, + { + "id": "cdn-examples-kv-store-rust#response-format", + "heading": "Response format", + "level": 2, + "anchor": "response-format", + "line_start": 577, + "line_end": 598, + "keywords": [ + "response", + "format", + "app", + "replaces", + "body", + "json", + "sets", + "content-type", + "application", + "successful", + "looks", + "like", + "store", + "my_store", + "action", + "get", + "key", + "user", + "alice", + "required", + "parameter", + "missing", + "operation", + "fails", + "responds", + "error", + "payload", + "param" + ] + }, + { + "id": "cdn-examples-kv-store-rust#notes", + "heading": "Notes", + "level": 2, + "anchor": "notes", + "line_start": 599, + "line_end": 605, + "keywords": [ + "notes", + "app", + "requires", + "query", + "parameters", + "run.", + "action", + "omitted", + "defaults", + "get", + "code", + "uses", + "fastedge", + "proxywasm", + "key_value", + "store", + "proxy_wasm", + "lifecycle", + "hooks", + "operate", + "store." + ] } ] }, { "id": "cdn-examples-large-dictionary-as", "title": "Large Dictionary — AssemblyScript (CDN)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-large-dictionary-as.md", "skill": "fastedge-docs", "category": "examples", @@ -14939,9 +15076,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "large", "dictionary", "overview", @@ -14950,7 +15087,7 @@ "environment", "variables" ], - "content_sha256": "5c0712f113a19fa2bcc1667657ca33586d5a538706d60bc80ad976fc408270c3", + "content_sha256": "06c3e8963a2738ac48fbbfbf6217cded6950009199039727a0ed53963ab8474d", "sections": [ { "id": "cdn-examples-large-dictionary-as#introduction", @@ -14967,9 +15104,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "large", "dictionary", "assemblyscript", @@ -15273,13 +15410,212 @@ "patterns", "fastedge-docs" ] + }, + { + "id": "cdn-examples-large-dictionary-as#source-material", + "heading": "Source Material", + "level": 2, + "anchor": "source-material", + "line_start": 140, + "line_end": 223, + "keywords": [ + "source", + "material", + "file", + "examples", + "largedictionary", + "assembly", + "index.ts", + "export", + "gcoredev", + "proxy-wasm-sdk-as", + "proxy", + "import", + "context", + "filterheadersstatusvalues", + "log", + "loglevelvalues", + "registerrootcontext", + "rootcontext", + "stream_context", + "getdictionary", + "setloglevel", + "fastedge", + "class", + "largedictionaryroot", + "extends", + "createcontext", + "context_id", + "u32", + "con" + ] + }, + { + "id": "cdn-examples-large-dictionary-as#when-to-use-getdictionary-vs-getenv", + "heading": "When to use `getDictionary` vs `getEnv`", + "level": 2, + "anchor": "when-to-use-getdictionary-vs-getenv", + "line_start": 224, + "line_end": 234, + "keywords": [ + "use", + "getdictionary", + "getenv", + "function", + "----------", + "name", + "variable", + "value", + "under", + "cases", + "exceed", + "wasi", + "env", + "var", + "size", + "limit", + "environment", + "interface", + "per", + "variable.", + "your", + "app", + "needs", + "read", + "larger", + "values", + "e.g.", + "large", + "json", + "configs", + "pem", + "certificates", + "policy", + "documents", + "calls", + "proxy_dictionary_get", + "bypasses", + "thi" + ] + }, + { + "id": "cdn-examples-large-dictionary-as#what-it-does", + "heading": "What it does", + "level": 2, + "anchor": "what-it-does", + "line_start": 235, + "line_end": 238, + "keywords": [ + "onrequestheaders", + "app", + "reads", + "large_config", + "environment", + "variable", + "using", + "getdictionary", + "logs", + "size", + "adds", + "x-config-size", + "request", + "header", + "upstream", + "see." + ] + }, + { + "id": "cdn-examples-large-dictionary-as#configuration", + "heading": "Configuration", + "level": 2, + "anchor": "configuration", + "line_start": 239, + "line_end": 246, + "keywords": [ + "configuration", + "set", + "following", + "your", + "fastedge", + "application", + "name", + "type", + "description", + "------", + "-------------", + "large_config", + "environment", + "variable", + "large", + "payload", + "e.g.", + "json", + "pem", + "certificate" + ] + }, + { + "id": "cdn-examples-large-dictionary-as#build", + "heading": "Build", + "level": 2, + "anchor": "build", + "line_start": 247, + "line_end": 260, + "keywords": [ + "build", + "pnpm", + "install", + "run", + "asbuild", + "output", + "file", + "description", + "------", + "-------------", + "largedictionary.wasm", + "optimised", + "release", + "binary", + "upload", + "fastedge", + "largedictionary-debug.wasm", + "debug", + "source", + "maps" + ] + }, + { + "id": "cdn-examples-large-dictionary-as#deploy", + "heading": "Deploy", + "level": 2, + "anchor": "deploy", + "line_start": 261, + "line_end": 265, + "keywords": [ + "deploy", + "upload", + "build", + "largedictionary.wasm", + "fastedge", + "portal", + "attach", + "your", + "cdn", + "application.", + "configure", + "large_config", + "environment", + "variable", + "application", + "settings." + ] } ] }, { "id": "cdn-examples-large-dictionary-rust", "title": "cdn-examples-large-dictionary-rust", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-large-dictionary-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -15301,9 +15637,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "large-env-var", @@ -15313,7 +15649,7 @@ "app_type", "languages" ], - "content_sha256": "1eb33add15b946d5567ac85d662c67d674c0322a60fd9aa28e0930be81001b54", + "content_sha256": "79abc10593f47efe0567a64ce1580bbb0c5be10f9cfca293be10963f46bb4c9c", "sections": [ { "id": "cdn-examples-large-dictionary-rust#introduction", @@ -15330,9 +15666,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "large-env-var", @@ -15399,7 +15735,7 @@ { "id": "cdn-examples-log-time-as", "title": "Log Time — CDN App (AssemblyScript)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-log-time-as.md", "skill": "fastedge-docs", "category": "examples", @@ -15423,9 +15759,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -15435,7 +15771,7 @@ "logging", "time" ], - "content_sha256": "0cd462da5aca1fa0b6b8f81e6775b0dea2879447776f153e4cc8522280774585", + "content_sha256": "5266245f16c9a92efe159d422b1d6efbb80268cecbd4be0e9cbf62f79073c1d5", "sections": [ { "id": "cdn-examples-log-time-as#introduction", @@ -15452,9 +15788,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -15798,7 +16134,7 @@ { "id": "cdn-examples-log-time-rust", "title": "Log Time — CDN (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-log-time-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -15820,9 +16156,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -15832,7 +16168,7 @@ "logging", "timing" ], - "content_sha256": "20055b088c670a075eae455b07e6b9a38488a69a6c3199d9566cab1f18d3beaf", + "content_sha256": "17de7b3f08a526cb98293c820d7bd7c1613cadab078a2b31d101893d8def383e", "sections": [ { "id": "cdn-examples-log-time-rust#introduction", @@ -15849,9 +16185,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -16189,7 +16525,7 @@ { "id": "cdn-examples-md2html-rust", "title": "CDN Example: Markdown to HTML (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-md2html-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -16211,9 +16547,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -16223,7 +16559,7 @@ "response-body-transform", "request-path-rewrite" ], - "content_sha256": "1b26d02c4a91ae4a45b55116506d088b7e878c81183e345f40fb5d7a4e9c6f95", + "content_sha256": "f8fbf0e4875baadddcd666f15ec0b2921599d2698c6c647e115d812aa0130fce", "sections": [ { "id": "cdn-examples-md2html-rust#introduction", @@ -16240,9 +16576,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -16671,7 +17007,7 @@ { "id": "cdn-examples-properties-as", "title": "CDN Runtime Properties — AssemblyScript", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-properties-as.md", "skill": "fastedge-docs", "category": "examples", @@ -16693,9 +17029,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "runtime", "properties", "language", @@ -16705,7 +17041,7 @@ "type", "overview" ], - "content_sha256": "1a7cb1c6e4a4a24400ab5988ca4ec6145ff264706a8559555d2c0a9c37c4273c", + "content_sha256": "3bbe18f8ddfeb71ed284002040e77bd67ef56bb6a5281f9165ebb30794f1cf43", "sections": [ { "id": "cdn-examples-properties-as#introduction", @@ -16722,9 +17058,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "cdn", "runtime", "properties", @@ -17222,7 +17558,7 @@ { "id": "cdn-examples-properties-rust", "title": "Request Properties — CDN App Example (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-properties-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -17244,9 +17580,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -17256,7 +17592,7 @@ "request-properties", "geo-data" ], - "content_sha256": "eb4c151ead93e097ac9ac3e38b0515c3c08db7a6c4eaf57ed6516291ea67ae49", + "content_sha256": "f5e9104e3624d8f2bb64dfb10d2389a9ef745159f38f2ce8dc7fdeff64000933", "sections": [ { "id": "cdn-examples-properties-rust#introduction", @@ -17273,9 +17609,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -18244,7 +18580,7 @@ { "id": "host-services-rust", "title": "Rust Host Services Reference", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/host-services-rust.md", "skill": "fastedge-docs", "category": "sdk", @@ -18263,9 +18599,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "host", "services", "reference", @@ -18276,7 +18612,7 @@ "storage", "secret" ], - "content_sha256": "815f0408c27342ac5a6ee1babbd38b3bf41d35228b85062807f8172c7ef86788", + "content_sha256": "3c1895152a7a969acdb7c1f5e670bd6441f6b3d44fadf5a8640adab15cc3185e", "sections": [ { "id": "host-services-rust#introduction", @@ -18293,9 +18629,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "rust", "host", "services", @@ -18443,6 +18779,13 @@ "change", "lifetime", "deployment.", + "config", + "key_value", + "persistent", + "data", + "secret", + "encrypted", + "credentials.", "api", "rust", "pub", @@ -18462,15 +18805,7 @@ "decoded", "utf-8.", "environment", - "variables", - "set", - "deployment", - "time", - "via", - "platform", - "same", - "management", - "mechanism" + "vari" ] }, { @@ -18565,7 +18900,7 @@ { "id": "http-examples-ab-testing-js", "title": "A/B Testing — FastEdge Example", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-ab-testing-js.md", "skill": "fastedge-docs", "category": "examples", @@ -18587,9 +18922,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "testing", "fastedge", "example", @@ -18600,7 +18935,7 @@ "visitors", "test" ], - "content_sha256": "25feb56e225dc3c2de096f569836c7a02371f3ad66f47c95f09b1d43cae9d0af", + "content_sha256": "035d8a71d445ebe35d7be302675769576440de7ae354afe090ab0810e7efa2ae", "sections": [ { "id": "http-examples-ab-testing-js#introduction", @@ -18617,9 +18952,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "testing", "fastedge", "example" @@ -19126,7 +19461,7 @@ { "id": "http-examples-ab-testing-wasi-rust", "title": "Example: A/B Testing (WASI, Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-ab-testing-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -19148,9 +19483,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -19160,7 +19495,7 @@ "ab-testing", "cookie-parsing" ], - "content_sha256": "21cff74a5cb7a1216109a412f205162be95a99647d070c31cfb71ff8c06626fb", + "content_sha256": "cc40993ca04fabb9520799bde4b5cca46303197434948ca87de607ddb25b659f", "sections": [ { "id": "http-examples-ab-testing-wasi-rust#introduction", @@ -19177,9 +19512,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -19654,7 +19989,7 @@ { "id": "http-examples-api-wrapper-basic-rust", "title": "examples-api-wrapper-basic-rust", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-api-wrapper-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -19676,9 +20011,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "examples-api-wrapper-basic-rust", "type", "example", @@ -19688,7 +20023,7 @@ "language", "app" ], - "content_sha256": "eb2a0df93df00172d7020dc806527d1f98e18809247273240ede8f6952fccbf6", + "content_sha256": "e441eccf269500eb32517fe80bc7b7dcc0840b906593b5298f97ea78452293fd", "sections": [ { "id": "http-examples-api-wrapper-basic-rust#introduction", @@ -19705,9 +20040,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "examples-api-wrapper-basic-rust", "type", "http", @@ -20237,7 +20572,7 @@ { "id": "http-examples-auth-js", "title": "Authentication Patterns (JavaScript)", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-auth-js.md", "skill": "fastedge-docs", "category": "examples", @@ -20259,9 +20594,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "authentication", "patterns", "fastedge", @@ -20272,7 +20607,7 @@ "shared", "secrets" ], - "content_sha256": "2e7f44f68db995e99a39e614304ec39247aa583cb6ccb04e1674dd9b579b49e7", + "content_sha256": "3b2f936aaf35dbf11bd593c13d4027863de2650ffc16c981b157e041ad29dbfd", "sections": [ { "id": "http-examples-auth-js#introduction", @@ -20289,9 +20624,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "authentication", "patterns", "javascript", @@ -20588,7 +20923,7 @@ { "id": "http-examples-backend-basic-rust", "title": "Example: Backend (URL Proxy) — Rust", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-backend-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -20610,9 +20945,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -20622,7 +20957,7 @@ "outbound-http", "query-params" ], - "content_sha256": "7ed671dc0d577b2f44a9be8be61ed5840b34e1ef7ff5b28f5169a14a97e79b0e", + "content_sha256": "653bed0caf43133e7cf62e0930264bec8ced4e99d9db75ad00188b1f618c266d", "sections": [ { "id": "http-examples-backend-basic-rust#introduction", @@ -20639,9 +20974,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -21063,207 +21398,13 @@ "handling", "patterns" ] - }, - { - "id": "http-examples-backend-basic-rust#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 157, - "line_end": 228, - "keywords": [ - "source", - "material", - "file", - "examples", - "http", - "basic", - "backend", - "src", - "lib.rs", - "rust", - "use", - "anyhow", - "error", - "result", - "fastedge", - "body", - "method", - "request", - "response", - "statuscode", - "allow", - "dead_code", - "main", - "req", - "let", - "parts", - "req.into_parts", - "query", - ".uri", - ".query", - ".ok_or", - "missing", - "uri", - "parameter", - "params", - "querystring", - "querify" - ] - }, - { - "id": "http-examples-backend-basic-rust#what-it-does", - "heading": "What it does", - "level": 2, - "anchor": "what-it-does", - "line_start": 229, - "line_end": 238, - "keywords": [ - "parses", - "url", - "query", - "parameter", - "request", - "uri", - "percent-decodes", - "via", - "urlencoding", - "decode", - "builds", - "outbound", - "get", - "using", - "fastedge", - "send_request", - "returns", - "http", - "200", - "plain-text", - "body", - "len", - "body-length", - "content-type", - "upstream-content-type", - "500", - "error", - "message", - "absent", - "string", - "missing." - ] - }, - { - "id": "http-examples-backend-basic-rust#apis-used", - "heading": "APIs used", - "level": 2, - "anchor": "apis-used", - "line_start": 239, - "line_end": 249, - "keywords": [ - "apis", - "used", - "api", - "purpose", - "---", - "fastedge", - "http", - "sync", - "request-response", - "handler", - "macro", - "send_request", - "request", - "blocking", - "outbound", - "response", - "statuscode", - "method", - "types", - "body", - "bodies", - "querystring", - "querify", - "parse", - "query", - "string", - "key-value", - "pairs", - "urlencoding", - "decode", - "percent-decode", - "url", - "value" - ] - }, - { - "id": "http-examples-backend-basic-rust#build", - "heading": "Build", - "level": 2, - "anchor": "build", - "line_start": 250, - "line_end": 256, - "keywords": [ - "build", - "cargo", - "--release", - "output", - "target", - "wasm32-wasip1", - "release", - "backend.wasm" - ] - }, - { - "id": "http-examples-backend-basic-rust#expected-behavior", - "heading": "Expected behavior", - "level": 2, - "anchor": "expected-behavior", - "line_start": 257, - "line_end": 267, - "keywords": [ - "expected", - "behavior", - "request", - "response", - "status", - "body", - "---", - "get", - "url", - "https", - "2fhttpbin.org", - "2fget", - "200", - "len", - "content-type", - "mime", - "hello", - "key", - "500", - "missing", - "parameter", - "query", - "string", - "uri", - "value", - "byte", - "length", - "upstream", - "body.", - "header", - "returned", - "server", - "formatted", - "rust", - "option" - ] } ] }, { "id": "http-examples-bloom-filter-denylist-wasi-rust", "title": "Example: Bloom Filter IP Denylist (WASI, Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-bloom-filter-denylist-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -21285,9 +21426,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -21297,7 +21438,7 @@ "kv-store", "bloom-filter" ], - "content_sha256": "fa4e6b140a8db8f8879eb511aa72c60e9e495039ae9a1b80cfd2c9841d0bef19", + "content_sha256": "a447a165a864934a9567ab24a9258a36cc441050690b08e0afe96a7a9523a505", "sections": [ { "id": "http-examples-bloom-filter-denylist-wasi-rust#introduction", @@ -21314,9 +21455,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -21769,13 +21910,195 @@ "platform-overview", "concepts" ] + }, + { + "id": "http-examples-bloom-filter-denylist-wasi-rust#source-material", + "heading": "Source Material", + "level": 2, + "anchor": "source-material", + "line_start": 154, + "line_end": 283, + "keywords": [ + "source", + "material", + "file", + "examples", + "http", + "wasi", + "bloom_filter_denylist", + "src", + "lib.rs", + "rust", + "copyright", + "2025", + "g-core", + "innovations", + "sarl", + "bloom-filter", + "denylist", + "example.", + "checks", + "client", + "x-real-ip", + "request", + "header", + "falling", + "back", + "x-forwarded-for", + "against", + "bloom", + "filter", + "stored", + "fastedge", + "kv.", + "returns", + "403", + "hit", + "200", + "otherwise.", + "required", + "configuration", + "environment" + ] + }, + { + "id": "http-examples-bloom-filter-denylist-wasi-rust#configuration", + "heading": "Configuration", + "level": 2, + "anchor": "configuration", + "line_start": 284, + "line_end": 289, + "keywords": [ + "configuration", + "environment", + "variable", + "denylist_store", + "name", + "store", + "holds", + "bloom", + "filter.", + "bloom-filter", + "key", + "hardcoded", + "blocked-ips", + "change", + "bloom_key", + "src", + "lib.rs", + "your", + "different." + ] + }, + { + "id": "http-examples-bloom-filter-denylist-wasi-rust#behaviour", + "heading": "Behaviour", + "level": 2, + "anchor": "behaviour", + "line_start": 290, + "line_end": 296, + "keywords": [ + "behaviour", + "bf_exists", + "blocked-ips", + "response", + "---", + "true", + "403", + "allowed", + "false", + "...", + "200" + ] + }, + { + "id": "http-examples-bloom-filter-denylist-wasi-rust#tradeoff-false-positives", + "heading": "Tradeoff: false positives", + "level": 2, + "anchor": "tradeoff-false-positives", + "line_start": 297, + "line_end": 304, + "keywords": [ + "tradeoff", + "false", + "positives", + "bloom", + "filters", + "answer", + "definitely", + "set", + "maybe", + "bf_exists", + "returns", + "true", + "probably", + "added", + "small", + "fraction", + "hits", + "meaning", + "legitimate", + "ips", + "over-blocked.", + "acceptable", + "denylist", + "allowlists", + "anything", + "requiring", + "exact", + "membership", + "use", + "store.get", + "against", + "regular", + "key", + "instead." + ] + }, + { + "id": "http-examples-bloom-filter-denylist-wasi-rust#populating-the-filter", + "heading": "Populating the filter", + "level": 2, + "anchor": "populating-the-filter", + "line_start": 305, + "line_end": 309, + "keywords": [ + "populating", + "filter", + "edge", + "handler", + "read-only.", + "populate", + "blocked-ips", + "out", + "band", + "example", + "via", + "fastedge", + "api" + ] + }, + { + "id": "http-examples-bloom-filter-denylist-wasi-rust#related", + "heading": "Related", + "level": 2, + "anchor": "related", + "line_start": 310, + "line_end": 314, + "keywords": [ + "related", + "mirror", + "fastedge-sdk-js", + "examples", + "bloom-filter-denylist" + ] } ] }, { "id": "http-examples-cache-basic-rust", "title": "Cache Basic (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-cache-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -21797,9 +22120,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -21809,7 +22132,7 @@ "cache", "basic" ], - "content_sha256": "51fe5b585b86d0b39142ab2d5313ea57a260b1d8830ad7d38bce3b839f9f9961", + "content_sha256": "58aa39343f1d956e9ab8ab5ea82eba707a1033fac18ca3f195c40b96b7b3016b", "sections": [ { "id": "http-examples-cache-basic-rust#introduction", @@ -21826,9 +22149,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -22221,13 +22544,199 @@ "selection", "guidance" ] + }, + { + "id": "http-examples-cache-basic-rust#source-material", + "heading": "Source Material", + "level": 2, + "anchor": "source-material", + "line_start": 137, + "line_end": 244, + "keywords": [ + "source", + "material", + "file", + "examples", + "http", + "basic", + "cache", + "src", + "lib.rs", + "rust", + "copyright", + "2025", + "g-core", + "innovations", + "sarl", + "example", + "app", + "demonstrating", + "cache-aside", + "pattern", + "via", + "interface.", + "request", + "builds", + "key", + "path.", + "returns", + "cached", + "body", + "immediately", + "hit", + "x-cache", + "miss", + "generates", + "response", + "stores", + "environment", + "variables", + "cache_ttl_ms", + "long" + ] + }, + { + "id": "http-examples-cache-basic-rust#configuration", + "heading": "Configuration", + "level": 2, + "anchor": "configuration", + "line_start": 245, + "line_end": 250, + "keywords": [ + "configuration", + "env", + "var", + "required", + "description", + "---", + "cache_ttl_ms", + "long", + "cache", + "response", + "milliseconds.", + "default", + "30000" + ] + }, + { + "id": "http-examples-cache-basic-rust#how-it-works", + "heading": "How it works", + "level": 2, + "anchor": "how-it-works", + "line_start": 251, + "line_end": 259, + "keywords": [ + "works", + "get", + "api", + "data", + "cache", + "miss", + "generate", + "body", + "store", + "200", + "x-cache", + "hit", + "return", + "cached", + "key", + "page", + "request-path", + "unique", + "path", + "gets", + "own", + "entry.", + "response", + "simple", + "html", + "includes", + "request", + "stand", + "expensive", + "computation", + "template", + "render." + ] + }, + { + "id": "http-examples-cache-basic-rust#what-it-returns", + "heading": "What it returns", + "level": 2, + "anchor": "what-it-returns", + "line_start": 260, + "line_end": 269, + "keywords": [ + "returns", + "http", + "1.1", + "200", + "content-type", + "text", + "html", + "x-cache", + "hit", + "miss", + "doctype", + "..." + ] + }, + { + "id": "http-examples-cache-basic-rust#build", + "heading": "Build", + "level": 2, + "anchor": "build", + "line_start": 270, + "line_end": 276, + "keywords": [ + "build", + "cargo", + "--release", + "output", + "target", + "wasm32-wasip1", + "release", + "cache_basic.wasm" + ] + }, + { + "id": "http-examples-cache-basic-rust#apis-used", + "heading": "APIs used", + "level": 2, + "anchor": "apis-used", + "line_start": 277, + "line_end": 282, + "keywords": [ + "apis", + "used", + "fastedge", + "cache", + "get", + "key", + "retrieve", + "cached", + "bytes", + "returns", + "option", + "vec", + "set", + "ttl_ms", + "store", + "optional", + "ttl", + "milliseconds", + "none", + "means", + "expiry" + ] } ] }, { "id": "http-examples-cache-js", "title": "FastEdge Cache — JavaScript Examples", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-cache-js.md", "skill": "fastedge-docs", "category": "examples", @@ -22251,9 +22760,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "cache", "module", @@ -22263,7 +22772,7 @@ "2.3.0", "app" ], - "content_sha256": "1836a727bbc36819e95787b311b6d05ca2b8ac657190824b76fc727e7fa81ceb", + "content_sha256": "c53a54daf9307b32c0aa69a72792c852be660acff331a69288bf9425b6a194a6", "sections": [ { "id": "http-examples-cache-js#introduction", @@ -22280,9 +22789,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "cache", "javascript", @@ -22611,63 +23120,13 @@ "response", "construction" ] - }, - { - "id": "http-examples-cache-js#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 335, - "line_end": 610, - "keywords": [ - "source", - "material", - "file", - "examples", - "cache", - "src", - "index.ts", - "fastedge", - "flagship", - "patterns", - "example", - "demonstrates", - "three", - "highest-value", - "uses", - "module", - "per-ip", - "rate", - "limiting", - "atomic", - "counters", - "origin-cache", - "proxy", - "manual", - "get", - "set", - "conditional", - "caching", - "json", - "memoisation", - "getorset", - "computed", - "populator", - "rely", - "strongly", - "consistent", - "within", - "pop", - "incr", - "returns" - ] } ] }, { "id": "http-examples-cache-wasi-rust", "title": "Cache (WASI) — Rust HTTP Example", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-cache-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -22689,9 +23148,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -22701,7 +23160,7 @@ "cache", "outbound-http" ], - "content_sha256": "31cfe4b83115feeb78ff407e5c37207e21a522d87f06aeb8d7607aa6ad31cd67", + "content_sha256": "7c58be673c4adce9e4ac6ad2928c95a42a645cf231c1f09d901ed10534e327cc", "sections": [ { "id": "http-examples-cache-wasi-rust#introduction", @@ -22718,9 +23177,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -23069,201 +23528,13 @@ "workflow", "skill" ] - }, - { - "id": "http-examples-cache-wasi-rust#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 192, - "line_end": 359, - "keywords": [ - "source", - "material", - "file", - "examples", - "http", - "wasi", - "cache", - "src", - "lib.rs", - "rust", - "copyright", - "2025", - "g-core", - "innovations", - "sarl", - "example", - "app", - "demonstrating", - "response", - "caching", - "purging", - "via", - "interface.", - "reads", - "origin_host", - "environment", - "forwards", - "incoming", - "request", - "origin", - "caches", - "body", - "keyed", - "path.", - "subsequent", - "requests", - "same", - "path", - "cached", - "returned" - ] - }, - { - "id": "http-examples-cache-wasi-rust#configuration", - "heading": "Configuration", - "level": 2, - "anchor": "configuration", - "line_start": 360, - "line_end": 366, - "keywords": [ - "configuration", - "env", - "var", - "required", - "description", - "---", - "origin_host", - "yes", - "base", - "url", - "upstream", - "origin", - "e.g.", - "https", - "api.example.com", - "returns", - "500", - "unset.", - "cache_ttl_ms", - "long", - "cache", - "responses", - "milliseconds.", - "default", - "60000" - ] - }, - { - "id": "http-examples-cache-wasi-rust#how-it-works", - "heading": "How it works", - "level": 2, - "anchor": "how-it-works", - "line_start": 367, - "line_end": 373, - "keywords": [ - "works", - "get", - "data", - "cache", - "miss", - "forward", - "origin_host", - "2xx", - "body", - "200", - "x-cache", - "hit", - "return", - "cached", - "key", - "path", - "query", - "only", - "responses", - "origin", - "error", - "pass", - "without", - "stored.", - "response", - "headers", - "replayed", - "cache-hit", - "use", - "content-type", - "application", - "octet-stream", - "sinc" - ] - }, - { - "id": "http-examples-cache-wasi-rust#build", - "heading": "Build", - "level": 2, - "anchor": "build", - "line_start": 374, - "line_end": 378, - "keywords": [ - "build", - "cargo", - "--release", - "output", - "target", - "wasm32-wasip2", - "release", - "cache_wasi.wasm" - ] - }, - { - "id": "http-examples-cache-wasi-rust#apis-used", - "heading": "APIs used", - "level": 2, - "anchor": "apis-used", - "line_start": 379, - "line_end": 385, - "keywords": [ - "apis", - "used", - "fastedge", - "cache", - "get", - "key", - "retrieve", - "cached", - "bytes", - "returns", - "option", - "vec", - "set", - "ttl_ms", - "store", - "optional", - "ttl", - "milliseconds", - "none", - "means", - "expiry", - "wstd", - "http", - "client", - "new", - ".send", - "req", - ".await", - "async", - "outbound", - "request", - "origin" - ] } ] }, { "id": "http-examples-diagnostic-logging-wasi-rust", "title": "Diagnostic Logging — Rust (WASI HTTP)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-diagnostic-logging-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -23285,9 +23556,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "diagnostic-logging", @@ -23297,7 +23568,7 @@ "languages", "diagnostic" ], - "content_sha256": "b55cd1e2b402fa75e701e2336c62aa6314ec4be802409333a130cb1ffcbfe91c", + "content_sha256": "e0b1cfb99fd9375902a7ab410213218de42cf836f17460e19e3cef595ebc872b", "sections": [ { "id": "http-examples-diagnostic-logging-wasi-rust#introduction", @@ -23314,9 +23585,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "diagnostic-logging", @@ -23817,230 +24088,13 @@ "store", "usage" ] - }, - { - "id": "http-examples-diagnostic-logging-wasi-rust#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 194, - "line_end": 307, - "keywords": [ - "source", - "material", - "file", - "examples", - "http", - "wasi", - "diagnostic_logging", - "src", - "lib.rs", - "rust", - "copyright", - "2025", - "g-core", - "innovations", - "sarl", - "diagnostic", - "logging", - "example.", - "tiny", - "pass-through", - "proxy", - "writes", - "single", - "set_user_diag", - "tag", - "per", - "request", - "summarising", - "outcome", - "config_error", - "origin_unreachable", - "proxied", - "appears", - "fastedge", - "platform", - "per-request", - "log", - "viewer", - "distinct", - "stdout" - ] - }, - { - "id": "http-examples-diagnostic-logging-wasi-rust#configuration", - "heading": "Configuration", - "level": 2, - "anchor": "configuration", - "line_start": 308, - "line_end": 311, - "keywords": [ - "configuration", - "origin_url", - "environment", - "variable", - "origin", - "requests", - "proxied", - "to." - ] - }, - { - "id": "http-examples-diagnostic-logging-wasi-rust#outcomes", - "heading": "Outcomes", - "level": 2, - "anchor": "outcomes", - "line_start": 312, - "line_end": 321, - "keywords": [ - "outcomes", - "request", - "writes", - "exactly", - "one", - "condition", - "tag", - "---", - "origin_url", - "missing", - "outcome", - "config_error", - "reason", - "origin_missing", - "origin", - "unreachable", - "origin_unreachable", - "method", - "path", - "err", - "proxied", - "status" - ] - }, - { - "id": "http-examples-diagnostic-logging-wasi-rust#set_user_diag-vs-println", - "heading": "`set_user_diag` vs `println!`", - "level": 2, - "anchor": "set_user_diag-vs-println", - "line_start": 322, - "line_end": 330, - "keywords": [ - "set_user_diag", - "println", - "---", - "channel", - "stdout", - "general", - "application", - "logs", - "per-request", - "structured", - "tag", - "platform", - "log", - "viewer", - "cardinality", - "many", - "per", - "request", - "one", - "multiple", - "calls", - "leave", - "only", - "last", - "concatenated", - "undefined", - "best", - "verbose", - "traces", - "debug", - "details", - "single", - "filterable", - "outcome", - "label", - "forbidden", - "secrets", - "pii", - "tags", - "appear" - ] - }, - { - "id": "http-examples-diagnostic-logging-wasi-rust#convention", - "heading": "Convention", - "level": 2, - "anchor": "convention", - "line_start": 331, - "line_end": 336, - "keywords": [ - "convention", - "call", - "set_user_diag", - "once", - "branch", - "late", - "enough", - "handler", - "know", - "outcome.", - "logfmt", - "-ish", - "format", - "outcome", - "verb", - "key", - "value", - "easy", - "slice", - "log", - "search", - "tooling", - "keep", - "keys", - "short", - "stable", - "they", - "make", - "good", - "filter", - "terms." - ] - }, - { - "id": "http-examples-diagnostic-logging-wasi-rust#related", - "heading": "Related", - "level": 2, - "anchor": "related", - "line_start": 337, - "line_end": 342, - "keywords": [ - "related", - "cdn", - "proxy-wasm", - "variant", - "fastedge", - "proxywasm", - "utils", - "set_user_diag", - "same", - "semantics", - "different", - "module", - "path.", - "see", - "docs", - "cdn_apps.md" - ] } ] }, { "id": "http-examples-fetch-js", "title": "http-examples-fetch-js", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-fetch-js.md", "skill": "fastedge-docs", "category": "examples", @@ -24062,9 +24116,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "fetch", "outbound", "requests", @@ -24075,7 +24129,7 @@ "standard", "url" ], - "content_sha256": "032adc2beba6b9b9dade30fcf609e1febf5a9b7ddc47a88c37889d1eec835870", + "content_sha256": "9d09d5b86b672a1ceca9e554cda3515013cbfff850d242803d0014706b1e022f", "sections": [ { "id": "http-examples-fetch-js#introduction", @@ -24092,9 +24146,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20" + "2026-09-22" ] }, { @@ -24151,7 +24205,7 @@ { "id": "http-examples-geo-redirect-js", "title": "http-examples-geo-redirect-js", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-geo-redirect-js.md", "skill": "fastedge-docs", "category": "examples", @@ -24173,9 +24227,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "example", "geo-redirect", "redirects", @@ -24187,7 +24241,7 @@ "visitor", "country" ], - "content_sha256": "07208f0d1266ed5eecd1ac212b47f0a27cb432220881b2f7fac6a6d4aee0bbd4", + "content_sha256": "f1a1a79fa9a815fb6ded9e34dbccf9e56e95413f718fa7a5203871f4814e706c", "sections": [ { "id": "http-examples-geo-redirect-js#introduction", @@ -24204,9 +24258,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20" + "2026-09-22" ] }, { @@ -24264,7 +24318,7 @@ { "id": "http-examples-geo-redirect-wasi-rust", "title": "Geo Redirect — WASI HTTP (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-geo-redirect-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -24286,9 +24340,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -24298,7 +24352,7 @@ "geo-redirect", "headers" ], - "content_sha256": "92d1d6dcd29aa84e8c9a383b7f31e2a4c3550686a7586e2c164187596b5df709", + "content_sha256": "ebf328ce37861f9d7fe2fd1a9d745988abae0e3f0d80397151c464f8ed4182cc", "sections": [ { "id": "http-examples-geo-redirect-wasi-rust#introduction", @@ -24315,9 +24369,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -24890,7 +24944,7 @@ { "id": "http-examples-headers-js", "title": "http-examples-headers-js", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-headers-js.md", "skill": "fastedge-docs", "category": "examples", @@ -24912,9 +24966,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "headers", "example", "fastedge", @@ -24926,7 +24980,7 @@ "environment", "variable" ], - "content_sha256": "d4a5d1b949bfe5116aee65279e796b023d55d59544854876eaf493c110eef90c", + "content_sha256": "a375b46028720ee5a9a69d73ca41c1884f6ca1e34db5f2e2ef475340fef83f6c", "sections": [ { "id": "http-examples-headers-js#introduction", @@ -24943,9 +24997,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20" + "2026-09-22" ] }, { @@ -24997,7 +25051,7 @@ { "id": "http-examples-headers-wasi-rust", "title": "HTTP Headers Example — WASI (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-headers-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -25019,9 +25073,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -25031,7 +25085,7 @@ "headers", "env-vars" ], - "content_sha256": "b6142b5b461c8cc47c3422fa749ff3d7ca808ac8618aa481eaecd952f6b80483", + "content_sha256": "faa792bdc1043deed4c61b7b4e581f50616924995335ac4293a7722745dddd4b", "sections": [ { "id": "http-examples-headers-wasi-rust#introduction", @@ -25048,9 +25102,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -25646,7 +25700,7 @@ { "id": "http-examples-hello-world-basic-rust", "title": "Hello World — Basic HTTP (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-hello-world-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -25668,9 +25722,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -25680,7 +25734,7 @@ "hello-world", "basic-handler" ], - "content_sha256": "c3aac88e44de0d555bc462d6d70424ab34d4f0dec25606a2625ceb5e39b67400", + "content_sha256": "37e082cfacf1c690062e7464ba6b456feb35ca7e3c27e75c4182965562a648da", "sections": [ { "id": "http-examples-hello-world-basic-rust#introduction", @@ -25697,9 +25751,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -26078,7 +26132,7 @@ { "id": "http-examples-hello-world-wasi-rust", "title": "Example: Hello World (WASI) — Rust", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-hello-world-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -26100,9 +26154,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -26112,7 +26166,7 @@ "hello-world", "wasi" ], - "content_sha256": "b15ce34c19d4cf004bf6f602e6bf370c34f33abd962e77ce72f4bc13969016fe", + "content_sha256": "d6dc36ec9e0a07fbf165cb7912f5025529a82884768c0b4f9af1305288940b2b", "sections": [ { "id": "http-examples-hello-world-wasi-rust#introduction", @@ -26129,9 +26183,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -26530,7 +26584,7 @@ { "id": "http-examples-hono-js", "title": "Hono Patterns on FastEdge (JavaScript/TypeScript)", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-hono-js.md", "skill": "fastedge-docs", "category": "examples", @@ -26554,9 +26608,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "hono", "patterns", "fastedge", @@ -26565,7 +26619,7 @@ "apps.", "small" ], - "content_sha256": "4c75f73bbc6d7fbc5686f1d701a49ba1af7af0c650a910e3d47ae72272afdf1e", + "content_sha256": "4332733a5c2543a348bf8e164983d9f7e108418959d01ef10691440e45081d31", "sections": [ { "id": "http-examples-hono-js#introduction", @@ -26582,9 +26636,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "hono", "patterns", "fastedge", @@ -26811,7 +26865,7 @@ { "id": "http-examples-kv-store-js", "title": "http-examples-kv-store-js", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-kv-store-js.md", "skill": "fastedge-docs", "category": "examples", @@ -26833,9 +26887,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "store", "example", "reference", @@ -26847,7 +26901,7 @@ "fastedge", "edge" ], - "content_sha256": "bbee208b19ac9c128c58c2b3a483f133bf01d56becf4d62a328e664fb466c646", + "content_sha256": "bba21afe2826aed5c7c9e8f316219400c9ae56a59e1d5c0230c64196b8d85b88", "sections": [ { "id": "http-examples-kv-store-js#introduction", @@ -26864,9 +26918,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20" + "2026-09-22" ] }, { @@ -26922,7 +26976,7 @@ { "id": "http-examples-kv-store-wasi-rust", "title": "KV Store — Rust (WASI HTTP)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-kv-store-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -26944,9 +26998,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "kv-store", @@ -26956,7 +27010,7 @@ "languages", "store" ], - "content_sha256": "315969c42f8aa2c0325e094018cc3d59e5f68550acd5744a480b2302a15d0860", + "content_sha256": "828de5dab25ce52b865c81265bfcd8f41ea2c236d44bafb9045985ef9759cb95", "sections": [ { "id": "http-examples-kv-store-wasi-rust#introduction", @@ -26973,9 +27027,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "kv-store", @@ -27408,7 +27462,7 @@ { "id": "http-examples-large-env-variable-wasi-rust", "title": "Large Environment Variable (WASI) — Rust HTTP Example", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-large-env-variable-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -27430,9 +27484,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "large", "environment", "variable", @@ -27442,7 +27496,7 @@ "demonstrates", "read" ], - "content_sha256": "ab40bc5e1a189d77f212f789961be555b81ceead639067c4ccfbdc9f2e4e1d6c", + "content_sha256": "094c1dcce620b2e59578200c905580766b4a3800979c0e057d373e855651f1d1", "sections": [ { "id": "http-examples-large-env-variable-wasi-rust#introduction", @@ -27459,9 +27513,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "large", "environment", "variable", @@ -27797,7 +27851,7 @@ { "id": "http-examples-markdown-render-basic-rust", "title": "HTTP Example: Markdown Render (Rust, Basic)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-markdown-render-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -27819,9 +27873,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -27831,7 +27885,7 @@ "outbound-fetch", "env-vars" ], - "content_sha256": "e170431974501dcb609073b8be6b0f0c93a73841a33255b961077dec00c66f68", + "content_sha256": "bf7a3959832f6f6813babb0f96e471a0c68d3cbc420f6baa775c2e2229ce1329", "sections": [ { "id": "http-examples-markdown-render-basic-rust#introduction", @@ -27848,9 +27902,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -28323,7 +28377,7 @@ { "id": "http-examples-outbound-fetch-basic-rust", "title": "Example: Outbound Fetch — Basic HTTP (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-outbound-fetch-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -28345,9 +28399,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -28357,7 +28411,7 @@ "outbound-fetch", "json-parsing" ], - "content_sha256": "7d9b8470977ba554efeff699feeee8f078a5b682b5d396d070f0589f49f8044f", + "content_sha256": "9d41b008474919364325a73334175ac51ca10b8fbaabee8bee40b6415b2b8c9e", "sections": [ { "id": "http-examples-outbound-fetch-basic-rust#introduction", @@ -28374,9 +28428,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -28750,7 +28804,7 @@ { "id": "http-examples-outbound-fetch-wasi-rust", "title": "Outbound Fetch — WASI (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-outbound-fetch-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -28772,9 +28826,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "outbound", "fetch", "wasi", @@ -28784,7 +28838,7 @@ "upstream", "origin" ], - "content_sha256": "c5a6c3a406e12b4a82281f715d7f268d84b732cc76ec9376b34314302cea12dc", + "content_sha256": "57f3381591f07f1ac6daab49fe28d96aa6a757531829f89c225680550a56abfb", "sections": [ { "id": "http-examples-outbound-fetch-wasi-rust#introduction", @@ -28801,9 +28855,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "outbound", "fetch", "wasi", @@ -29200,7 +29254,7 @@ { "id": "http-examples-outbound-modify-response-wasi-rust", "title": "Example: Outbound Modify Response (WASI, Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-outbound-modify-response-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -29222,9 +29276,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -29234,7 +29288,7 @@ "outbound-fetch", "json-transform" ], - "content_sha256": "f6509335e7b9957b364049295ea3a84967dce13ae1e03c5ebbd8412f6e0dfb05", + "content_sha256": "f8cc2f72f5324a9da973c0e8eac43544bd59637ba3cbcd84ea858acd9de6596f", "sections": [ { "id": "http-examples-outbound-modify-response-wasi-rust#introduction", @@ -29251,9 +29305,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -29647,7 +29701,7 @@ { "id": "http-examples-print-basic-rust", "title": "Example: Print (HTTP Request Echo) — Rust", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-print-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -29669,9 +29723,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -29681,7 +29735,7 @@ "request-inspection", "header-iteration" ], - "content_sha256": "7c8720cc88a63e99432da519839a4f5b8438520df5ac92432b3c524afbaa1f85", + "content_sha256": "b33f1a09f2dca08a64f23ac6419b228e8de755a66bc4de6a66fffadee231998c", "sections": [ { "id": "http-examples-print-basic-rust#introduction", @@ -29698,9 +29752,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -30097,209 +30151,13 @@ "building", "patterns" ] - }, - { - "id": "http-examples-print-basic-rust#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 151, - "line_end": 214, - "keywords": [ - "source", - "material", - "file", - "examples", - "http", - "basic", - "print", - "src", - "lib.rs", - "rust", - "use", - "anyhow", - "result", - "fastedge", - "body", - "request", - "response", - "statuscode", - "allow", - "dead_code", - "main", - "req", - "let", - "mut", - "string", - "method", - ".to_string", - "body.push_str", - "req.method", - ".as_str", - "nurl", - "req.uri", - "nheaders" - ] - }, - { - "id": "http-examples-print-basic-rust#what-it-demonstrates", - "heading": "What it demonstrates", - "level": 2, - "anchor": "what-it-demonstrates", - "line_start": 215, - "line_end": 222, - "keywords": [ - "demonstrates", - "reading", - "request", - "method", - "via", - "req.method", - ".as_str", - "uri", - "req.uri", - ".to_string", - "iterating", - "headers", - "req.headers", - "handling", - "non-utf-8", - "header", - "values", - "gracefully", - "match", - "v.to_str", - "building", - "plain-text", - "response", - "builder", - "body", - "..." - ] - }, - { - "id": "http-examples-print-basic-rust#apis-used", - "heading": "APIs used", - "level": 2, - "anchor": "apis-used", - "line_start": 223, - "line_end": 233, - "keywords": [ - "apis", - "used", - "api", - "purpose", - "-----", - "---------", - "req.method", - ".as_str", - "http", - "method", - "string", - "slice", - "req.uri", - ".to_string", - "full", - "request", - "uri", - "req.headers", - "iterator", - "over", - "headername", - "headervalue", - "pairs", - "v.to_str", - "decode", - "header", - "value", - "str", - "returns", - "err", - "non-utf-8", - "response", - "builder", - ".status", - "...", - ".body", - "build", - "body", - "create" - ] - }, - { - "id": "http-examples-print-basic-rust#build", - "heading": "Build", - "level": 2, - "anchor": "build", - "line_start": 234, - "line_end": 240, - "keywords": [ - "build", - "cargo", - "--release", - "output", - "target", - "wasm32-wasip1", - "release", - "print.wasm" - ] - }, - { - "id": "http-examples-print-basic-rust#expected-behaviour", - "heading": "Expected behaviour", - "level": 2, - "anchor": "expected-behaviour", - "line_start": 241, - "line_end": 259, - "keywords": [ - "expected", - "behaviour", - "request", - "response", - "body", - "plain-text", - "dump", - "details", - "method", - "get", - "url", - "path", - "query", - "value", - "headers", - "host", - "example.com", - "accept", - "...", - "status", - "200", - "content", - "plain", - "text", - "content-type", - "header", - "set", - "explicitly", - "platform", - "add", - "one", - "appears", - "own", - "line", - "indented", - "four", - "spaces", - "non-utf-8", - "values", - "replaced" - ] } ] }, { "id": "http-examples-proxy-js", "title": "Proxy and Response Transform Patterns (JavaScript/TypeScript)", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-proxy-js.md", "skill": "fastedge-docs", "category": "examples", @@ -30323,9 +30181,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "proxy", "response", "transform", @@ -30334,7 +30192,7 @@ "fastedge", "apps" ], - "content_sha256": "cf79e7be2bb9093568bcf8495bf36926610c71e4cb36df51b122a605fdfb3725", + "content_sha256": "08a57d5d0098acb645f51c29d3f5850d1dad67ec7d808d89c78453d0323ec904", "sections": [ { "id": "http-examples-proxy-js#introduction", @@ -30351,9 +30209,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "proxy", "response", "transform", @@ -30787,356 +30645,13 @@ "kvstore", "api" ] - }, - { - "id": "http-examples-proxy-js#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 254, - "line_end": 264, - "keywords": [ - "source", - "material", - "file", - "docs", - "proxy_patterns.md", - "maintenance", - "hand-authored.", - "produced", - "fastedge-plugin-source", - "generate-docs.sh.", - "edit", - "directly.", - "proxy", - "response", - "transform", - "patterns", - "fastedge", - "http", - "apps", - "act", - "thin", - "front", - "origin", - "upstream", - "api", - "fetching", - "transforming", - "returning", - "result.", - "document", - "covers", - "common", - "patterns." - ] - }, - { - "id": "http-examples-proxy-js#simple-proxy", - "heading": "Simple Proxy", - "level": 2, - "anchor": "simple-proxy", - "line_start": 265, - "line_end": 291, - "keywords": [ - "simple", - "proxy", - "fetch", - "upstream", - "return", - "body", - "unchanged", - "typescript", - "async", - "function", - "handle", - "request", - "const", - "url", - "new", - "request.url", - "https", - "backend.example.com", - "url.pathname", - "url.search", - "response", - "await", - "method", - "request.method", - "headers", - "request.headers", - "get", - "head", - "request.arraybuffer", - "undefined", - "addeventlistener" - ] - }, - { - "id": "http-examples-proxy-js#proxy-with-json-transform", - "heading": "Proxy with JSON Transform", - "level": 2, - "anchor": "proxy-with-json-transform", - "line_start": 292, - "line_end": 320, - "keywords": [ - "proxy", - "json", - "transform", - "modify", - "response", - "body", - "returning", - "it.", - "pattern", - "examples", - "outbound-modify-response", - "typescript", - "async", - "function", - "handle", - "const", - "upstream", - "await", - "fetch", - "https", - "jsonplaceholder.typicode.com", - "users", - "upstream.json", - "transformed", - "users.slice", - "total", - "skip", - "limit", - "return", - "new", - "json.stringify", - "status", - "200", - "headers", - "content-type" - ] - }, - { - "id": "http-examples-proxy-js#hono-proxy-with-transform", - "heading": "Hono Proxy with Transform", - "level": 2, - "anchor": "hono-proxy-with-transform", - "line_start": 321, - "line_end": 351, - "keywords": [ - "hono", - "proxy", - "transform", - "inside", - "app", - "use", - "c.req.raw.headers", - "forward", - "inbound", - "headers", - "c.req.arraybuffer", - "body", - "typescript", - "import", - "const", - "new", - "app.all", - "api", - "async", - "url", - "c.req.url", - "upstream", - "https", - "backend.example.com", - "url.pathname", - "url.search", - "response", - "await", - "fetch", - "method", - "c.req.method", - "get", - "c.r" - ] - }, - { - "id": "http-examples-proxy-js#header-manipulation-in-proxies", - "heading": "Header Manipulation in Proxies", - "level": 2, - "anchor": "header-manipulation-in-proxies", - "line_start": 352, - "line_end": 380, - "keywords": [ - "header", - "manipulation", - "proxies", - "strip", - "hop-by-hop", - "headers", - "forwarding", - "upstream", - "add", - "diagnostic", - "way", - "back", - "typescript", - "async", - "function", - "handle", - "request", - "const", - "upstreamheaders", - "new", - "request.headers", - "forwarded", - "upstreamheaders.delete", - "connection", - "keep-alive", - "transfer-encoding", - "await", - "fetch", - "https", - "backend.example.com", - "method", - "request.m" - ] - }, - { - "id": "http-examples-proxy-js#cache-aware-proxy-with-kv", - "heading": "Cache-aware Proxy with KV", - "level": 2, - "anchor": "cache-aware-proxy-with-kv", - "line_start": 381, - "line_end": 413, - "keywords": [ - "cache-aware", - "proxy", - "cache", - "upstream", - "responses", - "store", - "avoid", - "repeated", - "outbound", - "calls.", - "note", - "read-only", - "app", - "code", - "writes", - "happen", - "via", - "portal", - "api", - "typescript", - "import", - "kvstore", - "fastedge", - "async", - "function", - "handle", - "request", - "const", - "url", - "new", - "request.url", - "try", - "kvstore.open", - "api-cache", - "cached", - "cache.get", - "url.pathname", - "null", - "return", - "response" - ] - }, - { - "id": "http-examples-proxy-js#operational-notes", - "heading": "Operational Notes", - "level": 2, - "anchor": "operational-notes", - "line_start": 414, - "line_end": 419, - "keywords": [ - "operational", - "notes", - "outbound", - "fetch", - "budget.", - "invocation", - "limited", - "number", - "requests", - "basic", - "pro", - "parallelise", - "possible", - "promise.all", - "...", - "instead", - "sequential", - "await", - "execution", - "time", - "proxying", - "upstream", - "transforming", - "counts", - "against", - "50ms", - "200ms", - "slow", - "upstreams", - "trip", - "532", - "timeouts.", - "body", - "size", - "limits.", - "inbound", - "bodies", - "subject", - "configured", - "request" - ] - }, - { - "id": "http-examples-proxy-js#see-also", - "heading": "See Also", - "level": 2, - "anchor": "see-also", - "line_start": 420, - "line_end": 428, - "keywords": [ - "see", - "examples", - "outbound-modify-response", - "json", - "transform", - "upstream", - "response", - "outbound-fetch", - "basic", - "outbound", - "fetch", - "patterns", - "headers", - "request", - "header", - "manipulation", - "kv-store", - "kv-backed", - "caching" - ] } ] }, { "id": "http-examples-s3upload-basic-rust", "title": "S3 Upload — HTTP Example (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-s3upload-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -31158,9 +30673,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -31170,7 +30685,7 @@ "s3-upload", "presigned-url" ], - "content_sha256": "a8c2d5d395a46515ff38614cfb280eb3ac460c00da9f34cd6c710cf4df130f29", + "content_sha256": "72cff95ae062275b261acaf37d03d72affe87facf10960cd16531237ff6bd4cf", "sections": [ { "id": "http-examples-s3upload-basic-rust#introduction", @@ -31187,9 +30702,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -31628,247 +31143,13 @@ "documentation", "external" ] - }, - { - "id": "http-examples-s3upload-basic-rust#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 186, - "line_end": 369, - "keywords": [ - "source", - "material", - "file", - "examples", - "http", - "basic", - "s3upload", - "src", - "lib.rs", - "rust", - "use", - "std", - "time", - "duration", - "fastedge", - "body", - "header", - "error", - "method", - "request", - "response", - "statuscode", - "rusty_s3", - "bucket", - "credentials", - "s3action", - "urlstyle", - "collections", - "hashmap", - "env", - "url", - "main", - "req", - "result", - "match", - "req.method", - "allow", - "only", - "post", - "put" - ] - }, - { - "id": "http-examples-s3upload-basic-rust#what-it-does", - "heading": "What it does", - "level": 2, - "anchor": "what-it-does", - "line_start": 370, - "line_end": 379, - "keywords": [ - "accepts", - "post", - "put", - "only", - "returns", - "405", - "methods", - "requires", - "name", - "filename", - "query", - "parameter", - "non-empty", - "body", - "400", - "otherwise", - "enforces", - "max_file_size", - "set", - "413", - "exceeded", - "calls", - "prepare_s3", - "build", - "1-hour", - "presigned", - "url", - "using", - "rusty_s3", - "forwards", - "file", - "via", - "fastedge", - "send_request", - "success", - "200", - "responds", - "clean", - "object", - "string" - ] - }, - { - "id": "http-examples-s3upload-basic-rust#configuration", - "heading": "Configuration", - "level": 2, - "anchor": "configuration", - "line_start": 380, - "line_end": 393, - "keywords": [ - "configuration", - "env", - "var", - "required", - "description", - "---", - "access_key", - "access", - "key", - "secret_key", - "secret", - "region", - "e.g.", - "s-ed1", - "base_hostname", - "base", - "hostname", - "cloud.gcore.lu", - "bucket", - "name", - "scheme", - "optional", - "url", - "defaults", - "http", - "max_file_size", - "maximum", - "upload", - "size", - "bytes", - "limit", - "unset", - "constructed", - "endpoint", - "bucke" - ] - }, - { - "id": "http-examples-s3upload-basic-rust#build", - "heading": "Build", - "level": 2, - "anchor": "build", - "line_start": 394, - "line_end": 400, - "keywords": [ - "build", - "cargo", - "--release", - "output", - "target", - "wasm32-wasip1", - "release", - "s3upload.wasm" - ] - }, - { - "id": "http-examples-s3upload-basic-rust#usage", - "heading": "Usage", - "level": 2, - "anchor": "usage", - "line_start": 401, - "line_end": 411, - "keywords": [ - "usage", - "post", - "upload", - "name", - "photo.jpg", - "content-type", - "image", - "jpeg", - "file", - "bytes", - "success", - "200", - "response", - "body", - "clean", - "object", - "url", - "presign", - "query", - "parameters", - "stripped" - ] - }, - { - "id": "http-examples-s3upload-basic-rust#notes", - "heading": "Notes", - "level": 2, - "anchor": "notes", - "line_start": 412, - "line_end": 418, - "keywords": [ - "notes", - "options", - "method", - "returns", - "204", - "include", - "cors", - "headers", - "add", - "access-control-allow-", - "browser", - "preflight", - "support", - "needed.", - "presigned", - "url", - "expires", - "hour", - "since", - "upload", - "performed", - "server-side", - "practical", - "impact.", - "max_file_size", - "silently", - "ignored", - "set", - "non-numeric", - "value." - ] } ] }, { "id": "http-examples-secret-basic-rust", "title": "Secret Access — Rust HTTP Example", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-secret-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -31890,9 +31171,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "secret", "access", "example", @@ -31902,7 +31183,7 @@ "fastedge", "platform" ], - "content_sha256": "99a13e72a317ae2f8118520b3f21a52ecaaacabefc6ae0000004391353e8c1fa", + "content_sha256": "1d1ae1d9f636c28df70129574cad04baf9b39ec87e640e902ed814f97a07d13b", "sections": [ { "id": "http-examples-secret-basic-rust#introduction", @@ -31919,9 +31200,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "secret", "access", "rust", @@ -32311,13 +31592,284 @@ "list", "delete" ] + }, + { + "id": "http-examples-secret-basic-rust#source-material", + "heading": "Source Material", + "level": 2, + "anchor": "source-material", + "line_start": 255, + "line_end": 368, + "keywords": [ + "source", + "material", + "file", + "examples", + "http", + "basic", + "secret", + "src", + "lib.rs", + "rust", + "use", + "anyhow", + "error", + "result", + "std", + "time", + "systemtime", + "fastedge", + "body", + "request", + "response", + "statuscode", + "allow", + "dead_code", + "main", + "_req", + "let", + "value", + "match", + "get", + "err", + "accessdenied", + "return", + "builder" + ] + }, + { + "id": "http-examples-secret-basic-rust#what-it-does", + "heading": "What it does", + "level": 2, + "anchor": "what-it-does", + "line_start": 369, + "line_end": 378, + "keywords": [ + "request", + "handler", + "calls", + "secret", + "get", + "retrieves", + "current", + "value", + "named", + "missing", + "returned", + "none", + "returns", + "404", + "get_effective_at", + "unix_ts", + "effective", + "unix", + "timestamp", + "demonstrating", + "rotation", + "versioning", + "api.", + "success", + "200", + "values", + "body", + "debug" + ] + }, + { + "id": "http-examples-secret-basic-rust#apis-used", + "heading": "APIs used", + "level": 2, + "anchor": "apis-used", + "line_start": 379, + "line_end": 389, + "keywords": [ + "apis", + "used", + "api", + "purpose", + "---", + "fastedge", + "http", + "sync", + "request-response", + "handler", + "macro", + "secret", + "get", + "key", + "retrieve", + "current", + "value", + "named", + "get_effective_at", + "timestamp", + "effective", + "specific", + "unix", + "error", + "variants", + "accessdenied", + "msg", + "decrypterror", + "request", + "response", + "statuscode", + "types", + "body", + "respo" + ] + }, + { + "id": "http-examples-secret-basic-rust#secret-error-variants", + "heading": "Secret error variants", + "level": 2, + "anchor": "secret-error-variants", + "line_start": 390, + "line_end": 399, + "keywords": [ + "secret", + "error", + "variants", + "variant", + "http", + "response", + "meaning", + "---", + "value", + "200", + "body", + "found", + "none", + "404", + "empty", + "name", + "valid", + "set", + "err", + "accessdenied", + "403", + "app", + "permitted", + "read", + "msg", + "denial", + "human-readable", + "message", + "decrypterror", + "500", + "exists", + "decrypted" + ] + }, + { + "id": "http-examples-secret-basic-rust#build", + "heading": "Build", + "level": 2, + "anchor": "build", + "line_start": 400, + "line_end": 406, + "keywords": [ + "build", + "cargo", + "--release", + "output", + "target", + "wasm32-wasip1", + "release", + "secret.wasm" + ] + }, + { + "id": "http-examples-secret-basic-rust#expected-behavior", + "heading": "Expected behavior", + "level": 2, + "anchor": "expected-behavior", + "line_start": 407, + "line_end": 416, + "keywords": [ + "expected", + "behavior", + "scenario", + "secret", + "response", + "status", + "body", + "---", + "happy", + "path", + "my-value", + "200", + "get", + "nget_efective_at", + "set", + "absent", + "404", + "empty", + "access", + "denied", + "403", + "note", + "contains", + "typo", + "field", + "name", + "get_efective_at", + "instead", + "get_effective_at", + "known", + "cosmetic", + "issue", + "source." + ] + }, + { + "id": "http-examples-secret-basic-rust#local-testing", + "heading": "Local testing", + "level": 2, + "anchor": "local-testing", + "line_start": 417, + "line_end": 434, + "keywords": [ + "local", + "testing", + "inject", + "secret", + "via", + ".env", + "file", + "your", + "fixtures", + "directory", + "using", + "fastedge_var_secret_", + "name", + "prefix", + "fastedge_var_secret_secret", + "my-test-value", + "run", + "fixture", + "validator", + "node", + "tools", + "fixture-validator", + "index.mjs", + "fastedge-sdk-rust", + "examples", + "http", + "basic", + "--wasm", + "target", + "wasm32-wasip1", + "release", + "secret.wasm" + ] } ] }, { "id": "http-examples-secret-rollover-wasi-rust", "title": "Secret Rollover (WASI, Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-secret-rollover-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -32339,9 +31891,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "secret", "rollover", "wasi", @@ -32352,7 +31904,7 @@ "rotation", "using" ], - "content_sha256": "535ab5dbaa52d9d716c1762d05b466c6182ff507db6ec46650bf241318a0fb65", + "content_sha256": "2cd00d58e3f6047c79cb57ea352f8e2684f86dec50a7357dadfe62d4bf0d8151", "sections": [ { "id": "http-examples-secret-rollover-wasi-rust#introduction", @@ -32369,9 +31921,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "secret", "rollover", "wasi", @@ -32627,7 +32179,7 @@ "level": 2, "anchor": "implementation-pattern", "line_start": 124, - "line_end": 178, + "line_end": 177, "keywords": [ "implementation", "pattern", @@ -32653,20 +32205,19 @@ "result", "read", "slot", + "x-slot", "header", - "default", + "defaulting", "current", - "unix", "timestamp", "let", "u32", ".headers", ".get", - "x-slot", ".and_then", "v.to_str", ".ok", - "v.p" + ".and" ] }, { @@ -32674,8 +32225,8 @@ "heading": "Constraints and Gotchas", "level": 2, "anchor": "constraints-and-gotchas", - "line_start": 179, - "line_end": 186, + "line_start": 178, + "line_end": 185, "keywords": [ "constraints", "gotchas", @@ -32724,8 +32275,8 @@ "heading": "Build", "level": 2, "anchor": "build", - "line_start": 187, - "line_end": 193, + "line_start": 186, + "line_end": 192, "keywords": [ "build", "cargo", @@ -32742,8 +32293,8 @@ "heading": "See Also", "level": 2, "anchor": "see-also", - "line_start": 194, - "line_end": 200, + "line_start": 193, + "line_end": 199, "keywords": [ "see", "fastedge", @@ -32774,7 +32325,7 @@ { "id": "http-examples-simple-fetch-wasi-rust", "title": "Example: Simple Fetch (WASI HTTP, Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-simple-fetch-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -32796,9 +32347,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -32808,7 +32359,7 @@ "outbound-fetch", "header-read" ], - "content_sha256": "d8d6a23390c7c0c319f1e3e0db70657d19a195129c9633d73217efa35f1408b3", + "content_sha256": "ff728af48b322c2e67a2a06dd8e555818382d4535f559f6cf83b2f14e6732db5", "sections": [ { "id": "http-examples-simple-fetch-wasi-rust#introduction", @@ -32825,9 +32376,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -32901,7 +32452,7 @@ "level": 2, "anchor": "request-headers", "line_start": 30, - "line_end": 35, + "line_end": 36, "keywords": [ "request", "headers", @@ -32923,7 +32474,14 @@ "httpbin.org", "get", "fetch", - "outbound" + "outbound", + "x-fetch-header", + "key", + "value", + "additional", + "forward", + "parsed", + "separator" ] }, { @@ -32931,8 +32489,8 @@ "heading": "Behavior", "level": 2, "anchor": "behavior", - "line_start": 36, - "line_end": 42, + "line_start": 37, + "line_end": 45, "keywords": [ "behavior", "read", @@ -32947,27 +32505,33 @@ "get", "absent", "unparseable.", - "build", + "begin", + "building", "outbound", "url", "accept", "application", "json", "header.", + "x-fetch-header", + "present", + "parseable", + "key", + "value", + "split", + "first", + "add", + "builder.", + "finalize", + "builder", + ".body", + "body", + "empty", "send", "via", "client", "new", - ".send", - "req", - ".await", - "return", - "upstream", - "response", - "body", - "directly", - "caller", - "decomposition." + ".send" ] }, { @@ -32975,8 +32539,8 @@ "heading": "Key API Patterns", "level": 2, "anchor": "key-api-patterns", - "line_start": 43, - "line_end": 99, + "line_start": 46, + "line_end": 122, "keywords": [ "key", "api", @@ -33025,8 +32589,8 @@ "heading": "Logging", "level": 2, "anchor": "logging", - "line_start": 100, - "line_end": 109, + "line_start": 123, + "line_end": 132, "keywords": [ "logging", "rust", @@ -33049,8 +32613,8 @@ "heading": "Cargo.toml Requirements", "level": 2, "anchor": "cargotoml-requirements", - "line_start": 110, - "line_end": 126, + "line_start": 133, + "line_end": 149, "keywords": [ "cargo.toml", "requirements", @@ -33083,8 +32647,8 @@ "heading": "WASI vs Basic HTTP Comparison", "level": 2, "anchor": "wasi-vs-basic-http-comparison", - "line_start": 127, - "line_end": 135, + "line_start": 150, + "line_end": 158, "keywords": [ "wasi", "basic", @@ -33121,8 +32685,8 @@ "heading": "Gotchas", "level": 2, "anchor": "gotchas", - "line_start": 136, - "line_end": 143, + "line_start": 159, + "line_end": 168, "keywords": [ "gotchas", "url", @@ -33151,19 +32715,17 @@ "values", "silently", "discarded", - "anyhow", - "declared", - "dependency", - "use", - "macro.", - "examples", - "http", - "wasi", - "same", - "async", - "main", - "wstd", - "http_server" + "x-fetch-header", + "parsed", + ".split_once", + "only", + "first", + "used", + "separator", + "containing", + "preserved", + "correctly.", + "build" ] }, { @@ -33171,8 +32733,8 @@ "heading": "See Also", "level": 2, "anchor": "see-also", - "line_start": 144, - "line_end": 150, + "line_start": 169, + "line_end": 175, "keywords": [ "see", "fastedge-docs", @@ -33192,13 +32754,193 @@ "host", "services" ] + }, + { + "id": "http-examples-simple-fetch-wasi-rust#source-material", + "heading": "Source Material", + "level": 2, + "anchor": "source-material", + "line_start": 176, + "line_end": 271, + "keywords": [ + "source", + "material", + "file", + "examples", + "http", + "wasi", + "simple_fetch", + "src", + "lib.rs", + "rust", + "copyright", + "2025", + "g-core", + "innovations", + "sarl", + "example", + "app", + "demonstrating", + "wasi-http", + "interface", + "via", + "wstd", + "crate.", + "receives", + "incoming", + "request", + "makes", + "outbound", + "url", + "specified", + "x-fetch-url", + "header", + "defaults", + "https", + "httpbin.org", + "get", + "build", + "cargo-component", + "cargo", + "component" + ] + }, + { + "id": "http-examples-simple-fetch-wasi-rust#how-it-works", + "heading": "How it works", + "level": 2, + "anchor": "how-it-works", + "line_start": 272, + "line_end": 277, + "keywords": [ + "works", + "app", + "receives", + "incoming", + "request", + "reads", + "target", + "url", + "x-fetch-url", + "header", + "makes", + "outbound", + "get", + "streams", + "response", + "back", + "caller.", + "absent", + "defaults", + "https", + "httpbin.org" + ] + }, + { + "id": "http-examples-simple-fetch-wasi-rust#request-headers", + "heading": "Request headers", + "level": 2, + "anchor": "request-headers", + "line_start": 278, + "line_end": 283, + "keywords": [ + "request", + "headers", + "header", + "required", + "description", + "--------", + "----------", + "-------------", + "x-fetch-url", + "url", + "fetch.", + "defaults", + "https", + "httpbin.org", + "get" + ] + }, + { + "id": "http-examples-simple-fetch-wasi-rust#example", + "heading": "Example", + "level": 2, + "anchor": "example", + "line_start": 284, + "line_end": 289, + "keywords": [ + "example", + "bash", + "curl", + "x-fetch-url", + "https", + "httpbin.org", + "uuid", + "your-app-domain" + ] + }, + { + "id": "http-examples-simple-fetch-wasi-rust#build", + "heading": "Build", + "level": 2, + "anchor": "build", + "line_start": 290, + "line_end": 296, + "keywords": [ + "build", + "bash", + "cargo", + "--release", + "output", + "target", + "wasm32-wasip2", + "release", + "simple_fetch.wasm" + ] + }, + { + "id": "http-examples-simple-fetch-wasi-rust#key-differences-from-basic-http-examples", + "heading": "Key differences from basic HTTP examples", + "level": 2, + "anchor": "key-differences-from-basic-http-examples", + "line_start": 297, + "line_end": 306, + "keywords": [ + "key", + "differences", + "basic", + "http", + "examples", + "fastedge", + "crate", + "wasi", + "wstd", + "---", + "handler", + "main", + "req", + "sync", + "async", + "macro", + "http_server", + "outbound", + "send_request", + "client", + "new", + ".send", + ".await", + "build", + "target", + "wasm32-wasip1", + "wasm32-wasip2" + ] } ] }, { "id": "http-examples-smart-switch-basic-rust", "title": "Example: Smart Switch (Basic HTTP, Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-smart-switch-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -33220,9 +32962,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -33232,7 +32974,7 @@ "outbound-http", "env-vars" ], - "content_sha256": "3195fb4f9d583f55e2834ef95604d838f310817302a02705bec7c99b51685485", + "content_sha256": "c6819909d1d3bae6f1ad77d1911a32135ca0630d1e21028c5ff44435274e40ee", "sections": [ { "id": "http-examples-smart-switch-basic-rust#introduction", @@ -33249,9 +32991,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -33665,7 +33407,7 @@ { "id": "http-examples-static-assets-wasi-rust", "title": "Static Assets — WASI (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-static-assets-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -33689,9 +33431,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -33701,7 +33443,7 @@ "static-assets", "routing" ], - "content_sha256": "dcefd9ae20154d629c0a4b74b11bb152c2e0ddd0712407cb4ead1a03002ede52", + "content_sha256": "39d87feeba8b9d276b0f9d5d32b54faf0196b3dfd31a1aec8b88b3328960cbe2", "sections": [ { "id": "http-examples-static-assets-wasi-rust#introduction", @@ -33718,9 +33460,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -34267,7 +34009,7 @@ { "id": "http-examples-streaming-wasi-rust", "title": "Streaming Response — WASI (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-streaming-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -34289,9 +34031,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -34301,7 +34043,7 @@ "streaming", "async" ], - "content_sha256": "37832c99ab707686c986f78e014d061a2cd98753ae825dfc69b21c6217efd5fd", + "content_sha256": "fcd87ce4100ea3343d0f2b4543cce45409c480b856f3ded1838b4d752a43e3ea", "sections": [ { "id": "http-examples-streaming-wasi-rust#introduction", @@ -34318,9 +34060,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -34649,13 +34391,151 @@ "fastedge", "sdk" ] + }, + { + "id": "http-examples-streaming-wasi-rust#source-material", + "heading": "Source Material", + "level": 2, + "anchor": "source-material", + "line_start": 147, + "line_end": 225, + "keywords": [ + "source", + "material", + "file", + "examples", + "http", + "wasi", + "streaming", + "src", + "lib.rs", + "rust", + "copyright", + "2025", + "g-core", + "innovations", + "sarl", + "response", + "example.", + "generates", + "body", + "fly", + "five", + "text", + "chunks", + "one", + "200ms", + "using", + "from_stream", + "backed", + "futures_lite", + "stream", + "runtime", + "polls", + "sent", + "flow", + "client", + "they", + "produced", + "instead", + "once", + "end." + ] + }, + { + "id": "http-examples-streaming-wasi-rust#testing-the-streaming-behaviour", + "heading": "Testing the streaming behaviour", + "level": 2, + "anchor": "testing-the-streaming-behaviour", + "line_start": 226, + "line_end": 234, + "keywords": [ + "testing", + "streaming", + "behaviour", + "curl", + "https", + "your-app", + ".fastedge.cdn.gc.onl", + "disables", + "client-side", + "buffering", + "without", + "you", + "won", + "see", + "chunks", + "appear", + "one", + "time.", + "chunk", + "print", + "200ms", + "intervals." + ] + }, + { + "id": "http-examples-streaming-wasi-rust#other-streaming-patterns", + "heading": "Other streaming patterns", + "level": 2, + "anchor": "other-streaming-patterns", + "line_start": 235, + "line_end": 243, + "keywords": [ + "streaming", + "patterns", + "pass-through", + "return", + "upstream", + "response", + "body", + "directly.", + "see", + "outbound_fetch", + "no-buffer", + "variant.", + "transform", + "use", + "http_body_util", + "bodyext", + "map_frame", + "incoming", + "from_http_body", + "wrap", + "back.", + "useful", + "chunk-level", + "rewrites.", + "stream", + "bytes", + "from_stream", + "futures_lite", + "iter", + "chunks", + "iterable" + ] + }, + { + "id": "http-examples-streaming-wasi-rust#related", + "heading": "Related", + "level": 2, + "anchor": "related", + "line_start": 244, + "line_end": 248, + "keywords": [ + "related", + "mirror", + "fastedge-sdk-js", + "examples", + "streaming" + ] } ] }, { "id": "http-examples-variables-and-secrets-wasi-rust", "title": "Variables and Secrets — WASI (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-variables-and-secrets-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -34677,9 +34557,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -34689,7 +34569,7 @@ "env-vars", "secrets" ], - "content_sha256": "9d8807dc93609399f430a94d714047bb9d9458bc07f16c18e6a0814c194ffb94", + "content_sha256": "6437dc0501dd6889d30bfd370a0d370c4211dbad78063f0d8e1981a360070c6d", "sections": [ { "id": "http-examples-variables-and-secrets-wasi-rust#introduction", @@ -34706,9 +34586,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -35165,7 +35045,7 @@ { "id": "http-examples-watermark-basic-rust", "title": "HTTP Example: Watermark (Basic, Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-watermark-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -35187,9 +35067,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "example", "watermark", "basic", @@ -35199,7 +35079,7 @@ "handler", "fastedge" ], - "content_sha256": "1fee467e8245bcae3adf9bcb0e06e0dda564403fccf9374939f5a72c90358ab3", + "content_sha256": "3b885f5aaf85aabb9c3cc0ee1f3c2133bd266f799afb7defc58d391825e6adaf", "sections": [ { "id": "http-examples-watermark-basic-rust#introduction", @@ -35216,9 +35096,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "http", "example", "watermark", @@ -35740,7 +35620,7 @@ { "id": "js-runtime", "title": "FastEdge JS Runtime — Constraints & Compatibility", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/js-runtime.md", "skill": "fastedge-docs", "category": "platform", @@ -35756,9 +35636,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "runtime", "constraints", @@ -35770,7 +35650,7 @@ "particularly", "affecting" ], - "content_sha256": "cac0e481a35b2a82d139b5878410a53c91f3f39c30c0190dd1a4ae6a1b229904", + "content_sha256": "f6077c39210df74e17ef03a34f4e5ba18b9d0e1a8857e120c393a98b85ee0b48", "sections": [ { "id": "js-runtime#introduction", @@ -35787,9 +35667,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "runtime", "constraints", @@ -37079,6 +36959,348 @@ } ] }, + { + "id": "platform-cdn-filter-runtime", + "title": "CDN Filter Runtime — Capabilities and Traps", + "description": "What a proxy-wasm filter (CDN app) can and cannot do on FastEdge, and the host behaviours that silently differ from generic proxy-wasm or from HTTP apps. **Read this before designing or reviewing a CDN app** — most items here are invisible in local tests and only surface on a dep", + "path": "reference/fastedge-docs/platform/cdn-filter-runtime.md", + "skill": "fastedge-docs", + "category": "platform", + "app_types": [], + "languages": [], + "tags": [ + "platform", + "fastedge-docs", + "cdn", + "filter", + "runtime", + "capabilities", + "traps", + "proxy-wasm", + "app", + "cannot", + "fastedge", + "host", + "behaviours", + "silently", + "differ", + "generic", + "http", + "apps.", + "read", + "designing", + "reviewing", + "items" + ], + "content_sha256": "6279754b693e44807306ef152f9b733bb0a575ece2390a0bccb5755b2be9799e", + "sections": [ + { + "id": "platform-cdn-filter-runtime#introduction", + "heading": "Introduction", + "level": 1, + "anchor": "introduction", + "line_start": 1, + "line_end": 15, + "keywords": [ + "cdn", + "filter", + "runtime", + "capabilities", + "traps", + "proxy-wasm", + "app", + "cannot", + "fastedge", + "host", + "behaviours", + "silently", + "differ", + "generic", + "http", + "apps.", + "read", + "designing", + "reviewing", + "items", + "here", + "invisible", + "local", + "tests", + "only", + "surface", + "deployed", + "app.", + "claim", + "carries", + "provenance", + "tag", + "meaning", + "---", + "live", + "measured", + "against", + "real", + "resource", + "source" + ] + }, + { + "id": "platform-cdn-filter-runtime#capability-boundary-—-filter-vs-http-app", + "heading": "Capability boundary — filter vs HTTP app", + "level": 2, + "anchor": "capability-boundary-—-filter-vs-http-app", + "line_start": 16, + "line_end": 41, + "keywords": [ + "capability", + "boundary", + "filter", + "http", + "app", + "core", + "wasm", + "module", + "linked", + "against", + "proxy-wasm", + "env", + "abi.", + "different", + "execution", + "world", + "subset", + "it.", + "designs", + "assume", + "symmetry", + "http-app", + "sdk", + "fail", + "deploy.", + "cdn", + "---", + "read", + "same", + "six", + "operations", + "open", + "get", + "scan", + "zrange_by_score", + "zscan", + "bf_exists", + "source", + "write", + "api" + ] + }, + { + "id": "platform-cdn-filter-runtime#reading-the-request-—-use-properties-not-headers", + "heading": "Reading the request — use properties, not headers", + "level": 2, + "anchor": "reading-the-request-—-use-properties-not-headers", + "line_start": 42, + "line_end": 69, + "keywords": [ + "reading", + "request", + "use", + "properties", + "headers", + "several", + "proxy-wasm", + "developer", + "reach", + "mangled", + "absent.", + "failures", + "silent", + "live", + "read", + "via", + "result", + "---", + "property", + "request.host", + "clean", + "client-requested", + "host", + "origin", + "rewrite", + "edge", + "tier", + "shield", + "nodes", + "carry", + "shield_", + "prefix", + "request.x_real_ip", + "true", + "client", + "ipv4", + "ipv6", + "request.path", + "includes", + "query" + ] + }, + { + "id": "platform-cdn-filter-runtime#security-—-gating-filters", + "heading": "Security — gating filters", + "level": 2, + "anchor": "security-—-gating-filters", + "line_start": 70, + "line_end": 105, + "keywords": [ + "security", + "gating", + "filters", + "cdn", + "normalise", + "path", + "filter", + "runs", + "live", + "traversal", + "separator", + "sequences", + "arrive", + "verbatim", + "bash", + "curl", + "--path-as-is", + "...", + "app", + "test", + "request.path", + "bypasses", + "auth", + "prefix", + "public", + "wave", + "admin", + "origin", + "back", + "authentication", + "bypass" + ] + }, + { + "id": "platform-cdn-filter-runtime#synthetic-responses", + "heading": "Synthetic responses", + "level": 2, + "anchor": "synthetic-responses", + "line_start": 106, + "line_end": 111, + "keywords": [ + "synthetic", + "responses", + "live", + "filter", + "serve", + "complete", + "response", + "via", + "send_http_response", + "status", + "arbitrary", + "headers", + "multiple", + "set-cookie", + "one", + "bodies", + "least", + "without", + "truncation.", + "single-app", + "designs", + "challenge", + "pages", + "interstitials", + "error", + "second", + "http", + "app.", + "---" + ] + }, + { + "id": "platform-cdn-filter-runtime#what-local-testing-cannot-prove", + "heading": "What local testing cannot prove", + "level": 2, + "anchor": "what-local-testing-cannot-prove", + "line_start": 112, + "line_end": 117, + "keywords": [ + "local", + "testing", + "cannot", + "prove", + "gcoredev", + "fastedge-test", + "runs", + "proxy-wasm", + "filters", + "locally", + "proves", + "flow", + "logic", + "routing", + "header", + "manipulation", + "gate", + "decisions.", + "host", + "behaviour", + "property", + "semantics", + "mangling", + "path", + "non-normalisation", + "instantiation", + "failures", + "cache", + "interaction.", + "trap", + "page", + "passes", + "suite", + "green.", + "confirm", + "host-dependent", + "deployed", + "app", + "attached", + "real" + ] + }, + { + "id": "platform-cdn-filter-runtime#see-also", + "heading": "See Also", + "level": 2, + "anchor": "see-also", + "line_start": 118, + "line_end": 123, + "keywords": [ + "see", + "storage.md", + "cache", + "semantics", + "limits", + "measured", + "performance", + "cdn-integration.md", + "attaching", + "filters", + "cdn", + "resources", + "error-codes.md", + "530", + "diagnosis" + ] + } + ] + }, { "id": "platform-cdn-integration", "title": "CDN Integration — Attaching FastEdge Apps to CDN Resources", @@ -37117,7 +37339,7 @@ "effect", "app" ], - "content_sha256": "6cb942fb6413ec2d1faf71699c0e79ea10e04ccc089ed9e49aee100e7a6623fe", + "content_sha256": "e36fbf654e7eb8d595bd084a7fa6577ef61114287351099e7ccaa99cdf0f9eb6", "sections": [ { "id": "platform-cdn-integration#introduction", @@ -37272,7 +37494,7 @@ "level": 2, "anchor": "reading-and-updating", "line_start": 157, - "line_end": 185, + "line_end": 202, "keywords": [ "reading", "updating", @@ -37310,8 +37532,8 @@ "heading": "Operational Notes", "level": 2, "anchor": "operational-notes", - "line_start": 186, - "line_end": 195, + "line_start": 203, + "line_end": 212, "keywords": [ "operational", "notes", @@ -37358,8 +37580,8 @@ "heading": "See Also", "level": 2, "anchor": "see-also", - "line_start": 196, - "line_end": 203, + "line_start": 213, + "line_end": 220, "keywords": [ "see", "rust", @@ -37436,7 +37658,7 @@ "distinguish", "edge" ], - "content_sha256": "d47de15e41e07d9b842b6690558f41b840a4121f7ec91a85c4d86d1dc966a436", + "content_sha256": "e0561d0b112db5f5f509a1ce16da82dedfa2cea834283fcf1b6102a118136876", "sections": [ { "id": "platform-error-codes#introduction", @@ -37489,7 +37711,7 @@ "level": 2, "anchor": "530-—-app-initialization-failed", "line_start": 9, - "line_end": 29, + "line_end": 38, "keywords": [ "530", "app", @@ -37501,35 +37723,36 @@ "start", "processing", "request.", + "signal", + "cdn", + "fails", + "instantiate", + "returns", + "x-cdn-internal-status", + "3100", + "header", + "distinguishes", + "ran", + "errored", + "531", "common", "causes", - "missing", - "required", - "environment", - "variables", - "reads", - "corrupted", - "invalid", + "unresolved", + "imports", + "apps", "binary", - "compiled", - "wrong", - "target", - "wasm32-wasip1", - "large", - "platform", - "rejects", - "uploads", - "beyond", - "50mb", - "investigate", - "bundled", - "debugging", - "steps", - "verify", - "built", - "correctly", - "fastedge-build", - "src" + "host", + "function", + "proxy-wasm", + "provide", + "commonly", + "http-app", + "component-model", + "api", + "used", + "filter", + "e.g.", + "top-leve" ] }, { @@ -37537,8 +37760,8 @@ "heading": "531 — Runtime Error", "level": 2, "anchor": "531-—-runtime-error", - "line_start": 30, - "line_end": 61, + "line_start": 39, + "line_end": 71, "keywords": [ "531", "runtime", @@ -37554,6 +37777,19 @@ "processing.", "common", "causes", + "calling", + "getenv", + "getsecret", + "module", + "top", + "level", + "they", + "request-time", + "only", + "call", + "them", + "inside", + "handler", "uncaught", "javascript", "typeerror", @@ -37566,20 +37802,7 @@ "err", "failed", "fetch", - "call", - "without", - "handling", - "json", - "parse", - "malformed", - "body", - "accessing", - "undefined", - "properties", - "debugging", - "steps", - "test", - "locally" + "without" ] }, { @@ -37587,8 +37810,8 @@ "heading": "532 — Timeout Exceeded", "level": 2, "anchor": "532-—-timeout-exceeded", - "line_start": 62, - "line_end": 93, + "line_start": 72, + "line_end": 103, "keywords": [ "532", "timeout", @@ -37637,8 +37860,8 @@ "heading": "533 — Memory Limit Exceeded", "level": 2, "anchor": "533-—-memory-limit-exceeded", - "line_start": 94, - "line_end": 122, + "line_start": 104, + "line_end": 132, "keywords": [ "533", "memory", @@ -37687,8 +37910,8 @@ "heading": "General Debugging Strategy", "level": 2, "anchor": "general-debugging-strategy", - "line_start": 123, - "line_end": 131, + "line_start": 133, + "line_end": 141, "keywords": [ "general", "debugging", @@ -38283,7 +38506,7 @@ "instantiates", "app" ], - "content_sha256": "98c4a8456ad2cedcb63fe13b4f4556e3b0a8b09ab2a621f0111a59b942d65cb8", + "content_sha256": "350d18b69668668c510056232b304d8bb3d9d3354bfc1493438b059d93d586b6", "sections": [ { "id": "platform-overview#introduction", @@ -38485,7 +38708,7 @@ "level": 2, "anchor": "request-lifecycle", "line_start": 93, - "line_end": 101, + "line_end": 109, "keywords": [ "request", "lifecycle", @@ -38518,7 +38741,15 @@ "instance", "destroyed", "memory", - "freed" + "freed", + "scheduled", + "deferred", + "work", + "there", + "scheduler", + "durable", + "background", + "execution." ] }, { @@ -38526,8 +38757,8 @@ "heading": "Resource Limits", "level": 2, "anchor": "resource-limits", - "line_start": 102, - "line_end": 115, + "line_start": 110, + "line_end": 123, "keywords": [ "resource", "limits", @@ -38576,8 +38807,8 @@ "heading": "Plans", "level": 2, "anchor": "plans", - "line_start": 116, - "line_end": 120, + "line_start": 124, + "line_end": 128, "keywords": [ "plans", "basic", @@ -38599,8 +38830,8 @@ "heading": "App Statuses", "level": 2, "anchor": "app-statuses", - "line_start": 121, - "line_end": 128, + "line_start": 129, + "line_end": 136, "keywords": [ "app", "statuses", @@ -38620,8 +38851,8 @@ "heading": "Networking", "level": 2, "anchor": "networking", - "line_start": 129, - "line_end": 135, + "line_start": 137, + "line_end": 143, "keywords": [ "networking", "apps", @@ -38652,8 +38883,8 @@ "heading": "Logging & Monitoring", "level": 2, "anchor": "logging-&-monitoring", - "line_start": 136, - "line_end": 141, + "line_start": 144, + "line_end": 149, "keywords": [ "logging", "monitoring", @@ -38679,6 +38910,261 @@ } ] }, + { + "id": "platform-storage", + "title": "Storage Semantics — KV Store and Cache", + "description": "Behaviour of FastEdge's two storage primitives that the SDK references do not state: consistency, write shapes, TTL rules, missing operations, and measured performance. Applies to HTTP apps and CDN filters unless noted. For the per-language API, see the SDK reference for your lan", + "path": "reference/fastedge-docs/platform/storage.md", + "skill": "fastedge-docs", + "category": "platform", + "app_types": [], + "languages": [], + "tags": [ + "platform", + "fastedge-docs", + "storage", + "semantics", + "store", + "cache", + "behaviour", + "fastedge", + "two", + "primitives", + "sdk", + "references", + "state", + "consistency", + "write", + "shapes", + "ttl", + "rules", + "missing", + "operations", + "measured", + "performance." + ], + "content_sha256": "65116f9b1f97e5e14b18ff2a6af86b58e926d192ad3101290e37fd23e8db5d3e", + "sections": [ + { + "id": "platform-storage#introduction", + "heading": "Introduction", + "level": 1, + "anchor": "introduction", + "line_start": 1, + "line_end": 15, + "keywords": [ + "storage", + "semantics", + "store", + "cache", + "behaviour", + "fastedge", + "two", + "primitives", + "sdk", + "references", + "state", + "consistency", + "write", + "shapes", + "ttl", + "rules", + "missing", + "operations", + "measured", + "performance.", + "applies", + "http", + "apps", + "cdn", + "filters", + "unless", + "noted.", + "per-language", + "api", + "see", + "reference", + "your", + "language.", + "---", + "scope", + "global", + "account-level", + "assigned", + "per-pop", + "shared" + ] + }, + { + "id": "platform-storage#kv-store", + "heading": "KV Store", + "level": 2, + "anchor": "kv-store", + "line_start": 16, + "line_end": 58, + "keywords": [ + "store", + "get", + "cached", + "read", + "per", + "node", + "live", + "production", + "key", + "populates", + "per-node", + "cache", + "entry", + "lives", + "whether", + "existed", + "until", + "expires", + "keeps", + "returning", + "old", + "result", + "value", + "absent", + "now", + "exists.", + "sorted-set", + "reads", + "zrangebyscore", + "reflect", + "writes", + "write", + "visible", + "---", + "none", + "create", + "heavy", + "pol" + ] + }, + { + "id": "platform-storage#cache", + "heading": "Cache", + "level": 2, + "anchor": "cache", + "line_start": 59, + "line_end": 82, + "keywords": [ + "cache", + "interface", + "atomicity", + "source", + "get", + "set", + "delete", + "exists", + "incr", + "expire", + "purge", + "purge_prefix", + "only", + "atomic", + "primitive", + "compare-and-set", + "setnx", + "scripting", + "multi-key", + "operations", + "scan", + "coordination", + "expressible", + "increment", + "compare", + "returned", + "value", + "ttl", + "rules", + "live", + "ttls", + "silently", + "clamped", + "deployment", + "ceiling", + "default", + "days", + "rust", + "sdk", + "references" + ] + }, + { + "id": "platform-storage#measured-performance", + "heading": "Measured performance", + "level": 2, + "anchor": "measured-performance", + "line_start": 83, + "line_end": 103, + "keywords": [ + "measured", + "performance", + "live", + "production", + "point-in-time", + "one", + "account", + "mostly", + "pop", + "evidence", + "guarantees.", + "metric", + "value", + "---", + "cache.incr", + "p50", + "p95", + "max", + "102", + "cache.expire", + "write", + "visible", + "prior", + "get", + "polling", + "107", + "min", + "rate", + "client", + "sustained", + "writes", + "sorted-set", + "ingest", + "450", + "members", + "knee", + "concurrent", + "writers", + "largest", + "single" + ] + }, + { + "id": "platform-storage#see-also", + "heading": "See Also", + "level": 2, + "anchor": "see-also", + "line_start": 104, + "line_end": 108, + "keywords": [ + "see", + "cdn-filter-runtime.md", + "cdn", + "filter", + "access", + "overview.md", + "account-level", + "stores", + "resource", + "limits" + ] + } + ] + }, { "id": "quickstart", "title": "FastEdge Quickstart", @@ -38933,7 +39419,7 @@ { "id": "quickstart-as", "title": "Quickstart: AssemblyScript CDN Apps on FastEdge", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/quickstart-as.md", "skill": "fastedge-docs", "category": "reference", @@ -38954,9 +39440,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "quickstart", "cdn", "apps", @@ -38967,7 +39453,7 @@ "compile", "webassembly" ], - "content_sha256": "fff52212e2f6238e7ed758a19a80e19a19974e5089f08928df7abac1819c1ada", + "content_sha256": "44a67860b9459a777487ccc86b1f45572d7be137091e04b009c1cda5acfd6676", "sections": [ { "id": "quickstart-as#introduction", @@ -38984,9 +39470,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "quickstart", "assemblyscript", "cdn", @@ -39367,7 +39853,7 @@ { "id": "quickstart-js", "title": "FastEdge JavaScript Quickstart", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/quickstart-js.md", "skill": "fastedge-docs", "category": "reference", @@ -39388,9 +39874,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "quickstart", "prerequisites", @@ -39401,7 +39887,7 @@ "install", "bash" ], - "content_sha256": "51cef432b6305a0da282efc422dcd4b0a9f385cb40f047aee77022cb9258e771", + "content_sha256": "471dc8495fa13ecd040aad10ee3cba07813ec793a027cec8c4c507d6e75b64fa", "sections": [ { "id": "quickstart-js#introduction", @@ -39418,9 +39904,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "javascript", "quickstart" @@ -39708,7 +40194,7 @@ { "id": "quickstart-rust", "title": "FastEdge Rust SDK — Quickstart", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/quickstart-rust.md", "skill": "fastedge-docs", "category": "reference", @@ -39727,9 +40213,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "sdk", "quickstart", @@ -39739,7 +40225,7 @@ "wasm32-wasip1", "target" ], - "content_sha256": "4e1d3d5a01a3e8aaf9f864c197899fbbc06cc30f86aba6a34d8207f67a629c25", + "content_sha256": "e345fdfaec0a005a9969b4bced75bacadcf838209b350e6fc06de4fc330536ca", "sections": [ { "id": "quickstart-rust#introduction", @@ -39756,9 +40242,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "rust", "sdk", @@ -40453,7 +40939,7 @@ { "id": "sdk-reference-as", "title": "AssemblyScript Proxy-Wasm SDK Reference", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/sdk-reference-as.md", "skill": "fastedge-docs", "category": "sdk", @@ -40474,9 +40960,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "proxy-wasm", "reference", "gcoredev", @@ -40486,7 +40972,7 @@ "writing", "cdn" ], - "content_sha256": "76f2b7665b04f19b479f02f492977afaf6fffe062287c53fcfb4f387c5012e89", + "content_sha256": "a14b716b83a08310d5fea5c9097ebefc7fece6329111d0f21c21b97751bd7093", "sections": [ { "id": "sdk-reference-as#introduction", @@ -40503,9 +40989,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "assemblyscript", "proxy-wasm", "sdk", @@ -41000,7 +41486,7 @@ { "id": "sdk-reference-js", "title": "JavaScript SDK Reference (`@gcoredev/fastedge-sdk-js`)", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/sdk-reference-js.md", "skill": "fastedge-docs", "category": "sdk", @@ -41019,9 +41505,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "reference", "gcoredev", "source", @@ -41031,7 +41517,7 @@ "authoritative", "api" ], - "content_sha256": "b24418a0122025cc0863b8fa10c1295844a91aeb97a941495530e3cd5bcbcf1b", + "content_sha256": "cad65330e951f705a83aad21f8106ba15e3fd8cc2d51901140d09c58bc1577ee", "sections": [ { "id": "sdk-reference-js#introduction", @@ -41048,9 +41534,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "javascript", "sdk", "reference", @@ -41595,7 +42081,7 @@ { "id": "sdk-reference-rust", "title": "Rust SDK Reference (`fastedge` crate + `fastedge-derive`)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/sdk-reference-rust.md", "skill": "fastedge-docs", "category": "sdk", @@ -41614,9 +42100,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "reference", "fastedge", "crate", @@ -41626,7 +42112,7 @@ "start", "cargo.toml" ], - "content_sha256": "e3598e9cb99f2f28beb8527ea3284480bee8c63132151da4c8874089bf9bf01b", + "content_sha256": "6ac7d972a17430f2d0d829470c262db798ec8ff3e81ca8dfbf8bed93067b7496", "sections": [ { "id": "sdk-reference-rust#introduction", @@ -41643,9 +42129,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "rust", "sdk", "reference", diff --git a/reference-docs/docs-index.local.json b/reference-docs/docs-index.local.json index 0a140d0..4ef486d 100644 --- a/reference-docs/docs-index.local.json +++ b/reference-docs/docs-index.local.json @@ -1,16 +1,16 @@ { "schema_version": "1.0.0", - "generated_at": "2026-09-09T13:28:16.173Z", + "generated_at": "2026-09-24T09:24:50.621Z", "source": { "repo": "fastedge-plugin", - "commit": "99dc55a", + "commit": "503a8fc", "pipeline": "sync-reference-docs" }, "topics": [ { "id": "cdn-apps-rust", "title": "FastEdge Rust SDK — CDN Apps (Proxy-Wasm)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn-apps-rust.md", "skill": "fastedge-docs", "category": "reference", @@ -29,9 +29,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "sdk", "cdn", @@ -41,7 +41,7 @@ "building", "filters" ], - "content_sha256": "55cf970e41b7f8c4bce161ef5272413f4f155ed90b01d90510d5f21dce23930e", + "content_sha256": "6a79f809ecedc76ed7617ab078604096a5933da07a44a2059849f2042a42910a", "sections": [ { "id": "cdn-apps-rust#introduction", @@ -58,9 +58,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "rust", "sdk", @@ -150,9 +150,9 @@ "0.2", "log", "0.4", + "cache", "secrets", - "dictionary", - "depend" + "dictionary" ] }, { @@ -245,7 +245,7 @@ "callback", "phase", "description", - "-----------------------------------------------------------------", + "-----------------------------------------------------------------------------------------------", "----------------", "---------------------------------------------------", "on_http_request_headers", @@ -256,11 +256,7 @@ "action", "request", "headers", - "inspect", - "modify", - "forwarding", - "on_http_request_body", - "body_size" + "inspect" ] }, { @@ -431,7 +427,7 @@ "level": 2, "anchor": "host-services-for-cdn-apps", "line_start": 423, - "line_end": 733, + "line_end": 818, "keywords": [ "host", "services", @@ -477,8 +473,8 @@ "heading": "API Comparison: HTTP vs CDN", "level": 2, "anchor": "api-comparison-http-vs-cdn", - "line_start": 734, - "line_end": 746, + "line_start": 819, + "line_end": 832, "keywords": [ "api", "comparison", @@ -491,12 +487,11 @@ "proxywasm", "-------------", "-------------------------------------------------------------------", - "--------------------------------------------------------", + "-----------------------------------------------------------------", "key-value", "fastedge", "key_value", - "store", - "secrets" + "store" ] }, { @@ -504,8 +499,8 @@ "heading": "See Also", "level": 2, "anchor": "see-also", - "line_start": 747, - "line_end": 751, + "line_start": 833, + "line_end": 837, "keywords": [ "see", "sdk", @@ -534,7 +529,7 @@ { "id": "cdn-examples-ab-testing-as", "title": "A/B Testing — AssemblyScript (CDN)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-ab-testing-as.md", "skill": "fastedge-docs", "category": "examples", @@ -556,9 +551,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "testing", "cookie-based", "traffic", @@ -568,7 +563,7 @@ "requests", "different" ], - "content_sha256": "a8a65c5b6a1c0cfb93650966caa7539474e92037e1a305816ef0944e3e09a1fc", + "content_sha256": "271da479486db22cd96d1891a8b2e5755921af0d4fd4c733df1732ef35e67684", "sections": [ { "id": "cdn-examples-ab-testing-as#introduction", @@ -585,9 +580,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "testing", "assemblyscript", "cdn", @@ -1003,7 +998,7 @@ { "id": "cdn-examples-ab-testing-rust", "title": "A/B Testing — CDN App Example (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-ab-testing-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -1025,9 +1020,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -1037,7 +1032,7 @@ "ab-testing", "traffic-splitting" ], - "content_sha256": "02a0716c80b4d8908f4996e26cf4a36904a49faf5c7a78d99d5abacf7512e387", + "content_sha256": "8c9d6d203917852f4ca811313b5c30779ba0b4d523dab6f7597099f4675c2e4f", "sections": [ { "id": "cdn-examples-ab-testing-rust#introduction", @@ -1054,9 +1049,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -1660,7 +1655,7 @@ { "id": "cdn-examples-api-key-as", "title": "CDN Example: API Key Authentication (AssemblyScript)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-api-key-as.md", "skill": "fastedge-docs", "category": "examples", @@ -1682,9 +1677,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -1694,7 +1689,7 @@ "api-key-auth", "header-validation" ], - "content_sha256": "d47decc23a11899c2cdd3360355fb8c5e9db6fb48d6b2ca5c90bee4cc5c8ae2b", + "content_sha256": "44acbfa72b450892ad45f4e360dd734b0a451a6df664428a2925e1419a6f8a6e", "sections": [ { "id": "cdn-examples-api-key-as#introduction", @@ -1711,9 +1706,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -2075,7 +2070,7 @@ { "id": "cdn-examples-api-key-rust", "title": "API Key Validation — CDN (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-api-key-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -2097,9 +2092,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "api", "key", "validation", @@ -2109,7 +2104,7 @@ "requests", "against" ], - "content_sha256": "55118b7b2a0e68b75f57892ee0ea64dae4e5bffc4354ecf2941ae41658040b8e", + "content_sha256": "6c28a1664d639ebeb12397dea7294bdd293848795b65c88c2f5aab81e2bee614", "sections": [ { "id": "cdn-examples-api-key-rust#introduction", @@ -2126,9 +2121,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "api", "key", "validation", @@ -2373,56 +2368,6 @@ "traits", "types" ] - }, - { - "id": "cdn-examples-api-key-rust#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 163, - "line_end": 279, - "keywords": [ - "source", - "material", - "file", - "examples", - "cdn", - "api_key", - "src", - "lib.rs", - "rust", - "copyright", - "2025", - "g-core", - "innovations", - "sarl", - "example", - "app", - "demonstrating", - "api", - "key", - "validation.", - "validates", - "requests", - "using", - "x-api-key", - "header", - "checked", - "against", - "stored", - "secret.", - "simpler", - "alternative", - "jwt", - "token", - "expiry", - "claims", - "needed.", - "required", - "configuration", - "secret", - "use" - ] } ], "local_path": "reference-docs/cdn-examples-api-key-rust.md" @@ -2430,7 +2375,7 @@ { "id": "cdn-examples-auth-jwt-as", "title": "JWT Validation — CDN App (AssemblyScript)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 --> --- capabilities: - jwt-auth - request-header-inspection - secret-access - http-response type: example app_type: cdn languages: - assemblyscrip", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 --> --- capabilities: - jwt-auth - request-header-inspection - secret-access - http-response type: example app_type: cdn languages: - assemblyscrip", "path": "reference/fastedge-docs/cdn/examples-auth-jwt-as.md", "skill": "fastedge-docs", "category": "examples", @@ -2454,9 +2399,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "jwt-auth", @@ -2467,7 +2412,7 @@ "example", "app_type" ], - "content_sha256": "b1fb0a577490fc4af605c215e8ece9ba673631e87fe3755435cda8df374760f4", + "content_sha256": "7defe19d2cd21c1429dbf522d5fe31e212ec1f4880b241375b44f179c2add564", "sections": [ { "id": "cdn-examples-auth-jwt-as#introduction", @@ -2484,9 +2429,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "jwt-auth", @@ -2933,7 +2878,7 @@ { "id": "cdn-examples-auth-jwt-rust", "title": "JWT Authentication — CDN App (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-auth-jwt-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -2955,9 +2900,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -2967,7 +2912,7 @@ "auth", "jwt" ], - "content_sha256": "fab044cd88079e758ffa7433aa100275b9466d2b19457fe94f40539fca11ec06", + "content_sha256": "d154eba097a174823554d450040d60276c5d185a7c0875e5214ceb2ded34f624", "sections": [ { "id": "cdn-examples-auth-jwt-rust#introduction", @@ -2984,9 +2929,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -3490,7 +3435,7 @@ { "id": "cdn-examples-body-as", "title": "Body Manipulation — AssemblyScript (CDN)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-body-as.md", "skill": "fastedge-docs", "category": "examples", @@ -3512,9 +3457,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "title", "body", @@ -3524,7 +3469,7 @@ "app_type", "languages" ], - "content_sha256": "94226f2f7783dd5978e697ebea97008427e93dbddfd4b033a8c05d74268e9a34", + "content_sha256": "cf0366213848652a381fe943b6a887700b4a939b885f9bb54dc3c6232f8b6ab0", "sections": [ { "id": "cdn-examples-body-as#introduction", @@ -3541,9 +3486,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "title", "body", @@ -3977,7 +3922,7 @@ { "id": "cdn-examples-body-rust", "title": "CDN Body Inspection and Modification — Rust", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-body-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -3999,9 +3944,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -4011,7 +3956,7 @@ "body-inspection", "body-modification" ], - "content_sha256": "8ae1b1e52a1c6d5700b08e8892ae6cda7aad01471796e76d73ec79dcf32e297b", + "content_sha256": "dd9c88154cf902f53948cceb8f2653719e2fed5373b2dd3ab3c80ba7efca05e8", "sections": [ { "id": "cdn-examples-body-rust#introduction", @@ -4028,9 +3973,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -4434,7 +4379,7 @@ { "id": "cdn-examples-cache-control-as", "title": "Cache Control — AssemblyScript (CDN)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-cache-control-as.md", "skill": "fastedge-docs", "category": "examples", @@ -4458,9 +4403,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -4470,7 +4415,7 @@ "cache-control", "response-headers" ], - "content_sha256": "3b3e6161bccadfc2c7ed913237cf413f6147239e7386715b566aa6893587902d", + "content_sha256": "0a153a37be4f5636fac31f8469be52c9af84394259760e897788b7654ba00fb9", "sections": [ { "id": "cdn-examples-cache-control-as#introduction", @@ -4487,9 +4432,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -5065,7 +5010,7 @@ { "id": "cdn-examples-cache-control-rust", "title": "Cache Control — CDN App Example (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-cache-control-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -5087,9 +5032,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -5099,7 +5044,7 @@ "cache-control", "content-type-aware-caching" ], - "content_sha256": "b0fabdfa84d4803e073c0d36e6b51424537f4051ef1a9e6ba50b56a4e184e169", + "content_sha256": "4c8bfcc4519e20ce422726bb54b90f80816615eb4f5d26cc74cc14a067da4903", "sections": [ { "id": "cdn-examples-cache-control-rust#introduction", @@ -5116,9 +5061,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -5649,10 +5594,417 @@ ], "local_path": "reference-docs/cdn-examples-cache-control-rust.md" }, + { + "id": "cdn-examples-cache-rust", + "title": "CDN Cache — Rust Example", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", + "path": "reference/fastedge-docs/cdn/examples-cache-rust.md", + "skill": "fastedge-docs", + "category": "examples", + "app_types": [ + "cdn" + ], + "languages": [ + "rust" + ], + "tags": [ + "examples", + "fastedge-docs", + "cdn", + "rust", + "auto-updated", + "true", + "sources", + "fastedge-sdk-rust", + "ref", + "main", + "commit", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", + "updated", + "2026-09-22", + "cache", + "example", + "overview", + "app", + "demonstrating", + "operations" + ], + "content_sha256": "4c6cf165f6d058b5f6d401c04abf933162f423e82a02a2b81d3a9f1ada41c285", + "sections": [ + { + "id": "cdn-examples-cache-rust#introduction", + "heading": "Introduction", + "level": 1, + "anchor": "introduction", + "line_start": 1, + "line_end": 11, + "keywords": [ + "auto-updated", + "true", + "sources", + "fastedge-sdk-rust", + "ref", + "main", + "commit", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", + "updated", + "2026-09-22", + "cdn", + "cache", + "rust", + "example" + ] + }, + { + "id": "cdn-examples-cache-rust#overview", + "heading": "Overview", + "level": 2, + "anchor": "overview", + "line_start": 12, + "line_end": 17, + "keywords": [ + "overview", + "cdn", + "app", + "demonstrating", + "cache", + "operations", + "via", + "proxy-wasm", + "abi.", + "scoped", + "calling", + "application", + "addressed", + "key", + "alone", + "there", + "named", + "stores", + "handles", + "unlike", + "store", + "dispatched", + "query", + "parameters", + "incoming", + "request.", + "responses", + "always", + "json.", + "errors", + "return", + "http", + "500", + "error", + "message" + ] + }, + { + "id": "cdn-examples-cache-rust#app-type", + "heading": "App Type", + "level": 2, + "anchor": "app-type", + "line_start": 18, + "line_end": 23, + "keywords": [ + "app", + "type", + "interface", + "proxy-wasm", + "fastedge", + "proxywasm", + "cache", + "cdn", + "language", + "rust" + ] + }, + { + "id": "cdn-examples-cache-rust#request-interface", + "heading": "Request Interface", + "level": 2, + "anchor": "request-interface", + "line_start": 24, + "line_end": 38, + "keywords": [ + "request", + "interface", + "operations", + "specified", + "via", + "query", + "parameters.", + "action", + "parameter", + "selects", + "operation", + "get", + "default", + "omitted.", + "string", + "---", + "key", + "read", + "cached", + "value.", + "response", + "null", + "absent.", + "set", + "value", + "ttl", + "store", + "omitting", + "stores", + "expiry.", + "delete", + "key.", + "no-op", + "exists" + ] + }, + { + "id": "cdn-examples-cache-rust#api-reference", + "heading": "API Reference", + "level": 2, + "anchor": "api-reference", + "line_start": 39, + "line_end": 195, + "keywords": [ + "api", + "reference", + "functions", + "fastedge", + "proxywasm", + "cache", + "get", + "rust", + "pub", + "key", + "str", + "result", + "option", + "vec", + "retrieve", + "cached", + "bytes", + "key.", + "parameters", + "string", + "returns", + "exists", + "none", + "absent", + "err", + "failure", + "json", + "response", + "shape", + "action", + "value", + "null", + "---", + "set" + ] + }, + { + "id": "cdn-examples-cache-rust#error-handling", + "heading": "Error Handling", + "level": 2, + "anchor": "error-handling", + "line_start": 196, + "line_end": 202, + "keywords": [ + "error", + "handling", + "errors", + "return", + "http", + "500", + "body", + "message", + "missing", + "required", + "query", + "parameters", + "produce", + "descriptive", + "messages", + "e.g.", + "param", + "key", + "get", + "action", + "invalid", + "parameter", + "values", + "non-integer", + "ttl", + "delta", + "parse", + "messages.", + "unknown", + "listing", + "supported", + "actions." + ] + }, + { + "id": "cdn-examples-cache-rust#dependencies", + "heading": "Dependencies", + "level": 2, + "anchor": "dependencies", + "line_start": 203, + "line_end": 211, + "keywords": [ + "dependencies", + "toml", + "proxy-wasm", + "0.2", + "fastedge", + "path", + "...", + "features", + "proxywasm", + "querystring", + "1.1", + "serde_json" + ] + }, + { + "id": "cdn-examples-cache-rust#build", + "heading": "Build", + "level": 2, + "anchor": "build", + "line_start": 212, + "line_end": 218, + "keywords": [ + "build", + "cargo", + "--release", + "output", + "target", + "wasm32-wasip1", + "release", + "cache.wasm" + ] + }, + { + "id": "cdn-examples-cache-rust#lifecycle-notes", + "heading": "Lifecycle Notes", + "level": 2, + "anchor": "lifecycle-notes", + "line_start": 219, + "line_end": 225, + "keywords": [ + "lifecycle", + "notes", + "app", + "uses", + "proxy-wasm", + "rootcontext", + "httpcontext", + "pattern.", + "logic", + "executes", + "on_http_response_body", + "waits", + "end_of_stream", + "on_http_response_headers", + "strips", + "content-length", + "sets", + "content-type", + "application", + "json", + "transfer-encoding", + "chunked", + "body", + "processing.", + "query", + "string", + "read", + "request.query", + "via", + "get_property" + ] + }, + { + "id": "cdn-examples-cache-rust#key-constraints", + "heading": "Key Constraints", + "level": 2, + "anchor": "key-constraints", + "line_start": 226, + "line_end": 232, + "keywords": [ + "key", + "constraints", + "cache", + "operations", + "scoped", + "calling", + "application", + "keys", + "one", + "app", + "accessible", + "another.", + "there", + "named", + "stores", + "handles", + "sole", + "address.", + "ttl", + "values", + "always", + "milliseconds", + "delta", + "incr", + "signed", + "64-bit", + "integer", + "i64", + "missing", + "treated" + ] + }, + { + "id": "cdn-examples-cache-rust#see-also", + "heading": "See Also", + "level": 2, + "anchor": "see-also", + "line_start": 233, + "line_end": 238, + "keywords": [ + "see", + "fastedge-sdk-rust", + "cdn", + "key_value", + "example", + "named", + "store", + "handles", + "contrast", + "cache", + "api", + "examples", + "overview", + "proxy-wasm", + "httpcontext", + "rootcontext", + "trait", + "documentation" + ] + } + ], + "local_path": "reference-docs/cdn-examples-cache-rust.md" + }, { "id": "cdn-examples-convert-image-rust", "title": "CDN Example: Convert Image (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-convert-image-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -5674,9 +6026,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "example", "convert", "image", @@ -5686,7 +6038,7 @@ "avif", "format" ], - "content_sha256": "a13f67a53c9fe7aea572cc4340f710693d326f6f3b9570a1e7428e88b43da733", + "content_sha256": "c9e876d444727919f19871887b51f11a25b8653ddc28e5f19f241a707cadd786", "sections": [ { "id": "cdn-examples-convert-image-rust#introduction", @@ -5703,9 +6055,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "cdn", "example", "convert", @@ -6170,122 +6522,6 @@ "error", "codes" ] - }, - { - "id": "cdn-examples-convert-image-rust#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 206, - "line_end": 488, - "keywords": [ - "source", - "material", - "file", - "examples", - "cdn", - "convert_image", - "src", - "lib.rs", - "rust", - "use", - "image", - "proxy_wasm", - "traits", - "types", - "std", - "env", - "varerror", - "cursor", - "str", - "from_utf8", - "main", - "set_log_level", - "loglevel", - "trace", - "set_root_context", - "box", - "dyn", - "rootcontext", - "new", - "convertimageroot", - "struct", - "impl", - "context", - "get_type", - "self" - ] - }, - { - "id": "cdn-examples-convert-image-rust#configuration", - "heading": "Configuration", - "level": 2, - "anchor": "configuration", - "line_start": 489, - "line_end": 495, - "keywords": [ - "configuration", - "environment", - "variable", - "formats_to_transform", - "comma-separated", - "list", - "file", - "extensions", - "convert", - "e.g.", - "jpg", - "jpeg", - "png", - "ignored_ua_list", - "optional", - "user-agent", - "substrings", - "skip", - "avif_speed", - "avif", - "encoding", - "speed", - "1-10", - "default", - "avif_quality", - "quality", - "1-100" - ] - }, - { - "id": "cdn-examples-convert-image-rust#how-it-works", - "heading": "How it works", - "level": 2, - "anchor": "how-it-works", - "line_start": 496, - "line_end": 502, - "keywords": [ - "works", - "on_request_headers", - "checks", - "file", - "extension", - "user-agent", - "sets", - "image-format", - "header", - "cache", - "variation", - "on_response_headers", - "response", - "headers", - "avif", - "content", - "type", - "200", - "responses", - "on_response_body", - "decodes", - "original", - "image", - "re-encodes" - ] } ], "local_path": "reference-docs/cdn-examples-convert-image-rust.md" @@ -6293,7 +6529,7 @@ { "id": "cdn-examples-cors-as", "title": "CORS — AssemblyScript (CDN)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-cors-as.md", "skill": "fastedge-docs", "category": "examples", @@ -6315,9 +6551,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "cors", "response-header", "injection", @@ -6327,7 +6563,7 @@ "proxy-wasm", "sdk." ], - "content_sha256": "dcfb3c1c7467c4e745a43d3b8821e1ef8725789583876c7d2ffafd9955cc8efa", + "content_sha256": "204de98ec6e870b35f9cdd8f9b2a9d9b23c1e7152db0ee88fa8b62aaf3a5d02b", "sections": [ { "id": "cdn-examples-cors-as#introduction", @@ -6344,9 +6580,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "cors", "assemblyscript", "cdn", @@ -6916,7 +7152,7 @@ { "id": "cdn-examples-cors-rust", "title": "CORS — CDN App Example (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-cors-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -6938,9 +7174,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -6950,7 +7186,7 @@ "cors", "preflight" ], - "content_sha256": "0fb3e333f7c0f3374c1253af8febc8847afb1ee90ffeabcc90ca5cdd75762c5b", + "content_sha256": "02601a51af83f28ad9b82be9607ee55878e53af965ee28d0033dc33ac25c8fac", "sections": [ { "id": "cdn-examples-cors-rust#introduction", @@ -6967,9 +7203,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -7471,7 +7707,7 @@ { "id": "cdn-examples-custom-error-pages-as", "title": "Custom Error Pages — AssemblyScript (CDN)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-custom-error-pages-as.md", "skill": "fastedge-docs", "category": "examples", @@ -7493,9 +7729,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -7505,7 +7741,7 @@ "response-headers", "response-body" ], - "content_sha256": "d27efa1750b8e49c981eadabe5896041d527217f351a1935fb6b5da2ba740ce0", + "content_sha256": "db4273297015e84837b705d18e071b4684410000b7bc9fcf363fe82c1c58ea15", "sections": [ { "id": "cdn-examples-custom-error-pages-as#introduction", @@ -7522,9 +7758,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -7954,156 +8190,127 @@ "hook", "sequencing" ] - }, + } + ], + "local_path": "reference-docs/cdn-examples-custom-error-pages-as.md" + }, + { + "id": "cdn-examples-custom-error-pages-rust", + "title": "cdn-examples-custom-error-pages-rust", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", + "path": "reference/fastedge-docs/cdn/examples-custom-error-pages-rust.md", + "skill": "fastedge-docs", + "category": "examples", + "app_types": [ + "cdn" + ], + "languages": [ + "rust" + ], + "tags": [ + "examples", + "fastedge-docs", + "cdn", + "rust", + "auto-updated", + "true", + "sources", + "fastedge-sdk-rust", + "ref", + "main", + "commit", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", + "updated", + "2026-09-22", + "custom", + "error", + "pages", + "overview", + "intercepts", + "4xx", + "5xx", + "http" + ], + "content_sha256": "efad33874c535871854509dd840e49c337a0b3f8a7971d0743d6d1eebff0826d", + "sections": [ { - "id": "cdn-examples-custom-error-pages-as#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 296, - "line_end": 501, + "id": "cdn-examples-custom-error-pages-rust#introduction", + "heading": "Introduction", + "level": 1, + "anchor": "introduction", + "line_start": 1, + "line_end": 9, "keywords": [ - "source", - "material", - "file", - "examples", - "customerrorpages", - "assembly", - "index.ts", - "export", - "gcoredev", - "proxy-wasm-sdk-as", - "proxy", - "import", - "context", - "filterdatastatusvalues", - "filterheadersstatusvalues", - "get_property", - "log", - "loglevelvalues", - "registerrootcontext", - "rootcontext", - "set_buffer_bytes", - "buffertypevalues", - "stream_context", - "setloglevel", - "fastedge", - "class", - "errorpagesroot" + "auto-updated", + "true", + "sources", + "fastedge-sdk-rust", + "ref", + "main", + "commit", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", + "updated", + "2026-09-22" ] }, { - "id": "cdn-examples-custom-error-pages-as#what-it-does", - "heading": "What it does", + "id": "cdn-examples-custom-error-pages-rust#custom-error-pages-—-cdn-rust", + "heading": "Custom Error Pages — CDN (Rust)", "level": 2, - "anchor": "what-it-does", - "line_start": 502, - "line_end": 514, + "anchor": "custom-error-pages-—-cdn-rust", + "line_start": 10, + "line_end": 297, "keywords": [ - "onresponseheaders", - "app", - "reads", - "response.status", - "property.", - "400-599", - "range", - "sets", - "content-type", - "text", - "html", - "prepares", - "body", - "replacement.", - "onresponsebody", - "buffers", - "full", - "response", + "custom", + "error", + "pages", + "cdn", + "rust", + "overview", + "intercepts", + "4xx", + "5xx", + "http", + "responses", + "edge", "replaces", + "their", + "bodies", + "branded", + "html", + "rendered", + "via", + "handlebars", + "templates.", + "use", + "pattern", + "you", + "consistent", "styled", - "page", - "containing", - "numeric", - "status", - "code", - "human-readable", - "error", - "title", - "e.g.", - "found", - "bad", - "gateway", - "description", - "explaining", - "went", - "wrong", - "category", - "label", - "client", - "server" - ] - }, - { - "id": "cdn-examples-custom-error-pages-as#build", - "heading": "Build", - "level": 2, - "anchor": "build", - "line_start": 515, - "line_end": 528, - "keywords": [ - "build", - "pnpm", - "install", - "run", - "asbuild", - "output", - "file", - "description", - "------", - "-------------", - "customerrorpages.wasm", - "optimised", - "release", - "binary", - "upload", - "fastedge", - "customerrorpages-debug.wasm", - "debug", - "source", - "maps" - ] - }, - { - "id": "cdn-examples-custom-error-pages-as#deploy", - "heading": "Deploy", - "level": 2, - "anchor": "deploy", - "line_start": 529, - "line_end": 533, - "keywords": [ - "deploy", - "upload", + "served", + "regardless", + "origin", + "returns.", "build", - "customerrorpages.wasm", - "fastedge", - "portal", - "attach", - "your", - "cdn", - "application.", - "environment", - "variables", - "secrets", - "required." + "script", + "build.rs", + "runs", + "compile", + "time", + "embed", + "images", + "messages", + "public" ] } ], - "local_path": "reference-docs/cdn-examples-custom-error-pages-as.md" + "local_path": "reference-docs/cdn-examples-custom-error-pages-rust.md" }, { - "id": "cdn-examples-custom-error-pages-rust", - "title": "cdn-examples-custom-error-pages-rust", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", - "path": "reference/fastedge-docs/cdn/examples-custom-error-pages-rust.md", + "id": "cdn-examples-custom-rust", + "title": "CDN Example: Custom — Rust", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", + "path": "reference/fastedge-docs/cdn/examples-custom-rust.md", "skill": "fastedge-docs", "category": "examples", "app_types": [ @@ -8124,121 +8331,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", - "custom", - "error", - "pages", - "overview", - "intercepts", - "4xx", - "5xx", - "http" - ], - "content_sha256": "6ca59f2c7881b6cfa873c1aa90ca38a3135eeee3546ba894a62801be63e0266e", - "sections": [ - { - "id": "cdn-examples-custom-error-pages-rust#introduction", - "heading": "Introduction", - "level": 1, - "anchor": "introduction", - "line_start": 1, - "line_end": 9, - "keywords": [ - "auto-updated", - "true", - "sources", - "fastedge-sdk-rust", - "ref", - "main", - "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", - "updated", - "2026-08-20" - ] - }, - { - "id": "cdn-examples-custom-error-pages-rust#custom-error-pages-—-cdn-rust", - "heading": "Custom Error Pages — CDN (Rust)", - "level": 2, - "anchor": "custom-error-pages-—-cdn-rust", - "line_start": 10, - "line_end": 297, - "keywords": [ - "custom", - "error", - "pages", - "cdn", - "rust", - "overview", - "intercepts", - "4xx", - "5xx", - "http", - "responses", - "edge", - "replaces", - "their", - "bodies", - "branded", - "html", - "rendered", - "via", - "handlebars", - "templates.", - "use", - "pattern", - "you", - "consistent", - "styled", - "served", - "regardless", - "origin", - "returns.", - "build", - "script", - "build.rs", - "runs", - "compile", - "time", - "embed", - "images", - "messages", - "public" - ] - } - ], - "local_path": "reference-docs/cdn-examples-custom-error-pages-rust.md" - }, - { - "id": "cdn-examples-custom-rust", - "title": "CDN Example: Custom — Rust", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", - "path": "reference/fastedge-docs/cdn/examples-custom-rust.md", - "skill": "fastedge-docs", - "category": "examples", - "app_types": [ - "cdn" - ], - "languages": [ - "rust" - ], - "tags": [ - "examples", - "fastedge-docs", - "cdn", - "rust", - "auto-updated", - "true", - "sources", - "fastedge-sdk-rust", - "ref", - "main", - "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", - "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -8248,7 +8343,7 @@ "request-headers", "synthetic-response" ], - "content_sha256": "a73e35e2bec26a8caef88e750c20eec94b8a4e22bd45622922f8ab9f586d554a", + "content_sha256": "05c5008d51ac8a9fe2b0b76d6b1d52a5b3c964d3a4e07c1227591206ce8c70b0", "sections": [ { "id": "cdn-examples-custom-rust#introduction", @@ -8265,9 +8360,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -8656,7 +8751,7 @@ { "id": "cdn-examples-env-secrets-as", "title": "Environment Variables and Secrets — CDN (AssemblyScript)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 --> --- type: example app_type: cdn languages: [as] capabilities: [env-vars, secrets] ---", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 --> --- type: example app_type: cdn languages: [as] capabilities: [env-vars, secrets] ---", "path": "reference/fastedge-docs/cdn/examples-env-secrets-as.md", "skill": "fastedge-docs", "category": "examples", @@ -8678,9 +8773,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -8691,7 +8786,7 @@ "secrets", "environment" ], - "content_sha256": "0c73ed18f10ce8d8e06a88f54b4d3f23ac0b67968d5c25e974066c47408cfacb", + "content_sha256": "3c64cf405e55a27101a1b957168091583141e9c42e286db01b35cc3770d77601", "sections": [ { "id": "cdn-examples-env-secrets-as#introduction", @@ -8708,9 +8803,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -9128,7 +9223,7 @@ { "id": "cdn-examples-env-secrets-rust", "title": "Environment Variables and Secrets — CDN (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 --> --- type: example app_type: cdn languages: [rust] capabilities: [env-vars, secrets] ---", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 --> --- type: example app_type: cdn languages: [rust] capabilities: [env-vars, secrets] ---", "path": "reference/fastedge-docs/cdn/examples-env-secrets-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -9150,9 +9245,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -9162,7 +9257,7 @@ "env-vars", "secrets" ], - "content_sha256": "c649f355de98cfbff02eb0209ff30aec29948b20dda1e664b62b81a49e8a518a", + "content_sha256": "6a8766856d5c193566c9b8cdc05b6e635c040c503595795b5a2f9207b948cab2", "sections": [ { "id": "cdn-examples-env-secrets-rust#introduction", @@ -9179,9 +9274,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -9585,7 +9680,7 @@ { "id": "cdn-examples-geo-redirect-as", "title": "Geo Redirect — CDN (AssemblyScript)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-geo-redirect-as.md", "skill": "fastedge-docs", "category": "examples", @@ -9607,9 +9702,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -9619,7 +9714,7 @@ "geo-routing", "header-manipulation" ], - "content_sha256": "77bc8d7bb75d5073d55729d167f95732aae1c14e0d2cc8f5dbd17a584fe83bdf", + "content_sha256": "bfd821f4dcef5d6f8a06638c0f353365ad97cccd76619f27e6b5fc8ad6e1d48a", "sections": [ { "id": "cdn-examples-geo-redirect-as#introduction", @@ -9636,9 +9731,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -10211,7 +10306,7 @@ { "id": "cdn-examples-geo-redirect-rust", "title": "Geo Redirect — CDN (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-geo-redirect-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -10233,9 +10328,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -10245,7 +10340,7 @@ "geo-routing", "origin-rewrite" ], - "content_sha256": "e261c562cb83f75dba70f28b364fbf919b2f5013ba58235119ad284f266ad0d9", + "content_sha256": "a4ba8ac9ed821f5617d6bda76cfbd9d6d0d37c5b5b30e9206a0b2e15b713e730", "sections": [ { "id": "cdn-examples-geo-redirect-rust#introduction", @@ -10262,9 +10357,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -10768,7 +10863,7 @@ { "id": "cdn-examples-geoblock-as", "title": "Geoblock — CDN App Example (AssemblyScript)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-geoblock-as.md", "skill": "fastedge-docs", "category": "examples", @@ -10790,9 +10885,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -10802,7 +10897,7 @@ "geoblock", "geo-filtering" ], - "content_sha256": "84af0ea22b79918d77cf3d4bfb495acc76a3246c5535c41b1555f7052fcc183d", + "content_sha256": "763b705d33e44d10af681bf94505be744a28c35e28877e80f0b077006f56f37d", "sections": [ { "id": "cdn-examples-geoblock-as#introduction", @@ -10819,9 +10914,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -11298,7 +11393,7 @@ { "id": "cdn-examples-geoblock-rust", "title": "Geoblock — CDN App Example (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-geoblock-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -11320,9 +11415,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -11332,7 +11427,7 @@ "geoblock", "geo-filtering" ], - "content_sha256": "a7c062df70dea7d93851c4767e7e29ebd0ea6f820171bab1417c892702ee748e", + "content_sha256": "c88ed2e2cb497f3a3cac9866b08afcc3e2abd09c7f09fa25422cede185b2368c", "sections": [ { "id": "cdn-examples-geoblock-rust#introduction", @@ -11349,9 +11444,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -11829,7 +11924,7 @@ { "id": "cdn-examples-headers-as", "title": "CDN Headers Manipulation — AssemblyScript", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-headers-as.md", "skill": "fastedge-docs", "category": "examples", @@ -11853,9 +11948,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -11865,7 +11960,7 @@ "headers", "request-headers" ], - "content_sha256": "caec0cba8cdcb98575ff941504f05fe0ce60d9be18d75841452201ad7f996683", + "content_sha256": "eb268cb0cde0417bb082dbadb140da4f26f837195f2c6d93a907bc1643fc243e", "sections": [ { "id": "cdn-examples-headers-as#introduction", @@ -11882,9 +11977,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -12022,9 +12117,11 @@ "method", "signature", "description", - "-------------------", - "-----------------------------------------------", - "--------------------------------------------------------------------------------------------------------" + "--------------------------", + "---------------------------------------", + "-----------------------------------------------------------------------------------------------------", + "get", + "nam" ] }, { @@ -12463,7 +12560,7 @@ { "id": "cdn-examples-headers-rust", "title": "Headers — CDN (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-headers-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -12485,9 +12582,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -12497,7 +12594,7 @@ "headers", "request-headers" ], - "content_sha256": "26db929462e18b733d0d8ff6392d1a509520adb603ee47545516c24043493a11", + "content_sha256": "bf7f55f6e1a3e672e73e99857adf01eae6f05e539dcd246c132da96a418bbe7e", "sections": [ { "id": "cdn-examples-headers-rust#introduction", @@ -12514,9 +12611,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -12862,8 +12959,8 @@ }, { "id": "cdn-examples-http-call-as", - "title": "HTTP Call", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "title": "cdn-examples-http-call-as", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-http-call-as.md", "skill": "fastedge-docs", "category": "examples", @@ -12887,9 +12984,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "overview", "httpcall", "dispatches", @@ -12900,7 +12997,7 @@ "fastedge", "proxy-wasm" ], - "content_sha256": "86bdde87724666835a6a0c4dd7190437c0ea08fb8715e577c65cd2486a0b11c0", + "content_sha256": "5fd3877e09d4896bd6c69ed4c0cb9cc56dc6cd0d8fadb01c02391285f4b8bce6", "sections": [ { "id": "cdn-examples-http-call-as#introduction", @@ -12917,9 +13014,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20" + "2026-09-22" ] }, { @@ -13191,202 +13288,6 @@ "response", "patterns" ] - }, - { - "id": "cdn-examples-http-call-as#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 325, - "line_end": 485, - "keywords": [ - "source", - "material", - "file", - "examples", - "httpcall", - "assembly", - "index.ts", - "export", - "gcoredev", - "proxy-wasm-sdk-as", - "proxy", - "exports", - "required", - "functions", - "interact", - "us.", - "import", - "basecontext", - "buffertypevalues", - "context", - "filterheadersstatusvalues", - "get_buffer_bytes", - "headerpair", - "log", - "loglevelvalues", - "makeheaderpair", - "registerrootcontext", - "rootcontext", - "send_http_response", - "stream_context", - "wasmresultvalues", - "proxy-wasm-sdk-a" - ] - }, - { - "id": "cdn-examples-http-call-as#what-it-does", - "heading": "What it does", - "level": 2, - "anchor": "what-it-does", - "line_start": 486, - "line_end": 497, - "keywords": [ - "onrequestheaders", - "app", - "dispatches", - "outbound", - "http", - "get", - "request", - "httpbin.org", - "pauses", - "hook", - "stopiteration", - "until", - "response", - "arrives.", - "dispatch", - "latched", - "instance", - "field", - "second", - "invocation", - "processed", - "returns", - "continue", - "instead", - "dispatching", - "again.", - "inside", - "callback", - "passed", - "httpcall", - "checks", - "whether", - "call", - "succeeded", - "headers", - "value", - "indicates", - "failure", - "timeout", - "dns" - ] - }, - { - "id": "cdn-examples-http-call-as#key-concepts", - "heading": "Key concepts", - "level": 2, - "anchor": "key-concepts", - "line_start": 498, - "line_end": 504, - "keywords": [ - "key", - "concepts", - "httpcall", - "rootcontext", - "dispatches", - "async", - "http", - "request.", - "accepts", - "cluster", - "host", - "headers", - "body", - "trailers", - "timeout", - "milliseconds", - "originating", - "context", - "callback.", - "fastedge", - "resume", - "model.", - "returning", - "filterheadersstatusvalues.stopiteration", - "pauses", - "hook.", - "runtime", - "processes", - "response", - "invokes", - "callback", - "re-invokes", - "onrequestheaders", - "same", - "instance", - "httpcalldispatched", - "latch", - "gates", - "re-dispatch", - "hoo" - ] - }, - { - "id": "cdn-examples-http-call-as#build", - "heading": "Build", - "level": 2, - "anchor": "build", - "line_start": 505, - "line_end": 518, - "keywords": [ - "build", - "pnpm", - "install", - "run", - "asbuild", - "output", - "file", - "description", - "------", - "-------------", - "httpcall.wasm", - "optimised", - "release", - "binary", - "upload", - "fastedge", - "httpcall-debug.wasm", - "debug", - "source", - "maps" - ] - }, - { - "id": "cdn-examples-http-call-as#deploy", - "heading": "Deploy", - "level": 2, - "anchor": "deploy", - "line_start": 519, - "line_end": 523, - "keywords": [ - "deploy", - "upload", - "build", - "httpcall.wasm", - "fastedge", - "portal", - "attach", - "your", - "cdn", - "application.", - "environment", - "variables", - "secrets", - "required." - ] } ], "local_path": "reference-docs/cdn-examples-http-call-as.md" @@ -13394,7 +13295,7 @@ { "id": "cdn-examples-http-call-rust", "title": "HTTP Call — CDN (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-http-call-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -13416,9 +13317,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "http", "call", "makes", @@ -13428,7 +13329,7 @@ "services", "timeout" ], - "content_sha256": "d1e86eef023d89dc75f57a3863c60f70ab78a1b7f854f40563265c4f403fcb2b", + "content_sha256": "5e665b5b4838fd593db0ee7e992ade82f31afd9c62cf39aa13075f9ffdf2b6ee", "sections": [ { "id": "cdn-examples-http-call-rust#introduction", @@ -13445,9 +13346,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "http", "call", "cdn", @@ -13849,7 +13750,7 @@ "level": 2, "anchor": "complete-example", "line_start": 247, - "line_end": 359, + "line_end": 360, "keywords": [ "complete", "example", @@ -13889,8 +13790,8 @@ "heading": "Gotchas", "level": 2, "anchor": "gotchas", - "line_start": 360, - "line_end": 371, + "line_start": 361, + "line_end": 372, "keywords": [ "gotchas", "action", @@ -13939,8 +13840,8 @@ "heading": "See Also", "level": 2, "anchor": "see-also", - "line_start": 372, - "line_end": 378, + "line_start": 373, + "line_end": 379, "keywords": [ "see", "proxy-wasm", @@ -13968,7 +13869,7 @@ { "id": "cdn-examples-kv-store-as", "title": "KV Store — AssemblyScript CDN Example", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-kv-store-as.md", "skill": "fastedge-docs", "category": "examples", @@ -13992,9 +13893,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -14004,7 +13905,7 @@ "kv-store", "sorted-sets" ], - "content_sha256": "7c82be09762a859504b8de768a520016b4dd63da93c478964e74af2344eb76b3", + "content_sha256": "bfdb069b5c22829eb076f681740fba8b7d13263e17108b9905e3e513a3ae7350", "sections": [ { "id": "cdn-examples-kv-store-as#introduction", @@ -14021,9 +13922,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -14643,7 +14544,7 @@ { "id": "cdn-examples-kv-store-rust", "title": "KV Store — CDN (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-kv-store-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -14665,9 +14566,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "kv-store", @@ -14678,7 +14579,7 @@ "example", "app_type" ], - "content_sha256": "d382cf1a71b92057d477f9447f2538d3008c8abd3f00d3c51323f300c086227a", + "content_sha256": "23c7f8c100db8a05f960e1382c3a9933d52661da3f5ad5a253cfd75e1d720c90", "sections": [ { "id": "cdn-examples-kv-store-rust#introduction", @@ -14695,9 +14596,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "kv-store", @@ -14854,7 +14755,7 @@ "level": 2, "anchor": "gotchas", "line_start": 223, - "line_end": 237, + "line_end": 239, "keywords": [ "gotchas", "get", @@ -14903,8 +14804,8 @@ "heading": "Related", "level": 2, "anchor": "related", - "line_start": 238, - "line_end": 243, + "line_start": 240, + "line_end": 245, "keywords": [ "related", "host", @@ -14939,6 +14840,243 @@ "vs.", "differences" ] + }, + { + "id": "cdn-examples-kv-store-rust#source-material", + "heading": "Source Material", + "level": 2, + "anchor": "source-material", + "line_start": 246, + "line_end": 518, + "keywords": [ + "source", + "material", + "file", + "examples", + "cdn", + "key_value", + "src", + "lib.rs", + "rust", + "copyright", + "2025", + "g-core", + "innovations", + "sarl", + "example", + "app", + "demonstrating", + "store", + "operations", + "via", + "proxy-wasm", + "interface.", + "supports", + "query", + "parameters", + "name", + "action", + "get", + "key", + "scan", + "match", + "pattern", + "zrange", + "min", + "f64", + "max", + "zscan", + "bfexists", + "ite" + ] + }, + { + "id": "cdn-examples-kv-store-rust#what-it-does", + "heading": "What it does", + "level": 2, + "anchor": "what-it-does", + "line_start": 519, + "line_end": 535, + "keywords": [ + "app", + "supports", + "following", + "actions", + "get", + "fetch", + "one", + "key", + "scan", + "list", + "keys", + "matching", + "pattern", + "zrange", + "read", + "sorted-set", + "entries", + "score", + "range", + "zscan", + "bfexists", + "check", + "whether", + "bloom", + "filter", + "contains", + "item", + "request", + "include", + "least", + "store", + "name", + "action", + "operation", + "optional", + "defaults", + "validates", + "required", + "parameters", + "returns" + ] + }, + { + "id": "cdn-examples-kv-store-rust#supported-query-examples", + "heading": "Supported query examples", + "level": 2, + "anchor": "supported-query-examples", + "line_start": 536, + "line_end": 567, + "keywords": [ + "supported", + "query", + "examples", + "get", + "key", + "text", + "store", + "my_store", + "action", + "user", + "list", + "keys", + "pattern", + "scan", + "match", + "read", + "sorted", + "set", + "score", + "range", + "zrange", + "leaderboard", + "min", + "max", + "100", + "search", + "sorted-set", + "members", + "zscan", + "check", + "bloom", + "filter", + "item", + "bfexists", + "visitors", + "alice", + "examp" + ] + }, + { + "id": "cdn-examples-kv-store-rust#build", + "heading": "Build", + "level": 2, + "anchor": "build", + "line_start": 568, + "line_end": 576, + "keywords": [ + "build", + "cargo", + "--release", + "output", + "target", + "wasm32-wasip1", + "release", + "key_value.wasm", + "example", + "cdn", + "app", + "targets" + ] + }, + { + "id": "cdn-examples-kv-store-rust#response-format", + "heading": "Response format", + "level": 2, + "anchor": "response-format", + "line_start": 577, + "line_end": 598, + "keywords": [ + "response", + "format", + "app", + "replaces", + "body", + "json", + "sets", + "content-type", + "application", + "successful", + "looks", + "like", + "store", + "my_store", + "action", + "get", + "key", + "user", + "alice", + "required", + "parameter", + "missing", + "operation", + "fails", + "responds", + "error", + "payload", + "param" + ] + }, + { + "id": "cdn-examples-kv-store-rust#notes", + "heading": "Notes", + "level": 2, + "anchor": "notes", + "line_start": 599, + "line_end": 605, + "keywords": [ + "notes", + "app", + "requires", + "query", + "parameters", + "run.", + "action", + "omitted", + "defaults", + "get", + "code", + "uses", + "fastedge", + "proxywasm", + "key_value", + "store", + "proxy_wasm", + "lifecycle", + "hooks", + "operate", + "store." + ] } ], "local_path": "reference-docs/cdn-examples-kv-store-rust.md" @@ -14946,7 +15084,7 @@ { "id": "cdn-examples-large-dictionary-as", "title": "Large Dictionary — AssemblyScript (CDN)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-large-dictionary-as.md", "skill": "fastedge-docs", "category": "examples", @@ -14968,9 +15106,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "large", "dictionary", "overview", @@ -14979,7 +15117,7 @@ "environment", "variables" ], - "content_sha256": "5c0712f113a19fa2bcc1667657ca33586d5a538706d60bc80ad976fc408270c3", + "content_sha256": "06c3e8963a2738ac48fbbfbf6217cded6950009199039727a0ed53963ab8474d", "sections": [ { "id": "cdn-examples-large-dictionary-as#introduction", @@ -14996,9 +15134,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "large", "dictionary", "assemblyscript", @@ -15302,6 +15440,205 @@ "patterns", "fastedge-docs" ] + }, + { + "id": "cdn-examples-large-dictionary-as#source-material", + "heading": "Source Material", + "level": 2, + "anchor": "source-material", + "line_start": 140, + "line_end": 223, + "keywords": [ + "source", + "material", + "file", + "examples", + "largedictionary", + "assembly", + "index.ts", + "export", + "gcoredev", + "proxy-wasm-sdk-as", + "proxy", + "import", + "context", + "filterheadersstatusvalues", + "log", + "loglevelvalues", + "registerrootcontext", + "rootcontext", + "stream_context", + "getdictionary", + "setloglevel", + "fastedge", + "class", + "largedictionaryroot", + "extends", + "createcontext", + "context_id", + "u32", + "con" + ] + }, + { + "id": "cdn-examples-large-dictionary-as#when-to-use-getdictionary-vs-getenv", + "heading": "When to use `getDictionary` vs `getEnv`", + "level": 2, + "anchor": "when-to-use-getdictionary-vs-getenv", + "line_start": 224, + "line_end": 234, + "keywords": [ + "use", + "getdictionary", + "getenv", + "function", + "----------", + "name", + "variable", + "value", + "under", + "cases", + "exceed", + "wasi", + "env", + "var", + "size", + "limit", + "environment", + "interface", + "per", + "variable.", + "your", + "app", + "needs", + "read", + "larger", + "values", + "e.g.", + "large", + "json", + "configs", + "pem", + "certificates", + "policy", + "documents", + "calls", + "proxy_dictionary_get", + "bypasses", + "thi" + ] + }, + { + "id": "cdn-examples-large-dictionary-as#what-it-does", + "heading": "What it does", + "level": 2, + "anchor": "what-it-does", + "line_start": 235, + "line_end": 238, + "keywords": [ + "onrequestheaders", + "app", + "reads", + "large_config", + "environment", + "variable", + "using", + "getdictionary", + "logs", + "size", + "adds", + "x-config-size", + "request", + "header", + "upstream", + "see." + ] + }, + { + "id": "cdn-examples-large-dictionary-as#configuration", + "heading": "Configuration", + "level": 2, + "anchor": "configuration", + "line_start": 239, + "line_end": 246, + "keywords": [ + "configuration", + "set", + "following", + "your", + "fastedge", + "application", + "name", + "type", + "description", + "------", + "-------------", + "large_config", + "environment", + "variable", + "large", + "payload", + "e.g.", + "json", + "pem", + "certificate" + ] + }, + { + "id": "cdn-examples-large-dictionary-as#build", + "heading": "Build", + "level": 2, + "anchor": "build", + "line_start": 247, + "line_end": 260, + "keywords": [ + "build", + "pnpm", + "install", + "run", + "asbuild", + "output", + "file", + "description", + "------", + "-------------", + "largedictionary.wasm", + "optimised", + "release", + "binary", + "upload", + "fastedge", + "largedictionary-debug.wasm", + "debug", + "source", + "maps" + ] + }, + { + "id": "cdn-examples-large-dictionary-as#deploy", + "heading": "Deploy", + "level": 2, + "anchor": "deploy", + "line_start": 261, + "line_end": 265, + "keywords": [ + "deploy", + "upload", + "build", + "largedictionary.wasm", + "fastedge", + "portal", + "attach", + "your", + "cdn", + "application.", + "configure", + "large_config", + "environment", + "variable", + "application", + "settings." + ] } ], "local_path": "reference-docs/cdn-examples-large-dictionary-as.md" @@ -15309,7 +15646,7 @@ { "id": "cdn-examples-large-dictionary-rust", "title": "cdn-examples-large-dictionary-rust", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-large-dictionary-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -15331,9 +15668,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "large-env-var", @@ -15343,7 +15680,7 @@ "app_type", "languages" ], - "content_sha256": "1eb33add15b946d5567ac85d662c67d674c0322a60fd9aa28e0930be81001b54", + "content_sha256": "79abc10593f47efe0567a64ce1580bbb0c5be10f9cfca293be10963f46bb4c9c", "sections": [ { "id": "cdn-examples-large-dictionary-rust#introduction", @@ -15360,9 +15697,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "large-env-var", @@ -15430,7 +15767,7 @@ { "id": "cdn-examples-log-time-as", "title": "Log Time — CDN App (AssemblyScript)", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-log-time-as.md", "skill": "fastedge-docs", "category": "examples", @@ -15454,9 +15791,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -15466,7 +15803,7 @@ "logging", "time" ], - "content_sha256": "0cd462da5aca1fa0b6b8f81e6775b0dea2879447776f153e4cc8522280774585", + "content_sha256": "5266245f16c9a92efe159d422b1d6efbb80268cecbd4be0e9cbf62f79073c1d5", "sections": [ { "id": "cdn-examples-log-time-as#introduction", @@ -15483,9 +15820,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -15830,7 +16167,7 @@ { "id": "cdn-examples-log-time-rust", "title": "Log Time — CDN (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-log-time-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -15852,9 +16189,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -15864,7 +16201,7 @@ "logging", "timing" ], - "content_sha256": "20055b088c670a075eae455b07e6b9a38488a69a6c3199d9566cab1f18d3beaf", + "content_sha256": "17de7b3f08a526cb98293c820d7bd7c1613cadab078a2b31d101893d8def383e", "sections": [ { "id": "cdn-examples-log-time-rust#introduction", @@ -15881,9 +16218,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -16222,7 +16559,7 @@ { "id": "cdn-examples-md2html-rust", "title": "CDN Example: Markdown to HTML (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-md2html-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -16244,9 +16581,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -16256,7 +16593,7 @@ "response-body-transform", "request-path-rewrite" ], - "content_sha256": "1b26d02c4a91ae4a45b55116506d088b7e878c81183e345f40fb5d7a4e9c6f95", + "content_sha256": "f8fbf0e4875baadddcd666f15ec0b2921599d2698c6c647e115d812aa0130fce", "sections": [ { "id": "cdn-examples-md2html-rust#introduction", @@ -16273,9 +16610,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -16705,7 +17042,7 @@ { "id": "cdn-examples-properties-as", "title": "CDN Runtime Properties — AssemblyScript", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-properties-as.md", "skill": "fastedge-docs", "category": "examples", @@ -16727,9 +17064,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "runtime", "properties", "language", @@ -16739,7 +17076,7 @@ "type", "overview" ], - "content_sha256": "1a7cb1c6e4a4a24400ab5988ca4ec6145ff264706a8559555d2c0a9c37c4273c", + "content_sha256": "3bbe18f8ddfeb71ed284002040e77bd67ef56bb6a5281f9165ebb30794f1cf43", "sections": [ { "id": "cdn-examples-properties-as#introduction", @@ -16756,9 +17093,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "cdn", "runtime", "properties", @@ -17257,7 +17594,7 @@ { "id": "cdn-examples-properties-rust", "title": "Request Properties — CDN App Example (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/cdn/examples-properties-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -17279,9 +17616,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -17291,7 +17628,7 @@ "request-properties", "geo-data" ], - "content_sha256": "eb4c151ead93e097ac9ac3e38b0515c3c08db7a6c4eaf57ed6516291ea67ae49", + "content_sha256": "f5e9104e3624d8f2bb64dfb10d2389a9ef745159f38f2ce8dc7fdeff64000933", "sections": [ { "id": "cdn-examples-properties-rust#introduction", @@ -17308,9 +17645,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -18281,7 +18618,7 @@ { "id": "host-services-rust", "title": "Rust Host Services Reference", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/host-services-rust.md", "skill": "fastedge-docs", "category": "sdk", @@ -18300,9 +18637,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "host", "services", "reference", @@ -18313,7 +18650,7 @@ "storage", "secret" ], - "content_sha256": "815f0408c27342ac5a6ee1babbd38b3bf41d35228b85062807f8172c7ef86788", + "content_sha256": "3c1895152a7a969acdb7c1f5e670bd6441f6b3d44fadf5a8640adab15cc3185e", "sections": [ { "id": "host-services-rust#introduction", @@ -18330,9 +18667,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "rust", "host", "services", @@ -18480,6 +18817,13 @@ "change", "lifetime", "deployment.", + "config", + "key_value", + "persistent", + "data", + "secret", + "encrypted", + "credentials.", "api", "rust", "pub", @@ -18499,15 +18843,7 @@ "decoded", "utf-8.", "environment", - "variables", - "set", - "deployment", - "time", - "via", - "platform", - "same", - "management", - "mechanism" + "vari" ] }, { @@ -18603,7 +18939,7 @@ { "id": "http-examples-ab-testing-js", "title": "A/B Testing — FastEdge Example", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-ab-testing-js.md", "skill": "fastedge-docs", "category": "examples", @@ -18625,9 +18961,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "testing", "fastedge", "example", @@ -18638,7 +18974,7 @@ "visitors", "test" ], - "content_sha256": "25feb56e225dc3c2de096f569836c7a02371f3ad66f47c95f09b1d43cae9d0af", + "content_sha256": "035d8a71d445ebe35d7be302675769576440de7ae354afe090ab0810e7efa2ae", "sections": [ { "id": "http-examples-ab-testing-js#introduction", @@ -18655,9 +18991,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "testing", "fastedge", "example" @@ -19165,7 +19501,7 @@ { "id": "http-examples-ab-testing-wasi-rust", "title": "Example: A/B Testing (WASI, Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-ab-testing-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -19187,9 +19523,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -19199,7 +19535,7 @@ "ab-testing", "cookie-parsing" ], - "content_sha256": "21cff74a5cb7a1216109a412f205162be95a99647d070c31cfb71ff8c06626fb", + "content_sha256": "cc40993ca04fabb9520799bde4b5cca46303197434948ca87de607ddb25b659f", "sections": [ { "id": "http-examples-ab-testing-wasi-rust#introduction", @@ -19216,9 +19552,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -19694,7 +20030,7 @@ { "id": "http-examples-api-wrapper-basic-rust", "title": "examples-api-wrapper-basic-rust", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-api-wrapper-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -19716,9 +20052,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "examples-api-wrapper-basic-rust", "type", "example", @@ -19728,7 +20064,7 @@ "language", "app" ], - "content_sha256": "eb2a0df93df00172d7020dc806527d1f98e18809247273240ede8f6952fccbf6", + "content_sha256": "e441eccf269500eb32517fe80bc7b7dcc0840b906593b5298f97ea78452293fd", "sections": [ { "id": "http-examples-api-wrapper-basic-rust#introduction", @@ -19745,9 +20081,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "examples-api-wrapper-basic-rust", "type", "http", @@ -20278,7 +20614,7 @@ { "id": "http-examples-auth-js", "title": "Authentication Patterns (JavaScript)", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-auth-js.md", "skill": "fastedge-docs", "category": "examples", @@ -20300,9 +20636,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "authentication", "patterns", "fastedge", @@ -20313,7 +20649,7 @@ "shared", "secrets" ], - "content_sha256": "2e7f44f68db995e99a39e614304ec39247aa583cb6ccb04e1674dd9b579b49e7", + "content_sha256": "3b2f936aaf35dbf11bd593c13d4027863de2650ffc16c981b157e041ad29dbfd", "sections": [ { "id": "http-examples-auth-js#introduction", @@ -20330,9 +20666,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "authentication", "patterns", "javascript", @@ -20630,7 +20966,7 @@ { "id": "http-examples-backend-basic-rust", "title": "Example: Backend (URL Proxy) — Rust", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-backend-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -20652,9 +20988,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -20664,7 +21000,7 @@ "outbound-http", "query-params" ], - "content_sha256": "7ed671dc0d577b2f44a9be8be61ed5840b34e1ef7ff5b28f5169a14a97e79b0e", + "content_sha256": "653bed0caf43133e7cf62e0930264bec8ced4e99d9db75ad00188b1f618c266d", "sections": [ { "id": "http-examples-backend-basic-rust#introduction", @@ -20681,9 +21017,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -21105,200 +21441,6 @@ "handling", "patterns" ] - }, - { - "id": "http-examples-backend-basic-rust#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 157, - "line_end": 228, - "keywords": [ - "source", - "material", - "file", - "examples", - "http", - "basic", - "backend", - "src", - "lib.rs", - "rust", - "use", - "anyhow", - "error", - "result", - "fastedge", - "body", - "method", - "request", - "response", - "statuscode", - "allow", - "dead_code", - "main", - "req", - "let", - "parts", - "req.into_parts", - "query", - ".uri", - ".query", - ".ok_or", - "missing", - "uri", - "parameter", - "params", - "querystring", - "querify" - ] - }, - { - "id": "http-examples-backend-basic-rust#what-it-does", - "heading": "What it does", - "level": 2, - "anchor": "what-it-does", - "line_start": 229, - "line_end": 238, - "keywords": [ - "parses", - "url", - "query", - "parameter", - "request", - "uri", - "percent-decodes", - "via", - "urlencoding", - "decode", - "builds", - "outbound", - "get", - "using", - "fastedge", - "send_request", - "returns", - "http", - "200", - "plain-text", - "body", - "len", - "body-length", - "content-type", - "upstream-content-type", - "500", - "error", - "message", - "absent", - "string", - "missing." - ] - }, - { - "id": "http-examples-backend-basic-rust#apis-used", - "heading": "APIs used", - "level": 2, - "anchor": "apis-used", - "line_start": 239, - "line_end": 249, - "keywords": [ - "apis", - "used", - "api", - "purpose", - "---", - "fastedge", - "http", - "sync", - "request-response", - "handler", - "macro", - "send_request", - "request", - "blocking", - "outbound", - "response", - "statuscode", - "method", - "types", - "body", - "bodies", - "querystring", - "querify", - "parse", - "query", - "string", - "key-value", - "pairs", - "urlencoding", - "decode", - "percent-decode", - "url", - "value" - ] - }, - { - "id": "http-examples-backend-basic-rust#build", - "heading": "Build", - "level": 2, - "anchor": "build", - "line_start": 250, - "line_end": 256, - "keywords": [ - "build", - "cargo", - "--release", - "output", - "target", - "wasm32-wasip1", - "release", - "backend.wasm" - ] - }, - { - "id": "http-examples-backend-basic-rust#expected-behavior", - "heading": "Expected behavior", - "level": 2, - "anchor": "expected-behavior", - "line_start": 257, - "line_end": 267, - "keywords": [ - "expected", - "behavior", - "request", - "response", - "status", - "body", - "---", - "get", - "url", - "https", - "2fhttpbin.org", - "2fget", - "200", - "len", - "content-type", - "mime", - "hello", - "key", - "500", - "missing", - "parameter", - "query", - "string", - "uri", - "value", - "byte", - "length", - "upstream", - "body.", - "header", - "returned", - "server", - "formatted", - "rust", - "option" - ] } ], "local_path": "reference-docs/http-examples-backend-basic-rust.md" @@ -21306,7 +21448,7 @@ { "id": "http-examples-bloom-filter-denylist-wasi-rust", "title": "Example: Bloom Filter IP Denylist (WASI, Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-bloom-filter-denylist-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -21328,9 +21470,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -21340,7 +21482,7 @@ "kv-store", "bloom-filter" ], - "content_sha256": "fa4e6b140a8db8f8879eb511aa72c60e9e495039ae9a1b80cfd2c9841d0bef19", + "content_sha256": "a447a165a864934a9567ab24a9258a36cc441050690b08e0afe96a7a9523a505", "sections": [ { "id": "http-examples-bloom-filter-denylist-wasi-rust#introduction", @@ -21357,9 +21499,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -21812,6 +21954,188 @@ "platform-overview", "concepts" ] + }, + { + "id": "http-examples-bloom-filter-denylist-wasi-rust#source-material", + "heading": "Source Material", + "level": 2, + "anchor": "source-material", + "line_start": 154, + "line_end": 283, + "keywords": [ + "source", + "material", + "file", + "examples", + "http", + "wasi", + "bloom_filter_denylist", + "src", + "lib.rs", + "rust", + "copyright", + "2025", + "g-core", + "innovations", + "sarl", + "bloom-filter", + "denylist", + "example.", + "checks", + "client", + "x-real-ip", + "request", + "header", + "falling", + "back", + "x-forwarded-for", + "against", + "bloom", + "filter", + "stored", + "fastedge", + "kv.", + "returns", + "403", + "hit", + "200", + "otherwise.", + "required", + "configuration", + "environment" + ] + }, + { + "id": "http-examples-bloom-filter-denylist-wasi-rust#configuration", + "heading": "Configuration", + "level": 2, + "anchor": "configuration", + "line_start": 284, + "line_end": 289, + "keywords": [ + "configuration", + "environment", + "variable", + "denylist_store", + "name", + "store", + "holds", + "bloom", + "filter.", + "bloom-filter", + "key", + "hardcoded", + "blocked-ips", + "change", + "bloom_key", + "src", + "lib.rs", + "your", + "different." + ] + }, + { + "id": "http-examples-bloom-filter-denylist-wasi-rust#behaviour", + "heading": "Behaviour", + "level": 2, + "anchor": "behaviour", + "line_start": 290, + "line_end": 296, + "keywords": [ + "behaviour", + "bf_exists", + "blocked-ips", + "response", + "---", + "true", + "403", + "allowed", + "false", + "...", + "200" + ] + }, + { + "id": "http-examples-bloom-filter-denylist-wasi-rust#tradeoff-false-positives", + "heading": "Tradeoff: false positives", + "level": 2, + "anchor": "tradeoff-false-positives", + "line_start": 297, + "line_end": 304, + "keywords": [ + "tradeoff", + "false", + "positives", + "bloom", + "filters", + "answer", + "definitely", + "set", + "maybe", + "bf_exists", + "returns", + "true", + "probably", + "added", + "small", + "fraction", + "hits", + "meaning", + "legitimate", + "ips", + "over-blocked.", + "acceptable", + "denylist", + "allowlists", + "anything", + "requiring", + "exact", + "membership", + "use", + "store.get", + "against", + "regular", + "key", + "instead." + ] + }, + { + "id": "http-examples-bloom-filter-denylist-wasi-rust#populating-the-filter", + "heading": "Populating the filter", + "level": 2, + "anchor": "populating-the-filter", + "line_start": 305, + "line_end": 309, + "keywords": [ + "populating", + "filter", + "edge", + "handler", + "read-only.", + "populate", + "blocked-ips", + "out", + "band", + "example", + "via", + "fastedge", + "api" + ] + }, + { + "id": "http-examples-bloom-filter-denylist-wasi-rust#related", + "heading": "Related", + "level": 2, + "anchor": "related", + "line_start": 310, + "line_end": 314, + "keywords": [ + "related", + "mirror", + "fastedge-sdk-js", + "examples", + "bloom-filter-denylist" + ] } ], "local_path": "reference-docs/http-examples-bloom-filter-denylist-wasi-rust.md" @@ -21819,7 +22143,7 @@ { "id": "http-examples-cache-basic-rust", "title": "Cache Basic (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-cache-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -21841,9 +22165,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -21853,7 +22177,7 @@ "cache", "basic" ], - "content_sha256": "51fe5b585b86d0b39142ab2d5313ea57a260b1d8830ad7d38bce3b839f9f9961", + "content_sha256": "58aa39343f1d956e9ab8ab5ea82eba707a1033fac18ca3f195c40b96b7b3016b", "sections": [ { "id": "http-examples-cache-basic-rust#introduction", @@ -21870,9 +22194,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -22265,6 +22589,192 @@ "selection", "guidance" ] + }, + { + "id": "http-examples-cache-basic-rust#source-material", + "heading": "Source Material", + "level": 2, + "anchor": "source-material", + "line_start": 137, + "line_end": 244, + "keywords": [ + "source", + "material", + "file", + "examples", + "http", + "basic", + "cache", + "src", + "lib.rs", + "rust", + "copyright", + "2025", + "g-core", + "innovations", + "sarl", + "example", + "app", + "demonstrating", + "cache-aside", + "pattern", + "via", + "interface.", + "request", + "builds", + "key", + "path.", + "returns", + "cached", + "body", + "immediately", + "hit", + "x-cache", + "miss", + "generates", + "response", + "stores", + "environment", + "variables", + "cache_ttl_ms", + "long" + ] + }, + { + "id": "http-examples-cache-basic-rust#configuration", + "heading": "Configuration", + "level": 2, + "anchor": "configuration", + "line_start": 245, + "line_end": 250, + "keywords": [ + "configuration", + "env", + "var", + "required", + "description", + "---", + "cache_ttl_ms", + "long", + "cache", + "response", + "milliseconds.", + "default", + "30000" + ] + }, + { + "id": "http-examples-cache-basic-rust#how-it-works", + "heading": "How it works", + "level": 2, + "anchor": "how-it-works", + "line_start": 251, + "line_end": 259, + "keywords": [ + "works", + "get", + "api", + "data", + "cache", + "miss", + "generate", + "body", + "store", + "200", + "x-cache", + "hit", + "return", + "cached", + "key", + "page", + "request-path", + "unique", + "path", + "gets", + "own", + "entry.", + "response", + "simple", + "html", + "includes", + "request", + "stand", + "expensive", + "computation", + "template", + "render." + ] + }, + { + "id": "http-examples-cache-basic-rust#what-it-returns", + "heading": "What it returns", + "level": 2, + "anchor": "what-it-returns", + "line_start": 260, + "line_end": 269, + "keywords": [ + "returns", + "http", + "1.1", + "200", + "content-type", + "text", + "html", + "x-cache", + "hit", + "miss", + "doctype", + "..." + ] + }, + { + "id": "http-examples-cache-basic-rust#build", + "heading": "Build", + "level": 2, + "anchor": "build", + "line_start": 270, + "line_end": 276, + "keywords": [ + "build", + "cargo", + "--release", + "output", + "target", + "wasm32-wasip1", + "release", + "cache_basic.wasm" + ] + }, + { + "id": "http-examples-cache-basic-rust#apis-used", + "heading": "APIs used", + "level": 2, + "anchor": "apis-used", + "line_start": 277, + "line_end": 282, + "keywords": [ + "apis", + "used", + "fastedge", + "cache", + "get", + "key", + "retrieve", + "cached", + "bytes", + "returns", + "option", + "vec", + "set", + "ttl_ms", + "store", + "optional", + "ttl", + "milliseconds", + "none", + "means", + "expiry" + ] } ], "local_path": "reference-docs/http-examples-cache-basic-rust.md" @@ -22272,7 +22782,7 @@ { "id": "http-examples-cache-js", "title": "FastEdge Cache — JavaScript Examples", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-cache-js.md", "skill": "fastedge-docs", "category": "examples", @@ -22296,9 +22806,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "cache", "module", @@ -22308,7 +22818,7 @@ "2.3.0", "app" ], - "content_sha256": "1836a727bbc36819e95787b311b6d05ca2b8ac657190824b76fc727e7fa81ceb", + "content_sha256": "c53a54daf9307b32c0aa69a72792c852be660acff331a69288bf9425b6a194a6", "sections": [ { "id": "http-examples-cache-js#introduction", @@ -22325,9 +22835,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "cache", "javascript", @@ -22656,56 +23166,6 @@ "response", "construction" ] - }, - { - "id": "http-examples-cache-js#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 335, - "line_end": 610, - "keywords": [ - "source", - "material", - "file", - "examples", - "cache", - "src", - "index.ts", - "fastedge", - "flagship", - "patterns", - "example", - "demonstrates", - "three", - "highest-value", - "uses", - "module", - "per-ip", - "rate", - "limiting", - "atomic", - "counters", - "origin-cache", - "proxy", - "manual", - "get", - "set", - "conditional", - "caching", - "json", - "memoisation", - "getorset", - "computed", - "populator", - "rely", - "strongly", - "consistent", - "within", - "pop", - "incr", - "returns" - ] } ], "local_path": "reference-docs/http-examples-cache-js.md" @@ -22713,7 +23173,7 @@ { "id": "http-examples-cache-wasi-rust", "title": "Cache (WASI) — Rust HTTP Example", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-cache-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -22735,9 +23195,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -22747,7 +23207,7 @@ "cache", "outbound-http" ], - "content_sha256": "31cfe4b83115feeb78ff407e5c37207e21a522d87f06aeb8d7607aa6ad31cd67", + "content_sha256": "7c58be673c4adce9e4ac6ad2928c95a42a645cf231c1f09d901ed10534e327cc", "sections": [ { "id": "http-examples-cache-wasi-rust#introduction", @@ -22764,9 +23224,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -23115,194 +23575,6 @@ "workflow", "skill" ] - }, - { - "id": "http-examples-cache-wasi-rust#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 192, - "line_end": 359, - "keywords": [ - "source", - "material", - "file", - "examples", - "http", - "wasi", - "cache", - "src", - "lib.rs", - "rust", - "copyright", - "2025", - "g-core", - "innovations", - "sarl", - "example", - "app", - "demonstrating", - "response", - "caching", - "purging", - "via", - "interface.", - "reads", - "origin_host", - "environment", - "forwards", - "incoming", - "request", - "origin", - "caches", - "body", - "keyed", - "path.", - "subsequent", - "requests", - "same", - "path", - "cached", - "returned" - ] - }, - { - "id": "http-examples-cache-wasi-rust#configuration", - "heading": "Configuration", - "level": 2, - "anchor": "configuration", - "line_start": 360, - "line_end": 366, - "keywords": [ - "configuration", - "env", - "var", - "required", - "description", - "---", - "origin_host", - "yes", - "base", - "url", - "upstream", - "origin", - "e.g.", - "https", - "api.example.com", - "returns", - "500", - "unset.", - "cache_ttl_ms", - "long", - "cache", - "responses", - "milliseconds.", - "default", - "60000" - ] - }, - { - "id": "http-examples-cache-wasi-rust#how-it-works", - "heading": "How it works", - "level": 2, - "anchor": "how-it-works", - "line_start": 367, - "line_end": 373, - "keywords": [ - "works", - "get", - "data", - "cache", - "miss", - "forward", - "origin_host", - "2xx", - "body", - "200", - "x-cache", - "hit", - "return", - "cached", - "key", - "path", - "query", - "only", - "responses", - "origin", - "error", - "pass", - "without", - "stored.", - "response", - "headers", - "replayed", - "cache-hit", - "use", - "content-type", - "application", - "octet-stream", - "sinc" - ] - }, - { - "id": "http-examples-cache-wasi-rust#build", - "heading": "Build", - "level": 2, - "anchor": "build", - "line_start": 374, - "line_end": 378, - "keywords": [ - "build", - "cargo", - "--release", - "output", - "target", - "wasm32-wasip2", - "release", - "cache_wasi.wasm" - ] - }, - { - "id": "http-examples-cache-wasi-rust#apis-used", - "heading": "APIs used", - "level": 2, - "anchor": "apis-used", - "line_start": 379, - "line_end": 385, - "keywords": [ - "apis", - "used", - "fastedge", - "cache", - "get", - "key", - "retrieve", - "cached", - "bytes", - "returns", - "option", - "vec", - "set", - "ttl_ms", - "store", - "optional", - "ttl", - "milliseconds", - "none", - "means", - "expiry", - "wstd", - "http", - "client", - "new", - ".send", - "req", - ".await", - "async", - "outbound", - "request", - "origin" - ] } ], "local_path": "reference-docs/http-examples-cache-wasi-rust.md" @@ -23310,7 +23582,7 @@ { "id": "http-examples-diagnostic-logging-wasi-rust", "title": "Diagnostic Logging — Rust (WASI HTTP)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-diagnostic-logging-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -23332,9 +23604,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "diagnostic-logging", @@ -23344,7 +23616,7 @@ "languages", "diagnostic" ], - "content_sha256": "b55cd1e2b402fa75e701e2336c62aa6314ec4be802409333a130cb1ffcbfe91c", + "content_sha256": "e0b1cfb99fd9375902a7ab410213218de42cf836f17460e19e3cef595ebc872b", "sections": [ { "id": "http-examples-diagnostic-logging-wasi-rust#introduction", @@ -23361,9 +23633,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "diagnostic-logging", @@ -23864,223 +24136,6 @@ "store", "usage" ] - }, - { - "id": "http-examples-diagnostic-logging-wasi-rust#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 194, - "line_end": 307, - "keywords": [ - "source", - "material", - "file", - "examples", - "http", - "wasi", - "diagnostic_logging", - "src", - "lib.rs", - "rust", - "copyright", - "2025", - "g-core", - "innovations", - "sarl", - "diagnostic", - "logging", - "example.", - "tiny", - "pass-through", - "proxy", - "writes", - "single", - "set_user_diag", - "tag", - "per", - "request", - "summarising", - "outcome", - "config_error", - "origin_unreachable", - "proxied", - "appears", - "fastedge", - "platform", - "per-request", - "log", - "viewer", - "distinct", - "stdout" - ] - }, - { - "id": "http-examples-diagnostic-logging-wasi-rust#configuration", - "heading": "Configuration", - "level": 2, - "anchor": "configuration", - "line_start": 308, - "line_end": 311, - "keywords": [ - "configuration", - "origin_url", - "environment", - "variable", - "origin", - "requests", - "proxied", - "to." - ] - }, - { - "id": "http-examples-diagnostic-logging-wasi-rust#outcomes", - "heading": "Outcomes", - "level": 2, - "anchor": "outcomes", - "line_start": 312, - "line_end": 321, - "keywords": [ - "outcomes", - "request", - "writes", - "exactly", - "one", - "condition", - "tag", - "---", - "origin_url", - "missing", - "outcome", - "config_error", - "reason", - "origin_missing", - "origin", - "unreachable", - "origin_unreachable", - "method", - "path", - "err", - "proxied", - "status" - ] - }, - { - "id": "http-examples-diagnostic-logging-wasi-rust#set_user_diag-vs-println", - "heading": "`set_user_diag` vs `println!`", - "level": 2, - "anchor": "set_user_diag-vs-println", - "line_start": 322, - "line_end": 330, - "keywords": [ - "set_user_diag", - "println", - "---", - "channel", - "stdout", - "general", - "application", - "logs", - "per-request", - "structured", - "tag", - "platform", - "log", - "viewer", - "cardinality", - "many", - "per", - "request", - "one", - "multiple", - "calls", - "leave", - "only", - "last", - "concatenated", - "undefined", - "best", - "verbose", - "traces", - "debug", - "details", - "single", - "filterable", - "outcome", - "label", - "forbidden", - "secrets", - "pii", - "tags", - "appear" - ] - }, - { - "id": "http-examples-diagnostic-logging-wasi-rust#convention", - "heading": "Convention", - "level": 2, - "anchor": "convention", - "line_start": 331, - "line_end": 336, - "keywords": [ - "convention", - "call", - "set_user_diag", - "once", - "branch", - "late", - "enough", - "handler", - "know", - "outcome.", - "logfmt", - "-ish", - "format", - "outcome", - "verb", - "key", - "value", - "easy", - "slice", - "log", - "search", - "tooling", - "keep", - "keys", - "short", - "stable", - "they", - "make", - "good", - "filter", - "terms." - ] - }, - { - "id": "http-examples-diagnostic-logging-wasi-rust#related", - "heading": "Related", - "level": 2, - "anchor": "related", - "line_start": 337, - "line_end": 342, - "keywords": [ - "related", - "cdn", - "proxy-wasm", - "variant", - "fastedge", - "proxywasm", - "utils", - "set_user_diag", - "same", - "semantics", - "different", - "module", - "path.", - "see", - "docs", - "cdn_apps.md" - ] } ], "local_path": "reference-docs/http-examples-diagnostic-logging-wasi-rust.md" @@ -24088,7 +24143,7 @@ { "id": "http-examples-fetch-js", "title": "http-examples-fetch-js", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-fetch-js.md", "skill": "fastedge-docs", "category": "examples", @@ -24110,9 +24165,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "fetch", "outbound", "requests", @@ -24123,7 +24178,7 @@ "standard", "url" ], - "content_sha256": "032adc2beba6b9b9dade30fcf609e1febf5a9b7ddc47a88c37889d1eec835870", + "content_sha256": "9d09d5b86b672a1ceca9e554cda3515013cbfff850d242803d0014706b1e022f", "sections": [ { "id": "http-examples-fetch-js#introduction", @@ -24140,9 +24195,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20" + "2026-09-22" ] }, { @@ -24200,7 +24255,7 @@ { "id": "http-examples-geo-redirect-js", "title": "http-examples-geo-redirect-js", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-geo-redirect-js.md", "skill": "fastedge-docs", "category": "examples", @@ -24222,9 +24277,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "example", "geo-redirect", "redirects", @@ -24236,7 +24291,7 @@ "visitor", "country" ], - "content_sha256": "07208f0d1266ed5eecd1ac212b47f0a27cb432220881b2f7fac6a6d4aee0bbd4", + "content_sha256": "f1a1a79fa9a815fb6ded9e34dbccf9e56e95413f718fa7a5203871f4814e706c", "sections": [ { "id": "http-examples-geo-redirect-js#introduction", @@ -24253,9 +24308,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20" + "2026-09-22" ] }, { @@ -24314,7 +24369,7 @@ { "id": "http-examples-geo-redirect-wasi-rust", "title": "Geo Redirect — WASI HTTP (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-geo-redirect-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -24336,9 +24391,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -24348,7 +24403,7 @@ "geo-redirect", "headers" ], - "content_sha256": "92d1d6dcd29aa84e8c9a383b7f31e2a4c3550686a7586e2c164187596b5df709", + "content_sha256": "ebf328ce37861f9d7fe2fd1a9d745988abae0e3f0d80397151c464f8ed4182cc", "sections": [ { "id": "http-examples-geo-redirect-wasi-rust#introduction", @@ -24365,9 +24420,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -24941,7 +24996,7 @@ { "id": "http-examples-headers-js", "title": "http-examples-headers-js", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-headers-js.md", "skill": "fastedge-docs", "category": "examples", @@ -24963,9 +25018,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "headers", "example", "fastedge", @@ -24977,7 +25032,7 @@ "environment", "variable" ], - "content_sha256": "d4a5d1b949bfe5116aee65279e796b023d55d59544854876eaf493c110eef90c", + "content_sha256": "a375b46028720ee5a9a69d73ca41c1884f6ca1e34db5f2e2ef475340fef83f6c", "sections": [ { "id": "http-examples-headers-js#introduction", @@ -24994,9 +25049,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20" + "2026-09-22" ] }, { @@ -25049,7 +25104,7 @@ { "id": "http-examples-headers-wasi-rust", "title": "HTTP Headers Example — WASI (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-headers-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -25071,9 +25126,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -25083,7 +25138,7 @@ "headers", "env-vars" ], - "content_sha256": "b6142b5b461c8cc47c3422fa749ff3d7ca808ac8618aa481eaecd952f6b80483", + "content_sha256": "faa792bdc1043deed4c61b7b4e581f50616924995335ac4293a7722745dddd4b", "sections": [ { "id": "http-examples-headers-wasi-rust#introduction", @@ -25100,9 +25155,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -25699,7 +25754,7 @@ { "id": "http-examples-hello-world-basic-rust", "title": "Hello World — Basic HTTP (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-hello-world-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -25721,9 +25776,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -25733,7 +25788,7 @@ "hello-world", "basic-handler" ], - "content_sha256": "c3aac88e44de0d555bc462d6d70424ab34d4f0dec25606a2625ceb5e39b67400", + "content_sha256": "37e082cfacf1c690062e7464ba6b456feb35ca7e3c27e75c4182965562a648da", "sections": [ { "id": "http-examples-hello-world-basic-rust#introduction", @@ -25750,9 +25805,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -26132,7 +26187,7 @@ { "id": "http-examples-hello-world-wasi-rust", "title": "Example: Hello World (WASI) — Rust", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-hello-world-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -26154,9 +26209,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -26166,7 +26221,7 @@ "hello-world", "wasi" ], - "content_sha256": "b15ce34c19d4cf004bf6f602e6bf370c34f33abd962e77ce72f4bc13969016fe", + "content_sha256": "d6dc36ec9e0a07fbf165cb7912f5025529a82884768c0b4f9af1305288940b2b", "sections": [ { "id": "http-examples-hello-world-wasi-rust#introduction", @@ -26183,9 +26238,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -26585,7 +26640,7 @@ { "id": "http-examples-hono-js", "title": "Hono Patterns on FastEdge (JavaScript/TypeScript)", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-hono-js.md", "skill": "fastedge-docs", "category": "examples", @@ -26609,9 +26664,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "hono", "patterns", "fastedge", @@ -26620,7 +26675,7 @@ "apps.", "small" ], - "content_sha256": "4c75f73bbc6d7fbc5686f1d701a49ba1af7af0c650a910e3d47ae72272afdf1e", + "content_sha256": "4332733a5c2543a348bf8e164983d9f7e108418959d01ef10691440e45081d31", "sections": [ { "id": "http-examples-hono-js#introduction", @@ -26637,9 +26692,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "hono", "patterns", "fastedge", @@ -26867,7 +26922,7 @@ { "id": "http-examples-kv-store-js", "title": "http-examples-kv-store-js", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-kv-store-js.md", "skill": "fastedge-docs", "category": "examples", @@ -26889,9 +26944,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "store", "example", "reference", @@ -26903,7 +26958,7 @@ "fastedge", "edge" ], - "content_sha256": "bbee208b19ac9c128c58c2b3a483f133bf01d56becf4d62a328e664fb466c646", + "content_sha256": "bba21afe2826aed5c7c9e8f316219400c9ae56a59e1d5c0230c64196b8d85b88", "sections": [ { "id": "http-examples-kv-store-js#introduction", @@ -26920,9 +26975,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20" + "2026-09-22" ] }, { @@ -26979,7 +27034,7 @@ { "id": "http-examples-kv-store-wasi-rust", "title": "KV Store — Rust (WASI HTTP)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-kv-store-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -27001,9 +27056,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "kv-store", @@ -27013,7 +27068,7 @@ "languages", "store" ], - "content_sha256": "315969c42f8aa2c0325e094018cc3d59e5f68550acd5744a480b2302a15d0860", + "content_sha256": "828de5dab25ce52b865c81265bfcd8f41ea2c236d44bafb9045985ef9759cb95", "sections": [ { "id": "http-examples-kv-store-wasi-rust#introduction", @@ -27030,9 +27085,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "capabilities", "kv-store", @@ -27466,7 +27521,7 @@ { "id": "http-examples-large-env-variable-wasi-rust", "title": "Large Environment Variable (WASI) — Rust HTTP Example", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-large-env-variable-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -27488,9 +27543,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "large", "environment", "variable", @@ -27500,7 +27555,7 @@ "demonstrates", "read" ], - "content_sha256": "ab40bc5e1a189d77f212f789961be555b81ceead639067c4ccfbdc9f2e4e1d6c", + "content_sha256": "094c1dcce620b2e59578200c905580766b4a3800979c0e057d373e855651f1d1", "sections": [ { "id": "http-examples-large-env-variable-wasi-rust#introduction", @@ -27517,9 +27572,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "large", "environment", "variable", @@ -27856,7 +27911,7 @@ { "id": "http-examples-markdown-render-basic-rust", "title": "HTTP Example: Markdown Render (Rust, Basic)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-markdown-render-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -27878,9 +27933,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -27890,7 +27945,7 @@ "outbound-fetch", "env-vars" ], - "content_sha256": "e170431974501dcb609073b8be6b0f0c93a73841a33255b961077dec00c66f68", + "content_sha256": "bf7a3959832f6f6813babb0f96e471a0c68d3cbc420f6baa775c2e2229ce1329", "sections": [ { "id": "http-examples-markdown-render-basic-rust#introduction", @@ -27907,9 +27962,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -28383,7 +28438,7 @@ { "id": "http-examples-outbound-fetch-basic-rust", "title": "Example: Outbound Fetch — Basic HTTP (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-outbound-fetch-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -28405,9 +28460,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -28417,7 +28472,7 @@ "outbound-fetch", "json-parsing" ], - "content_sha256": "7d9b8470977ba554efeff699feeee8f078a5b682b5d396d070f0589f49f8044f", + "content_sha256": "9d41b008474919364325a73334175ac51ca10b8fbaabee8bee40b6415b2b8c9e", "sections": [ { "id": "http-examples-outbound-fetch-basic-rust#introduction", @@ -28434,9 +28489,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -28811,7 +28866,7 @@ { "id": "http-examples-outbound-fetch-wasi-rust", "title": "Outbound Fetch — WASI (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-outbound-fetch-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -28833,9 +28888,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "outbound", "fetch", "wasi", @@ -28845,7 +28900,7 @@ "upstream", "origin" ], - "content_sha256": "c5a6c3a406e12b4a82281f715d7f268d84b732cc76ec9376b34314302cea12dc", + "content_sha256": "57f3381591f07f1ac6daab49fe28d96aa6a757531829f89c225680550a56abfb", "sections": [ { "id": "http-examples-outbound-fetch-wasi-rust#introduction", @@ -28862,9 +28917,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "outbound", "fetch", "wasi", @@ -29262,7 +29317,7 @@ { "id": "http-examples-outbound-modify-response-wasi-rust", "title": "Example: Outbound Modify Response (WASI, Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-outbound-modify-response-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -29284,9 +29339,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -29296,7 +29351,7 @@ "outbound-fetch", "json-transform" ], - "content_sha256": "f6509335e7b9957b364049295ea3a84967dce13ae1e03c5ebbd8412f6e0dfb05", + "content_sha256": "f8cc2f72f5324a9da973c0e8eac43544bd59637ba3cbcd84ea858acd9de6596f", "sections": [ { "id": "http-examples-outbound-modify-response-wasi-rust#introduction", @@ -29313,9 +29368,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -29710,7 +29765,7 @@ { "id": "http-examples-print-basic-rust", "title": "Example: Print (HTTP Request Echo) — Rust", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-print-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -29732,9 +29787,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -29744,7 +29799,7 @@ "request-inspection", "header-iteration" ], - "content_sha256": "7c8720cc88a63e99432da519839a4f5b8438520df5ac92432b3c524afbaa1f85", + "content_sha256": "b33f1a09f2dca08a64f23ac6419b228e8de755a66bc4de6a66fffadee231998c", "sections": [ { "id": "http-examples-print-basic-rust#introduction", @@ -29761,9 +29816,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -30160,202 +30215,6 @@ "building", "patterns" ] - }, - { - "id": "http-examples-print-basic-rust#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 151, - "line_end": 214, - "keywords": [ - "source", - "material", - "file", - "examples", - "http", - "basic", - "print", - "src", - "lib.rs", - "rust", - "use", - "anyhow", - "result", - "fastedge", - "body", - "request", - "response", - "statuscode", - "allow", - "dead_code", - "main", - "req", - "let", - "mut", - "string", - "method", - ".to_string", - "body.push_str", - "req.method", - ".as_str", - "nurl", - "req.uri", - "nheaders" - ] - }, - { - "id": "http-examples-print-basic-rust#what-it-demonstrates", - "heading": "What it demonstrates", - "level": 2, - "anchor": "what-it-demonstrates", - "line_start": 215, - "line_end": 222, - "keywords": [ - "demonstrates", - "reading", - "request", - "method", - "via", - "req.method", - ".as_str", - "uri", - "req.uri", - ".to_string", - "iterating", - "headers", - "req.headers", - "handling", - "non-utf-8", - "header", - "values", - "gracefully", - "match", - "v.to_str", - "building", - "plain-text", - "response", - "builder", - "body", - "..." - ] - }, - { - "id": "http-examples-print-basic-rust#apis-used", - "heading": "APIs used", - "level": 2, - "anchor": "apis-used", - "line_start": 223, - "line_end": 233, - "keywords": [ - "apis", - "used", - "api", - "purpose", - "-----", - "---------", - "req.method", - ".as_str", - "http", - "method", - "string", - "slice", - "req.uri", - ".to_string", - "full", - "request", - "uri", - "req.headers", - "iterator", - "over", - "headername", - "headervalue", - "pairs", - "v.to_str", - "decode", - "header", - "value", - "str", - "returns", - "err", - "non-utf-8", - "response", - "builder", - ".status", - "...", - ".body", - "build", - "body", - "create" - ] - }, - { - "id": "http-examples-print-basic-rust#build", - "heading": "Build", - "level": 2, - "anchor": "build", - "line_start": 234, - "line_end": 240, - "keywords": [ - "build", - "cargo", - "--release", - "output", - "target", - "wasm32-wasip1", - "release", - "print.wasm" - ] - }, - { - "id": "http-examples-print-basic-rust#expected-behaviour", - "heading": "Expected behaviour", - "level": 2, - "anchor": "expected-behaviour", - "line_start": 241, - "line_end": 259, - "keywords": [ - "expected", - "behaviour", - "request", - "response", - "body", - "plain-text", - "dump", - "details", - "method", - "get", - "url", - "path", - "query", - "value", - "headers", - "host", - "example.com", - "accept", - "...", - "status", - "200", - "content", - "plain", - "text", - "content-type", - "header", - "set", - "explicitly", - "platform", - "add", - "one", - "appears", - "own", - "line", - "indented", - "four", - "spaces", - "non-utf-8", - "values", - "replaced" - ] } ], "local_path": "reference-docs/http-examples-print-basic-rust.md" @@ -30363,7 +30222,7 @@ { "id": "http-examples-proxy-js", "title": "Proxy and Response Transform Patterns (JavaScript/TypeScript)", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-proxy-js.md", "skill": "fastedge-docs", "category": "examples", @@ -30387,9 +30246,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "proxy", "response", "transform", @@ -30398,7 +30257,7 @@ "fastedge", "apps" ], - "content_sha256": "cf79e7be2bb9093568bcf8495bf36926610c71e4cb36df51b122a605fdfb3725", + "content_sha256": "08a57d5d0098acb645f51c29d3f5850d1dad67ec7d808d89c78453d0323ec904", "sections": [ { "id": "http-examples-proxy-js#introduction", @@ -30415,9 +30274,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "proxy", "response", "transform", @@ -30851,349 +30710,6 @@ "kvstore", "api" ] - }, - { - "id": "http-examples-proxy-js#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 254, - "line_end": 264, - "keywords": [ - "source", - "material", - "file", - "docs", - "proxy_patterns.md", - "maintenance", - "hand-authored.", - "produced", - "fastedge-plugin-source", - "generate-docs.sh.", - "edit", - "directly.", - "proxy", - "response", - "transform", - "patterns", - "fastedge", - "http", - "apps", - "act", - "thin", - "front", - "origin", - "upstream", - "api", - "fetching", - "transforming", - "returning", - "result.", - "document", - "covers", - "common", - "patterns." - ] - }, - { - "id": "http-examples-proxy-js#simple-proxy", - "heading": "Simple Proxy", - "level": 2, - "anchor": "simple-proxy", - "line_start": 265, - "line_end": 291, - "keywords": [ - "simple", - "proxy", - "fetch", - "upstream", - "return", - "body", - "unchanged", - "typescript", - "async", - "function", - "handle", - "request", - "const", - "url", - "new", - "request.url", - "https", - "backend.example.com", - "url.pathname", - "url.search", - "response", - "await", - "method", - "request.method", - "headers", - "request.headers", - "get", - "head", - "request.arraybuffer", - "undefined", - "addeventlistener" - ] - }, - { - "id": "http-examples-proxy-js#proxy-with-json-transform", - "heading": "Proxy with JSON Transform", - "level": 2, - "anchor": "proxy-with-json-transform", - "line_start": 292, - "line_end": 320, - "keywords": [ - "proxy", - "json", - "transform", - "modify", - "response", - "body", - "returning", - "it.", - "pattern", - "examples", - "outbound-modify-response", - "typescript", - "async", - "function", - "handle", - "const", - "upstream", - "await", - "fetch", - "https", - "jsonplaceholder.typicode.com", - "users", - "upstream.json", - "transformed", - "users.slice", - "total", - "skip", - "limit", - "return", - "new", - "json.stringify", - "status", - "200", - "headers", - "content-type" - ] - }, - { - "id": "http-examples-proxy-js#hono-proxy-with-transform", - "heading": "Hono Proxy with Transform", - "level": 2, - "anchor": "hono-proxy-with-transform", - "line_start": 321, - "line_end": 351, - "keywords": [ - "hono", - "proxy", - "transform", - "inside", - "app", - "use", - "c.req.raw.headers", - "forward", - "inbound", - "headers", - "c.req.arraybuffer", - "body", - "typescript", - "import", - "const", - "new", - "app.all", - "api", - "async", - "url", - "c.req.url", - "upstream", - "https", - "backend.example.com", - "url.pathname", - "url.search", - "response", - "await", - "fetch", - "method", - "c.req.method", - "get", - "c.r" - ] - }, - { - "id": "http-examples-proxy-js#header-manipulation-in-proxies", - "heading": "Header Manipulation in Proxies", - "level": 2, - "anchor": "header-manipulation-in-proxies", - "line_start": 352, - "line_end": 380, - "keywords": [ - "header", - "manipulation", - "proxies", - "strip", - "hop-by-hop", - "headers", - "forwarding", - "upstream", - "add", - "diagnostic", - "way", - "back", - "typescript", - "async", - "function", - "handle", - "request", - "const", - "upstreamheaders", - "new", - "request.headers", - "forwarded", - "upstreamheaders.delete", - "connection", - "keep-alive", - "transfer-encoding", - "await", - "fetch", - "https", - "backend.example.com", - "method", - "request.m" - ] - }, - { - "id": "http-examples-proxy-js#cache-aware-proxy-with-kv", - "heading": "Cache-aware Proxy with KV", - "level": 2, - "anchor": "cache-aware-proxy-with-kv", - "line_start": 381, - "line_end": 413, - "keywords": [ - "cache-aware", - "proxy", - "cache", - "upstream", - "responses", - "store", - "avoid", - "repeated", - "outbound", - "calls.", - "note", - "read-only", - "app", - "code", - "writes", - "happen", - "via", - "portal", - "api", - "typescript", - "import", - "kvstore", - "fastedge", - "async", - "function", - "handle", - "request", - "const", - "url", - "new", - "request.url", - "try", - "kvstore.open", - "api-cache", - "cached", - "cache.get", - "url.pathname", - "null", - "return", - "response" - ] - }, - { - "id": "http-examples-proxy-js#operational-notes", - "heading": "Operational Notes", - "level": 2, - "anchor": "operational-notes", - "line_start": 414, - "line_end": 419, - "keywords": [ - "operational", - "notes", - "outbound", - "fetch", - "budget.", - "invocation", - "limited", - "number", - "requests", - "basic", - "pro", - "parallelise", - "possible", - "promise.all", - "...", - "instead", - "sequential", - "await", - "execution", - "time", - "proxying", - "upstream", - "transforming", - "counts", - "against", - "50ms", - "200ms", - "slow", - "upstreams", - "trip", - "532", - "timeouts.", - "body", - "size", - "limits.", - "inbound", - "bodies", - "subject", - "configured", - "request" - ] - }, - { - "id": "http-examples-proxy-js#see-also", - "heading": "See Also", - "level": 2, - "anchor": "see-also", - "line_start": 420, - "line_end": 428, - "keywords": [ - "see", - "examples", - "outbound-modify-response", - "json", - "transform", - "upstream", - "response", - "outbound-fetch", - "basic", - "outbound", - "fetch", - "patterns", - "headers", - "request", - "header", - "manipulation", - "kv-store", - "kv-backed", - "caching" - ] } ], "local_path": "reference-docs/http-examples-proxy-js.md" @@ -31201,7 +30717,7 @@ { "id": "http-examples-s3upload-basic-rust", "title": "S3 Upload — HTTP Example (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-s3upload-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -31223,9 +30739,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -31235,7 +30751,7 @@ "s3-upload", "presigned-url" ], - "content_sha256": "a8c2d5d395a46515ff38614cfb280eb3ac460c00da9f34cd6c710cf4df130f29", + "content_sha256": "72cff95ae062275b261acaf37d03d72affe87facf10960cd16531237ff6bd4cf", "sections": [ { "id": "http-examples-s3upload-basic-rust#introduction", @@ -31252,9 +30768,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -31693,240 +31209,6 @@ "documentation", "external" ] - }, - { - "id": "http-examples-s3upload-basic-rust#source-material", - "heading": "Source Material", - "level": 2, - "anchor": "source-material", - "line_start": 186, - "line_end": 369, - "keywords": [ - "source", - "material", - "file", - "examples", - "http", - "basic", - "s3upload", - "src", - "lib.rs", - "rust", - "use", - "std", - "time", - "duration", - "fastedge", - "body", - "header", - "error", - "method", - "request", - "response", - "statuscode", - "rusty_s3", - "bucket", - "credentials", - "s3action", - "urlstyle", - "collections", - "hashmap", - "env", - "url", - "main", - "req", - "result", - "match", - "req.method", - "allow", - "only", - "post", - "put" - ] - }, - { - "id": "http-examples-s3upload-basic-rust#what-it-does", - "heading": "What it does", - "level": 2, - "anchor": "what-it-does", - "line_start": 370, - "line_end": 379, - "keywords": [ - "accepts", - "post", - "put", - "only", - "returns", - "405", - "methods", - "requires", - "name", - "filename", - "query", - "parameter", - "non-empty", - "body", - "400", - "otherwise", - "enforces", - "max_file_size", - "set", - "413", - "exceeded", - "calls", - "prepare_s3", - "build", - "1-hour", - "presigned", - "url", - "using", - "rusty_s3", - "forwards", - "file", - "via", - "fastedge", - "send_request", - "success", - "200", - "responds", - "clean", - "object", - "string" - ] - }, - { - "id": "http-examples-s3upload-basic-rust#configuration", - "heading": "Configuration", - "level": 2, - "anchor": "configuration", - "line_start": 380, - "line_end": 393, - "keywords": [ - "configuration", - "env", - "var", - "required", - "description", - "---", - "access_key", - "access", - "key", - "secret_key", - "secret", - "region", - "e.g.", - "s-ed1", - "base_hostname", - "base", - "hostname", - "cloud.gcore.lu", - "bucket", - "name", - "scheme", - "optional", - "url", - "defaults", - "http", - "max_file_size", - "maximum", - "upload", - "size", - "bytes", - "limit", - "unset", - "constructed", - "endpoint", - "bucke" - ] - }, - { - "id": "http-examples-s3upload-basic-rust#build", - "heading": "Build", - "level": 2, - "anchor": "build", - "line_start": 394, - "line_end": 400, - "keywords": [ - "build", - "cargo", - "--release", - "output", - "target", - "wasm32-wasip1", - "release", - "s3upload.wasm" - ] - }, - { - "id": "http-examples-s3upload-basic-rust#usage", - "heading": "Usage", - "level": 2, - "anchor": "usage", - "line_start": 401, - "line_end": 411, - "keywords": [ - "usage", - "post", - "upload", - "name", - "photo.jpg", - "content-type", - "image", - "jpeg", - "file", - "bytes", - "success", - "200", - "response", - "body", - "clean", - "object", - "url", - "presign", - "query", - "parameters", - "stripped" - ] - }, - { - "id": "http-examples-s3upload-basic-rust#notes", - "heading": "Notes", - "level": 2, - "anchor": "notes", - "line_start": 412, - "line_end": 418, - "keywords": [ - "notes", - "options", - "method", - "returns", - "204", - "include", - "cors", - "headers", - "add", - "access-control-allow-", - "browser", - "preflight", - "support", - "needed.", - "presigned", - "url", - "expires", - "hour", - "since", - "upload", - "performed", - "server-side", - "practical", - "impact.", - "max_file_size", - "silently", - "ignored", - "set", - "non-numeric", - "value." - ] } ], "local_path": "reference-docs/http-examples-s3upload-basic-rust.md" @@ -31934,7 +31216,7 @@ { "id": "http-examples-secret-basic-rust", "title": "Secret Access — Rust HTTP Example", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-secret-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -31956,9 +31238,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "secret", "access", "example", @@ -31968,7 +31250,7 @@ "fastedge", "platform" ], - "content_sha256": "99a13e72a317ae2f8118520b3f21a52ecaaacabefc6ae0000004391353e8c1fa", + "content_sha256": "1d1ae1d9f636c28df70129574cad04baf9b39ec87e640e902ed814f97a07d13b", "sections": [ { "id": "http-examples-secret-basic-rust#introduction", @@ -31985,9 +31267,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "secret", "access", "rust", @@ -32377,6 +31659,277 @@ "list", "delete" ] + }, + { + "id": "http-examples-secret-basic-rust#source-material", + "heading": "Source Material", + "level": 2, + "anchor": "source-material", + "line_start": 255, + "line_end": 368, + "keywords": [ + "source", + "material", + "file", + "examples", + "http", + "basic", + "secret", + "src", + "lib.rs", + "rust", + "use", + "anyhow", + "error", + "result", + "std", + "time", + "systemtime", + "fastedge", + "body", + "request", + "response", + "statuscode", + "allow", + "dead_code", + "main", + "_req", + "let", + "value", + "match", + "get", + "err", + "accessdenied", + "return", + "builder" + ] + }, + { + "id": "http-examples-secret-basic-rust#what-it-does", + "heading": "What it does", + "level": 2, + "anchor": "what-it-does", + "line_start": 369, + "line_end": 378, + "keywords": [ + "request", + "handler", + "calls", + "secret", + "get", + "retrieves", + "current", + "value", + "named", + "missing", + "returned", + "none", + "returns", + "404", + "get_effective_at", + "unix_ts", + "effective", + "unix", + "timestamp", + "demonstrating", + "rotation", + "versioning", + "api.", + "success", + "200", + "values", + "body", + "debug" + ] + }, + { + "id": "http-examples-secret-basic-rust#apis-used", + "heading": "APIs used", + "level": 2, + "anchor": "apis-used", + "line_start": 379, + "line_end": 389, + "keywords": [ + "apis", + "used", + "api", + "purpose", + "---", + "fastedge", + "http", + "sync", + "request-response", + "handler", + "macro", + "secret", + "get", + "key", + "retrieve", + "current", + "value", + "named", + "get_effective_at", + "timestamp", + "effective", + "specific", + "unix", + "error", + "variants", + "accessdenied", + "msg", + "decrypterror", + "request", + "response", + "statuscode", + "types", + "body", + "respo" + ] + }, + { + "id": "http-examples-secret-basic-rust#secret-error-variants", + "heading": "Secret error variants", + "level": 2, + "anchor": "secret-error-variants", + "line_start": 390, + "line_end": 399, + "keywords": [ + "secret", + "error", + "variants", + "variant", + "http", + "response", + "meaning", + "---", + "value", + "200", + "body", + "found", + "none", + "404", + "empty", + "name", + "valid", + "set", + "err", + "accessdenied", + "403", + "app", + "permitted", + "read", + "msg", + "denial", + "human-readable", + "message", + "decrypterror", + "500", + "exists", + "decrypted" + ] + }, + { + "id": "http-examples-secret-basic-rust#build", + "heading": "Build", + "level": 2, + "anchor": "build", + "line_start": 400, + "line_end": 406, + "keywords": [ + "build", + "cargo", + "--release", + "output", + "target", + "wasm32-wasip1", + "release", + "secret.wasm" + ] + }, + { + "id": "http-examples-secret-basic-rust#expected-behavior", + "heading": "Expected behavior", + "level": 2, + "anchor": "expected-behavior", + "line_start": 407, + "line_end": 416, + "keywords": [ + "expected", + "behavior", + "scenario", + "secret", + "response", + "status", + "body", + "---", + "happy", + "path", + "my-value", + "200", + "get", + "nget_efective_at", + "set", + "absent", + "404", + "empty", + "access", + "denied", + "403", + "note", + "contains", + "typo", + "field", + "name", + "get_efective_at", + "instead", + "get_effective_at", + "known", + "cosmetic", + "issue", + "source." + ] + }, + { + "id": "http-examples-secret-basic-rust#local-testing", + "heading": "Local testing", + "level": 2, + "anchor": "local-testing", + "line_start": 417, + "line_end": 434, + "keywords": [ + "local", + "testing", + "inject", + "secret", + "via", + ".env", + "file", + "your", + "fixtures", + "directory", + "using", + "fastedge_var_secret_", + "name", + "prefix", + "fastedge_var_secret_secret", + "my-test-value", + "run", + "fixture", + "validator", + "node", + "tools", + "fixture-validator", + "index.mjs", + "fastedge-sdk-rust", + "examples", + "http", + "basic", + "--wasm", + "target", + "wasm32-wasip1", + "release", + "secret.wasm" + ] } ], "local_path": "reference-docs/http-examples-secret-basic-rust.md" @@ -32384,7 +31937,7 @@ { "id": "http-examples-secret-rollover-wasi-rust", "title": "Secret Rollover (WASI, Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-secret-rollover-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -32406,9 +31959,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "secret", "rollover", "wasi", @@ -32419,7 +31972,7 @@ "rotation", "using" ], - "content_sha256": "535ab5dbaa52d9d716c1762d05b466c6182ff507db6ec46650bf241318a0fb65", + "content_sha256": "2cd00d58e3f6047c79cb57ea352f8e2684f86dec50a7357dadfe62d4bf0d8151", "sections": [ { "id": "http-examples-secret-rollover-wasi-rust#introduction", @@ -32436,9 +31989,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "secret", "rollover", "wasi", @@ -32694,7 +32247,7 @@ "level": 2, "anchor": "implementation-pattern", "line_start": 124, - "line_end": 178, + "line_end": 177, "keywords": [ "implementation", "pattern", @@ -32720,20 +32273,19 @@ "result", "read", "slot", + "x-slot", "header", - "default", + "defaulting", "current", - "unix", "timestamp", "let", "u32", ".headers", ".get", - "x-slot", ".and_then", "v.to_str", ".ok", - "v.p" + ".and" ] }, { @@ -32741,8 +32293,8 @@ "heading": "Constraints and Gotchas", "level": 2, "anchor": "constraints-and-gotchas", - "line_start": 179, - "line_end": 186, + "line_start": 178, + "line_end": 185, "keywords": [ "constraints", "gotchas", @@ -32791,8 +32343,8 @@ "heading": "Build", "level": 2, "anchor": "build", - "line_start": 187, - "line_end": 193, + "line_start": 186, + "line_end": 192, "keywords": [ "build", "cargo", @@ -32809,8 +32361,8 @@ "heading": "See Also", "level": 2, "anchor": "see-also", - "line_start": 194, - "line_end": 200, + "line_start": 193, + "line_end": 199, "keywords": [ "see", "fastedge", @@ -32842,7 +32394,7 @@ { "id": "http-examples-simple-fetch-wasi-rust", "title": "Example: Simple Fetch (WASI HTTP, Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-simple-fetch-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -32864,9 +32416,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -32876,7 +32428,7 @@ "outbound-fetch", "header-read" ], - "content_sha256": "d8d6a23390c7c0c319f1e3e0db70657d19a195129c9633d73217efa35f1408b3", + "content_sha256": "ff728af48b322c2e67a2a06dd8e555818382d4535f559f6cf83b2f14e6732db5", "sections": [ { "id": "http-examples-simple-fetch-wasi-rust#introduction", @@ -32893,9 +32445,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -32969,7 +32521,7 @@ "level": 2, "anchor": "request-headers", "line_start": 30, - "line_end": 35, + "line_end": 36, "keywords": [ "request", "headers", @@ -32991,7 +32543,14 @@ "httpbin.org", "get", "fetch", - "outbound" + "outbound", + "x-fetch-header", + "key", + "value", + "additional", + "forward", + "parsed", + "separator" ] }, { @@ -32999,8 +32558,8 @@ "heading": "Behavior", "level": 2, "anchor": "behavior", - "line_start": 36, - "line_end": 42, + "line_start": 37, + "line_end": 45, "keywords": [ "behavior", "read", @@ -33015,27 +32574,33 @@ "get", "absent", "unparseable.", - "build", + "begin", + "building", "outbound", "url", "accept", "application", "json", "header.", + "x-fetch-header", + "present", + "parseable", + "key", + "value", + "split", + "first", + "add", + "builder.", + "finalize", + "builder", + ".body", + "body", + "empty", "send", "via", "client", "new", - ".send", - "req", - ".await", - "return", - "upstream", - "response", - "body", - "directly", - "caller", - "decomposition." + ".send" ] }, { @@ -33043,8 +32608,8 @@ "heading": "Key API Patterns", "level": 2, "anchor": "key-api-patterns", - "line_start": 43, - "line_end": 99, + "line_start": 46, + "line_end": 122, "keywords": [ "key", "api", @@ -33093,8 +32658,8 @@ "heading": "Logging", "level": 2, "anchor": "logging", - "line_start": 100, - "line_end": 109, + "line_start": 123, + "line_end": 132, "keywords": [ "logging", "rust", @@ -33117,8 +32682,8 @@ "heading": "Cargo.toml Requirements", "level": 2, "anchor": "cargotoml-requirements", - "line_start": 110, - "line_end": 126, + "line_start": 133, + "line_end": 149, "keywords": [ "cargo.toml", "requirements", @@ -33151,8 +32716,8 @@ "heading": "WASI vs Basic HTTP Comparison", "level": 2, "anchor": "wasi-vs-basic-http-comparison", - "line_start": 127, - "line_end": 135, + "line_start": 150, + "line_end": 158, "keywords": [ "wasi", "basic", @@ -33189,8 +32754,8 @@ "heading": "Gotchas", "level": 2, "anchor": "gotchas", - "line_start": 136, - "line_end": 143, + "line_start": 159, + "line_end": 168, "keywords": [ "gotchas", "url", @@ -33219,19 +32784,17 @@ "values", "silently", "discarded", - "anyhow", - "declared", - "dependency", - "use", - "macro.", - "examples", - "http", - "wasi", - "same", - "async", - "main", - "wstd", - "http_server" + "x-fetch-header", + "parsed", + ".split_once", + "only", + "first", + "used", + "separator", + "containing", + "preserved", + "correctly.", + "build" ] }, { @@ -33239,8 +32802,8 @@ "heading": "See Also", "level": 2, "anchor": "see-also", - "line_start": 144, - "line_end": 150, + "line_start": 169, + "line_end": 175, "keywords": [ "see", "fastedge-docs", @@ -33260,6 +32823,186 @@ "host", "services" ] + }, + { + "id": "http-examples-simple-fetch-wasi-rust#source-material", + "heading": "Source Material", + "level": 2, + "anchor": "source-material", + "line_start": 176, + "line_end": 271, + "keywords": [ + "source", + "material", + "file", + "examples", + "http", + "wasi", + "simple_fetch", + "src", + "lib.rs", + "rust", + "copyright", + "2025", + "g-core", + "innovations", + "sarl", + "example", + "app", + "demonstrating", + "wasi-http", + "interface", + "via", + "wstd", + "crate.", + "receives", + "incoming", + "request", + "makes", + "outbound", + "url", + "specified", + "x-fetch-url", + "header", + "defaults", + "https", + "httpbin.org", + "get", + "build", + "cargo-component", + "cargo", + "component" + ] + }, + { + "id": "http-examples-simple-fetch-wasi-rust#how-it-works", + "heading": "How it works", + "level": 2, + "anchor": "how-it-works", + "line_start": 272, + "line_end": 277, + "keywords": [ + "works", + "app", + "receives", + "incoming", + "request", + "reads", + "target", + "url", + "x-fetch-url", + "header", + "makes", + "outbound", + "get", + "streams", + "response", + "back", + "caller.", + "absent", + "defaults", + "https", + "httpbin.org" + ] + }, + { + "id": "http-examples-simple-fetch-wasi-rust#request-headers", + "heading": "Request headers", + "level": 2, + "anchor": "request-headers", + "line_start": 278, + "line_end": 283, + "keywords": [ + "request", + "headers", + "header", + "required", + "description", + "--------", + "----------", + "-------------", + "x-fetch-url", + "url", + "fetch.", + "defaults", + "https", + "httpbin.org", + "get" + ] + }, + { + "id": "http-examples-simple-fetch-wasi-rust#example", + "heading": "Example", + "level": 2, + "anchor": "example", + "line_start": 284, + "line_end": 289, + "keywords": [ + "example", + "bash", + "curl", + "x-fetch-url", + "https", + "httpbin.org", + "uuid", + "your-app-domain" + ] + }, + { + "id": "http-examples-simple-fetch-wasi-rust#build", + "heading": "Build", + "level": 2, + "anchor": "build", + "line_start": 290, + "line_end": 296, + "keywords": [ + "build", + "bash", + "cargo", + "--release", + "output", + "target", + "wasm32-wasip2", + "release", + "simple_fetch.wasm" + ] + }, + { + "id": "http-examples-simple-fetch-wasi-rust#key-differences-from-basic-http-examples", + "heading": "Key differences from basic HTTP examples", + "level": 2, + "anchor": "key-differences-from-basic-http-examples", + "line_start": 297, + "line_end": 306, + "keywords": [ + "key", + "differences", + "basic", + "http", + "examples", + "fastedge", + "crate", + "wasi", + "wstd", + "---", + "handler", + "main", + "req", + "sync", + "async", + "macro", + "http_server", + "outbound", + "send_request", + "client", + "new", + ".send", + ".await", + "build", + "target", + "wasm32-wasip1", + "wasm32-wasip2" + ] } ], "local_path": "reference-docs/http-examples-simple-fetch-wasi-rust.md" @@ -33267,7 +33010,7 @@ { "id": "http-examples-smart-switch-basic-rust", "title": "Example: Smart Switch (Basic HTTP, Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-smart-switch-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -33289,9 +33032,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -33301,7 +33044,7 @@ "outbound-http", "env-vars" ], - "content_sha256": "3195fb4f9d583f55e2834ef95604d838f310817302a02705bec7c99b51685485", + "content_sha256": "c6819909d1d3bae6f1ad77d1911a32135ca0630d1e21028c5ff44435274e40ee", "sections": [ { "id": "http-examples-smart-switch-basic-rust#introduction", @@ -33318,9 +33061,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -33735,7 +33478,7 @@ { "id": "http-examples-static-assets-wasi-rust", "title": "Static Assets — WASI (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-static-assets-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -33759,9 +33502,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -33771,7 +33514,7 @@ "static-assets", "routing" ], - "content_sha256": "dcefd9ae20154d629c0a4b74b11bb152c2e0ddd0712407cb4ead1a03002ede52", + "content_sha256": "39d87feeba8b9d276b0f9d5d32b54faf0196b3dfd31a1aec8b88b3328960cbe2", "sections": [ { "id": "http-examples-static-assets-wasi-rust#introduction", @@ -33788,9 +33531,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -34338,7 +34081,7 @@ { "id": "http-examples-streaming-wasi-rust", "title": "Streaming Response — WASI (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-streaming-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -34360,9 +34103,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -34372,7 +34115,7 @@ "streaming", "async" ], - "content_sha256": "37832c99ab707686c986f78e014d061a2cd98753ae825dfc69b21c6217efd5fd", + "content_sha256": "fcd87ce4100ea3343d0f2b4543cce45409c480b856f3ded1838b4d752a43e3ea", "sections": [ { "id": "http-examples-streaming-wasi-rust#introduction", @@ -34389,9 +34132,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -34720,6 +34463,144 @@ "fastedge", "sdk" ] + }, + { + "id": "http-examples-streaming-wasi-rust#source-material", + "heading": "Source Material", + "level": 2, + "anchor": "source-material", + "line_start": 147, + "line_end": 225, + "keywords": [ + "source", + "material", + "file", + "examples", + "http", + "wasi", + "streaming", + "src", + "lib.rs", + "rust", + "copyright", + "2025", + "g-core", + "innovations", + "sarl", + "response", + "example.", + "generates", + "body", + "fly", + "five", + "text", + "chunks", + "one", + "200ms", + "using", + "from_stream", + "backed", + "futures_lite", + "stream", + "runtime", + "polls", + "sent", + "flow", + "client", + "they", + "produced", + "instead", + "once", + "end." + ] + }, + { + "id": "http-examples-streaming-wasi-rust#testing-the-streaming-behaviour", + "heading": "Testing the streaming behaviour", + "level": 2, + "anchor": "testing-the-streaming-behaviour", + "line_start": 226, + "line_end": 234, + "keywords": [ + "testing", + "streaming", + "behaviour", + "curl", + "https", + "your-app", + ".fastedge.cdn.gc.onl", + "disables", + "client-side", + "buffering", + "without", + "you", + "won", + "see", + "chunks", + "appear", + "one", + "time.", + "chunk", + "print", + "200ms", + "intervals." + ] + }, + { + "id": "http-examples-streaming-wasi-rust#other-streaming-patterns", + "heading": "Other streaming patterns", + "level": 2, + "anchor": "other-streaming-patterns", + "line_start": 235, + "line_end": 243, + "keywords": [ + "streaming", + "patterns", + "pass-through", + "return", + "upstream", + "response", + "body", + "directly.", + "see", + "outbound_fetch", + "no-buffer", + "variant.", + "transform", + "use", + "http_body_util", + "bodyext", + "map_frame", + "incoming", + "from_http_body", + "wrap", + "back.", + "useful", + "chunk-level", + "rewrites.", + "stream", + "bytes", + "from_stream", + "futures_lite", + "iter", + "chunks", + "iterable" + ] + }, + { + "id": "http-examples-streaming-wasi-rust#related", + "heading": "Related", + "level": 2, + "anchor": "related", + "line_start": 244, + "line_end": 248, + "keywords": [ + "related", + "mirror", + "fastedge-sdk-js", + "examples", + "streaming" + ] } ], "local_path": "reference-docs/http-examples-streaming-wasi-rust.md" @@ -34727,7 +34608,7 @@ { "id": "http-examples-variables-and-secrets-wasi-rust", "title": "Variables and Secrets — WASI (Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-variables-and-secrets-wasi-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -34749,9 +34630,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -34761,7 +34642,7 @@ "env-vars", "secrets" ], - "content_sha256": "9d8807dc93609399f430a94d714047bb9d9458bc07f16c18e6a0814c194ffb94", + "content_sha256": "6437dc0501dd6889d30bfd370a0d370c4211dbad78063f0d8e1981a360070c6d", "sections": [ { "id": "http-examples-variables-and-secrets-wasi-rust#introduction", @@ -34778,9 +34659,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "---", "type", "example", @@ -35238,7 +35119,7 @@ { "id": "http-examples-watermark-basic-rust", "title": "HTTP Example: Watermark (Basic, Rust)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/http/examples-watermark-basic-rust.md", "skill": "fastedge-docs", "category": "examples", @@ -35260,9 +35141,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "example", "watermark", "basic", @@ -35272,7 +35153,7 @@ "handler", "fastedge" ], - "content_sha256": "1fee467e8245bcae3adf9bcb0e06e0dda564403fccf9374939f5a72c90358ab3", + "content_sha256": "3b885f5aaf85aabb9c3cc0ee1f3c2133bd266f799afb7defc58d391825e6adaf", "sections": [ { "id": "http-examples-watermark-basic-rust#introduction", @@ -35289,9 +35170,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "http", "example", "watermark", @@ -35814,7 +35695,7 @@ { "id": "js-runtime", "title": "FastEdge JS Runtime — Constraints & Compatibility", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/js-runtime.md", "skill": "fastedge-docs", "category": "platform", @@ -35830,9 +35711,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "runtime", "constraints", @@ -35844,7 +35725,7 @@ "particularly", "affecting" ], - "content_sha256": "cac0e481a35b2a82d139b5878410a53c91f3f39c30c0190dd1a4ae6a1b229904", + "content_sha256": "f6077c39210df74e17ef03a34f4e5ba18b9d0e1a8857e120c393a98b85ee0b48", "sections": [ { "id": "js-runtime#introduction", @@ -35861,9 +35742,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "runtime", "constraints", @@ -37156,6 +37037,349 @@ ], "local_path": "reference-docs/platform-best-practices.md" }, + { + "id": "platform-cdn-filter-runtime", + "title": "CDN Filter Runtime — Capabilities and Traps", + "description": "What a proxy-wasm filter (CDN app) can and cannot do on FastEdge, and the host behaviours that silently differ from generic proxy-wasm or from HTTP apps. **Read this before designing or reviewing a CDN app** — most items here are invisible in local tests and only surface on a dep", + "path": "reference/fastedge-docs/platform/cdn-filter-runtime.md", + "skill": "fastedge-docs", + "category": "platform", + "app_types": [], + "languages": [], + "tags": [ + "platform", + "fastedge-docs", + "cdn", + "filter", + "runtime", + "capabilities", + "traps", + "proxy-wasm", + "app", + "cannot", + "fastedge", + "host", + "behaviours", + "silently", + "differ", + "generic", + "http", + "apps.", + "read", + "designing", + "reviewing", + "items" + ], + "content_sha256": "6279754b693e44807306ef152f9b733bb0a575ece2390a0bccb5755b2be9799e", + "sections": [ + { + "id": "platform-cdn-filter-runtime#introduction", + "heading": "Introduction", + "level": 1, + "anchor": "introduction", + "line_start": 1, + "line_end": 15, + "keywords": [ + "cdn", + "filter", + "runtime", + "capabilities", + "traps", + "proxy-wasm", + "app", + "cannot", + "fastedge", + "host", + "behaviours", + "silently", + "differ", + "generic", + "http", + "apps.", + "read", + "designing", + "reviewing", + "items", + "here", + "invisible", + "local", + "tests", + "only", + "surface", + "deployed", + "app.", + "claim", + "carries", + "provenance", + "tag", + "meaning", + "---", + "live", + "measured", + "against", + "real", + "resource", + "source" + ] + }, + { + "id": "platform-cdn-filter-runtime#capability-boundary-—-filter-vs-http-app", + "heading": "Capability boundary — filter vs HTTP app", + "level": 2, + "anchor": "capability-boundary-—-filter-vs-http-app", + "line_start": 16, + "line_end": 41, + "keywords": [ + "capability", + "boundary", + "filter", + "http", + "app", + "core", + "wasm", + "module", + "linked", + "against", + "proxy-wasm", + "env", + "abi.", + "different", + "execution", + "world", + "subset", + "it.", + "designs", + "assume", + "symmetry", + "http-app", + "sdk", + "fail", + "deploy.", + "cdn", + "---", + "read", + "same", + "six", + "operations", + "open", + "get", + "scan", + "zrange_by_score", + "zscan", + "bf_exists", + "source", + "write", + "api" + ] + }, + { + "id": "platform-cdn-filter-runtime#reading-the-request-—-use-properties-not-headers", + "heading": "Reading the request — use properties, not headers", + "level": 2, + "anchor": "reading-the-request-—-use-properties-not-headers", + "line_start": 42, + "line_end": 69, + "keywords": [ + "reading", + "request", + "use", + "properties", + "headers", + "several", + "proxy-wasm", + "developer", + "reach", + "mangled", + "absent.", + "failures", + "silent", + "live", + "read", + "via", + "result", + "---", + "property", + "request.host", + "clean", + "client-requested", + "host", + "origin", + "rewrite", + "edge", + "tier", + "shield", + "nodes", + "carry", + "shield_", + "prefix", + "request.x_real_ip", + "true", + "client", + "ipv4", + "ipv6", + "request.path", + "includes", + "query" + ] + }, + { + "id": "platform-cdn-filter-runtime#security-—-gating-filters", + "heading": "Security — gating filters", + "level": 2, + "anchor": "security-—-gating-filters", + "line_start": 70, + "line_end": 105, + "keywords": [ + "security", + "gating", + "filters", + "cdn", + "normalise", + "path", + "filter", + "runs", + "live", + "traversal", + "separator", + "sequences", + "arrive", + "verbatim", + "bash", + "curl", + "--path-as-is", + "...", + "app", + "test", + "request.path", + "bypasses", + "auth", + "prefix", + "public", + "wave", + "admin", + "origin", + "back", + "authentication", + "bypass" + ] + }, + { + "id": "platform-cdn-filter-runtime#synthetic-responses", + "heading": "Synthetic responses", + "level": 2, + "anchor": "synthetic-responses", + "line_start": 106, + "line_end": 111, + "keywords": [ + "synthetic", + "responses", + "live", + "filter", + "serve", + "complete", + "response", + "via", + "send_http_response", + "status", + "arbitrary", + "headers", + "multiple", + "set-cookie", + "one", + "bodies", + "least", + "without", + "truncation.", + "single-app", + "designs", + "challenge", + "pages", + "interstitials", + "error", + "second", + "http", + "app.", + "---" + ] + }, + { + "id": "platform-cdn-filter-runtime#what-local-testing-cannot-prove", + "heading": "What local testing cannot prove", + "level": 2, + "anchor": "what-local-testing-cannot-prove", + "line_start": 112, + "line_end": 117, + "keywords": [ + "local", + "testing", + "cannot", + "prove", + "gcoredev", + "fastedge-test", + "runs", + "proxy-wasm", + "filters", + "locally", + "proves", + "flow", + "logic", + "routing", + "header", + "manipulation", + "gate", + "decisions.", + "host", + "behaviour", + "property", + "semantics", + "mangling", + "path", + "non-normalisation", + "instantiation", + "failures", + "cache", + "interaction.", + "trap", + "page", + "passes", + "suite", + "green.", + "confirm", + "host-dependent", + "deployed", + "app", + "attached", + "real" + ] + }, + { + "id": "platform-cdn-filter-runtime#see-also", + "heading": "See Also", + "level": 2, + "anchor": "see-also", + "line_start": 118, + "line_end": 123, + "keywords": [ + "see", + "storage.md", + "cache", + "semantics", + "limits", + "measured", + "performance", + "cdn-integration.md", + "attaching", + "filters", + "cdn", + "resources", + "error-codes.md", + "530", + "diagnosis" + ] + } + ], + "local_path": "reference-docs/platform-cdn-filter-runtime.md" + }, { "id": "platform-cdn-integration", "title": "CDN Integration — Attaching FastEdge Apps to CDN Resources", @@ -37194,7 +37418,7 @@ "effect", "app" ], - "content_sha256": "6cb942fb6413ec2d1faf71699c0e79ea10e04ccc089ed9e49aee100e7a6623fe", + "content_sha256": "e36fbf654e7eb8d595bd084a7fa6577ef61114287351099e7ccaa99cdf0f9eb6", "sections": [ { "id": "platform-cdn-integration#introduction", @@ -37349,7 +37573,7 @@ "level": 2, "anchor": "reading-and-updating", "line_start": 157, - "line_end": 185, + "line_end": 202, "keywords": [ "reading", "updating", @@ -37387,8 +37611,8 @@ "heading": "Operational Notes", "level": 2, "anchor": "operational-notes", - "line_start": 186, - "line_end": 195, + "line_start": 203, + "line_end": 212, "keywords": [ "operational", "notes", @@ -37435,8 +37659,8 @@ "heading": "See Also", "level": 2, "anchor": "see-also", - "line_start": 196, - "line_end": 203, + "line_start": 213, + "line_end": 220, "keywords": [ "see", "rust", @@ -37514,7 +37738,7 @@ "distinguish", "edge" ], - "content_sha256": "d47de15e41e07d9b842b6690558f41b840a4121f7ec91a85c4d86d1dc966a436", + "content_sha256": "e0561d0b112db5f5f509a1ce16da82dedfa2cea834283fcf1b6102a118136876", "sections": [ { "id": "platform-error-codes#introduction", @@ -37567,7 +37791,7 @@ "level": 2, "anchor": "530-—-app-initialization-failed", "line_start": 9, - "line_end": 29, + "line_end": 38, "keywords": [ "530", "app", @@ -37579,35 +37803,36 @@ "start", "processing", "request.", + "signal", + "cdn", + "fails", + "instantiate", + "returns", + "x-cdn-internal-status", + "3100", + "header", + "distinguishes", + "ran", + "errored", + "531", "common", "causes", - "missing", - "required", - "environment", - "variables", - "reads", - "corrupted", - "invalid", + "unresolved", + "imports", + "apps", "binary", - "compiled", - "wrong", - "target", - "wasm32-wasip1", - "large", - "platform", - "rejects", - "uploads", - "beyond", - "50mb", - "investigate", - "bundled", - "debugging", - "steps", - "verify", - "built", - "correctly", - "fastedge-build", - "src" + "host", + "function", + "proxy-wasm", + "provide", + "commonly", + "http-app", + "component-model", + "api", + "used", + "filter", + "e.g.", + "top-leve" ] }, { @@ -37615,8 +37840,8 @@ "heading": "531 — Runtime Error", "level": 2, "anchor": "531-—-runtime-error", - "line_start": 30, - "line_end": 61, + "line_start": 39, + "line_end": 71, "keywords": [ "531", "runtime", @@ -37632,6 +37857,19 @@ "processing.", "common", "causes", + "calling", + "getenv", + "getsecret", + "module", + "top", + "level", + "they", + "request-time", + "only", + "call", + "them", + "inside", + "handler", "uncaught", "javascript", "typeerror", @@ -37644,20 +37882,7 @@ "err", "failed", "fetch", - "call", - "without", - "handling", - "json", - "parse", - "malformed", - "body", - "accessing", - "undefined", - "properties", - "debugging", - "steps", - "test", - "locally" + "without" ] }, { @@ -37665,8 +37890,8 @@ "heading": "532 — Timeout Exceeded", "level": 2, "anchor": "532-—-timeout-exceeded", - "line_start": 62, - "line_end": 93, + "line_start": 72, + "line_end": 103, "keywords": [ "532", "timeout", @@ -37715,8 +37940,8 @@ "heading": "533 — Memory Limit Exceeded", "level": 2, "anchor": "533-—-memory-limit-exceeded", - "line_start": 94, - "line_end": 122, + "line_start": 104, + "line_end": 132, "keywords": [ "533", "memory", @@ -37765,8 +37990,8 @@ "heading": "General Debugging Strategy", "level": 2, "anchor": "general-debugging-strategy", - "line_start": 123, - "line_end": 131, + "line_start": 133, + "line_end": 141, "keywords": [ "general", "debugging", @@ -38364,7 +38589,7 @@ "instantiates", "app" ], - "content_sha256": "98c4a8456ad2cedcb63fe13b4f4556e3b0a8b09ab2a621f0111a59b942d65cb8", + "content_sha256": "350d18b69668668c510056232b304d8bb3d9d3354bfc1493438b059d93d586b6", "sections": [ { "id": "platform-overview#introduction", @@ -38566,7 +38791,7 @@ "level": 2, "anchor": "request-lifecycle", "line_start": 93, - "line_end": 101, + "line_end": 109, "keywords": [ "request", "lifecycle", @@ -38599,7 +38824,15 @@ "instance", "destroyed", "memory", - "freed" + "freed", + "scheduled", + "deferred", + "work", + "there", + "scheduler", + "durable", + "background", + "execution." ] }, { @@ -38607,8 +38840,8 @@ "heading": "Resource Limits", "level": 2, "anchor": "resource-limits", - "line_start": 102, - "line_end": 115, + "line_start": 110, + "line_end": 123, "keywords": [ "resource", "limits", @@ -38657,8 +38890,8 @@ "heading": "Plans", "level": 2, "anchor": "plans", - "line_start": 116, - "line_end": 120, + "line_start": 124, + "line_end": 128, "keywords": [ "plans", "basic", @@ -38680,8 +38913,8 @@ "heading": "App Statuses", "level": 2, "anchor": "app-statuses", - "line_start": 121, - "line_end": 128, + "line_start": 129, + "line_end": 136, "keywords": [ "app", "statuses", @@ -38701,8 +38934,8 @@ "heading": "Networking", "level": 2, "anchor": "networking", - "line_start": 129, - "line_end": 135, + "line_start": 137, + "line_end": 143, "keywords": [ "networking", "apps", @@ -38733,8 +38966,8 @@ "heading": "Logging & Monitoring", "level": 2, "anchor": "logging-&-monitoring", - "line_start": 136, - "line_end": 141, + "line_start": 144, + "line_end": 149, "keywords": [ "logging", "monitoring", @@ -38761,6 +38994,262 @@ ], "local_path": "reference-docs/platform-overview.md" }, + { + "id": "platform-storage", + "title": "Storage Semantics — KV Store and Cache", + "description": "Behaviour of FastEdge's two storage primitives that the SDK references do not state: consistency, write shapes, TTL rules, missing operations, and measured performance. Applies to HTTP apps and CDN filters unless noted. For the per-language API, see the SDK reference for your lan", + "path": "reference/fastedge-docs/platform/storage.md", + "skill": "fastedge-docs", + "category": "platform", + "app_types": [], + "languages": [], + "tags": [ + "platform", + "fastedge-docs", + "storage", + "semantics", + "store", + "cache", + "behaviour", + "fastedge", + "two", + "primitives", + "sdk", + "references", + "state", + "consistency", + "write", + "shapes", + "ttl", + "rules", + "missing", + "operations", + "measured", + "performance." + ], + "content_sha256": "65116f9b1f97e5e14b18ff2a6af86b58e926d192ad3101290e37fd23e8db5d3e", + "sections": [ + { + "id": "platform-storage#introduction", + "heading": "Introduction", + "level": 1, + "anchor": "introduction", + "line_start": 1, + "line_end": 15, + "keywords": [ + "storage", + "semantics", + "store", + "cache", + "behaviour", + "fastedge", + "two", + "primitives", + "sdk", + "references", + "state", + "consistency", + "write", + "shapes", + "ttl", + "rules", + "missing", + "operations", + "measured", + "performance.", + "applies", + "http", + "apps", + "cdn", + "filters", + "unless", + "noted.", + "per-language", + "api", + "see", + "reference", + "your", + "language.", + "---", + "scope", + "global", + "account-level", + "assigned", + "per-pop", + "shared" + ] + }, + { + "id": "platform-storage#kv-store", + "heading": "KV Store", + "level": 2, + "anchor": "kv-store", + "line_start": 16, + "line_end": 58, + "keywords": [ + "store", + "get", + "cached", + "read", + "per", + "node", + "live", + "production", + "key", + "populates", + "per-node", + "cache", + "entry", + "lives", + "whether", + "existed", + "until", + "expires", + "keeps", + "returning", + "old", + "result", + "value", + "absent", + "now", + "exists.", + "sorted-set", + "reads", + "zrangebyscore", + "reflect", + "writes", + "write", + "visible", + "---", + "none", + "create", + "heavy", + "pol" + ] + }, + { + "id": "platform-storage#cache", + "heading": "Cache", + "level": 2, + "anchor": "cache", + "line_start": 59, + "line_end": 82, + "keywords": [ + "cache", + "interface", + "atomicity", + "source", + "get", + "set", + "delete", + "exists", + "incr", + "expire", + "purge", + "purge_prefix", + "only", + "atomic", + "primitive", + "compare-and-set", + "setnx", + "scripting", + "multi-key", + "operations", + "scan", + "coordination", + "expressible", + "increment", + "compare", + "returned", + "value", + "ttl", + "rules", + "live", + "ttls", + "silently", + "clamped", + "deployment", + "ceiling", + "default", + "days", + "rust", + "sdk", + "references" + ] + }, + { + "id": "platform-storage#measured-performance", + "heading": "Measured performance", + "level": 2, + "anchor": "measured-performance", + "line_start": 83, + "line_end": 103, + "keywords": [ + "measured", + "performance", + "live", + "production", + "point-in-time", + "one", + "account", + "mostly", + "pop", + "evidence", + "guarantees.", + "metric", + "value", + "---", + "cache.incr", + "p50", + "p95", + "max", + "102", + "cache.expire", + "write", + "visible", + "prior", + "get", + "polling", + "107", + "min", + "rate", + "client", + "sustained", + "writes", + "sorted-set", + "ingest", + "450", + "members", + "knee", + "concurrent", + "writers", + "largest", + "single" + ] + }, + { + "id": "platform-storage#see-also", + "heading": "See Also", + "level": 2, + "anchor": "see-also", + "line_start": 104, + "line_end": 108, + "keywords": [ + "see", + "cdn-filter-runtime.md", + "cdn", + "filter", + "access", + "overview.md", + "account-level", + "stores", + "resource", + "limits" + ] + } + ], + "local_path": "reference-docs/platform-storage.md" + }, { "id": "quickstart", "title": "FastEdge Quickstart", @@ -39016,7 +39505,7 @@ { "id": "quickstart-as", "title": "Quickstart: AssemblyScript CDN Apps on FastEdge", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/quickstart-as.md", "skill": "fastedge-docs", "category": "reference", @@ -39037,9 +39526,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "quickstart", "cdn", "apps", @@ -39050,7 +39539,7 @@ "compile", "webassembly" ], - "content_sha256": "fff52212e2f6238e7ed758a19a80e19a19974e5089f08928df7abac1819c1ada", + "content_sha256": "44a67860b9459a777487ccc86b1f45572d7be137091e04b009c1cda5acfd6676", "sections": [ { "id": "quickstart-as#introduction", @@ -39067,9 +39556,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "quickstart", "assemblyscript", "cdn", @@ -39451,7 +39940,7 @@ { "id": "quickstart-js", "title": "FastEdge JavaScript Quickstart", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/quickstart-js.md", "skill": "fastedge-docs", "category": "reference", @@ -39472,9 +39961,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "quickstart", "prerequisites", @@ -39485,7 +39974,7 @@ "install", "bash" ], - "content_sha256": "51cef432b6305a0da282efc422dcd4b0a9f385cb40f047aee77022cb9258e771", + "content_sha256": "471dc8495fa13ecd040aad10ee3cba07813ec793a027cec8c4c507d6e75b64fa", "sections": [ { "id": "quickstart-js#introduction", @@ -39502,9 +39991,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "javascript", "quickstart" @@ -39793,7 +40282,7 @@ { "id": "quickstart-rust", "title": "FastEdge Rust SDK — Quickstart", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/quickstart-rust.md", "skill": "fastedge-docs", "category": "reference", @@ -39812,9 +40301,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "sdk", "quickstart", @@ -39824,7 +40313,7 @@ "wasm32-wasip1", "target" ], - "content_sha256": "4e1d3d5a01a3e8aaf9f864c197899fbbc06cc30f86aba6a34d8207f67a629c25", + "content_sha256": "e345fdfaec0a005a9969b4bced75bacadcf838209b350e6fc06de4fc330536ca", "sections": [ { "id": "quickstart-rust#introduction", @@ -39841,9 +40330,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "fastedge", "rust", "sdk", @@ -40540,7 +41029,7 @@ { "id": "sdk-reference-as", "title": "AssemblyScript Proxy-Wasm SDK Reference", - "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: proxy-wasm-sdk-as ref: master commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/sdk-reference-as.md", "skill": "fastedge-docs", "category": "sdk", @@ -40561,9 +41050,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "proxy-wasm", "reference", "gcoredev", @@ -40573,7 +41062,7 @@ "writing", "cdn" ], - "content_sha256": "76f2b7665b04f19b479f02f492977afaf6fffe062287c53fcfb4f387c5012e89", + "content_sha256": "a14b716b83a08310d5fea5c9097ebefc7fece6329111d0f21c21b97751bd7093", "sections": [ { "id": "sdk-reference-as#introduction", @@ -40590,9 +41079,9 @@ "ref", "master", "commit", - "8e3bb621bc013a0aed7e52122066b417ad62a207", + "ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31", "updated", - "2026-08-20", + "2026-09-22", "assemblyscript", "proxy-wasm", "sdk", @@ -41088,7 +41577,7 @@ { "id": "sdk-reference-js", "title": "JavaScript SDK Reference (`@gcoredev/fastedge-sdk-js`)", - "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 81145a9a43ec499240c687bd49376ab20c72b11c updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-js ref: main commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/sdk-reference-js.md", "skill": "fastedge-docs", "category": "sdk", @@ -41107,9 +41596,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "reference", "gcoredev", "source", @@ -41119,7 +41608,7 @@ "authoritative", "api" ], - "content_sha256": "b24418a0122025cc0863b8fa10c1295844a91aeb97a941495530e3cd5bcbcf1b", + "content_sha256": "cad65330e951f705a83aad21f8106ba15e3fd8cc2d51901140d09c58bc1577ee", "sections": [ { "id": "sdk-reference-js#introduction", @@ -41136,9 +41625,9 @@ "ref", "main", "commit", - "81145a9a43ec499240c687bd49376ab20c72b11c", + "9c8c7886f0d1ec5ac2296b4080805966a96ca817", "updated", - "2026-08-20", + "2026-09-22", "javascript", "sdk", "reference", @@ -41684,7 +42173,7 @@ { "id": "sdk-reference-rust", "title": "Rust SDK Reference (`fastedge` crate + `fastedge-derive`)", - "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 updated: 2026-08-20 -->", + "description": "auto-updated: true sources: - id: fastedge-sdk-rust ref: main commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 updated: 2026-09-22 -->", "path": "reference/fastedge-docs/sdk-reference-rust.md", "skill": "fastedge-docs", "category": "sdk", @@ -41703,9 +42192,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "reference", "fastedge", "crate", @@ -41715,7 +42204,7 @@ "start", "cargo.toml" ], - "content_sha256": "e3598e9cb99f2f28beb8527ea3284480bee8c63132151da4c8874089bf9bf01b", + "content_sha256": "6ac7d972a17430f2d0d829470c262db798ec8ff3e81ca8dfbf8bed93067b7496", "sections": [ { "id": "sdk-reference-rust#introduction", @@ -41732,9 +42221,9 @@ "ref", "main", "commit", - "6347a7c2fda0d03e66f1214db5eec041c16801b7", + "6eedcca9d5c0ddd4ff79ca475965393891da2d75", "updated", - "2026-08-20", + "2026-09-22", "rust", "sdk", "reference", diff --git a/reference-docs/host-services-rust.md b/reference-docs/host-services-rust.md index 7bcf9c1..3214224 100644 --- a/reference-docs/host-services-rust.md +++ b/reference-docs/host-services-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> # Rust Host Services Reference @@ -260,7 +260,7 @@ async fn main(_request: Request) -> anyhow::Result> { Module: `fastedge::dictionary` -Provides fast, read-only lookups for configuration values that do not change during the lifetime of a deployment. +Provides fast, read-only lookups for configuration values that do not change during the lifetime of a deployment. Dictionary = read-only config, key_value = persistent data, secret = encrypted credentials. ### API diff --git a/reference-docs/http-examples-ab-testing-js.md b/reference-docs/http-examples-ab-testing-js.md index 4c0c294..2400018 100644 --- a/reference-docs/http-examples-ab-testing-js.md +++ b/reference-docs/http-examples-ab-testing-js.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-js ref: main - commit: 81145a9a43ec499240c687bd49376ab20c72b11c - updated: 2026-08-20 + commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 + updated: 2026-09-22 --> # A/B Testing — FastEdge Example diff --git a/reference-docs/http-examples-ab-testing-wasi-rust.md b/reference-docs/http-examples-ab-testing-wasi-rust.md index 75ff192..745791f 100644 --- a/reference-docs/http-examples-ab-testing-wasi-rust.md +++ b/reference-docs/http-examples-ab-testing-wasi-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/http-examples-api-wrapper-basic-rust.md b/reference-docs/http-examples-api-wrapper-basic-rust.md index 6699d03..c772314 100644 --- a/reference-docs/http-examples-api-wrapper-basic-rust.md +++ b/reference-docs/http-examples-api-wrapper-basic-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> # examples-api-wrapper-basic-rust diff --git a/reference-docs/http-examples-auth-js.md b/reference-docs/http-examples-auth-js.md index e4a5086..aa6fc7e 100644 --- a/reference-docs/http-examples-auth-js.md +++ b/reference-docs/http-examples-auth-js.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-js ref: main - commit: 81145a9a43ec499240c687bd49376ab20c72b11c - updated: 2026-08-20 + commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 + updated: 2026-09-22 --> # Authentication Patterns (JavaScript) diff --git a/reference-docs/http-examples-backend-basic-rust.md b/reference-docs/http-examples-backend-basic-rust.md index 6de33d5..eeb5488 100644 --- a/reference-docs/http-examples-backend-basic-rust.md +++ b/reference-docs/http-examples-backend-basic-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- @@ -153,114 +153,3 @@ cargo build --release --target wasm32-wasip1 - platform-overview (FastEdge request lifecycle, outbound request capabilities) - sdk-reference-rust (`fastedge::send_request`, `Body`, HTTP types) - best-practices (body buffering considerations, error handling patterns) - -## Source Material - -### FILE: examples/http/basic/backend/src/lib.rs - -```rust -use anyhow::{anyhow, Error, Result}; -use fastedge::body::Body; -use fastedge::http::{Method, Request, Response, StatusCode}; - -#[allow(dead_code)] -#[fastedge::http] -fn main(req: Request) -> Result> { - let (parts, body) = req.into_parts(); - let query = parts - .uri - .query() - .ok_or(anyhow!("missing uri query parameter"))?; - let params = querystring::querify(query); - let url = params - .iter() - .find(|(k, _)| k == &"url") - .ok_or(anyhow!("missing url parameter"))?; - let url = urlencoding::decode(url.1)?.to_string(); - println!("url = {:?}", url); - let request = Request::builder().uri(url).method(Method::GET).body(body)?; - - let response = fastedge::send_request(request).map_err(Error::msg)?; - - Response::builder() - .status(StatusCode::OK) - .body(Body::from(format!( - "len = {}, content-type = {:?}", - response.body().len(), - response.headers().get("Content-Type") - ))) - .map_err(Error::msg) -} -``` - - -### FILE: examples/http/basic/backend/Cargo.toml - -```toml -[workspace] - -[package] -name = "backend" -version = "0.1.0" -edition = "2021" - -[lib] -crate-type = ["cdylib"] - -[dependencies] -fastedge = "0.4" -anyhow = "1" -querystring = "1.1" -urlencoding = "2.1" -``` - - -### FILE: examples/http/basic/backend/README.md - -``` -[← Back to examples](../../../README.md) - -# Backend (URL Proxy) - -A FastEdge application that accepts a `?url=` query parameter, makes an outbound GET request to that URL via `fastedge::send_request`, and returns a summary of the upstream response (`len` and `content-type`) in the response body. - -> **When to use this example:** When you want to see how to make outbound HTTP requests from a FastEdge edge function using the legacy sync handler (`#[fastedge::http]`). For new apps, prefer the async WASI handler — see [`examples/http/wasi/hello_world`](../../wasi/hello_world/README.md). - -## What it does - -1. Parses the `?url=` query parameter from the request URI (percent-decodes it via `urlencoding::decode`). -2. Builds an outbound `GET` request to that URL using `fastedge::send_request`. -3. Returns HTTP 200 with a plain-text body: - ``` - len = , content-type = - ``` -4. Returns HTTP 500 with an error message if `?url=` is absent or the query string is missing. - -## APIs used - -| API | Purpose | -|---|---| -| `#[fastedge::http]` | Sync request-response handler macro | -| `fastedge::send_request(request)` | Blocking outbound HTTP request | -| `fastedge::http::{Request, Response, StatusCode, Method}` | HTTP types | -| `fastedge::body::Body` | Request and response bodies | -| `querystring::querify` | Parse query string into key-value pairs | -| `urlencoding::decode` | Percent-decode the `?url=` value | - -## Build - -```sh -cargo build --release -# Output: target/wasm32-wasip1/release/backend.wasm -``` - -## Expected behavior - -| Request | Response status | Response body | -|---|---|---| -| `GET /?url=https%3A%2F%2Fhttpbin.org%2Fget` | 200 | `len = , content-type = Some("")` | -| `GET /?q=hello` (no `url` key) | 500 | `missing url parameter` | -| `GET /` (no query string) | 500 | `missing uri query parameter` | - -The `len` value is the byte length of the upstream response body. The `content-type` value is the `Content-Type` header returned by the upstream server, formatted as a Rust `Option` debug string (e.g. `Some("application/json")`). -``` diff --git a/reference-docs/http-examples-bloom-filter-denylist-wasi-rust.md b/reference-docs/http-examples-bloom-filter-denylist-wasi-rust.md index d9377ed..7acebb4 100644 --- a/reference-docs/http-examples-bloom-filter-denylist-wasi-rust.md +++ b/reference-docs/http-examples-bloom-filter-denylist-wasi-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- @@ -150,3 +150,164 @@ Uses the `wstd` WASI Component Model HTTP server macro. - KV Store provisioning and population via FastEdge API - examples-bloom-filter-denylist-js (JavaScript mirror of this example) - platform-overview (KV Store concepts) + +## Source Material + +### FILE: examples/http/wasi/bloom_filter_denylist/src/lib.rs + +```rust +/* + * Copyright 2025 G-Core Innovations SARL + */ +/* +Bloom-filter IP denylist example. + +Checks the client IP (from the `x-real-ip` request header, falling back to +`x-forwarded-for`) against a bloom filter stored in FastEdge KV. Returns 403 +on a hit, 200 otherwise. + +Required configuration: + - Environment variable: DENYLIST_STORE (KV store name holding the bloom filter) + +The bloom-filter key is hardcoded to `blocked-ips`. The handler is read-only; +populate the filter out of band. + +Mirror of the FastEdge-sdk-js `bloom-filter-denylist` example. +*/ + +use std::env; + +use anyhow::anyhow; +use fastedge::key_value::{Error as StoreError, Store}; +use serde_json::json; +use wstd::http::body::Body; +use wstd::http::{Request, Response}; + +const BLOOM_KEY: &str = "blocked-ips"; + +#[wstd::http_server] +async fn main(req: Request) -> anyhow::Result> { + let store_name = match env::var("DENYLIST_STORE") { + Ok(s) if !s.trim().is_empty() => s, + _ => { + return json_response( + 500, + json!({ "error": "DENYLIST_STORE environment variable is not configured" }), + ); + } + }; + + let headers = req.headers(); + let client_ip = headers + .get("x-real-ip") + .or_else(|| headers.get("x-forwarded-for")) + .and_then(|v| v.to_str().ok()) + .and_then(|v| v.split(',').next()) + .map(str::trim) + .filter(|s| !s.is_empty()); + + let Some(ip) = client_ip else { + return json_response(500, json!({ "error": "client IP not available" })); + }; + + let store = match Store::open(&store_name) { + Ok(s) => s, + Err(StoreError::AccessDenied) => { + return json_response( + 403, + json!({ "error": "access denied opening denylist store" }), + ); + } + Err(e) => { + return json_response(500, json!({ "error": format!("store open error: {e}") })); + } + }; + + let blocked = store + .bf_exists(BLOOM_KEY, ip) + .map_err(|e| anyhow!("bf_exists error: {e}"))?; + + if blocked { + // Bloom filter says "maybe in set" — a small fraction of hits will be false + // positives. Acceptable for a denylist (you over-block some legitimate users); + // not acceptable for allowlists — use `store.get()` against a regular key instead. + return json_response(403, json!({ "allowed": false, "ip": ip })); + } + + json_response(200, json!({ "allowed": true, "ip": ip })) +} + +fn json_response(status: u16, value: serde_json::Value) -> anyhow::Result> { + Ok(Response::builder() + .status(status) + .header("content-type", "application/json") + .body(Body::from(value.to_string()))?) +} +``` + + +### FILE: examples/http/wasi/bloom_filter_denylist/Cargo.toml + +```toml +[workspace] + +[package] +name = "bloom_filter_denylist_wasi" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +wstd = "0.6" +fastedge = "0.4" +anyhow = "1" +serde_json = "1" +``` + + +### FILE: examples/http/wasi/bloom_filter_denylist/README.md + +``` +[← Back to examples](../../../README.md) + +# Bloom Filter — IP Denylist (WASI) + +Rejects requests from IPs present in a KV Store bloom filter. Reads the client IP from the +`x-real-ip` request header (falling back to `x-forwarded-for`), checks it against a +pre-populated bloom filter, and returns **403** on a hit or **200** otherwise. + +Demonstrates `fastedge::key_value::Store` + `bf_exists()` and the conventional way to obtain +the client IP from a Component Model HTTP handler. + +## Configuration + +- Environment variable `DENYLIST_STORE` — name of the KV store that holds the bloom filter. +- Bloom-filter key — hardcoded to `blocked-ips`. Change `BLOOM_KEY` in `src/lib.rs` if your + key is different. + +## Behaviour + +| `bf_exists("blocked-ips", ip)` | Response | +| --- | --- | +| `true` | `403` `{ "allowed": false, "ip": "..." }` | +| `false` | `200` `{ "allowed": true, "ip": "..." }` | + +## Tradeoff: false positives + +Bloom filters answer "**definitely not** in set" vs "**maybe** in set". When `bf_exists` +returns `true`, the IP *probably* was added — but a small fraction of hits will be false +positives, meaning some legitimate IPs will be over-blocked. Acceptable for a denylist; for +allowlists or anything requiring exact membership, use `store.get()` against a regular key +instead. + +## Populating the filter + +The edge handler is read-only. Populate `blocked-ips` out of band (for example, via the +FastEdge API). + +## Related + +Mirror of `FastEdge-sdk-js/examples/bloom-filter-denylist/`. +``` diff --git a/reference-docs/http-examples-cache-basic-rust.md b/reference-docs/http-examples-cache-basic-rust.md index cc1509e..a1e64c6 100644 --- a/reference-docs/http-examples-cache-basic-rust.md +++ b/reference-docs/http-examples-cache-basic-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- @@ -133,3 +133,149 @@ use fastedge::http::{Request, Response, StatusCode}; - examples-cache-basic-rust (this file) pairs with the HTTP app deploy reference for upload and wiring steps - platform-overview for cache subsystem lifecycle and eviction behavior - best-practices for cache key namespacing and TTL selection guidance + +## Source Material + +### FILE: examples/http/basic/cache/src/lib.rs + +```rust +/* + * Copyright 2025 G-Core Innovations SARL + */ +/* +Example app demonstrating cache-aside pattern via the cache interface. + +On each request the app: + 1. Builds a cache key from the request path. + 2. Returns the cached body immediately on a hit (x-cache: hit). + 3. On a miss, generates a response body, stores it in the cache, and + returns it (x-cache: miss). + +Environment variables: + CACHE_TTL_MS How long to cache the generated body in milliseconds + (default: 30000) + +Build: + cargo build --release +*/ + +use std::env; + +use fastedge::body::Body; +use fastedge::cache; +use fastedge::http::{Request, Response, StatusCode}; + +#[fastedge::http] +fn main(req: Request) -> anyhow::Result> { + let ttl_ms: u64 = env::var("CACHE_TTL_MS") + .ok() + .and_then(|v| v.parse().ok()) + .unwrap_or(30_000); + + let path = req.uri().path().to_string(); + let cache_key = format!("page:{path}"); + + // Cache hit — return stored body + if let Some(cached) = cache::get(&cache_key)? { + println!("cache hit: {cache_key}"); + return Ok(Response::builder() + .status(StatusCode::OK) + .header("content-type", "text/html") + .header("x-cache", "hit") + .body(Body::from(cached))?); + } + + // Cache miss — generate the response body + println!("cache miss: {cache_key}"); + let body = generate_body(&path); + + // Store in cache with TTL + cache::set(&cache_key, body.as_bytes(), Some(ttl_ms))?; + + Ok(Response::builder() + .status(StatusCode::OK) + .header("content-type", "text/html") + .header("x-cache", "miss") + .body(Body::from(body))?) +} + +/// Simulates an expensive computation or template render. +fn generate_body(path: &str) -> String { + format!( + "\ + FastEdge Cache Demo\ + \ +

Hello from FastEdge

\ +

Path: {path}

\ +

This response was generated and is now cached.

\ + " + ) +} +``` + + +### FILE: examples/http/basic/cache/Cargo.toml + +```toml +[workspace] + +[package] +name = "cache_basic" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +fastedge = "0.4" +anyhow = "1" +``` + + +### FILE: examples/http/basic/cache/README.md + +``` +[← Back to examples](../../../README.md) + +# Cache (Basic) + +Demonstrates the cache-aside pattern using `fastedge::cache` — store a generated response body with a TTL and serve it directly on subsequent requests without re-computing it. + +## Configuration + +| Env var | Required | Description | +|---|---|---| +| `CACHE_TTL_MS` | No | How long to cache each response in milliseconds. Default: `30000` (30 s). | + +## How it works + +``` +GET /api/data → cache miss → generate body → store in cache → 200 (x-cache: miss) +GET /api/data → cache hit → return cached body → 200 (x-cache: hit) +``` + +The cache key is `page:`. Each unique path gets its own cache entry. The response body is a simple HTML page that includes the request path — stand in for any expensive computation or template render. + +## What it returns + +``` +HTTP/1.1 200 OK +content-type: text/html +x-cache: hit | miss + +... +``` + +## Build + +```sh +cargo build --release +# Output: target/wasm32-wasip1/release/cache_basic.wasm +``` + +## APIs used + +- `fastedge::cache::get(key)` — retrieve cached bytes by key; returns `Ok(Option>)` +- `fastedge::cache::set(key, bytes, ttl_ms)` — store bytes with optional TTL in milliseconds; `None` means no expiry +``` diff --git a/reference-docs/http-examples-cache-js.md b/reference-docs/http-examples-cache-js.md index c3bc2f1..46d3c9c 100644 --- a/reference-docs/http-examples-cache-js.md +++ b/reference-docs/http-examples-cache-js.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-js ref: main - commit: 81145a9a43ec499240c687bd49376ab20c72b11c - updated: 2026-08-20 + commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 + updated: 2026-09-22 --> # FastEdge Cache — JavaScript Examples @@ -331,279 +331,3 @@ Validation errors (e.g., conflicting `WriteOptions`) are thrown synchronously. H - platform-overview (POP topology, request lifecycle) - deploy skill reference (fastedge-build CLI, binary upload) - best-practices (error handling patterns, response construction) - -## Source Material - -### FILE: examples/cache/src/index.ts - -```ts -// FastEdge Cache — flagship patterns -// -// This example demonstrates the three highest-value uses of the -// `fastedge::cache` module: -// -// 1. Per-IP rate limiting (atomic counters) -// 2. Origin-cache proxy (manual get/set with conditional caching) -// 3. JSON memoisation (getOrSet with a computed populator) -// -// All three patterns rely on the cache being: -// - **Strongly consistent within a POP** — atomic `incr` returns a -// correct count under concurrent load, which `fastedge::kv` cannot. -// - **Fast for both reads and writes** — sub-millisecond on the hot -// path, so caching is cheaper than recomputing or refetching. -// - **POP-local** — values do not replicate across data centers. -// This is acceptable (and often desirable) for transient state. - -import { Cache } from 'fastedge::cache'; - -// --------------------------------------------------------------------------- -// Pattern 1 — Rate limiting via atomic incr + expire -// --------------------------------------------------------------------------- -// -// Increment a per-IP counter. On the first hit (count === 1) we attach -// a TTL to create a fixed 60-second window anchored to that request: -// the counter resets 60 seconds after the user's *first* request, not -// after every request. -// -// `Cache.incr` is atomic: under concurrent load, two simultaneous -// requests cannot both see "count === 1" and double-set the expiry. -// This is the property that makes the cache suitable for limiting, -// quotas, locks, and other counter primitives. - -const RATE_LIMIT_MAX = 10; // Requests per window. -const RATE_LIMIT_WINDOW_S = 60; // Window length, seconds. - -async function rateLimit(event: FetchEvent): Promise { - // `event.client.address` is the trusted-edge client IP. Sourced from - // `x-real-ip` (with fallback to `x-forwarded-for`); both are set by - // the FastEdge POP, not the client, so they're safe to key on. - const ip = event.client.address || 'unknown'; - - const key = `rl:${ip}`; - - const count = await Cache.incr(key); - - // Only set the expiry on the first hit of a new window. If we set it - // on every request, the window would never close — each new request - // would push the deadline another 60 seconds out. - if (count === 1) { - await Cache.expire(key, { ttl: RATE_LIMIT_WINDOW_S }); - } - - if (count > RATE_LIMIT_MAX) { - return Response.json( - { error: 'Too Many Requests', limit: RATE_LIMIT_MAX, count }, - { status: 429, headers: { 'retry-after': String(RATE_LIMIT_WINDOW_S) } }, - ); - } - - return Response.json({ - pattern: 'rate-limit', - ip, - count, - remaining: RATE_LIMIT_MAX - count, - windowSeconds: RATE_LIMIT_WINDOW_S, - }); -} - -// --------------------------------------------------------------------------- -// Pattern 2 — Origin-cache proxy with conditional caching -// --------------------------------------------------------------------------- -// -// Cache successful upstream responses for PROXY_TTL_S seconds; pass -// non-2xx and redirects through *without* caching, so a transient 404 -// or 500 doesn't get pinned for the rest of the window. The cache is -// a byte cache (no status/headers), so we only cache when "200 OK with -// application/octet-stream" is a faithful replay of the upstream. -// -// `getOrSet` is not used here because its populator can't signal -// "fetched, but don't cache" — we need that distinction to handle -// error responses safely. See Pattern 3 for `getOrSet` in a context -// where every populator output is cacheable. - -const PROXY_TTL_S = 30; - -async function proxy(url: string): Promise { - // Validate the URL before we use it as a cache key. - let parsed: URL; - try { - parsed = new URL(url); - } catch { - return Response.json({ error: `Invalid url: "${url}"` }, { status: 400 }); - } - - // Strip the fragment: fetch() never sends it to the origin, so - // `https://example.com/#a` and `#b` are the same upstream resource - // and must share one cache entry. - parsed.hash = ''; - - const key = `proxy:${parsed.toString()}`; - - // Cache hit — replay the bytes as 200 OK. Status/headers from the - // original response are not preserved by the byte cache. - const cached = await Cache.get(key); - if (cached !== null) { - return new Response(await cached.arrayBuffer(), { - headers: { - 'content-type': 'application/octet-stream', - 'x-cache': 'hit', - 'x-cache-ttl': String(PROXY_TTL_S), - }, - }); - } - - // Cache miss — fetch upstream and only cache successful responses. - // Non-2xx and redirects flow through unchanged so callers see the - // real status code instead of a synthetic 200. - const upstream = await fetch(parsed.toString()); - if (!upstream.ok) { - return upstream; - } - - const bytes = await upstream.arrayBuffer(); - await Cache.set(key, bytes, { ttl: PROXY_TTL_S }); - return new Response(bytes, { - headers: { - 'content-type': 'application/octet-stream', - 'x-cache': 'miss', - 'x-cache-ttl': String(PROXY_TTL_S), - }, - }); -} - -// --------------------------------------------------------------------------- -// Pattern 3 — JSON memoisation via getOrSet with a computed populator -// --------------------------------------------------------------------------- -// -// Same shape as the proxy pattern, but the populator does CPU work -// instead of network I/O. Use this whenever you compute the same -// expensive answer many times in a row — search index lookups, -// signed-token verification, derived report rollups, JSON -// transformations of slow-changing source data. -// -// We embed `generatedAt` in the result so a client refreshing the -// page can see the timestamp stay constant within the cache window -// and update once it expires. - -const MEMO_TTL_S = 60; - -async function memo(): Promise { - const entry = await Cache.getOrSet( - 'memo:report', - () => { - // Stand-in for "expensive computation". The populator can be - // synchronous or async — both are accepted. - const report = { - generatedAt: new Date().toISOString(), - topItems: ['alpha', 'beta', 'gamma'].map((name, i) => ({ - name, - score: Math.round(Math.random() * 1000) / 10, - rank: i + 1, - })), - }; - // The populator returns the value to store. Because we want - // structured JSON back later, we serialise here and re-parse - // via `entry.json()` on read. - return JSON.stringify(report); - }, - { ttl: MEMO_TTL_S }, - ); - - // `entry.json()` parses the cached UTF-8 bytes as JSON. Use - // `entry.text()` for a string, or `entry.arrayBuffer()` for bytes. - const report = await entry.json(); - - return Response.json({ - pattern: 'memo', - note: `Cached for ${MEMO_TTL_S}s. Refresh to confirm 'generatedAt' stays the same until expiry.`, - report, - }); -} - -// --------------------------------------------------------------------------- -// Default landing — usage menu when no action is supplied -// --------------------------------------------------------------------------- - -function landing(): Response { - return Response.json({ - name: 'FastEdge Cache patterns', - actions: { - 'rate-limit': '/?action=rate-limit', - proxy: '/?action=proxy&url=https://www.example.com', - memo: '/?action=memo', - }, - }); -} - -// --------------------------------------------------------------------------- -// Router -// --------------------------------------------------------------------------- - -async function eventHandler(event: FetchEvent): Promise { - try { - const url = new URL(event.request.url); - const action = url.searchParams.get('action'); - - switch (action) { - case 'rate-limit': - return await rateLimit(event); - case 'proxy': - return await proxy(url.searchParams.get('url') ?? ''); - case 'memo': - return await memo(); - case null: - return landing(); - default: - return Response.json( - { error: `Unknown action: "${action}". Use one of: rate-limit, proxy, memo.` }, - { status: 400 }, - ); - } - } catch (error: unknown) { - // Validation errors thrown by Cache.* (e.g. conflicting WriteOptions - // fields) are synchronous; host errors arrive as Promise rejections. - // Both are caught by this single handler. - return Response.json({ error: (error as Error).message }, { status: 500 }); - } -} - -addEventListener('fetch', (event: FetchEvent) => { - event.respondWith(eventHandler(event)); -}); -``` - -### FILE: examples/cache/package.json - -```json -{ - "name": "fastedge-example-cache", - "version": "1.0.0", - "description": "FastEdge JS example: Cache patterns — rate limiting, origin-cache proxy, memoisation", - "type": "module", - "scripts": { - "build": "fastedge-build -c" - }, - "dependencies": { - "@gcoredev/fastedge-sdk-js": "^2.3.0" - } -} -``` - -### FILE: examples/cache/tsconfig.json - -```json -{ - "compilerOptions": { - "target": "ES2023", - "module": "ESNext", - "moduleResolution": "Bundler", - "strict": true, - "skipLibCheck": true, - "noEmit": true, - "lib": ["ES2023"], - "types": ["@gcoredev/fastedge-sdk-js"] - }, - "include": ["src/**/*"], - "exclude": ["node_modules"] -} -``` diff --git a/reference-docs/http-examples-cache-wasi-rust.md b/reference-docs/http-examples-cache-wasi-rust.md index a84bdad..b8d5f3c 100644 --- a/reference-docs/http-examples-cache-wasi-rust.md +++ b/reference-docs/http-examples-cache-wasi-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- @@ -188,197 +188,3 @@ cargo build --release - HTTP outbound requests via wstd (sdk-reference-rust) - Environment variable configuration (platform-overview) - HTTP app deploy workflow (deploy skill) - -## Source Material - -### FILE: examples/http/wasi/cache/src/lib.rs - -```rust -/* - * Copyright 2025 G-Core Innovations SARL - */ -/* -Example app demonstrating response caching and cache purging via the cache interface. - -The app reads ORIGIN_HOST from the environment, forwards the incoming request -to that origin, and caches the response body keyed by the request path. -On subsequent requests for the same path the cached body is returned directly -without hitting the origin. - -Cache reads and writes use the synchronous `fastedge::cache` API; upstream -HTTP I/O still uses the async `wstd` client. - -Special purge routes (handled before any origin call): - GET /purge — purge all cached keys; returns 200 with deleted count - GET /purge/ — purge keys whose cache key starts with cache:/ - -Environment variables: - ORIGIN_HOST Base URL of the upstream origin, e.g. https://api.example.com - CACHE_TTL_MS How long to cache responses in milliseconds (default: 60000) - -Build: - cargo build --release -*/ - -use std::env; - -use anyhow::anyhow; -use fastedge::cache; -use wstd::http::body::Body; -use wstd::http::{Client, Request, Response}; - -#[wstd::http_server] -async fn main(req: Request) -> anyhow::Result> { - let origin = env::var("ORIGIN_HOST") - .map_err(|_| anyhow!("ORIGIN_HOST environment variable is not set"))?; - - let ttl_ms = req.headers().get("cache-ttl-ms").and_then(|v| v.to_str().ok()) - .and_then(|s| s.parse().ok()) - .unwrap_or_else(|| { - env::var("CACHE_TTL_MS") - .ok() - .and_then(|v| v.parse().ok()) - .unwrap_or(60_000) - }); - - // Build cache key from the request path (and query string if present) - let path_and_query = req - .uri() - .path_and_query() - .map(|pq| pq.as_str()) - .unwrap_or("/"); - - - // Handle purge requests before any cache/origin logic - if path_and_query == "/purge" { - let deleted = cache::purge()?; - println!("purge all: {deleted} keys removed"); - return Ok(Response::builder() - .status(204) - .body(Body::empty())?); - } - if let Some(prefix) = path_and_query.strip_prefix("/purge/") { - let prefix = format!("cache:/{prefix}"); - let deleted = cache::purge_prefix(&prefix)?; - println!("purge prefix '{prefix}': {deleted} keys removed"); - return Ok(Response::builder() - .status(204) - .body(Body::empty())?); - } - - if let Some(prefix) = path_and_query.strip_prefix("/delete/") { - let prefix = format!("cache:/{prefix}"); - cache::delete(&prefix)?; - println!("prefix '{prefix}': removed"); - return Ok(Response::builder() - .status(204) - .body(Body::empty())?); - } - - let cache_key = format!("cache:{path_and_query}"); - - // Return cached response if available - if let Some(cached) = cache::get(&cache_key)? { - println!("cache hit: {cache_key}"); - return Ok(Response::builder() - .status(200) - .header("content-type", "application/octet-stream") - .header("x-cache", "hit") - .body(Body::from(cached))?); - } - - // Cache miss — forward request to origin - let upstream_url = format!("{}{}", origin.trim_end_matches('/'), path_and_query); - println!("cache miss: {cache_key} → {upstream_url}"); - - let upstream_req = Request::get(&upstream_url) - .body(Body::empty()) - .map_err(|e| anyhow!("failed to build upstream request: {e}"))?; - - let upstream_resp = Client::new() - .send(upstream_req) - .await - .map_err(|e| anyhow!("upstream request failed: {e}"))?; - - let status = upstream_resp.status(); - let headers: Vec<(String, String)> = upstream_resp - .headers() - .iter() - .map(|(k, v)| (k.to_string(), v.to_str().unwrap_or("").to_string())) - .collect(); - - // Read body bytes - let mut body = upstream_resp.into_body(); - let body_bytes = body.contents().await?.to_vec(); - - // Only cache successful responses - if status.is_success() { - cache::set(&cache_key, &body_bytes, Some(ttl_ms))?; - } - - // Replay original response - let mut builder = Response::builder() - .status(status) - .header("x-cache", "miss"); - for (k, v) in &headers { - builder = builder.header(k, v); - } - Ok(builder.body(Body::from(body_bytes))?) -} -``` - - -### FILE: examples/http/wasi/cache/Cargo.toml - -```toml -[workspace] - -[package] -name = "cache_wasi" -version = "0.1.0" -edition = "2021" - -[lib] -crate-type = ["cdylib"] - -[dependencies] -wstd = "0.6" -fastedge = "0.4" -anyhow = "1" -``` - - -### FILE: examples/http/wasi/cache/README.md - -``` -[← Back to examples](../../../README.md) - -# Cache (WASI) - -Demonstrates the cache-aside pattern with origin forwarding using `fastedge::cache`. Forwards incoming requests to `ORIGIN_HOST`, caches successful response bodies keyed by path and query string, and serves cached bytes directly on subsequent matching requests. - -## Configuration - -| Env var | Required | Description | -|---|---|---| -| `ORIGIN_HOST` | Yes | Base URL of the upstream origin (e.g. `https://api.example.com`). Returns 500 if unset. | -| `CACHE_TTL_MS` | No | How long to cache responses in milliseconds. Default: `60000` (60 s). | - -## How it works - -GET /data?id=1 → cache miss → forward to ORIGIN_HOST/data?id=1 → cache 2xx body → 200 (x-cache: miss) -GET /data?id=1 → cache hit → return cached body → 200 (x-cache: hit) - -Cache key is `cache:?`. Only 2xx responses from the origin are cached — error responses pass through without being stored. The origin's response headers are replayed on cache miss; cache-hit responses use `content-type: application/octet-stream` since the original content-type is not stored alongside the body bytes. - -## Build - -cargo build --release -# Output: target/wasm32-wasip2/release/cache_wasi.wasm - -## APIs used - -- `fastedge::cache::get(key)` — retrieve cached bytes by key; returns `Ok(Option>)` -- `fastedge::cache::set(key, bytes, ttl_ms)` — store bytes with optional TTL in milliseconds; `None` means no expiry -- `wstd::http::Client::new().send(req).await` — async outbound HTTP request to origin -``` diff --git a/reference-docs/http-examples-diagnostic-logging-wasi-rust.md b/reference-docs/http-examples-diagnostic-logging-wasi-rust.md index 05dd5fe..da2a970 100644 --- a/reference-docs/http-examples-diagnostic-logging-wasi-rust.md +++ b/reference-docs/http-examples-diagnostic-logging-wasi-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- @@ -190,152 +190,3 @@ Use `key=value` pairs separated by spaces (`logfmt`-ish format). Benefits: - host-services-rust (other host service integrations available to Rust WASI apps) - CDN (proxy-wasm) variant: `fastedge::proxywasm::utils::set_user_diag` — same semantics, different module path (see CDN apps reference) - examples-kv-store-wasi-rust (another Rust WASI HTTP example showing KV Store usage) - -## Source Material - -### FILE: examples/http/wasi/diagnostic_logging/src/lib.rs - -```rust -/* - * Copyright 2025 G-Core Innovations SARL - */ -/* -Diagnostic logging example. - -Tiny pass-through proxy that writes a single `set_user_diag` tag per request -summarising the outcome (config_error, origin_unreachable, or proxied). The -tag appears in the FastEdge platform's per-request log viewer and is distinct -from stdout — it's intended for filterable outcome labels, not verbose -traces. - -Required configuration: - - Environment variable: ORIGIN_URL (origin to proxy to) - -Uses `logfmt`-ish formatting (`outcome= key=value ...`) so the tag is -easy to slice in log search tooling. -*/ - -use std::env; - -use fastedge::utils::set_user_diag; -use wstd::http::body::Body; -use wstd::http::{Client, Request, Response}; - -#[wstd::http_server] -async fn main(req: Request) -> anyhow::Result> { - let method = req.method().as_str().to_string(); - let path = req.uri().path().to_string(); - - let origin = match env::var("ORIGIN_URL") { - Ok(u) if !u.trim().is_empty() => u, - _ => { - set_user_diag("outcome=config_error reason=origin_missing"); - return Ok(Response::builder() - .status(500) - .header("content-type", "text/plain; charset=utf-8") - .body(Body::from("ORIGIN_URL is not configured"))?); - } - }; - - let outbound = Request::get(&origin).body(Body::empty())?; - let resp = match Client::new().send(outbound).await { - Ok(r) => r, - Err(e) => { - set_user_diag(&format!( - "outcome=origin_unreachable method={method} path={path} err={e}" - )); - return Ok(Response::builder() - .status(502) - .header("content-type", "text/plain; charset=utf-8") - .body(Body::from("origin unreachable"))?); - } - }; - - let status = resp.status().as_u16(); - set_user_diag(&format!( - "outcome=proxied method={method} path={path} status={status}" - )); - - let (parts, mut body) = resp.into_parts(); - let bytes = body.contents().await?; - let content_type = parts - .headers - .get("content-type") - .and_then(|v| v.to_str().ok()) - .unwrap_or("application/octet-stream") - .to_string(); - - Ok(Response::builder() - .status(parts.status) - .header("content-type", content_type) - .body(Body::from(bytes))?) -} -``` - - -### FILE: examples/http/wasi/diagnostic_logging/Cargo.toml - -```toml -[workspace] - -[package] -name = "diagnostic_logging_wasi" -version = "0.1.0" -edition = "2021" - -[lib] -crate-type = ["cdylib"] - -[dependencies] -wstd = "0.6" -fastedge = "0.4" -anyhow = "1" -``` - - -### FILE: examples/http/wasi/diagnostic_logging/README.md - -``` -[← Back to examples](../../../README.md) - -# Diagnostic Logging (WASI) - -Pass-through proxy that writes a single `fastedge::utils::set_user_diag` tag per request -summarising the outcome. The tag appears in the FastEdge platform's per-request log viewer, -distinct from stdout, and is designed to be filtered/counted/aggregated by SREs looking at -per-request outcomes. - -## Configuration - -- `ORIGIN_URL` environment variable — the origin that requests are proxied to. - -## Outcomes - -Each request writes exactly one of: - -| Condition | Tag | -| --- | --- | -| `ORIGIN_URL` missing | `outcome=config_error reason=origin_missing` | -| Origin unreachable | `outcome=origin_unreachable method= path=

err=` | -| Request proxied | `outcome=proxied method= path=

status=` | - -## `set_user_diag` vs `println!` - -| | `println!` | `set_user_diag` | -| --- | --- | --- | -| Channel | stdout — general application logs | per-request structured tag in platform log viewer | -| Cardinality | many per request | **one per request** — multiple calls leave only the last or are concatenated (undefined) | -| Best for | verbose traces, debug details | a single filterable outcome label | -| Forbidden | — | secrets and PII (tags appear in platform logs) | - -## Convention - -Call `set_user_diag` **once**, on every branch, late enough in the handler to know the -outcome. The `logfmt`-ish format (`outcome= key=value key=value …`) is easy to slice in -log search tooling — keep keys short and stable so they make good filter terms. - -## Related - -CDN (proxy-wasm) variant: `fastedge::proxywasm::utils::set_user_diag` — same semantics, -different module path. See `docs/CDN_APPS.md`. -``` diff --git a/reference-docs/http-examples-fetch-js.md b/reference-docs/http-examples-fetch-js.md index 4db84f6..7b5cf8c 100644 --- a/reference-docs/http-examples-fetch-js.md +++ b/reference-docs/http-examples-fetch-js.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-js ref: main - commit: 81145a9a43ec499240c687bd49376ab20c72b11c - updated: 2026-08-20 + commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 + updated: 2026-09-22 --> ## fetch — Outbound HTTP Requests diff --git a/reference-docs/http-examples-geo-redirect-js.md b/reference-docs/http-examples-geo-redirect-js.md index b0f32ea..dad6840 100644 --- a/reference-docs/http-examples-geo-redirect-js.md +++ b/reference-docs/http-examples-geo-redirect-js.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-js ref: main - commit: 81145a9a43ec499240c687bd49376ab20c72b11c - updated: 2026-08-20 + commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 + updated: 2026-09-22 --> ## Example: Geo-Redirect diff --git a/reference-docs/http-examples-geo-redirect-wasi-rust.md b/reference-docs/http-examples-geo-redirect-wasi-rust.md index 156e1a1..1b51b47 100644 --- a/reference-docs/http-examples-geo-redirect-wasi-rust.md +++ b/reference-docs/http-examples-geo-redirect-wasi-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/http-examples-headers-js.md b/reference-docs/http-examples-headers-js.md index 7add540..dc5cdf6 100644 --- a/reference-docs/http-examples-headers-js.md +++ b/reference-docs/http-examples-headers-js.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-js ref: main - commit: 81145a9a43ec499240c687bd49376ab20c72b11c - updated: 2026-08-20 + commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 + updated: 2026-09-22 --> ## Headers Example — FastEdge JS diff --git a/reference-docs/http-examples-headers-wasi-rust.md b/reference-docs/http-examples-headers-wasi-rust.md index aa0c50f..56a90a3 100644 --- a/reference-docs/http-examples-headers-wasi-rust.md +++ b/reference-docs/http-examples-headers-wasi-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/http-examples-hello-world-basic-rust.md b/reference-docs/http-examples-hello-world-basic-rust.md index 0d256e6..97dec3d 100644 --- a/reference-docs/http-examples-hello-world-basic-rust.md +++ b/reference-docs/http-examples-hello-world-basic-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/http-examples-hello-world-wasi-rust.md b/reference-docs/http-examples-hello-world-wasi-rust.md index 7fe9ca6..ab30b5e 100644 --- a/reference-docs/http-examples-hello-world-wasi-rust.md +++ b/reference-docs/http-examples-hello-world-wasi-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/http-examples-hono-js.md b/reference-docs/http-examples-hono-js.md index 7dd139b..61364a2 100644 --- a/reference-docs/http-examples-hono-js.md +++ b/reference-docs/http-examples-hono-js.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-js ref: main - commit: 81145a9a43ec499240c687bd49376ab20c72b11c - updated: 2026-08-20 + commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 + updated: 2026-09-22 --> # Hono Patterns on FastEdge (JavaScript/TypeScript) diff --git a/reference-docs/http-examples-kv-store-js.md b/reference-docs/http-examples-kv-store-js.md index eb54e64..76aae72 100644 --- a/reference-docs/http-examples-kv-store-js.md +++ b/reference-docs/http-examples-kv-store-js.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-js ref: main - commit: 81145a9a43ec499240c687bd49376ab20c72b11c - updated: 2026-08-20 + commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 + updated: 2026-09-22 --> ## KV Store — Example Reference diff --git a/reference-docs/http-examples-kv-store-wasi-rust.md b/reference-docs/http-examples-kv-store-wasi-rust.md index 99f207d..f629d30 100644 --- a/reference-docs/http-examples-kv-store-wasi-rust.md +++ b/reference-docs/http-examples-kv-store-wasi-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/http-examples-large-env-variable-wasi-rust.md b/reference-docs/http-examples-large-env-variable-wasi-rust.md index 5215a84..18a78c4 100644 --- a/reference-docs/http-examples-large-env-variable-wasi-rust.md +++ b/reference-docs/http-examples-large-env-variable-wasi-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> # Large Environment Variable (WASI) — Rust HTTP Example diff --git a/reference-docs/http-examples-markdown-render-basic-rust.md b/reference-docs/http-examples-markdown-render-basic-rust.md index 7e480df..93ce19f 100644 --- a/reference-docs/http-examples-markdown-render-basic-rust.md +++ b/reference-docs/http-examples-markdown-render-basic-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/http-examples-outbound-fetch-basic-rust.md b/reference-docs/http-examples-outbound-fetch-basic-rust.md index 50f4454..2be77e3 100644 --- a/reference-docs/http-examples-outbound-fetch-basic-rust.md +++ b/reference-docs/http-examples-outbound-fetch-basic-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/http-examples-outbound-fetch-wasi-rust.md b/reference-docs/http-examples-outbound-fetch-wasi-rust.md index 05d01a2..67088ca 100644 --- a/reference-docs/http-examples-outbound-fetch-wasi-rust.md +++ b/reference-docs/http-examples-outbound-fetch-wasi-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> # Outbound Fetch — WASI (Rust) diff --git a/reference-docs/http-examples-outbound-modify-response-wasi-rust.md b/reference-docs/http-examples-outbound-modify-response-wasi-rust.md index 83b2f9f..46414f6 100644 --- a/reference-docs/http-examples-outbound-modify-response-wasi-rust.md +++ b/reference-docs/http-examples-outbound-modify-response-wasi-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/http-examples-print-basic-rust.md b/reference-docs/http-examples-print-basic-rust.md index b0699e3..0c80045 100644 --- a/reference-docs/http-examples-print-basic-rust.md +++ b/reference-docs/http-examples-print-basic-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- @@ -147,112 +147,3 @@ cargo build --release - sdk-reference-rust (full API reference for `fastedge` crate) - platform-overview (request lifecycle, header forwarding behaviour) - best-practices (response building patterns) - -## Source Material - -### FILE: examples/http/basic/print/src/lib.rs - -```rust -use anyhow::Result; -use fastedge::body::Body; -use fastedge::http::{Request, Response, StatusCode}; - -#[allow(dead_code)] -#[fastedge::http] -fn main(req: Request) -> Result> { - let mut body: String = "Method: ".to_string(); - body.push_str(req.method().as_str()); - - body.push_str("\nURL: "); - body.push_str(req.uri().to_string().as_str()); - - body.push_str("\nHeaders:"); - for (h, v) in req.headers() { - body.push_str("\n "); - body.push_str(h.as_str()); - body.push_str(": "); - match v.to_str() { - Err(_) => body.push_str("not a valid text"), - Ok(a) => body.push_str(a), - } - } - let res = Response::builder() - .status(StatusCode::OK) - .body(Body::from(body))?; - Ok(res) -} -``` - -### FILE: examples/http/basic/print/Cargo.toml - -```toml -[workspace] - -[package] -name = "print" -version = "0.1.0" -edition = "2021" - -[lib] -crate-type = ["cdylib"] - -[dependencies] -fastedge = "0.4" -anyhow = "1" -``` - -### FILE: examples/http/basic/print/README.md - -``` -[← Back to examples](../../../README.md) - -# Print - -Echoes the incoming request's method, URL, and all headers back in the response body as plain text. Useful for debugging and inspecting what a FastEdge app receives from clients and the platform. - -> **Note:** This example uses the legacy `#[fastedge::http]` sync handler (`wasm32-wasip1`). For new apps, prefer `#[wstd::http_server]` (async, `wasm32-wasip2`) — see [`examples/http/wasi/`](../../wasi/). - -## What it demonstrates - -- Reading request method via `req.method().as_str()` -- Reading the request URI via `req.uri().to_string()` -- Iterating all request headers via `req.headers()` -- Handling non-UTF-8 header values gracefully with a `match` on `v.to_str()` -- Building a plain-text response with `Response::builder()` and `Body::from(...)` - -## APIs used - -| API | Purpose | -|-----|---------| -| `req.method().as_str()` | HTTP method as a string slice | -| `req.uri().to_string()` | Full request URI as a `String` | -| `req.headers()` | Iterator over `(HeaderName, HeaderValue)` pairs | -| `v.to_str()` | Decode a header value to `&str` (returns `Err` for non-UTF-8) | -| `Response::builder().status(...).body(...)` | Build the HTTP response | -| `Body::from(string)` | Create a response body from a `String` | - -## Build - -```sh -cargo build --release -# Output: target/wasm32-wasip1/release/print.wasm -``` - -## Expected behaviour - -For any request, the response body is a plain-text dump of the request details: - -``` -Method: GET -URL: /some/path?query=value -Headers: - host: example.com - accept: */* - ... -``` - -- Status: `200 OK` -- Content: plain text (no `content-type` header is set explicitly; the platform may add one) -- Each header appears on its own line, indented with four spaces -- Non-UTF-8 header values are replaced with `not a valid text` -``` diff --git a/reference-docs/http-examples-proxy-js.md b/reference-docs/http-examples-proxy-js.md index e9a2822..b61ea98 100644 --- a/reference-docs/http-examples-proxy-js.md +++ b/reference-docs/http-examples-proxy-js.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-js ref: main - commit: 81145a9a43ec499240c687bd49376ab20c72b11c - updated: 2026-08-20 + commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 + updated: 2026-09-22 --> # Proxy and Response Transform Patterns (JavaScript/TypeScript) @@ -250,178 +250,3 @@ Returns: `ArrayBuffer | null` — `null` if the key does not exist. - examples/kv-store — KV-backed caching patterns - platform-overview reference — plan limits, execution budget, and body size constraints - sdk-reference-js reference — full KvStore API - -## Source Material - -### FILE: docs/PROXY_PATTERNS.md - -``` - - -# Proxy and Response Transform Patterns - -FastEdge HTTP apps can act as a thin proxy in front of an origin or upstream API — fetching a response, transforming it, and returning the result. This document covers the common proxy and transform patterns. - -## Simple Proxy - -Fetch from an upstream and return the body unchanged: - -```typescript -async function handle(request) { - const url = new URL(request.url); - const upstream = `https://backend.example.com${url.pathname}${url.search}`; - - const response = await fetch(upstream, { - method: request.method, - headers: request.headers, - body: request.method !== "GET" && request.method !== "HEAD" - ? await request.arrayBuffer() - : undefined, - }); - - return response; -} - -addEventListener("fetch", (event) => { - event.respondWith(handle(event.request)); -}); -``` - -`fetch()` returns a streamable `Response`; returning it directly forwards body chunks without buffering everything in memory. - -## Proxy with JSON Transform - -Modify the response body before returning it. This is the pattern from `examples/outbound-modify-response/`: - -```typescript -async function handle() { - const upstream = await fetch("https://jsonplaceholder.typicode.com/users"); - const users = await upstream.json(); - - const transformed = { - users: users.slice(0, 5), - total: 5, - skip: 0, - limit: 30, - }; - - return new Response(JSON.stringify(transformed), { - status: 200, - headers: { "content-type": "application/json" }, - }); -} - -addEventListener("fetch", (event) => { - event.respondWith(handle()); -}); -``` - -Reading `await upstream.json()` consumes the body; you cannot read it again. Read the body once, transform what you need, then return. - -## Hono Proxy with Transform - -Inside a Hono app, use `c.req.raw.headers` to forward the inbound headers and `c.req.arrayBuffer()` for the body: - -```typescript -import { Hono } from "hono"; - -const app = new Hono(); - -app.all("/api/*", async (c) => { - const url = new URL(c.req.url); - const upstream = `https://backend.example.com${url.pathname}${url.search}`; - - const response = await fetch(upstream, { - method: c.req.method, - headers: c.req.raw.headers, - body: c.req.method !== "GET" && c.req.method !== "HEAD" - ? await c.req.arrayBuffer() - : undefined, - }); - - const data = await response.json(); - data.processedAt = new Date().toISOString(); - return c.json(data, response.status); -}); - -addEventListener("fetch", (event) => { - event.respondWith(app.fetch(event.request)); -}); -``` - -## Header Manipulation in Proxies - -Strip hop-by-hop headers before forwarding to upstream, and add diagnostic headers on the way back: - -```typescript -async function handle(request) { - const upstreamHeaders = new Headers(request.headers); - // Hop-by-hop headers should not be forwarded - upstreamHeaders.delete("connection"); - upstreamHeaders.delete("keep-alive"); - upstreamHeaders.delete("transfer-encoding"); - - const upstream = await fetch("https://backend.example.com", { - method: request.method, - headers: upstreamHeaders, - }); - - const responseHeaders = new Headers(upstream.headers); - responseHeaders.set("X-Proxied-By", "FastEdge"); - - return new Response(upstream.body, { - status: upstream.status, - headers: responseHeaders, - }); -} -``` - -`new Response(upstream.body, ...)` streams the body through without reading it into memory — preferred for large responses. - -## Cache-aware Proxy with KV - -Cache upstream responses in the KV store to avoid repeated outbound calls. Note: KV is read-only from app code; writes happen via the portal/API: - -```typescript -import { KvStore } from "fastedge::kv"; - -async function handle(request) { - const url = new URL(request.url); - - try { - const cache = KvStore.open("api-cache"); - const cached = cache.get(url.pathname); - if (cached !== null) { - return new Response(cached, { - status: 200, - headers: { "content-type": "application/json", "x-cache": "hit" }, - }); - } - } catch { - // KV store unavailable — fall through to upstream fetch - } - - const upstream = await fetch(`https://backend.example.com${url.pathname}`); - return new Response(await upstream.arrayBuffer(), { - status: upstream.status, - headers: { ...Object.fromEntries(upstream.headers), "x-cache": "miss" }, - }); -} -``` - -`KvStore.open(name)` returns a `KvStoreInstance` (it does not return null) but can throw if the named store is not provisioned — wrap the open call in `try/catch`. `cache.get(key)` returns `ArrayBuffer | null`; check for `null`, not falsy, since an empty buffer is a valid value. - -## Operational Notes - -- **Outbound fetch budget.** Each invocation has a limited number of outbound requests (5 on Basic, 20 on Pro). Parallelise where possible with `Promise.all([...])` instead of sequential `await fetch(...)`. -- **Execution time budget.** Proxying upstream + transforming counts against the 50ms (Basic) / 200ms (Pro) execution budget. Slow upstreams will trip 532 timeouts. -- **Body size limits.** Inbound and outbound bodies are subject to the configured request/response size limits. Stream where possible rather than buffering with `arrayBuffer()` / `text()` / `json()`. - -## See Also - -- `examples/outbound-modify-response/` — JSON transform of upstream response -- `examples/outbound-fetch/` — basic outbound `fetch()` patterns -- `examples/headers/` — request/response header manipulation -- `examples/kv-store/` — KV-backed caching patterns - -``` diff --git a/reference-docs/http-examples-s3upload-basic-rust.md b/reference-docs/http-examples-s3upload-basic-rust.md index f789dad..f523acd 100644 --- a/reference-docs/http-examples-s3upload-basic-rust.md +++ b/reference-docs/http-examples-s3upload-basic-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- @@ -182,236 +182,3 @@ cargo build --release - sdk-reference-rust (`fastedge::send_request`, `Body`, `Request`, `Response`) - host-services-rust (outbound HTTP) - rusty-s3 crate documentation (external) - -## Source Material - -### FILE: examples/http/basic/s3upload/src/lib.rs - -```rust -use std::time::Duration; - -use fastedge::{ - body::Body, - http::{header, Error, Method, Request, Response, StatusCode}, -}; -use rusty_s3::{Bucket, Credentials, S3Action, UrlStyle}; -use std::{collections::HashMap, env}; -use url::Url; - -#[fastedge::http] -fn main(req: Request) -> Result, Error> { - match req.method() { - // Allow only POST and PUT requests - &Method::POST | &Method::PUT => (), - - &Method::OPTIONS => { - return Response::builder() - .status(StatusCode::NO_CONTENT) - .body(Body::empty()); - } - - // Deny anything else - _ => { - return Response::builder() - .status(StatusCode::METHOD_NOT_ALLOWED) - .header(header::ALLOW, "PUT, POST") - .body(Body::from("This method is not allowed\n")); - } - }; - - /* get request params */ - let query_pairs = |q: &str| { - q.split('&') - .filter_map(|q| { - let mut i = q.splitn(2, '='); - let k = i.next()?; - let v = i.next()?; - Some((k, v)) - }) - .map(|(k, v)| (k.to_owned(), v.to_owned())) - .collect::>() - }; - let hash_query: HashMap = req.uri().query().map_or(HashMap::new(), query_pairs); - - let fname = match hash_query.get("name") { - None => { - return Response::builder() - .status(StatusCode::BAD_REQUEST) - .body(Body::from("Malformed request\n")) - } - Some(i) => i, - }; - if req.body().is_empty() { - return Response::builder() - .status(StatusCode::BAD_REQUEST) - .body(Body::from("Malformed request\n")); - } - let content_type = match req.headers().get("Content-Type") { - None => "application/octet-stream", - Some(v) => v.to_str().unwrap_or("application/octet-stream"), - }; - let content_type = content_type.to_owned(); - let content = req.into_body(); - - match env::var("MAX_FILE_SIZE").ok() { - None => {} - Some(l) => match l.parse::() { - Err(_) => {} - Ok(v) => { - if content.len() > v { - let msg = format!("File exceeds allowed limit of {} bytes\n", v); - return Response::builder() - .status(StatusCode::PAYLOAD_TOO_LARGE) - .body(Body::from(msg.as_str().to_owned())); - } - } - }, - } - - let (signed_url, host) = match prepare_s3(fname) { - Err(_) => { - return Response::builder() - .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from("App misconfigured\n")) - } - Ok((u, h)) => (u, h), - }; - - /* build outgoing req */ - let out_req = Request::builder() - .method(Method::PUT) - .uri(signed_url.as_str()) - .header("Host", host) - .header("Accept-Encoding", "identity") - .header("Content-Length", content.len().to_string()) - .header("Content-Type", content_type); - - let Ok(req) = out_req.body(content) else { - return Response::builder() - .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from("Malformed request\n")); - }; - - let rsp = match fastedge::send_request(req) { - Err(_) => { - return Response::builder() - .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::empty()) - } - Ok(r) => r, - }; - let (parts, body) = rsp.into_parts(); - let body = if parts.status == StatusCode::OK { - let mut tmp_url = signed_url.clone(); - tmp_url.set_query(None); - Body::from(tmp_url.to_string()) - } else { - body - }; - Ok(Response::from_parts(parts, body)) -} - -fn prepare_s3(fname: &str) -> anyhow::Result<(Url, String)> { - /* read S3 access params from env */ - let access_key = env::var("ACCESS_KEY")?; - let secret_key = env::var("SECRET_KEY")?; - let region = env::var("REGION")?; - let base_hostname = env::var("BASE_HOSTNAME")?; - let bucket = env::var("BUCKET")?; - let scheme = env::var("SCHEME").unwrap_or_else(|_| "http".to_string()); - - /* set S3 request params */ - let host = region.clone() + "." + base_hostname.as_str(); - let upload_url = scheme + "://" + host.as_str(); - let parsed_url = upload_url.parse()?; - let bucket = Bucket::new(parsed_url, UrlStyle::Path, bucket, region)?; - - let creds = Credentials::new(access_key, secret_key); - let action = bucket.put_object(Some(&creds), fname); - let signed_url = action.sign(Duration::from_secs(60 * 60)); - - Ok((signed_url, host)) -} -``` - - -### FILE: examples/http/basic/s3upload/Cargo.toml - -```toml -[workspace] - -[package] -name = "s3upload" -version = "0.1.0" -edition = "2021" - -[lib] -crate-type = ["cdylib"] - -[dependencies] -fastedge = "0.4" -url = "2.3" -rusty-s3 = "0.5" -anyhow = "1" -``` - - -### FILE: examples/http/basic/s3upload/README.md - -``` -[← Back to examples](../../../README.md) - -# S3 Upload - -FastEdge edge function that accepts a file upload, signs an S3 PUT request on the fly, uploads the file directly to an S3-compatible bucket, and returns the clean object URL to the caller. - -> **Legacy handler:** Uses `#[fastedge::http]` (sync, `wasm32-wasip1`). For new apps prefer the async WASI handler — see [`examples/http/wasi/`](../../wasi/). - -## What it does - -1. Accepts `POST` or `PUT` only — returns 405 for other methods -2. Requires `?name=` query parameter and a non-empty body — returns 400 otherwise -3. Enforces `MAX_FILE_SIZE` if set — returns 413 if exceeded -4. Calls `prepare_s3()` to build a 1-hour presigned `PUT` URL using `rusty_s3` -5. Forwards the file body to S3 via `fastedge::send_request` -6. On success (S3 returns 200): responds with the clean object URL (no query string) -7. On S3 error: forwards the S3 status and error body back to the caller - -## Configuration - -| Env var | Required | Description | -|---|---|---| -| `ACCESS_KEY` | ✅ | S3 access key | -| `SECRET_KEY` | ✅ | S3 secret key | -| `REGION` | ✅ | S3 region (e.g. `s-ed1`) | -| `BASE_HOSTNAME` | ✅ | S3 base hostname (e.g. `cloud.gcore.lu`) | -| `BUCKET` | ✅ | S3 bucket name | -| `SCHEME` | optional | URL scheme — defaults to `http` | -| `MAX_FILE_SIZE` | optional | Maximum upload size in bytes — no limit if unset | - -The constructed endpoint is `://.//`. - -## Build - -```sh -cargo build --release -# Output: target/wasm32-wasip1/release/s3upload.wasm -``` - -## Usage - -``` -POST /upload?name=photo.jpg -Content-Type: image/jpeg - - -``` - -On success (200), the response body is the clean S3 object URL (presign query parameters stripped). - -## Notes - -- The `OPTIONS` method returns 204 but does **not** include CORS headers — add `Access-Control-Allow-*` headers if browser preflight support is needed. -- The presigned URL expires after 1 hour, but since the upload is performed server-side this has no practical impact. -- `MAX_FILE_SIZE` is silently ignored if set to a non-numeric value. -``` diff --git a/reference-docs/http-examples-secret-basic-rust.md b/reference-docs/http-examples-secret-basic-rust.md index d65296b..44ff104 100644 --- a/reference-docs/http-examples-secret-basic-rust.md +++ b/reference-docs/http-examples-secret-basic-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> # Secret Access — Rust HTTP Example @@ -251,3 +251,183 @@ node tools/fixture-validator/index.mjs \ - fastedge-docs skill reference: sdk-reference-rust - fastedge-docs skill reference: error-codes - manage skill: secret management subcommands (set, list, delete) + +## Source Material + +### FILE: examples/http/basic/secret/src/lib.rs + +```rust +use anyhow::{Error, Result}; +use std::time::SystemTime; + +use fastedge::body::Body; +use fastedge::http::{Request, Response, StatusCode}; +use fastedge::secret; + +#[allow(dead_code)] +#[fastedge::http] +fn main(_req: Request) -> Result> { + let value = match secret::get("SECRET") { + Ok(value) => value, + Err(secret::Error::AccessDenied) => { + return Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::empty()) + .map_err(Error::msg); + } + Err(secret::Error::Other(msg)) => { + return Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from(msg)) + .map_err(Error::msg); + } + Err(secret::Error::DecryptError) => { + return Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::empty()) + .map_err(Error::msg); + } + }; + + if value.is_none() { + return Response::builder() + .status(StatusCode::NOT_FOUND) + .body(Body::empty()) + .map_err(Error::msg); + } + + let ts = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .expect("Time went backwards") + .as_secs(); + let effective_at_value = match secret::get_effective_at("SECRET", ts as u32) { + Ok(value) => value, + Err(secret::Error::AccessDenied) => { + return Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::empty()) + .map_err(Error::msg); + } + Err(secret::Error::Other(msg)) => { + return Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from(msg)) + .map_err(Error::msg); + } + Err(secret::Error::DecryptError) => { + return Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::empty()) + .map_err(Error::msg); + } + }; + + if effective_at_value.is_none() { + return Response::builder() + .status(StatusCode::NOT_FOUND) + .body(Body::empty()) + .map_err(Error::msg); + } + + Response::builder() + .status(StatusCode::OK) + .body(Body::from(format!( + "get={:?}\nget_efective_at={:?}\n", + value, effective_at_value + ))) + .map_err(Error::msg) +} +``` + +### FILE: examples/http/basic/secret/Cargo.toml + +```toml +[workspace] + +[package] +name = "secret" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +fastedge = "0.4" +anyhow = "1" +``` + +### FILE: examples/http/basic/secret/README.md + +``` +[← Back to examples](../../../README.md) + +# Secret + +Demonstrates accessing encrypted secrets injected by the FastEdge platform using `secret::get()` and `secret::get_effective_at()`. Shows how to handle all error variants (access denied, decrypt error) and the time-based secret rotation API. + +## What it does + +On every request, the handler: + +1. Calls `secret::get("SECRET")` — retrieves the current value of the secret named `SECRET`. +2. If the secret is missing (returned as `None`), returns **404**. +3. Calls `secret::get_effective_at("SECRET", )` — retrieves the secret value effective at the current Unix timestamp, demonstrating the rotation/versioning API. +4. If that value is also missing, returns **404**. +5. On success, returns **200** with both values in the body (Debug format). + +## APIs used + +| API | Purpose | +|---|---| +| `#[fastedge::http]` | Sync request-response handler macro | +| `fastedge::secret::get(key)` | Retrieve the current value of a named secret | +| `fastedge::secret::get_effective_at(key, timestamp)` | Retrieve the secret value effective at a specific Unix timestamp | +| `fastedge::secret::Error` | Error variants: `AccessDenied`, `Other(msg)`, `DecryptError` | +| `fastedge::http::{Request, Response, StatusCode}` | HTTP types | +| `fastedge::body::Body` | Response body | + +## Secret error variants + +| Variant | HTTP response | Meaning | +|---|---|---| +| `Ok(Some(value))` | 200 with body | Secret found | +| `Ok(None)` | 404 empty | Secret name is valid but not set | +| `Err(AccessDenied)` | 403 empty | App is not permitted to read this secret | +| `Err(Other(msg))` | 403 with `msg` body | Other denial with a human-readable message | +| `Err(DecryptError)` | 500 empty | Secret exists but could not be decrypted | + +## Build + +```sh +cargo build --release +# Output: target/wasm32-wasip1/release/secret.wasm +``` + +## Expected behavior + +| Scenario | Secret `SECRET` | Response status | Response body | +|---|---|---|---| +| Happy path | `"my-value"` | 200 | `get=Some("my-value")\nget_efective_at=Some("my-value")\n` | +| Secret not set | (absent) | 404 | (empty) | +| Access denied | — | 403 | (empty) | + +> **Note:** The response body contains a typo in the field name (`get_efective_at` instead of `get_effective_at`). This is a known cosmetic issue in the source. + +## Local testing + +Inject the secret via a `.env` file in your fixtures directory using the `FASTEDGE_VAR_SECRET_` prefix: + +``` +# fixtures/.env +FASTEDGE_VAR_SECRET_SECRET=my-test-value +``` + +Run with the fixture validator: + +```sh +node tools/fixture-validator/index.mjs \ + FastEdge-sdk-rust/examples/http/basic/secret/ \ + --wasm FastEdge-sdk-rust/examples/http/basic/secret/target/wasm32-wasip1/release/secret.wasm +``` +``` diff --git a/reference-docs/http-examples-secret-rollover-wasi-rust.md b/reference-docs/http-examples-secret-rollover-wasi-rust.md index df75287..70416dc 100644 --- a/reference-docs/http-examples-secret-rollover-wasi-rust.md +++ b/reference-docs/http-examples-secret-rollover-wasi-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> # Secret Rollover (WASI, Rust) @@ -134,7 +134,7 @@ use wstd::http::{Request, Response}; #[wstd::http_server] async fn main(request: Request) -> anyhow::Result> { - // Read slot from header, default to current unix timestamp + // Read the slot from the x-slot header, defaulting to current timestamp let slot: u32 = request .headers() .get("x-slot") @@ -153,11 +153,10 @@ async fn main(request: Request) -> anyhow::Result> { .and_then(|v| v.to_str().ok()) .unwrap_or("TOKEN_SECRET"); - // Get current (latest) value - let current = secret::get(secret_name) - .map_err(|e| anyhow!("secret::get failed: {e}"))?; + // Get the current secret value (latest slot) + let current = secret::get(secret_name).map_err(|e| anyhow!("secret::get failed: {e}"))?; - // Get value effective at the given slot + // Get the secret effective at the requested slot let effective = secret::get_effective_at(secret_name, slot) .map_err(|e| anyhow!("secret::get_effective_at failed: {e}"))?; diff --git a/reference-docs/http-examples-simple-fetch-wasi-rust.md b/reference-docs/http-examples-simple-fetch-wasi-rust.md index 5d19fe4..56c7e10 100644 --- a/reference-docs/http-examples-simple-fetch-wasi-rust.md +++ b/reference-docs/http-examples-simple-fetch-wasi-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- @@ -16,7 +16,7 @@ capabilities: [outbound-fetch, header-read, async] # Example: Simple Fetch (WASI HTTP, Rust) -Demonstrates outbound HTTP requests using the WASI-HTTP interface via the `wstd` crate. Reads a target URL from an incoming request header and proxies the response back to the caller. +Demonstrates outbound HTTP requests using the WASI-HTTP interface via the `wstd` crate. Reads a target URL from an incoming request header and proxies the response back to the caller. Optionally forwards a custom header to the outbound request. ## Crate and Handler @@ -32,13 +32,16 @@ Demonstrates outbound HTTP requests using the WASI-HTTP interface via the `wstd` | Header | Required | Type | Default | Description | |--------|----------|------|---------|-------------| | `x-fetch-url` | No | String (fully-qualified URL) | `https://httpbin.org/get` | URL to fetch outbound | +| `x-fetch-header` | No | String (`key: value`) | — | Additional header to forward to the outbound request; parsed on `:` separator | ## Behavior 1. Read `x-fetch-url` header from the incoming request; fall back to `https://httpbin.org/get` if absent or unparseable. -2. Build an outbound `GET` request to that URL with `accept: application/json` header. -3. Send via `Client::new().send(req).await`. -4. Return the upstream `Response` directly to the caller — no decomposition. +2. Begin building an outbound `GET` request to that URL with `accept: application/json` header. +3. If `x-fetch-header` is present and parseable as `key: value` (split on first `:`), add that header to the outbound request builder. +4. Finalize the builder with `.body(Body::empty())`. +5. Send via `Client::new().send(req).await`. +6. Return the upstream `Response` directly to the caller — no decomposition. ## Key API Patterns @@ -58,14 +61,34 @@ let target_url = request - `.unwrap_or(default)` provides a safe fallback - `.to_string()` required — `Request::get` takes a `&str` or `String`; ensure the URL is owned before use +### Conditionally Adding an Outbound Header + +```rust +let mut builder = Request::get(&target_url).header("accept", "application/json"); + +if let Some(fetch_header) = request + .headers() + .get("x-fetch-header") + .and_then(|v| v.to_str().ok()) +{ + if let Some((key, value)) = fetch_header.split_once(':') { + builder = builder.header(key.trim(), value.trim()); + } +} +``` + +- The builder is `mut` to allow conditional chaining. +- `.split_once(':')` splits on the first `:`, returning `Option<(&str, &str)>`. +- `.trim()` removes surrounding whitespace from key and value before passing to `.header()`. +- If `x-fetch-header` is absent or unparseable, the builder proceeds without the extra header. + ### Building an Outbound Request ```rust use wstd::http::{Client, Request}; use wstd::http::body::Body; -let upstream_req = Request::get(&target_url) - .header("accept", "application/json") +let upstream_req = builder .body(Body::empty()) .map_err(|e| anyhow!("failed to build request: {e}"))?; ``` @@ -138,6 +161,8 @@ package = "component:simple_fetch" - The URL extracted from the header must be converted to an owned `String` with `.to_string()` before passing to `Request::get`. - The header parsing chain (`.get` → `.to_str()` → `.ok()`) returns `Option` — always provide a fallback via `.unwrap_or`. - Non-UTF-8 header values are silently discarded by `.to_str().ok()`. +- `x-fetch-header` is parsed with `.split_once(':')` — only the first `:` is used as the separator; values containing `:` are preserved correctly. +- The request builder must be declared `mut` when conditionally adding headers after initial construction. - `anyhow` must be declared as a dependency to use the `anyhow!()` macro. - All examples in `examples/http/wasi/` use the same `async fn main` + `#[wstd::http_server]` pattern. @@ -147,3 +172,134 @@ package = "component:simple_fetch" - sdk-reference-rust - examples-simple-request-rust (basic sync HTTP handler, `fastedge` crate) - host-services-rust (outbound fetch via host services) + +## Source Material + +### FILE: examples/http/wasi/simple_fetch/src/lib.rs + +```rust +/* +* Copyright 2025 G-Core Innovations SARL +*/ +/* +Example app demonstrating the WASI-HTTP interface via the wstd crate. + +The app receives an incoming HTTP request and makes an outbound HTTP request +to the URL specified in the `x-fetch-url` header (defaults to https://httpbin.org/get). + +Build with cargo-component: + cargo component build --release +*/ + +use anyhow::anyhow; +use wstd::http::body::Body; +use wstd::http::{Client, Request, Response}; + +#[wstd::http_server] +async fn main(request: Request) -> anyhow::Result> { + let target_url = request + .headers() + .get("x-fetch-url") + .and_then(|v| v.to_str().ok()) + .unwrap_or("https://httpbin.org/get") + .to_string(); + + println!("Fetching: {target_url}"); + + let mut builder = Request::get(&target_url).header("accept", "application/json"); + + if let Some(fetch_header) = request + .headers() + .get("x-fetch-header") + .and_then(|v| v.to_str().ok()) + { + if let Some((key, value)) = fetch_header.split_once(':') { + builder = builder.header(key.trim(), value.trim()); + } + } + + let upstream_req = builder + .body(Body::empty()) + .map_err(|e| anyhow!("failed to build request: {e}"))?; + + let client = Client::new(); + let response = client + .send(upstream_req) + .await + .map_err(|e| anyhow!("request failed: {e}"))?; + + println!("Response status: {}", response.status()); + + Ok(response) +} +``` + + +### FILE: examples/http/wasi/simple_fetch/Cargo.toml + +```toml +[workspace] + +[package] +name = "simple_fetch" +version = "0.1.1" +edition = "2021" +publish = false + +[lib] +crate-type = ["cdylib"] + +[dependencies] +wstd = "0.6" +anyhow = "1" + +[package.metadata.component] +package = "component:simple_fetch" +``` + + +### FILE: examples/http/wasi/simple_fetch/README.md + +``` +[← Back to examples](../../../README.md) + +# Simple Fetch + +A minimal example demonstrating outbound HTTP requests using the WASI-HTTP interface via the `wstd` crate. + +Uses the WASI component model with an **async** handler and a proper HTTP client (`wstd::http::Client`). The same async pattern is used by all examples in `examples/http/wasi/`. + +## How it works + +The app receives an incoming request, reads the target URL from the `x-fetch-url` header, makes an outbound GET request to that URL, and streams the response back to the caller. + +If the `x-fetch-url` header is absent, it defaults to `https://httpbin.org/get`. + +## Request headers + +| Header | Required | Description | +|--------|----------|-------------| +| `x-fetch-url` | No | URL to fetch. Defaults to `https://httpbin.org/get` | + +## Example + +```bash +curl -H "x-fetch-url: https://httpbin.org/uuid" https:/// +``` + +## Build + +```bash +cargo build --release +# Output: target/wasm32-wasip2/release/simple_fetch.wasm +``` + +## Key differences from basic HTTP examples + +| | Basic HTTP (`fastedge` crate) | WASI HTTP (`wstd` crate) | +|---|---|---| +| Handler | `fn main(req)` — sync | `async fn main(req)` — async | +| Macro | `#[fastedge::http]` | `#[wstd::http_server]` | +| Outbound HTTP | `fastedge::send_request(req)` | `Client::new().send(req).await` | +| Build target | `wasm32-wasip1` | `wasm32-wasip2` | +``` diff --git a/reference-docs/http-examples-smart-switch-basic-rust.md b/reference-docs/http-examples-smart-switch-basic-rust.md index caea588..fc7af6b 100644 --- a/reference-docs/http-examples-smart-switch-basic-rust.md +++ b/reference-docs/http-examples-smart-switch-basic-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/http-examples-static-assets-wasi-rust.md b/reference-docs/http-examples-static-assets-wasi-rust.md index c3a255f..3174471 100644 --- a/reference-docs/http-examples-static-assets-wasi-rust.md +++ b/reference-docs/http-examples-static-assets-wasi-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/http-examples-streaming-wasi-rust.md b/reference-docs/http-examples-streaming-wasi-rust.md index 8a6e7c9..f972648 100644 --- a/reference-docs/http-examples-streaming-wasi-rust.md +++ b/reference-docs/http-examples-streaming-wasi-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- @@ -143,3 +143,105 @@ chunk 4 - examples-streaming-js reference (JavaScript mirror of this example) - wstd HTTP body reference - FastEdge SDK Rust reference + +## Source Material + +### FILE: examples/http/wasi/streaming/src/lib.rs + +```rust +/* + * Copyright 2025 G-Core Innovations SARL + */ +/* +Streaming response example. + +Generates a response body on the fly — five text chunks, one every 200ms — +using `Body::from_stream` backed by a `futures_lite::Stream`. The runtime +polls the stream as the body is sent, so chunks flow to the client as they +are produced instead of all at once at the end. + +Watch it stream with `curl -N https:///` (`-N` disables client-side +buffering). + +Mirror of the FastEdge-sdk-js `streaming` example. +*/ + +use futures_lite::stream; +use wstd::http::body::Body; +use wstd::http::{Request, Response}; +use wstd::time::{Duration, Timer}; + +#[wstd::http_server] +async fn main(_request: Request) -> anyhow::Result> { + let chunk_stream = stream::unfold(0u32, |i| async move { + if i >= 5 { + return None; + } + Timer::after(Duration::from_millis(200)).wait().await; + Some((format!("chunk {i}\n"), i + 1)) + }); + + Ok(Response::builder() + .status(200) + .header("content-type", "text/plain; charset=utf-8") + .body(Body::from_stream(chunk_stream))?) +} +``` + + +### FILE: examples/http/wasi/streaming/Cargo.toml + +```toml +[workspace] + +[package] +name = "streaming_wasi" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +wstd = "0.6" +anyhow = "1" +futures-lite = "1" +``` + + +### FILE: examples/http/wasi/streaming/README.md + +``` +[← Back to examples](../../../README.md) + +# Streaming Response (WASI) + +Generates a response body on the fly — five text chunks, one every 200 ms — using +`Body::from_stream` backed by a `futures_lite::Stream`. Each chunk flows to the client as it +is produced, not all at once at the end. + +Demonstrates `wstd::http::body::Body::from_stream`, `futures_lite::stream::unfold` for async +stream generation, and `wstd::time::Timer` for per-chunk delays. + +## Testing the streaming behaviour + +```sh +curl -N https://.fastedge.cdn.gc.onl/ +``` + +`-N` disables curl's client-side buffering; without it you won't see chunks appear one at a +time. You should see `chunk 0`…`chunk 4` print at ~200ms intervals. + +## Other streaming patterns + +- **Pass-through streaming** — return an upstream response's body directly. See + [outbound_fetch/](../outbound_fetch/) for the no-buffer variant. +- **Transform streaming** — use `http_body_util::BodyExt::map_frame` on the incoming body, + then `Body::from_http_body` to wrap it back. Useful for chunk-level rewrites. +- **Stream from bytes** — `Body::from_stream(futures_lite::stream::iter(chunks))` where + `chunks` is any iterable of `Into`. + +## Related + +Mirror of `FastEdge-sdk-js/examples/streaming/`. +``` diff --git a/reference-docs/http-examples-variables-and-secrets-wasi-rust.md b/reference-docs/http-examples-variables-and-secrets-wasi-rust.md index 7fa38af..82558b5 100644 --- a/reference-docs/http-examples-variables-and-secrets-wasi-rust.md +++ b/reference-docs/http-examples-variables-and-secrets-wasi-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> --- diff --git a/reference-docs/http-examples-watermark-basic-rust.md b/reference-docs/http-examples-watermark-basic-rust.md index c4910c8..33ae651 100644 --- a/reference-docs/http-examples-watermark-basic-rust.md +++ b/reference-docs/http-examples-watermark-basic-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> # HTTP Example: Watermark (Basic, Rust) diff --git a/reference-docs/js-runtime.md b/reference-docs/js-runtime.md index d97f55f..c37305a 100644 --- a/reference-docs/js-runtime.md +++ b/reference-docs/js-runtime.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-js ref: main - commit: 81145a9a43ec499240c687bd49376ab20c72b11c - updated: 2026-08-20 + commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 + updated: 2026-09-22 --> # FastEdge JS Runtime — Constraints & Compatibility diff --git a/reference-docs/platform-cdn-filter-runtime.md b/reference-docs/platform-cdn-filter-runtime.md new file mode 100644 index 0000000..91b5ad4 --- /dev/null +++ b/reference-docs/platform-cdn-filter-runtime.md @@ -0,0 +1,122 @@ +# CDN Filter Runtime — Capabilities and Traps + +What a proxy-wasm filter (CDN app) can and cannot do on FastEdge, and the host behaviours that silently differ from generic proxy-wasm or from HTTP apps. **Read this before designing or reviewing a CDN app** — most items here are invisible in local tests and only surface on a deployed app. + +Every claim carries its provenance: + +| Tag | Meaning | +|---|---| +| `[live]` | Measured against a deployed app on a real CDN resource | +| `[source]` | Read from the FastEdge runtime or SDK source | + +Last verified: 2026-08-25 (SDK surface re-checked 2026-09-23). + +--- + +## Capability boundary — filter vs HTTP app + +A filter is a core wasm module linked against the proxy-wasm `env` ABI. It is a different execution world from an HTTP app, not a subset of it. Designs that assume symmetry with the HTTP-app SDK fail at deploy. + +| Capability | HTTP app | CDN filter | +|---|---|---| +| KV read | ✅ | ✅ same six operations: `open · get · scan · zrange_by_score · zscan · bf_exists` `[source]` | +| KV write | ❌ (API only — see [storage.md](./storage.md)) | ❌ (API only) | +| Cache (`get/set/delete/exists/incr/expire/purge/purgePrefix`) | ✅ | ✅ host-supported; **SDK support varies — check the SDK reference for your language** | +| Secrets / dictionary | ✅ | ✅ via the SDK's proxy-wasm module | +| Outbound `fetch` | ✅ | proxy-wasm `http_call` only | +| Deferred / background work | JS `waitUntil` only (not a timer) | ❌ none | +| State between requests | ❌ | ❌ — consecutive requests hit different nodes `[live]` | + +### Use only the SDK's proxy-wasm modules + +HTTP-app host APIs are component-model (WIT) imports. A proxy-wasm host cannot resolve them, so **one reference anywhere in a filter makes the app fail to instantiate — HTTP 530 on every path**, including paths that never reach the call `[live]`. It compiles and links with no warning. + +- **Rust:** in a filter import only from `fastedge::proxywasm::*`. Never use a top-level `fastedge::` module (`fastedge::cache`, `fastedge::secret`, …) — each has a `fastedge::proxywasm::` counterpart. +- **Check before deploying** — any `gcore:fastedge/...` import in a filter build means a 530 at runtime: + ```bash + wasm-tools print app.wasm | grep -o '(import "[^"]*"' | sort -u + ``` + +--- + +## Reading the request — use properties, not headers + +Several headers a proxy-wasm developer would reach for are mangled or absent. **All failures are silent** `[live]`. + +| Read via | Result | +|---|---| +| property `request.host` | ✅ clean client-requested host (before any origin host rewrite) on the edge tier; on shield nodes it may carry a `shield_` prefix | +| property `request.x_real_ip` | ✅ true client IP, IPv4 and IPv6 | +| property `request.path` | ⚠️ **includes the query string** — see below | +| property `request.query` | ✅ query without `?`; not set by the host when there is no query (how "not set" surfaces — `None`, empty buffer — depends on the SDK) | +| property `request.asn` / `.country` / `.city` / `.region` / `.continent` | ✅ | +| property `source.address` | ❌ does not exist (Envoy's name) — returns nothing | +| header `host` | ❌ mangled to `_cache_sharded` | +| headers `:path`, `:authority` | ❌ absent | +| headers `x-real-ip`, `x-forwarded-for`, `cookie`, `user-agent` | ✅ intact (`cookie` is visible even with `ignore_cookie: true`) | + +### `request.path` includes the query string + +``` +GET /x?a=1&b=2 +request.path = "/x?a=1&b=2" +request.query = "a=1&b=2" +``` + +Prefix checks are unaffected; **equality checks silently fail on any request with a query** — auth callbacks are exactly where equality checks live. Split on `?` first. Corollary: because it is path+query, `request.path` works directly as a relative `Location` for a same-origin redirect, which avoids the mangled `host` header. + +--- + +## Security — gating filters + +### The CDN does not normalise the path before the filter runs + +`[live]` Traversal and separator sequences arrive verbatim: + +```bash +curl --path-as-is ".../app/x/../test" # request.path = "/app/x/../test" +curl --path-as-is ".../app//test" # request.path = "/app//test" +``` + +A filter that bypasses auth on a prefix (`/auth/`, `/public/`) will wave through `/auth/../admin`, which the origin may normalise back to `/admin`. **That is an authentication bypass**, and it is the natural way to write the code. + +Reject suspicious sequences before any prefix bypass, and **fail closed** — fall through to the auth check. Never normalise the path yourself and proceed; you will not match the origin's rules. + +```rust +fn has_suspicious_sequence(path: &str) -> bool { + if path.contains("..") || path.contains("//") || path.contains('\\') { return true; } + let lower = path.to_ascii_lowercase(); + lower.contains("%2e") || lower.contains("%2f") + || lower.contains("%5c") || lower.contains("%25") // %25 catches double-encoding +} +``` + +### Filters run before the CDN cache lookup + +`[live, edge tier only]` A request-phase filter runs on **every** request, including cache hits. + +- **Security:** a cached response cannot bypass a request-phase gate. +- **Cost:** every request pays for whatever the filter does — KV reads, cache ops — even on cache hits. +- A `no-store` response from a filter is not cached. Varying the cache key on a session cookie fragments the cache per visitor. + +Only `execute_on_edge` was measured; ordering on the shield tier is unverified. + +--- + +## Synthetic responses + +`[live]` A filter can serve a complete response via `send_http_response`: any status, arbitrary headers, multiple `Set-Cookie` headers on one response, and bodies up to at least 1 MB without truncation. Single-app designs (challenge pages, interstitials, error pages) do not need a second HTTP app. + +--- + +## What local testing cannot prove + +`@gcoredev/fastedge-test` runs proxy-wasm filters locally and proves **flow logic** — routing, header manipulation, gate decisions. It cannot prove **host behaviour**: property semantics, header mangling, path non-normalisation, instantiation failures, cache interaction. Every trap on this page passes a local suite green. Confirm host-dependent behaviour on a deployed app attached to a real CDN resource. + +--- + +## See Also + +- [storage.md](./storage.md) — KV and Cache semantics, limits, measured performance +- [cdn-integration.md](./cdn-integration.md) — attaching filters to CDN resources +- [error-codes.md](./error-codes.md) — 530 diagnosis diff --git a/reference-docs/platform-cdn-integration.md b/reference-docs/platform-cdn-integration.md index 2024764..49aa783 100644 --- a/reference-docs/platform-cdn-integration.md +++ b/reference-docs/platform-cdn-integration.md @@ -181,8 +181,25 @@ curl -s -X PATCH "https://api.gcore.com/cdn/resources/" \ }' ``` +**`PATCH /cdn/resources/{id}` merges `options`** — keys you omit (e.g. `hostHeader`) are kept `[live]`. Do not confuse this with the rule-vs-resource replace semantics above, which govern request-time override, not the API. + Rules are managed through their own endpoints under `/cdn/resources/{resource_id}/rules`. The full rule API is in the Gcore CDN documentation. +### Cached content after a routing change + +Request-phase filters run before the cache lookup (see [cdn-filter-runtime.md](./cdn-filter-runtime.md)), so attaching or changing an `on_request_headers` filter takes effect on cached paths without a purge. What does **not** change on its own is content already cached from the previous configuration — e.g. after a rule that points a path at a different origin, or a change to response-phase output. That content keeps being served until it expires (observed ~15 min). + +In that case, purge only the affected paths, then verify: + +```bash +curl -s -X POST "https://api.gcore.com/cdn/resources//purge" \ + -H "Authorization: APIKey $GCORE_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{"paths": ["/affected/path/*"]}' +``` + +`{"paths": []}` purges **the entire resource** and sends all traffic back to origin — use it only with explicit user confirmation. The FastEdge MCP server's default access policy blocks this endpoint; when it is blocked, give the user the command to run themselves. + ## Operational Notes - **`app_id` is a string.** The FastEdge apps API (`GET /fastedge/v1/apps`) returns `id` as an integer, but in the `options.fastedge..app_id` field it must be quoted as a string. Mixing types is a common source of validation errors. @@ -191,7 +208,7 @@ Rules are managed through their own endpoints under `/cdn/resources/{resource_id - **Hook absence vs. `enabled: false`.** Both result in the hook not running. Removing the key entirely is cleaner; toggling `enabled: false` preserves the hook's other config for easy re-enable. - **`execute_on_shield` only matters when origin shielding is on.** If `shielded: false` on the resource, the shield-layer setting has no effect — the hook only ever runs at the edge. - **Rule weight ordering.** When multiple rules match a request path, only the rule with the lowest weight applies. Rules don't compose. -- **Changes propagate.** CDN configuration changes can take a few minutes to propagate to all PoPs. The resource may briefly be in `status: "processed"` after an update. +- **Changes propagate.** CDN configuration changes can take a few minutes to propagate to all PoPs. The resource may briefly be in `status: "processed"` after an update. Content cached under the old configuration may also need a path-scoped purge (above). ## See Also diff --git a/reference-docs/platform-error-codes.md b/reference-docs/platform-error-codes.md index 23b24f5..fb81210 100644 --- a/reference-docs/platform-error-codes.md +++ b/reference-docs/platform-error-codes.md @@ -10,7 +10,10 @@ FastEdge returns specific HTTP status codes (530-533) when the Wasm runtime enco **Meaning:** The Wasm module failed to start up before processing the request. +**Signal:** a CDN app that fails to instantiate also returns `x-cdn-internal-status: 3100`. That header distinguishes "failed to start" from "the app ran and errored" (531). + **Common Causes:** +- **Unresolved imports (CDN apps)** — the binary imports a host function the proxy-wasm host does not provide, most commonly an HTTP-app (component-model) API used in a filter, e.g. top-level `fastedge::cache` in Rust instead of `fastedge::proxywasm::cache`. **Every path returns 530**, including paths that never reach the call, and the build gives no warning. See [cdn-filter-runtime.md](./cdn-filter-runtime.md). - Missing required environment variables that the app reads during initialization - Corrupted or invalid Wasm binary - Binary was compiled for the wrong target (not `wasm32-wasip1`) @@ -21,9 +24,15 @@ FastEdge returns specific HTTP status codes (530-533) when the Wasm runtime enco - JS: `fastedge-build ./src/index.js ./.wasm` completed without errors - Rust: `cargo build --release --target wasm32-wasip1` succeeded 2. Check binary size: `ls -la *.wasm` or `ls -la target/wasm32-wasip1/release/*.wasm` -3. Test locally: `fastedge-run http -w ./app.wasm --port 8080` -4. Verify all required env vars are set via API or portal -5. Re-upload the binary and update the app +3. **CDN apps:** inspect the import table — any `gcore:fastedge/...` import in a proxy-wasm build is unresolvable: + ```bash + wasm-tools print app.wasm | grep -o '(import "[^"]*"' | sort -u + ``` +4. Run locally: + - HTTP apps: `fastedge-run http -w ./app.wasm --port 8080` + - CDN apps: `fastedge-run` does not run proxy-wasm — use `@gcoredev/fastedge-test`. Note a local run does not reproduce host instantiation, so a clean local run does not rule out step 3. +5. Verify all required env vars are set via API or portal +6. Re-upload the binary and update the app --- @@ -32,6 +41,7 @@ FastEdge returns specific HTTP status codes (530-533) when the Wasm runtime enco **Meaning:** The app started successfully but threw an unhandled exception during request processing. **Common Causes:** +- Calling `getEnv()` / `getSecret()` at module top level (JS) — they are request-time only; call them inside the handler - Uncaught JavaScript exception (TypeError, ReferenceError, etc.) - Rust panic (`unwrap()` on `None` or `Err`) - Failed `fetch()` call without error handling diff --git a/reference-docs/platform-overview.md b/reference-docs/platform-overview.md index 415dc14..78300ee 100644 --- a/reference-docs/platform-overview.md +++ b/reference-docs/platform-overview.md @@ -99,6 +99,14 @@ What is appropriate: per-end-user or per-session key prefixes within your app's 5. **Response Delivery** — Response sent back to client 6. **Cleanup** — Wasm instance destroyed, memory freed +### No scheduled or deferred work + +There is no scheduler or durable background execution. Timers exist within a request (e.g. JS `setTimeout`) but live only as long as that instance. JS `event.waitUntil()` extends the instance until a promise settles, starting immediately after the response — `waitUntil(sleep(30_000).then(work))` just pins one instance per request for 30 s. Rust has no post-response work API. Rewrite "do X in L seconds" as "on each request, do X if L has elapsed"; periodic jobs need an external cron. + +### PoP identity + +`getEnv("dc")` returns the PoP's lowercase short code (e.g. `ls1`, `am3`) — the only PoP identifier available to an app. **It can be empty**; an empty-string fallback silently merges every PoP's keys into one namespace. Fail loudly instead. Node count per PoP varies, and the number of active PoPs is not discoverable from inside an app. + ## Resource Limits | Resource | Basic Plan | Pro Plan | diff --git a/reference-docs/platform-storage.md b/reference-docs/platform-storage.md new file mode 100644 index 0000000..e55ac0c --- /dev/null +++ b/reference-docs/platform-storage.md @@ -0,0 +1,107 @@ +# Storage Semantics — KV Store and Cache + +Behaviour of FastEdge's two storage primitives that the SDK references do not state: consistency, write shapes, TTL rules, missing operations, and measured performance. Applies to HTTP apps and CDN filters unless noted. For the per-language API, see the SDK reference for your language. + +| | KV Store | Cache | +|---|---|---| +| Scope | Global, account-level, assigned to apps | Per-PoP, shared by every node in the PoP `[source + told]` | +| Consistency | Eventually consistent; **reads cached per node** (below) | Strong within a PoP | +| Writes from app code | ❌ API only | ✅ | +| Atomic primitive | — | `incr` only | + +Provenance tags: `[live]` measured on a deployed app · `[source]` read from the runtime source · `[told]` stated by the FastEdge team · `[unverified]` not yet confirmed. Last verified: 2026-08-27. + +--- + +## KV Store + +### `get()` is a cached read — ~30 s per node + +`[live, production]` Each `get(key)` populates a per-node cache entry that lives ~30 s, **whether or not the key existed**. Until it expires, that node keeps returning the old result — the old value, or "absent" for a key that now exists. Sorted-set reads (`zrangeByScore`) are **not** cached and reflect writes in 0–1 s. + +| Reads before the write | Write | Visible after | +|---|---|---| +| none | create `kv` key | 1 s | +| heavy `get()` polling of the absent key | create `kv` key | **31 s** | +| heavy `get()` polling of the existing key | update its value | **30 s, then flapped** | +| heavy `zrangeByScore` polling | add `sorted_set` member | 0 s | + +- **Values flap.** Warm and expired nodes answer differently at the same instant, so a polled `kv` flag can turn on, off, and on again during the window. For access gating this is worse than a delay. +- **Polling makes it worse** — every poll refreshes the staleness hiding the change. +- **Absence is not a safe signal.** "Key missing ⇒ not started" fails in the direction of "my change hasn't happened". + +**Rule:** use `kv` + `get()` for values written once and read as configuration. For anything polled that must see changes promptly (a "has this happened yet?" flag), use a **sorted set with one member whose score is the timestamp** — uncached and consistent across nodes. + +### Writes go through the API only + +`[live]` `PUT /fastedge/v1/kv/{store_id}/data` — never from inside an app. Many entries can be batched in one call. + +```jsonc +[{ "op": "add", // add | del_key | del_entries — REQUIRED + "key": "…", + "datatype": "kv", // kv | sorted_set | bloom_filter + "payload": { "value": "…", "encoding": "plain" } }] // encoding: plain | base64 | sha256 +``` + +- **`sorted_set` nests differently:** its `payload` *is* the member array. The 400 only says `doesn't match any schema from "anyOf"`. To learn a payload shape, write one entry by hand and read it back with `GET /fastedge/v1/kv/{store}/data/{key}` — the read shape mirrors the write shape. +- **`datatype` scopes `del_key`.** Deleting a `kv` key with `datatype: "sorted_set"` returns **200 with `del_count: 0`** and removes nothing; a later `zrangeByScore` on that name then throws a type error. **Check `del_count`** on cleanup writes, especially when migrating a key between datatypes. +- The response includes `revision`, a store-wide monotonic counter — a freshness signal independent of clocks. +- Attaching a store to an app: `stores: {"": {"id": }}`; omit the inner `name` (read-only). + +### Missing operations + +`[source]` The read surface is exactly `open · get · scan · zrange_by_score · zscan · bf_exists`. There is **no** rank-based `ZRANGE`, `ZCOUNT`, `ZCARD` or `ZSCORE`. Do not emulate them in app code: `zrange_by_score(-inf, +inf)` transfers every member with its score into the wasm instance on every call. + +`zrange_by_score` on a missing key returns an empty list, not an error. + +--- + +## Cache + +### Interface and atomicity + +`[source]` `get · set · delete · exists · incr · expire · purge · purge_prefix`. **`incr` is the only atomic primitive** — no compare-and-set, `SETNX`, scripting, multi-key operations, or `SCAN`. Coordination must be expressible as "increment and compare the returned value". + +### TTL rules + +`[source + live]` + +- **TTLs are silently clamped** to a deployment ceiling (default 4 days). The JS and Rust SDK references describe `set` without a TTL as "no expiry"; the host actually applies the default ceiling (runtime source, and a no-TTL `set` key measured gone within 22 days). **Treat the host behaviour as authoritative** — do not rely on any entry outliving ~4 days. There is no TTL-read primitive, so the clamp is invisible. +- **`incr` sets no TTL and does not index the key.** `incr`-created keys escape both the default-TTL cleanup and `purge_prefix` — measured still present after 22 days. Every `incr` key needs an `expire`, but *when* depends on the key shape — `expire` sets a deadline relative to now, so calling it again pushes the deadline out: + - **Fixed key** (e.g. `rl:`): call `expire` only when `incr` returns `1`, and retry that `expire` within the request budget. Expiring on every call resets the window and keeps the key alive under continuous traffic. If the one `expire` fails for good, the key never expires — there is no TTL-read to detect it. + - **Time-bucketed key** (window id in the name, e.g. `rl::`): calling `expire` on every call is safe and self-healing — writes stop when the window passes, so the key expires one TTL after its last write even if earlier `expire` calls failed. Prefer this shape when a permanently leaked key is costly. +- `expire` returns `false` for an absent key and `Err` for a failure. Do not collapse the two. + +### Failures are real — retry + +`[live, production]` Cache operations fail outright with explicit errors (not timeouts) at ~0.44% overall, bursty and PoP-specific (one PoP showed 1.5%). Plan for retries rather than assuming success, but bound them by the remaining execution budget — a single op can take ~100 ms at the tail, beyond the Basic plan's 50 ms limit. Decide deliberately whether an exhausted retry fails open or closed. + +> **CDN filters:** the figures and TTL behaviour on this page were measured through HTTP apps. Proxy-wasm cache support is newer and is `[unverified]` to share the same backend behaviour. + +--- + +## Measured performance + +`[live, production]` Point-in-time, one account, mostly one PoP — evidence, not guarantees. + +| Metric | Value | +|---|---| +| `Cache.incr` | p50 1 ms · p95 27 ms · max 102 ms | +| `Cache.expire` | p50 2 ms · p95 6 ms · max 21 ms | +| KV write → visible (no prior `get()` polling) | 61 / 80 / 107 ms (min / p50 / max) | +| KV write rate, one client | sustained ~94 writes/s | +| KV sorted-set ingest | ~2,450 members/s; knee at 32–64 concurrent writers | +| Largest single batched `PUT` | ~1,560 entries — bounded by a 30 s gateway timeout, not payload size | +| Sorted-set storage | ~31 bytes/member | +| Intra-PoP clock skew | ≤5 ms, probably ≤1 ms | + +### Preprod is not production + +Preprod KV propagation was bimodal — typically ~210 ms, but ~1 in 8–15 writes invisible for over 45 s. Production did not do this. Do not benchmark or size designs on preprod. Before attributing a ~30 s delay to either, check the cached-read behaviour above: if something was polling the key with `get()`, or the value flaps once it appears, it is the per-node read cache. + +--- + +## See Also + +- [cdn-filter-runtime.md](./cdn-filter-runtime.md) — what a CDN filter can access +- [overview.md](./overview.md) — account-level KV stores, resource limits diff --git a/reference-docs/quickstart-as.md b/reference-docs/quickstart-as.md index 9078785..fcee56a 100644 --- a/reference-docs/quickstart-as.md +++ b/reference-docs/quickstart-as.md @@ -3,8 +3,8 @@ sources: - id: proxy-wasm-sdk-as ref: master - commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 - updated: 2026-08-20 + commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 + updated: 2026-09-22 --> # Quickstart: AssemblyScript CDN Apps on FastEdge diff --git a/reference-docs/quickstart-js.md b/reference-docs/quickstart-js.md index 8daded8..8bd2b3e 100644 --- a/reference-docs/quickstart-js.md +++ b/reference-docs/quickstart-js.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-js ref: main - commit: 81145a9a43ec499240c687bd49376ab20c72b11c - updated: 2026-08-20 + commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 + updated: 2026-09-22 --> # FastEdge JavaScript Quickstart diff --git a/reference-docs/quickstart-rust.md b/reference-docs/quickstart-rust.md index 6d38e26..a54981d 100644 --- a/reference-docs/quickstart-rust.md +++ b/reference-docs/quickstart-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> # FastEdge Rust SDK — Quickstart diff --git a/reference-docs/sdk-reference-as.md b/reference-docs/sdk-reference-as.md index cad60ae..3a8d32e 100644 --- a/reference-docs/sdk-reference-as.md +++ b/reference-docs/sdk-reference-as.md @@ -3,8 +3,8 @@ sources: - id: proxy-wasm-sdk-as ref: master - commit: 8e3bb621bc013a0aed7e52122066b417ad62a207 - updated: 2026-08-20 + commit: ddb8d2e76e8f4fab30de6bce8dd0150231cd7d31 + updated: 2026-09-22 --> # AssemblyScript Proxy-Wasm SDK Reference diff --git a/reference-docs/sdk-reference-js.md b/reference-docs/sdk-reference-js.md index 05fe7e0..e52332f 100644 --- a/reference-docs/sdk-reference-js.md +++ b/reference-docs/sdk-reference-js.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-js ref: main - commit: 81145a9a43ec499240c687bd49376ab20c72b11c - updated: 2026-08-20 + commit: 9c8c7886f0d1ec5ac2296b4080805966a96ca817 + updated: 2026-09-22 --> # JavaScript SDK Reference (`@gcoredev/fastedge-sdk-js`) diff --git a/reference-docs/sdk-reference-rust.md b/reference-docs/sdk-reference-rust.md index 9c8406d..c6cf49c 100644 --- a/reference-docs/sdk-reference-rust.md +++ b/reference-docs/sdk-reference-rust.md @@ -3,8 +3,8 @@ sources: - id: fastedge-sdk-rust ref: main - commit: 6347a7c2fda0d03e66f1214db5eec041c16801b7 - updated: 2026-08-20 + commit: 6eedcca9d5c0ddd4ff79ca475965393891da2d75 + updated: 2026-09-22 --> # Rust SDK Reference (`fastedge` crate + `fastedge-derive`)