Skip to content

Commit

Permalink
Updated to axum 0.7.1, dropped http-body dependency (#21)
Browse files Browse the repository at this point in the history
* Updated to support axum 0.7.1

* Updated example to the latest axum 0.7.1 and workers 0.0.18.

* Added default compilation target so that cargo build and cargo checks work just fine.

* Dropped dependency http-body.

* Fixed for stable - removed flag commited by mistake.

* Added compatibility date back in.

---------

Co-authored-by: Logan Keenan <[email protected]>
  • Loading branch information
spigaz and logankeenan authored Nov 29, 2023
1 parent cd4ff2b commit 5ad675b
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 64 deletions.
2 changes: 2 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[build]
target = "wasm32-unknown-unknown"
6 changes: 3 additions & 3 deletions adapter/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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."
Expand All @@ -15,10 +15,10 @@ 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"
Expand Down
104 changes: 55 additions & 49 deletions adapter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,37 +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 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<Request<Body>, 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()
.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())?,
Expand All @@ -89,26 +82,24 @@ pub async fn to_axum_request(mut worker_request: WorkerRequest) -> Result<Reques
Ok(http_request)
}

pub async fn to_worker_response(mut response: Response) -> Result<WorkerResponse, Error> {
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<Body>) -> Result<WorkerResponse, Error> {
let mut bytes: Vec<u8> = Vec::<u8>::new();

let (parts, body) = response.into_parts();

let code = response.status().as_u16();
let mut stream = body.into_data_stream();
while let Some(chunk) = stream.try_next().await? {
bytes.extend_from_slice(&chunk);
}

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() {
headers.set(
key.as_str(),
value.to_str()?,
).unwrap()
for (key, value) in parts.headers.iter() {
headers.set(key.as_str(), value.to_str()?).unwrap()
}
worker_response = worker_response.with_headers(headers);

Expand All @@ -124,9 +115,7 @@ pub struct EnvWrapper {

impl EnvWrapper {
pub fn new(env: worker::Env) -> Self {
Self {
env: Arc::new(env),
}
Self { env: Arc::new(env) }
}
}

Expand All @@ -137,13 +126,9 @@ unsafe impl Sync for EnvWrapper {}
#[cfg(test)]
mod tests {
use super::*;
use axum::{
body::Bytes,
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]
Expand All @@ -154,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();

Expand All @@ -169,12 +155,19 @@ 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 request = to_axum_request(worker_request).await.unwrap();
let mut bytes: Vec<u8> = Vec::<u8>::new();

let body_bytes: Bytes = http_body::Body::data(request.body_mut()).await.unwrap().unwrap();
assert_eq!(body_bytes.to_vec(), b"hello world!");
let mut stream = request.into_body().into_data_stream();
while let Some(chunk) = stream.try_next().await.unwrap() {
bytes.extend_from_slice(&chunk);
}

assert_eq!(bytes.to_vec(), b"hello world!");
}

#[wasm_bindgen_test]
Expand All @@ -183,31 +176,44 @@ 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!");
}

#[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")
.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);
}
Expand Down
15 changes: 7 additions & 8 deletions example/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "todo-worker"
version = "0.0.0"
edition = "2018"
edition = "2021"

[lib]
crate-type = ["cdylib", "rlib"]
Expand All @@ -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
Expand Down
9 changes: 5 additions & 4 deletions example/wrangler.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
name = "axum-cloudflare-adapter-example"
workers_dev = true
compatibility_date = "2023-11-29"

main = "build/worker/shim.mjs"
compatibility_date = "2022-01-20"

[vars]
WORKERS_RS_VERSION = "0.0.11"
WORKERS_RS_VERSION = "0.0.18"

[build]
command = "cargo install -q worker-build --version 0.0.10 && worker-build --release"
command = "cargo install -q worker-build && worker-build --release"

0 comments on commit 5ad675b

Please sign in to comment.