Share owned host API state between HTTP hooks and native pages
This commit is contained in:
@@ -6,7 +6,7 @@ use std::sync::Arc;
|
||||
use wasmtime_wasi_http::{Error, RequestOptions};
|
||||
use wasmtime_wasi_http::{WasiBody, WasiHttpHooks};
|
||||
type Io = Box<dyn Future<Output = Result<(), Error>> + Send>;
|
||||
pub type Router = fn(&Caller, Request<Bytes>) -> Response<Bytes>;
|
||||
pub type Router = Arc<crate::api::Api>;
|
||||
pub(super) struct Hooks {
|
||||
pub caller: Caller,
|
||||
pub cred: Arc<Cred>,
|
||||
@@ -14,21 +14,6 @@ pub(super) struct Hooks {
|
||||
pub policy: Arc<super::net::NetPolicy>,
|
||||
pub router: Router,
|
||||
}
|
||||
pub fn whoami(caller: &Caller, request: Request<Bytes>) -> Response<Bytes> {
|
||||
let (status, body) = if request.uri().path() == "/whoami" {
|
||||
(200, serde_json::to_vec(caller).unwrap())
|
||||
} else {
|
||||
(
|
||||
404,
|
||||
serde_json::to_vec(&serde_json::json!({"error":"unknown host API route"})).unwrap(),
|
||||
)
|
||||
};
|
||||
Response::builder()
|
||||
.status(status)
|
||||
.header("content-type", "application/json")
|
||||
.body(Bytes::from(body))
|
||||
.unwrap()
|
||||
}
|
||||
fn response(response: Response<Bytes>) -> (Response<WasiBody>, Io) {
|
||||
(
|
||||
response.map(|b| Full::new(b).map_err(|n| match n {}).boxed_unsync()),
|
||||
@@ -51,7 +36,7 @@ impl WasiHttpHooks for Hooks {
|
||||
let cred = self.cred.clone();
|
||||
let script = self.script.clone();
|
||||
let policy = self.policy.clone();
|
||||
let router = self.router;
|
||||
let router = self.router.clone();
|
||||
Box::new(async move {
|
||||
let (parts, mut body) = request.into_parts();
|
||||
if parts
|
||||
@@ -60,7 +45,9 @@ impl WasiHttpHooks for Hooks {
|
||||
.is_some_and(|h| h.eq_ignore_ascii_case("host.sausage"))
|
||||
{
|
||||
let bytes = body.collect().await?.to_bytes();
|
||||
return Ok(response(router(&caller, Request::from_parts(parts, bytes))));
|
||||
return Ok(response(
|
||||
crate::api::handle(&router, caller, Request::from_parts(parts, bytes)).await,
|
||||
));
|
||||
}
|
||||
if !matches!(parts.uri.scheme_str(), Some("http" | "https")) {
|
||||
while let Some(frame) = body.frame().await {
|
||||
|
||||
+17
-10
@@ -164,7 +164,7 @@ impl Runtime {
|
||||
}
|
||||
fn with_compiler(world: World, compiler: Arc<cache::Compiler>) -> anyhow::Result<Arc<Self>> {
|
||||
let cred = Arc::new(crate::cred::Cred::open(&world.host_dir)?);
|
||||
Self::with_hooks(world, compiler, cred, default_script(), http::whoami)
|
||||
Self::with_hooks(world, compiler, cred, default_script(), None)
|
||||
}
|
||||
/// Share credentials and the host API router with the host's other subsystems.
|
||||
pub fn new_with_hooks(
|
||||
@@ -173,21 +173,24 @@ impl Runtime {
|
||||
script: Arc<dyn crate::cred::script::Script>,
|
||||
router: Option<Router>,
|
||||
) -> anyhow::Result<Arc<Self>> {
|
||||
Self::with_hooks(
|
||||
world,
|
||||
cache::shared()?,
|
||||
cred,
|
||||
script,
|
||||
router.unwrap_or(http::whoami),
|
||||
)
|
||||
Self::with_hooks(world, cache::shared()?, cred, script, router)
|
||||
}
|
||||
fn with_hooks(
|
||||
world: World,
|
||||
compiler: Arc<cache::Compiler>,
|
||||
cred: Arc<crate::cred::Cred>,
|
||||
script: Arc<dyn crate::cred::script::Script>,
|
||||
router: http::Router,
|
||||
router: Option<http::Router>,
|
||||
) -> anyhow::Result<Arc<Self>> {
|
||||
let router = match router {
|
||||
Some(api) => api,
|
||||
None => Arc::new(crate::api::Api::open(
|
||||
cred.clone(),
|
||||
&world.host_dir,
|
||||
"localhost",
|
||||
"http://localhost:8081",
|
||||
)?),
|
||||
};
|
||||
let network = Arc::new(net::NetPolicy::open(&world.host_dir)?);
|
||||
let engine = compiler.engine.clone();
|
||||
let alive = Arc::new(AtomicBool::new(true));
|
||||
@@ -215,6 +218,10 @@ impl Runtime {
|
||||
cache::precompile(runtime.compiler.clone(), runtime.world.root.clone());
|
||||
Ok(runtime)
|
||||
}
|
||||
/// Register native listener ports through the shared network policy.
|
||||
pub fn network_policy(&self) -> &net::NetPolicy {
|
||||
&self.network
|
||||
}
|
||||
/// Number of distinct program contents compiled by this runtime.
|
||||
pub fn compiled_programs(&self) -> usize {
|
||||
self.cache.lock().unwrap().len()
|
||||
@@ -428,7 +435,7 @@ impl Runtime {
|
||||
cred: self.cred.clone(),
|
||||
script: self.script.clone(),
|
||||
policy: self.network.clone(),
|
||||
router: self.router,
|
||||
router: self.router.clone(),
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user