Skip to content

Commit 1ef1f20

Browse files
committed
Call namespaced Pingora hosts from RustScript
1 parent f8c86c3 commit 1ef1f20

8 files changed

Lines changed: 323 additions & 118 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ edition = "2024"
55
license = "Apache-2.0"
66

77
[dependencies]
8+
pd-host-function = { path = "../rustscript/pd-vm/pd-host-function" }
89
pingora = "0.8.1"
910
vm = { package = "pd-vm", path = "../rustscript/pd-vm", default-features = false, features = ["runtime"] }
1011

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ Standalone Pingora integration demo for `pd-vm` / RustScript.
44

55
## What it proves
66

7-
A Pingora gateway can keep the framework and proxy code compiled while moving request policy into RustScript:
7+
A Pingora gateway can keep the framework and proxy code compiled while moving request/response policy into RustScript:
88

9-
- input from `pingora::http::RequestHeader`: method, path, `x-user-tier`
10-
- scripted output: `allow`, `route:<upstream>`, or `deny:<status>:<reason>`
11-
- optional conversion of deny decisions back into `pingora::http::ResponseHeader`
9+
- live `pingora::http::RequestHeader` reads: `pingora::request::method`, `pingora::request::path`, `pingora::request::header`
10+
- live Pingora mutations: `pingora::request::insert_header`, `pingora::response::set_status`, `pingora::response::insert_header`
11+
- host functions are exported with `#[pd_host_function(name = "pingora::...")]`; the `.rss` names and namespaces match the bound host names exactly
1212

13-
This does not fork or patch Pingora. It depends on the upstream `pingora` crate and local `pd-vm` path only.
13+
This does not fork or patch Pingora. It depends on the upstream `pingora` crate plus local `pd-vm` / `pd-host-function` paths only.
1414

1515
## Run
1616

examples/decision.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,22 @@ fn main() {
99
.insert_header("x-user-tier", "free")
1010
.expect("tier header should insert");
1111

12-
let decision = policy
13-
.evaluate_request(&request)
12+
let response = policy
13+
.evaluate_request(&mut request)
1414
.expect("policy should evaluate");
15-
println!("{decision:?}");
15+
let reason = response
16+
.headers
17+
.get("x-rustscript-deny-reason")
18+
.and_then(|value| value.to_str().ok())
19+
.unwrap_or("");
20+
println!(
21+
"status={}, reason={}, request_checked={}",
22+
response.status.as_u16(),
23+
reason,
24+
request
25+
.headers
26+
.get("x-rustscript-checked")
27+
.and_then(|value| value.to_str().ok())
28+
.unwrap_or("")
29+
);
1630
}

scripts/gateway_policy.rss

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
1-
fn gateway_decision(decision) -> string;
2-
3-
let blocked_admin = path == "/admin" && tier != "pro";
4-
let canary = path == "/canary" && method == "GET";
5-
let decision = if blocked_admin => {
6-
"deny:403:upgrade required"
7-
} else if canary => {
8-
"route:canary-upstream"
9-
} else => {
10-
"allow"
11-
};
12-
gateway_decision(decision);
1+
use pingora;
2+
3+
let method: string = pingora::request::method();
4+
let path: string = pingora::request::path();
5+
let tier: string = pingora::request::header("x-user-tier");
6+
7+
let request_marked: bool = pingora::request::insert_header("x-rustscript-checked", "true");
8+
let policy_marked: bool = pingora::response::insert_header("x-rustscript-policy", "gateway_policy");
9+
10+
if path == "/admin" && tier != "pro" {
11+
pingora::response::set_status(403);
12+
pingora::response::insert_header("x-rustscript-deny-reason", "upgrade required");
13+
} else if path == "/canary" && method == "GET" {
14+
pingora::response::set_status(200);
15+
pingora::response::insert_header("x-rustscript-upstream", "canary-upstream");
16+
} else {
17+
pingora::response::set_status(204);
18+
}
19+
20+
pingora::response::status();

0 commit comments

Comments
 (0)