mirror of
https://github.com/Start9Labs/rpc-toolkit.git
synced 2026-03-26 02:11:56 +00:00
support axum instead of hyper
This commit is contained in:
127
Cargo.lock
generated
127
Cargo.lock
generated
@@ -123,6 +123,61 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d09dbe0e490df5da9d69b36dca48a76635288a82f92eca90024883a56202026d"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum-core",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http 1.0.0",
|
||||
"http-body 1.0.0",
|
||||
"http-body-util",
|
||||
"hyper 1.1.0",
|
||||
"hyper-util",
|
||||
"itoa",
|
||||
"matchit",
|
||||
"memchr",
|
||||
"mime",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustversion",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_path_to_error",
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-core"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e87c8503f93e6d144ee5690907ba22db7ba79ab001a932ab99034f0fe836b3df"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http 1.0.0",
|
||||
"http-body 1.0.0",
|
||||
"http-body-util",
|
||||
"mime",
|
||||
"pin-project-lite",
|
||||
"rustversion",
|
||||
"sync_wrapper",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.69"
|
||||
@@ -604,7 +659,6 @@ dependencies = [
|
||||
"itoa",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -620,6 +674,24 @@ dependencies = [
|
||||
"tokio-native-tls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bdea9aac0dbe5a9240d68cfd9501e2db94222c6dc06843e06640b9e07f0fdc67"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"http 1.0.0",
|
||||
"http-body 1.0.0",
|
||||
"hyper 1.1.0",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.5.0"
|
||||
@@ -744,6 +816,12 @@ version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
|
||||
[[package]]
|
||||
name = "matchit"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.1"
|
||||
@@ -1026,11 +1104,11 @@ version = "0.2.3"
|
||||
dependencies = [
|
||||
"async-stream",
|
||||
"async-trait",
|
||||
"axum",
|
||||
"clap",
|
||||
"futures",
|
||||
"http 1.0.0",
|
||||
"http-body-util",
|
||||
"hyper 1.1.0",
|
||||
"imbl-value",
|
||||
"itertools",
|
||||
"lazy_format",
|
||||
@@ -1087,6 +1165,12 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.16"
|
||||
@@ -1172,6 +1256,16 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_path_to_error"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebd154a240de39fdebcf5775d2675c204d7c13cf39a4c697be6493c8e734337c"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.1"
|
||||
@@ -1246,6 +1340,12 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sync_wrapper"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration"
|
||||
version = "0.5.1"
|
||||
@@ -1380,6 +1480,28 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"pin-project",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-layer"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.2"
|
||||
@@ -1392,6 +1514,7 @@ version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
|
||||
dependencies = [
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
@@ -16,13 +16,14 @@ cbor = ["serde_cbor"]
|
||||
default = ["cbor"]
|
||||
|
||||
[dependencies]
|
||||
axum = "0.7.3"
|
||||
async-stream = "0.3"
|
||||
async-trait = "0.1"
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
futures = "0.3"
|
||||
http = "1"
|
||||
http-body-util = "0.1"
|
||||
hyper = { version = "1", features = ["server", "http1", "http2", "client"] }
|
||||
# hyper = { version = "1", features = ["server", "http1", "http2", "client"] }
|
||||
itertools = "0.12"
|
||||
imbl-value = { git = "https://github.com/Start9Labs/imbl-value.git" }
|
||||
lazy_format = "2"
|
||||
|
||||
@@ -25,7 +25,7 @@ pub use handler::*;
|
||||
/// See also: [arg](rpc_toolkit_macro::arg), [context](rpc_toolkit_macro::context)
|
||||
pub use rpc_toolkit_macro::command;
|
||||
pub use server::*;
|
||||
pub use {clap, futures, hyper, reqwest, serde, serde_json, tokio, url, yajrc};
|
||||
pub use {clap, futures, reqwest, serde, serde_json, tokio, url, yajrc};
|
||||
|
||||
mod cli;
|
||||
pub mod command_helpers;
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
use std::any::TypeId;
|
||||
|
||||
use axum::body::Body;
|
||||
use axum::extract::Request;
|
||||
use axum::handler::Handler;
|
||||
use axum::response::Response;
|
||||
use futures::future::{join_all, BoxFuture};
|
||||
use futures::FutureExt;
|
||||
use http::header::{CONTENT_LENGTH, CONTENT_TYPE};
|
||||
use http_body_util::BodyExt;
|
||||
use hyper::body::{Bytes, Incoming};
|
||||
use hyper::service::Service;
|
||||
use hyper::{Request, Response};
|
||||
use imbl_value::imbl::Vector;
|
||||
use imbl_value::Value;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
@@ -18,15 +20,15 @@ use crate::{HandleAny, Server};
|
||||
|
||||
const FALLBACK_ERROR: &str = "{\"error\":{\"code\":-32603,\"message\":\"Internal error\",\"data\":\"Failed to serialize rpc response\"}}";
|
||||
|
||||
pub fn fallback_rpc_error_response() -> Response<Bytes> {
|
||||
pub fn fallback_rpc_error_response() -> Response {
|
||||
Response::builder()
|
||||
.header(CONTENT_TYPE, "application/json")
|
||||
.header(CONTENT_LENGTH, FALLBACK_ERROR.len())
|
||||
.body(Bytes::from_static(FALLBACK_ERROR.as_bytes()))
|
||||
.body(Body::from(FALLBACK_ERROR.as_bytes()))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn json_http_response<T: Serialize>(t: &T) -> Response<Bytes> {
|
||||
pub fn json_http_response<T: Serialize>(t: &T) -> Response {
|
||||
let body = match serde_json::to_vec(t) {
|
||||
Ok(a) => a,
|
||||
Err(_) => return fallback_rpc_error_response(),
|
||||
@@ -34,12 +36,10 @@ pub fn json_http_response<T: Serialize>(t: &T) -> Response<Bytes> {
|
||||
Response::builder()
|
||||
.header(CONTENT_TYPE, "application/json")
|
||||
.header(CONTENT_LENGTH, body.len())
|
||||
.body(Bytes::from(body))
|
||||
.body(Body::from(body))
|
||||
.unwrap_or_else(|_| fallback_rpc_error_response())
|
||||
}
|
||||
|
||||
pub type BoxBody = http_body_util::combinators::BoxBody<Bytes, hyper::Error>;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait Middleware<Context: Send + 'static>: Clone + Send + Sync + 'static {
|
||||
type Metadata: DeserializeOwned + Send + 'static;
|
||||
@@ -47,8 +47,8 @@ pub trait Middleware<Context: Send + 'static>: Clone + Send + Sync + 'static {
|
||||
async fn process_http_request(
|
||||
&mut self,
|
||||
context: &Context,
|
||||
request: &mut Request<BoxBody>,
|
||||
) -> Result<(), Response<Bytes>> {
|
||||
request: &mut Request,
|
||||
) -> Result<(), Response> {
|
||||
Ok(())
|
||||
}
|
||||
#[allow(unused_variables)]
|
||||
@@ -63,7 +63,7 @@ pub trait Middleware<Context: Send + 'static>: Clone + Send + Sync + 'static {
|
||||
#[allow(unused_variables)]
|
||||
async fn process_rpc_response(&mut self, context: &Context, response: &mut RpcResponse) {}
|
||||
#[allow(unused_variables)]
|
||||
async fn process_http_response(&mut self, context: &Context, response: &mut Response<Bytes>) {}
|
||||
async fn process_http_response(&mut self, context: &Context, response: &mut Response) {}
|
||||
}
|
||||
|
||||
#[allow(private_bounds)]
|
||||
@@ -72,8 +72,8 @@ trait _Middleware<Context>: Send + Sync {
|
||||
fn process_http_request<'a>(
|
||||
&'a mut self,
|
||||
context: &'a Context,
|
||||
request: &'a mut Request<BoxBody>,
|
||||
) -> BoxFuture<'a, Result<(), Response<Bytes>>>;
|
||||
request: &'a mut Request,
|
||||
) -> BoxFuture<'a, Result<(), Response>>;
|
||||
fn process_rpc_request<'a>(
|
||||
&'a mut self,
|
||||
context: &'a Context,
|
||||
@@ -89,7 +89,7 @@ trait _Middleware<Context>: Send + Sync {
|
||||
fn process_http_response<'a>(
|
||||
&'a mut self,
|
||||
context: &'a Context,
|
||||
response: &'a mut Response<Bytes>,
|
||||
response: &'a mut Response,
|
||||
) -> BoxFuture<'a, ()>;
|
||||
}
|
||||
impl<Context: Send + 'static, T: Middleware<Context> + Send + Sync> _Middleware<Context> for T {
|
||||
@@ -99,8 +99,8 @@ impl<Context: Send + 'static, T: Middleware<Context> + Send + Sync> _Middleware<
|
||||
fn process_http_request<'a>(
|
||||
&'a mut self,
|
||||
context: &'a Context,
|
||||
request: &'a mut Request<BoxBody>,
|
||||
) -> BoxFuture<'a, Result<(), Response<Bytes>>> {
|
||||
request: &'a mut Request,
|
||||
) -> BoxFuture<'a, Result<(), Response>> {
|
||||
<Self as Middleware<Context>>::process_http_request(self, context, request)
|
||||
}
|
||||
fn process_rpc_request<'a>(
|
||||
@@ -129,7 +129,7 @@ impl<Context: Send + 'static, T: Middleware<Context> + Send + Sync> _Middleware<
|
||||
fn process_http_response<'a>(
|
||||
&'a mut self,
|
||||
context: &'a Context,
|
||||
response: &'a mut Response<Bytes>,
|
||||
response: &'a mut Response,
|
||||
) -> BoxFuture<'a, ()> {
|
||||
<Self as Middleware<Context>>::process_http_response(self, context, response)
|
||||
}
|
||||
@@ -144,7 +144,7 @@ impl<Context> Clone for DynMiddleware<Context> {
|
||||
|
||||
pub struct HttpServer<Context: crate::Context> {
|
||||
inner: Server<Context>,
|
||||
middleware: Vec<DynMiddleware<Context>>,
|
||||
middleware: Vector<DynMiddleware<Context>>,
|
||||
}
|
||||
impl<Context: crate::Context> Clone for HttpServer<Context> {
|
||||
fn clone(&self) -> Self {
|
||||
@@ -158,7 +158,7 @@ impl<Context: crate::Context> Server<Context> {
|
||||
pub fn for_http(self) -> HttpServer<Context> {
|
||||
HttpServer {
|
||||
inner: self,
|
||||
middleware: Vec::new(),
|
||||
middleware: Vector::new(),
|
||||
}
|
||||
}
|
||||
pub fn middleware<T: Middleware<Context>>(self, middleware: T) -> HttpServer<Context> {
|
||||
@@ -167,10 +167,11 @@ impl<Context: crate::Context> Server<Context> {
|
||||
}
|
||||
impl<Context: crate::Context> HttpServer<Context> {
|
||||
pub fn middleware<T: Middleware<Context>>(mut self, middleware: T) -> Self {
|
||||
self.middleware.push(DynMiddleware(Box::new(middleware)));
|
||||
self.middleware
|
||||
.push_back(DynMiddleware(Box::new(middleware)));
|
||||
self
|
||||
}
|
||||
async fn process_http_request(&self, mut req: Request<BoxBody>) -> Response<Bytes> {
|
||||
async fn process_http_request(&self, mut req: Request) -> Response {
|
||||
let mut mid = self.middleware.clone();
|
||||
match async {
|
||||
let ctx = (self.inner.make_ctx)().await?;
|
||||
@@ -234,7 +235,7 @@ impl<Context: crate::Context> HttpServer<Context> {
|
||||
async fn process_rpc_request(
|
||||
&self,
|
||||
ctx: &Context,
|
||||
mid: &mut Vec<DynMiddleware<Context>>,
|
||||
mid: &mut Vector<DynMiddleware<Context>>,
|
||||
mut req: RpcRequest,
|
||||
) -> RpcResponse {
|
||||
let metadata = Value::Object(
|
||||
@@ -278,25 +279,15 @@ impl<Context: crate::Context> HttpServer<Context> {
|
||||
}
|
||||
res
|
||||
}
|
||||
pub fn handle(&self, req: Request<Incoming>) -> BoxFuture<'static, Response<Bytes>> {
|
||||
pub fn handle(&self, req: Request) -> BoxFuture<'static, Response> {
|
||||
let server = self.clone();
|
||||
async move {
|
||||
server
|
||||
.process_http_request(req.map(|b| BoxBody::new(b)))
|
||||
.await
|
||||
}
|
||||
.boxed()
|
||||
async move { server.process_http_request(req).await }.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Context: crate::Context> Service<Request<Incoming>> for HttpServer<Context> {
|
||||
type Response = Response<Bytes>;
|
||||
type Error = hyper::Error;
|
||||
type Future = futures::future::Map<
|
||||
BoxFuture<'static, Self::Response>,
|
||||
fn(Self::Response) -> Result<Self::Response, Self::Error>,
|
||||
>;
|
||||
fn call(&self, req: Request<Incoming>) -> Self::Future {
|
||||
self.handle(req).map(Ok)
|
||||
impl<Context: crate::Context> Handler<(), ()> for HttpServer<Context> {
|
||||
type Future = BoxFuture<'static, Response>;
|
||||
fn call(self, req: Request, _: ()) -> Self::Future {
|
||||
self.handle(req)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user