feat(web): Implement tower::Layer for tonic_web::Config (#1119)
Signed-off-by: slinkydeveloper <[email protected]>
This commit is contained in:
@@ -24,6 +24,7 @@ hyper = "0.14"
|
|||||||
pin-project = "1"
|
pin-project = "1"
|
||||||
tonic = {version = "0.8", path = "../tonic", default-features = false, features = ["transport"]}
|
tonic = {version = "0.8", path = "../tonic", default-features = false, features = ["transport"]}
|
||||||
tower-service = "0.3"
|
tower-service = "0.3"
|
||||||
|
tower-layer = "0.3"
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use http::{header::HeaderName, HeaderValue};
|
use http::{header::HeaderName, HeaderValue};
|
||||||
use tonic::body::BoxBody;
|
use tonic::body::BoxBody;
|
||||||
use tonic::transport::NamedService;
|
|
||||||
use tower_service::Service;
|
use tower_service::Service;
|
||||||
|
|
||||||
use crate::service::GrpcWeb;
|
use crate::service::GrpcWeb;
|
||||||
@@ -152,11 +151,10 @@ impl Config {
|
|||||||
pub fn enable<S>(&self, service: S) -> GrpcWeb<S>
|
pub fn enable<S>(&self, service: S) -> GrpcWeb<S>
|
||||||
where
|
where
|
||||||
S: Service<http::Request<hyper::Body>, Response = http::Response<BoxBody>>,
|
S: Service<http::Request<hyper::Body>, Response = http::Response<BoxBody>>,
|
||||||
S: NamedService + Clone + Send + 'static,
|
S: Clone + Send + 'static,
|
||||||
S::Future: Send + 'static,
|
S::Future: Send + 'static,
|
||||||
S::Error: Into<BoxError> + Send,
|
S::Error: Into<BoxError> + Send,
|
||||||
{
|
{
|
||||||
tracing::trace!("enabled for {}", S::NAME);
|
|
||||||
GrpcWeb::new(service, self.clone())
|
GrpcWeb::new(service, self.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<S> Layer<S> for GrpcWebLayer
|
||||||
|
where
|
||||||
|
S: Service<http::Request<hyper::Body>, Response = http::Response<BoxBody>>,
|
||||||
|
S: Clone + Send + 'static,
|
||||||
|
S::Future: Send + 'static,
|
||||||
|
S::Error: Into<BoxError> + Send,
|
||||||
|
{
|
||||||
|
type Service = GrpcWeb<S>;
|
||||||
|
|
||||||
|
fn layer(&self, inner: S) -> Self::Service {
|
||||||
|
Config::default().enable(inner)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -88,17 +88,18 @@
|
|||||||
#![doc(issue_tracker_base_url = "https://github.com/hyperium/tonic/issues/")]
|
#![doc(issue_tracker_base_url = "https://github.com/hyperium/tonic/issues/")]
|
||||||
|
|
||||||
pub use config::Config;
|
pub use config::Config;
|
||||||
|
pub use layer::GrpcWebLayer;
|
||||||
|
pub use service::GrpcWeb;
|
||||||
|
|
||||||
mod call;
|
mod call;
|
||||||
mod config;
|
mod config;
|
||||||
mod cors;
|
mod cors;
|
||||||
|
mod layer;
|
||||||
mod service;
|
mod service;
|
||||||
|
|
||||||
use crate::service::GrpcWeb;
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use tonic::body::BoxBody;
|
use tonic::body::BoxBody;
|
||||||
use tonic::transport::NamedService;
|
|
||||||
use tower_service::Service;
|
use tower_service::Service;
|
||||||
|
|
||||||
/// enable a tonic service to handle grpc-web requests with the default configuration.
|
/// enable a tonic service to handle grpc-web requests with the default configuration.
|
||||||
@@ -107,7 +108,7 @@ use tower_service::Service;
|
|||||||
pub fn enable<S>(service: S) -> GrpcWeb<S>
|
pub fn enable<S>(service: S) -> GrpcWeb<S>
|
||||||
where
|
where
|
||||||
S: Service<http::Request<hyper::Body>, Response = http::Response<BoxBody>>,
|
S: Service<http::Request<hyper::Body>, Response = http::Response<BoxBody>>,
|
||||||
S: NamedService + Clone + Send + 'static,
|
S: Clone + Send + 'static,
|
||||||
S::Future: Send + 'static,
|
S::Future: Send + 'static,
|
||||||
S::Error: Into<BoxError> + Send,
|
S::Error: Into<BoxError> + Send,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ use crate::{BoxError, BoxFuture, Config};
|
|||||||
|
|
||||||
const GRPC: &str = "application/grpc";
|
const GRPC: &str = "application/grpc";
|
||||||
|
|
||||||
|
/// Service implementing the grpc-web protocol.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct GrpcWeb<S> {
|
pub struct GrpcWeb<S> {
|
||||||
inner: S,
|
inner: S,
|
||||||
@@ -266,6 +267,7 @@ mod tests {
|
|||||||
mod grpc_web {
|
mod grpc_web {
|
||||||
use super::*;
|
use super::*;
|
||||||
use http::HeaderValue;
|
use http::HeaderValue;
|
||||||
|
use tower_layer::Layer;
|
||||||
|
|
||||||
fn request() -> Request<Body> {
|
fn request() -> Request<Body> {
|
||||||
Request::builder()
|
Request::builder()
|
||||||
@@ -284,6 +286,14 @@ mod tests {
|
|||||||
assert_eq!(res.status(), StatusCode::OK);
|
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]
|
#[tokio::test]
|
||||||
async fn without_origin() {
|
async fn without_origin() {
|
||||||
let mut svc = crate::enable(Svc);
|
let mut svc = crate::enable(Svc);
|
||||||
|
|||||||
Reference in New Issue
Block a user