From c5975cd734d80846a39fb272307f6c2fdf165b44 Mon Sep 17 00:00:00 2001 From: Alexandre Faria Date: Tue, 28 Nov 2023 16:41:11 +0000 Subject: [PATCH 1/6] Updated to support axum 0.7.1 --- adapter/Cargo.toml | 5 +++-- adapter/src/lib.rs | 44 +++++++++++++++++++++++++++----------------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/adapter/Cargo.toml b/adapter/Cargo.toml index bf9feb1..6265432 100644 --- a/adapter/Cargo.toml +++ b/adapter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "axum-cloudflare-adapter" -version = "0.6.1" +version = "0.7.1" edition = "2021" authors = ["Logan Keenan"] description = "An adapter to easily run an Axum server in a Cloudflare worker." @@ -15,10 +15,11 @@ crate-type = ["cdylib", "lib"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -axum = { version = "^0.6.19", default-features = false } +axum = { version = "^0.7.1", default-features = false } worker = { version = "^0.0.18" } http-body = "^0.4.5" axum-wasm-macros = "^0.1.0" +futures = "0.3.29" [dev-dependencies] wasm-bindgen-test = "^0.3.34" diff --git a/adapter/src/lib.rs b/adapter/src/lib.rs index fcceb8d..de0e028 100644 --- a/adapter/src/lib.rs +++ b/adapter/src/lib.rs @@ -1,3 +1,5 @@ +#![feature(ascii_char)] + //! Axum Cloudflare Adapter //! //! A collection of tools allowing Axum to be run within a Cloudflare worker. See example usage below. @@ -56,6 +58,7 @@ use axum::{ http::header::HeaderName, response::Response, }; +use futures::TryStreamExt; use worker::{ Request as WorkerRequest, Response as WorkerResponse, @@ -64,7 +67,7 @@ use worker::{ pub use error::Error; pub async fn to_axum_request(mut worker_request: WorkerRequest) -> Result, Error> { - let method = Method::from_str(worker_request.method().to_string().as_str())?; + let method = Method::from_bytes(worker_request.method().to_string().as_bytes())?; let uri = Uri::from_str(worker_request.url()? .to_string() @@ -89,22 +92,23 @@ pub async fn to_axum_request(mut worker_request: WorkerRequest) -> Result Result { - let bytes = match http_body::Body::data(response.body_mut()).await { - None => vec![], - Some(body_bytes) => match body_bytes { - Ok(bytes) => bytes.to_vec(), - Err(_) => vec![] - }, - }; +pub async fn to_worker_response(response: Response) -> Result { + let mut bytes: Vec = Vec::::new(); + + let (parts, body) = response.into_parts(); + + let mut stream = body.into_data_stream(); + while let Some(chunk) = stream.try_next().await? { + bytes.extend_from_slice(&chunk); + } - let code = response.status().as_u16(); + let code = parts.status.as_u16(); let mut worker_response = WorkerResponse::from_bytes(bytes)?; worker_response = worker_response.with_status(code); let mut headers = Headers::new(); - for (key, value) in response.headers().iter() { + for (key, value) in parts.headers.iter() { headers.set( key.as_str(), value.to_str()?, @@ -138,8 +142,7 @@ unsafe impl Sync for EnvWrapper {} mod tests { use super::*; use axum::{ - body::Bytes, - response::{Html}, + response::Html, response::IntoResponse, }; use wasm_bindgen_test::{*}; @@ -171,10 +174,17 @@ mod tests { request_init.with_method(WorkerMethod::Post); let worker_request = WorkerRequest::new_with_init("https://logankeenan.com", &request_init).unwrap(); - let mut request = to_axum_request(worker_request).await.unwrap(); + let request = to_axum_request(worker_request).await.unwrap(); + + + let mut bytes: Vec = Vec::::new(); + + let mut stream = request.into_body().into_data_stream(); + while let Some(chunk) = stream.try_next().await.unwrap() { + bytes.extend_from_slice(&chunk); + } - let body_bytes: Bytes = http_body::Body::data(request.body_mut()).await.unwrap().unwrap(); - assert_eq!(body_bytes.to_vec(), b"hello world!"); + assert_eq!(bytes.to_vec(), b"hello world!"); } #[wasm_bindgen_test] @@ -193,7 +203,7 @@ mod tests { #[wasm_bindgen_test] async fn it_should_convert_the_axum_response_to_a_worker_response_with_an_empty_body() { - let body = http_body::combinators::UnsyncBoxBody::default(); + let body = Body::empty(); let response = Response::builder() .status(200) .header("Content-Type", "text/html") From fcb7620a4b4a84dd190f8dc4c46017eec064c86d Mon Sep 17 00:00:00 2001 From: Alexandre Faria Date: Tue, 28 Nov 2023 16:58:38 +0000 Subject: [PATCH 2/6] Updated example to the latest axum 0.7.1 and workers 0.0.18. --- example/Cargo.toml | 15 +++++++-------- example/wrangler.toml | 8 ++++---- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/example/Cargo.toml b/example/Cargo.toml index 0a4da19..b6c97c1 100644 --- a/example/Cargo.toml +++ b/example/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "todo-worker" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] crate-type = ["cdylib", "rlib"] @@ -11,15 +11,14 @@ default = ["console_error_panic_hook"] [dependencies] cfg-if = "1.0.0" -worker = "0.0.18" -serde_json = "1.0.96" -axum = { version = "0.6.16", default-features = false } -tower-service = "0.3.2" +axum = { version = "^0.7.1", default-features = false } axum-cloudflare-adapter = { path = "../adapter" } -wasm-bindgen-futures = "0.4.34" -oneshot = "0.1.5" +oneshot = "0.1.6" +serde_json = "1.0.108" +tower-service = "0.3.2" url = "2.3.1" - +wasm-bindgen-futures = "0.4.34" +worker = "0.0.18" # The `console_error_panic_hook` crate provides better debugging of panics by # logging them with `console.error`. This is great for development, but requires diff --git a/example/wrangler.toml b/example/wrangler.toml index 3662ab2..ea1ce40 100644 --- a/example/wrangler.toml +++ b/example/wrangler.toml @@ -1,9 +1,9 @@ -name = "axum-cloudflare-adapter-example" +workers_dev = true + main = "build/worker/shim.mjs" -compatibility_date = "2022-01-20" [vars] -WORKERS_RS_VERSION = "0.0.11" +WORKERS_RS_VERSION = "0.1.8" [build] -command = "cargo install -q worker-build --version 0.0.10 && worker-build --release" +command = "cargo install -q worker-build && worker-build --release" From b5d12517424711a1ced32eeb727db76aa9841934 Mon Sep 17 00:00:00 2001 From: Alexandre Faria Date: Tue, 28 Nov 2023 17:05:03 +0000 Subject: [PATCH 3/6] Added default compilation target so that cargo build and cargo checks work just fine. --- .cargo/config.toml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .cargo/config.toml diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..f4e8c00 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[build] +target = "wasm32-unknown-unknown" From 8e3489638ba13c5ed28fdf62526b0d35b241bb30 Mon Sep 17 00:00:00 2001 From: Alexandre Faria Date: Tue, 28 Nov 2023 17:20:08 +0000 Subject: [PATCH 4/6] Dropped dependency http-body. --- adapter/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/adapter/Cargo.toml b/adapter/Cargo.toml index 6265432..2ba25ad 100644 --- a/adapter/Cargo.toml +++ b/adapter/Cargo.toml @@ -17,7 +17,6 @@ crate-type = ["cdylib", "lib"] [dependencies] axum = { version = "^0.7.1", default-features = false } worker = { version = "^0.0.18" } -http-body = "^0.4.5" axum-wasm-macros = "^0.1.0" futures = "0.3.29" From f0341666be8d7d152c73d7bd5b799ae4a495bc0c Mon Sep 17 00:00:00 2001 From: Alexandre Faria Date: Wed, 29 Nov 2023 01:51:29 +0000 Subject: [PATCH 5/6] Fixed for stable - removed flag commited by mistake. --- adapter/src/lib.rs | 70 ++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 37 deletions(-) diff --git a/adapter/src/lib.rs b/adapter/src/lib.rs index de0e028..4a351ad 100644 --- a/adapter/src/lib.rs +++ b/adapter/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(ascii_char)] - //! Axum Cloudflare Adapter //! //! A collection of tools allowing Axum to be run within a Cloudflare worker. See example usage below. @@ -50,38 +48,30 @@ //! ``` mod error; -use std::str::FromStr; -use std::sync::Arc; use axum::{ body::Body, - http::{Method, Request, Uri}, http::header::HeaderName, + http::{Method, Request, Uri}, response::Response, }; -use futures::TryStreamExt; -use worker::{ - Request as WorkerRequest, - Response as WorkerResponse, - Headers, -}; pub use error::Error; +use futures::TryStreamExt; +use std::str::FromStr; +use std::sync::Arc; +use worker::{Headers, Request as WorkerRequest, Response as WorkerResponse}; pub async fn to_axum_request(mut worker_request: WorkerRequest) -> Result, Error> { let method = Method::from_bytes(worker_request.method().to_string().as_bytes())?; - let uri = Uri::from_str(worker_request.url()? - .to_string() - .as_str())?; + let uri = Uri::from_str(worker_request.url()?.to_string().as_str())?; let body = worker_request.bytes().await?; - let mut http_request = Request::builder() .method(method) .uri(uri) .body(Body::from(body))?; - for (header_name, header_value) in worker_request.headers() { http_request.headers_mut().insert( HeaderName::from_str(header_name.as_str())?, @@ -109,10 +99,7 @@ pub async fn to_worker_response(response: Response) -> Result Self { - Self { - env: Arc::new(env), - } + Self { env: Arc::new(env) } } } @@ -141,12 +126,9 @@ unsafe impl Sync for EnvWrapper {} #[cfg(test)] mod tests { use super::*; - use axum::{ - response::Html, - response::IntoResponse, - }; - use wasm_bindgen_test::{*}; - use worker::{RequestInit, ResponseBody, Method as WorkerMethod}; + use axum::{response::Html, response::IntoResponse}; + use wasm_bindgen_test::*; + use worker::{Method as WorkerMethod, RequestInit, ResponseBody}; wasm_bindgen_test_configure!(run_in_browser); #[wasm_bindgen_test] @@ -157,7 +139,8 @@ mod tests { headers.append("Cache-Control", "no-cache").unwrap(); request_init.with_headers(headers); request_init.with_method(WorkerMethod::Get); - let worker_request = WorkerRequest::new_with_init("https://logankeenan.com", &request_init).unwrap(); + let worker_request = + WorkerRequest::new_with_init("https://logankeenan.com", &request_init).unwrap(); let request = to_axum_request(worker_request).await.unwrap(); @@ -172,11 +155,11 @@ mod tests { let mut request_init = RequestInit::new(); request_init.with_body(Some("hello world!".into())); request_init.with_method(WorkerMethod::Post); - let worker_request = WorkerRequest::new_with_init("https://logankeenan.com", &request_init).unwrap(); + let worker_request = + WorkerRequest::new_with_init("https://logankeenan.com", &request_init).unwrap(); let request = to_axum_request(worker_request).await.unwrap(); - let mut bytes: Vec = Vec::::new(); let mut stream = request.into_body().into_data_stream(); @@ -193,10 +176,17 @@ mod tests { let worker_response = to_worker_response(response).await.unwrap(); assert_eq!(worker_response.status_code(), 200); - assert_eq!(worker_response.headers().get("Content-Type").unwrap().unwrap(), "text/html; charset=utf-8"); + assert_eq!( + worker_response + .headers() + .get("Content-Type") + .unwrap() + .unwrap(), + "text/html; charset=utf-8" + ); let body = match worker_response.body() { ResponseBody::Body(body) => body.clone(), - _ => vec![] + _ => vec![], }; assert_eq!(body, b"Hello World!"); } @@ -210,14 +200,20 @@ mod tests { .body(body) .unwrap(); - let worker_response = to_worker_response(response).await.unwrap(); assert_eq!(worker_response.status_code(), 200); - assert_eq!(worker_response.headers().get("Content-Type").unwrap().unwrap(), "text/html"); + assert_eq!( + worker_response + .headers() + .get("Content-Type") + .unwrap() + .unwrap(), + "text/html" + ); let body = match worker_response.body() { ResponseBody::Body(body) => body.clone(), - _ => b"should be empty".to_vec() + _ => b"should be empty".to_vec(), }; assert_eq!(body.len(), 0); } From d2e0d0491354ffe56dc7dfc8fc60f5d47207b9fb Mon Sep 17 00:00:00 2001 From: Alexandre Faria Date: Wed, 29 Nov 2023 12:52:18 +0000 Subject: [PATCH 6/6] Added compatibility date back in. --- example/wrangler.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/example/wrangler.toml b/example/wrangler.toml index ea1ce40..4f14f75 100644 --- a/example/wrangler.toml +++ b/example/wrangler.toml @@ -1,9 +1,10 @@ workers_dev = true +compatibility_date = "2023-11-29" main = "build/worker/shim.mjs" [vars] -WORKERS_RS_VERSION = "0.1.8" +WORKERS_RS_VERSION = "0.0.18" [build] command = "cargo install -q worker-build && worker-build --release"