diff --git a/tonic-web/Cargo.toml b/tonic-web/Cargo.toml index fed2817f2..d8e4b7bb6 100644 --- a/tonic-web/Cargo.toml +++ b/tonic-web/Cargo.toml @@ -24,6 +24,7 @@ hyper = "0.14" pin-project = "1" tonic = {version = "0.8", path = "../tonic", default-features = false, features = ["transport"]} tower-service = "0.3" +tower-layer = "0.3" tracing = "0.1" [dev-dependencies] diff --git a/tonic-web/src/config.rs b/tonic-web/src/config.rs index e27698f2e..5c965a18a 100644 --- a/tonic-web/src/config.rs +++ b/tonic-web/src/config.rs @@ -4,7 +4,6 @@ use std::time::Duration; use http::{header::HeaderName, HeaderValue}; use tonic::body::BoxBody; -use tonic::transport::NamedService; use tower_service::Service; use crate::service::GrpcWeb; @@ -152,11 +151,10 @@ impl Config { pub fn enable(&self, service: S) -> GrpcWeb where S: Service, Response = http::Response>, - S: NamedService + Clone + Send + 'static, + S: Clone + Send + 'static, S::Future: Send + 'static, S::Error: Into + Send, { - tracing::trace!("enabled for {}", S::NAME); GrpcWeb::new(service, self.clone()) } } diff --git a/tonic-web/src/layer.rs b/tonic-web/src/layer.rs new file mode 100644 index 000000000..95ca2ef66 --- /dev/null +++ b/tonic-web/src/layer.rs @@ -0,0 +1,31 @@ +use super::{BoxBody, BoxError, Config, GrpcWeb}; + +use tower_layer::Layer; +use tower_service::Service; + +/// Layer implementing the grpc-web protocol. +#[derive(Debug, Clone)] +pub struct GrpcWebLayer { + _priv: (), +} + +impl GrpcWebLayer { + /// Create a new grpc-web layer. + pub fn new() -> GrpcWebLayer { + Self { _priv: () } + } +} + +impl Layer for GrpcWebLayer +where + S: Service, Response = http::Response>, + S: Clone + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + Send, +{ + type Service = GrpcWeb; + + fn layer(&self, inner: S) -> Self::Service { + Config::default().enable(inner) + } +} diff --git a/tonic-web/src/lib.rs b/tonic-web/src/lib.rs index eb46b3d04..ad8799d2c 100644 --- a/tonic-web/src/lib.rs +++ b/tonic-web/src/lib.rs @@ -88,17 +88,18 @@ #![doc(issue_tracker_base_url = "https://github.com/hyperium/tonic/issues/")] pub use config::Config; +pub use layer::GrpcWebLayer; +pub use service::GrpcWeb; mod call; mod config; mod cors; +mod layer; mod service; -use crate::service::GrpcWeb; use std::future::Future; use std::pin::Pin; use tonic::body::BoxBody; -use tonic::transport::NamedService; use tower_service::Service; /// enable a tonic service to handle grpc-web requests with the default configuration. @@ -107,7 +108,7 @@ use tower_service::Service; pub fn enable(service: S) -> GrpcWeb where S: Service, Response = http::Response>, - S: NamedService + Clone + Send + 'static, + S: Clone + Send + 'static, S::Future: Send + 'static, S::Error: Into + Send, { diff --git a/tonic-web/src/service.rs b/tonic-web/src/service.rs index 03f31b221..c4beac1a0 100644 --- a/tonic-web/src/service.rs +++ b/tonic-web/src/service.rs @@ -15,6 +15,7 @@ use crate::{BoxError, BoxFuture, Config}; const GRPC: &str = "application/grpc"; +/// Service implementing the grpc-web protocol. #[derive(Debug, Clone)] pub struct GrpcWeb { inner: S, @@ -266,6 +267,7 @@ mod tests { mod grpc_web { use super::*; use http::HeaderValue; + use tower_layer::Layer; fn request() -> Request { Request::builder() @@ -284,6 +286,14 @@ mod tests { assert_eq!(res.status(), StatusCode::OK); } + #[tokio::test] + async fn web_layer() { + let mut svc = crate::GrpcWebLayer::new().layer(Svc); + let res = svc.call(request()).await.unwrap(); + + assert_eq!(res.status(), StatusCode::OK); + } + #[tokio::test] async fn without_origin() { let mut svc = crate::enable(Svc);