Skip to content
Prev Previous commit
Next Next commit
Fetcher http flag
  • Loading branch information
kflansburg committed Mar 12, 2024
commit 99970ca06eeff90ac48028e9287bc883f01414cd
4 changes: 2 additions & 2 deletions worker-sandbox/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -688,14 +688,14 @@ pub async fn main(
})
.get_async("/remote-by-request", |req, ctx| async move {
let fetcher = ctx.service("remote")?;
fetcher.fetch_request(req).await
fetcher.fetch_request(req.into()).await.map(|r| r.into())
})
.get_async("/remote-by-path", |req, ctx| async move {
let fetcher = ctx.service("remote")?;
let mut init = RequestInit::new();
init.with_method(Method::Post);

fetcher.fetch(req.url()?.to_string(), Some(init)).await
fetcher.fetch(req.url()?.to_string(), Some(init)).await.map(|r| r.into())
})
.post_async("/queue/send/:id", |_req, ctx| async move {
let id = match ctx.param("id").map(|id|Uuid::try_parse(id).ok()).and_then(|u|u) {
Expand Down
25 changes: 22 additions & 3 deletions worker/src/fetcher.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,53 @@
use wasm_bindgen::{JsCast, JsValue};
use wasm_bindgen_futures::JsFuture;

use crate::{env::EnvBinding, Request, RequestInit, Response, Result};
use crate::{env::EnvBinding, RequestInit, Result};

#[cfg(feature = "http")]
use crate::{HttpRequest, HttpResponse};
#[cfg(not(feature = "http"))]
use crate::{Request, Response};
/// A struct for invoking fetch events to other Workers.
pub struct Fetcher(worker_sys::Fetcher);

#[cfg(not(feature = "http"))]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to do the same thing in global.rs with Fetch, on the other hand I really don't like the design of Fetch and we can save it for when we can think of a better API that's more idiomatic before we commit to anything.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, good catch, did not realize there are two implementations.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started going down this route and it turned out to be a can of worms, so I think this will need to be done in a follow up PR.

Mainly, it would involve a lot of changes in the many places that the global fetcher is used.

It also forced me to think about being able to convert between old and new types by reference. Supporting that is pretty painful and I'm on the fence whether it is even reasonable. So we may want to change Fetch::fetch_with_request to take an owned request if that seems ok. The only use case I can think of having a reference here is making multiple fetches with the same request, which must also not have a body. I'm not sure how common that is.

type FetchResponseType = Response;
#[cfg(feature = "http")]
type FetchResponseType = HttpResponse;

impl Fetcher {
/// Invoke a fetch event in a worker with a url and optionally a [RequestInit].
pub async fn fetch(
&self,
url: impl Into<String>,
init: Option<RequestInit>,
) -> Result<Response> {
) -> Result<FetchResponseType> {
let path = url.into();
let promise = match init {
Some(ref init) => self.0.fetch_with_str_and_init(&path, &init.into()),
None => self.0.fetch_with_str(&path),
};

let resp_sys: web_sys::Response = JsFuture::from(promise).await?.dyn_into()?;
Ok(Response::from(resp_sys))
#[cfg(not(feature = "http"))]
let result = Ok(Response::from(resp_sys));
#[cfg(feature = "http")]
let result = Ok(crate::response_from_wasm(resp_sys));
result
}

/// Invoke a fetch event with an existing [Request].
#[cfg(not(feature = "http"))]
pub async fn fetch_request(&self, request: Request) -> Result<Response> {
let promise = self.0.fetch(request.inner());
let resp_sys: web_sys::Response = JsFuture::from(promise).await?.dyn_into()?;
Ok(Response::from(resp_sys))
}

#[cfg(feature = "http")]
pub async fn fetch_request(&self, _request: HttpRequest) -> Result<HttpResponse> {
todo!()
}
}

impl EnvBinding for Fetcher {
Expand Down
4 changes: 4 additions & 0 deletions worker/src/http/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ use crate::http::body::Body;
pub fn from_wasm(_req: web_sys::Request) -> http::Request<Body> {
todo!()
}

pub fn to_wasm(_req: http::Request<Body>) -> web_sys::Request {
todo!()
}
4 changes: 4 additions & 0 deletions worker/src/http/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ use crate::http::body::Body;
pub fn to_wasm(_resp: http::Response<Body>) -> web_sys::Response {
todo!()
}

pub fn from_wasm(_resp: web_sys::Response) -> http::Response<Body> {
todo!()
}
5 changes: 4 additions & 1 deletion worker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ mod websocket;
pub type Result<T> = StdResult<T, error::Error>;

pub use http::body::Body;
pub use http::{request::from_wasm as request_from_wasm, response::to_wasm as response_to_wasm};
pub use http::{
request::from_wasm as request_from_wasm, request::to_wasm as request_to_wasm,
response::from_wasm as response_from_wasm, response::to_wasm as response_to_wasm,
};
pub type HttpRequest = ::http::Request<http::body::Body>;
pub type HttpResponse = ::http::Response<http::body::Body>;
7 changes: 7 additions & 0 deletions worker/src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ impl From<crate::HttpRequest> for Request {
}
}

#[cfg(feature = "http")]
impl From<Request> for crate::HttpRequest {
fn from(_req: Request) -> Self {
todo!()
}
}

impl From<web_sys::Request> for Request {
fn from(req: web_sys::Request) -> Self {
Self {
Expand Down