Skip to content

Commit

Permalink
Ensure that scheme and authority are populated in the incoming handler (
Browse files Browse the repository at this point in the history
  • Loading branch information
elliottt authored Nov 15, 2023
1 parent e74b5c9 commit bba4ee7
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 14 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ async-trait = { workspace = true }
bytes = { workspace = true }
tokio = { workspace = true, optional = true, features = [ "signal", "macros" ] }
hyper = { workspace = true, optional = true }
http = { workspace = true, optional = true }
http-body-util = { workspace = true, optional = true }

[target.'cfg(unix)'.dependencies]
Expand Down Expand Up @@ -359,7 +360,7 @@ old-cli = []

# CLI subcommands for the `wasmtime` executable. See `wasmtime $cmd --help`
# for more information on each subcommand.
serve = ["wasi-http", "component-model", "dep:http-body-util"]
serve = ["wasi-http", "component-model", "dep:http-body-util", "dep:http"]
explore = ["dep:wasmtime-explorer"]
wast = ["dep:wasmtime-wast"]
config = ["cache"]
Expand Down
4 changes: 4 additions & 0 deletions crates/test-programs/src/bin/api_proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ struct T;

impl bindings::exports::wasi::http::incoming_handler::Guest for T {
fn handle(request: IncomingRequest, outparam: ResponseOutparam) {
assert!(request.scheme().is_some());
assert!(request.authority().is_some());
assert!(request.path_with_query().is_some());

let header = String::from("custom-forbidden-header");
let req_hdrs = request.headers();

Expand Down
2 changes: 2 additions & 0 deletions crates/test-programs/src/bin/api_proxy_streaming.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ impl bindings::exports::wasi::http::incoming_handler::Guest for Handler {
async fn handle_request(request: IncomingRequest, response_out: ResponseOutparam) {
let headers = request.headers().entries();

assert!(request.authority().is_some());

match (request.method(), request.path_with_query().as_deref()) {
(Method::Get, Some("/hash-all")) => {
// Send outgoing GET requests to the specified URLs and stream the hashes of the response bodies as
Expand Down
19 changes: 11 additions & 8 deletions crates/wasi-http/tests/all/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,11 +199,10 @@ async fn run_wasi_http(

#[test_log::test(tokio::test)]
async fn wasi_http_proxy_tests() -> anyhow::Result<()> {
let mut req = hyper::Request::builder().method(http::Method::GET);

req.headers_mut()
.unwrap()
.append("custom-forbidden-header", "yes".parse().unwrap());
let req = hyper::Request::builder()
.header("custom-forbidden-header", "yes")
.uri("http://example.com:8080/test-path")
.method(http::Method::GET);

let resp = run_wasi_http(
test_programs_artifacts::API_PROXY_COMPONENT,
Expand Down Expand Up @@ -326,7 +325,9 @@ async fn do_wasi_http_hash_all(override_send_request: bool) -> Result<()> {
None
};

let mut request = hyper::Request::get("/hash-all");
let mut request = hyper::Request::builder()
.method(http::Method::GET)
.uri("http://example.com:8080/hash-all");
for path in bodies.keys() {
request = request.header("url", format!("{prefix}{path}"));
}
Expand Down Expand Up @@ -448,8 +449,10 @@ async fn do_wasi_http_echo(uri: &str, url_header: Option<&str>) -> Result<()> {
.collect::<Vec<_>>()
};

let mut request =
hyper::Request::post(&format!("/{uri}")).header("content-type", "application/octet-stream");
let mut request = hyper::Request::builder()
.method(http::Method::POST)
.uri(format!("http://example.com:8080/{uri}"))
.header("content-type", "application/octet-stream");

if let Some(url_header) = url_header {
request = request.header("url", url_header);
Expand Down
39 changes: 34 additions & 5 deletions src/commands/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ use wasmtime_wasi::preview2::{
self, StreamError, StreamResult, Table, WasiCtx, WasiCtxBuilder, WasiView,
};
use wasmtime_wasi_http::{
body::HyperOutgoingBody, hyper_response_error, WasiHttpCtx, WasiHttpView,
bindings::http::types as http_types, body::HyperOutgoingBody, hyper_response_error,
WasiHttpCtx, WasiHttpView,
};

#[cfg(feature = "wasi-nn")]
Expand Down Expand Up @@ -356,6 +357,37 @@ impl hyper::service::Service<Request> for ProxyHandler {
// TODO: need to track the join handle, but don't want to block the response on it
tokio::task::spawn(async move {
let req_id = inner.next_req_id();
let (mut parts, body) = req.into_parts();

parts.uri = {
let uri_parts = parts.uri.into_parts();

let scheme = uri_parts.scheme.unwrap_or(http::uri::Scheme::HTTP);

let host = if let Some(val) = parts.headers.get(hyper::header::HOST) {
std::str::from_utf8(val.as_bytes())
.map_err(|_| http_types::ErrorCode::HttpRequestUriInvalid)?
} else {
uri_parts
.authority
.as_ref()
.ok_or(http_types::ErrorCode::HttpRequestUriInvalid)?
.host()
};

let path_with_query = uri_parts
.path_and_query
.ok_or(http_types::ErrorCode::HttpRequestUriInvalid)?;

hyper::Uri::builder()
.scheme(scheme)
.authority(host)
.path_and_query(path_with_query)
.build()
.map_err(|_| http_types::ErrorCode::HttpRequestUriInvalid)?
};

let req = hyper::Request::from_parts(parts, body.map_err(hyper_response_error).boxed());

log::info!(
"Request {req_id} handling {} to {}",
Expand All @@ -365,10 +397,7 @@ impl hyper::service::Service<Request> for ProxyHandler {

let mut store = inner.cmd.new_store(&inner.engine, req_id)?;

let req = store
.data_mut()
.new_incoming_request(req.map(|body| body.map_err(hyper_response_error).boxed()))?;

let req = store.data_mut().new_incoming_request(req)?;
let out = store.data_mut().new_response_outparam(sender)?;

let (proxy, _inst) =
Expand Down

0 comments on commit bba4ee7

Please sign in to comment.