Skip to content

Commit

Permalink
feat(transport): port router to axum (#830)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidpdrsn committed Feb 18, 2022
1 parent 0f7344a commit 6dfc20e
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 310 deletions.
2 changes: 1 addition & 1 deletion tonic-build/src/server.rs
Expand Up @@ -124,7 +124,7 @@ pub fn generate<T: Service>(
B::Error: Into<StdError> + Send + 'static,
{
type Response = http::Response<tonic::body::BoxBody>;
type Error = Never;
type Error = std::convert::Infallible;
type Future = BoxFuture<Self::Response, Self::Error>;

fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Expand Down
2 changes: 2 additions & 0 deletions tonic/Cargo.toml
Expand Up @@ -32,6 +32,7 @@ tls-roots = ["tls-roots-common", "rustls-native-certs"]
tls-roots-common = ["tls"]
tls-webpki-roots = ["tls-roots-common", "webpki-roots"]
transport = [
"axum",
"h2",
"hyper",
"tokio",
Expand Down Expand Up @@ -77,6 +78,7 @@ tokio = {version = "1.0.1", features = ["net"], optional = true}
tokio-stream = "0.1"
tower = {version = "0.4.7", features = ["balance", "buffer", "discover", "limit", "load", "make", "timeout", "util"], optional = true}
tracing-futures = {version = "0.2", optional = true}
axum = {version = "0.4", default_features = false, optional = true}

# rustls
rustls-pemfile = { version = "0.2.1", optional = true }
Expand Down
9 changes: 9 additions & 0 deletions tonic/src/body.rs
Expand Up @@ -5,6 +5,15 @@ use http_body::Body;
/// A type erased HTTP body used for tonic services.
pub type BoxBody = http_body::combinators::UnsyncBoxBody<bytes::Bytes, crate::Status>;

/// Convert a [`http_body::Body`] into a [`BoxBody`].
pub(crate) fn boxed<B>(body: B) -> BoxBody
where
B: http_body::Body<Data = bytes::Bytes> + Send + 'static,
B::Error: Into<crate::Error>,
{
body.map_err(crate::Status::map_error).boxed_unsync()
}

// this also exists in `crate::codegen` but we need it here since `codegen` has
// `#[cfg(feature = "codegen")]`.
/// Create an empty `BoxBody`
Expand Down
11 changes: 0 additions & 11 deletions tonic/src/codegen.rs
Expand Up @@ -24,17 +24,6 @@ pub mod http {
pub use http::*;
}

#[derive(Debug)]
pub enum Never {}

impl std::fmt::Display for Never {
fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {}
}
}

impl std::error::Error for Never {}

pub fn empty_body() -> crate::body::BoxBody {
http_body::Empty::new()
.map_err(|err| match err {})
Expand Down
37 changes: 24 additions & 13 deletions tonic/src/service/interceptor.rs
Expand Up @@ -2,7 +2,11 @@
//!
//! See [`Interceptor`] for more details.

use crate::{request::SanitizeHeaders, Status};
use crate::{
body::{boxed, BoxBody},
request::SanitizeHeaders,
Status,
};
use bytes::Bytes;
use pin_project::pin_project;
use std::{
Expand Down Expand Up @@ -145,15 +149,16 @@ where
F: Interceptor,
S: Service<http::Request<ReqBody>, Response = http::Response<ResBody>>,
S::Error: Into<crate::Error>,
ResBody: http_body::Body<Data = bytes::Bytes> + Send + 'static,
ResBody::Error: Into<crate::Error>,
{
type Response = http::Response<ResBody>;
type Error = crate::Error;
type Response = http::Response<BoxBody>;
type Error = S::Error;
type Future = ResponseFuture<S::Future>;

#[inline]
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.inner.poll_ready(cx).map_err(Into::into)
self.inner.poll_ready(cx)
}

fn call(&mut self, req: http::Request<ReqBody>) -> Self::Future {
Expand All @@ -171,7 +176,7 @@ where
let req = req.into_http(uri, SanitizeHeaders::No);
ResponseFuture::future(self.inner.call(req))
}
Err(status) => ResponseFuture::error(status),
Err(status) => ResponseFuture::status(status),
}
}
}
Expand Down Expand Up @@ -200,9 +205,9 @@ impl<F> ResponseFuture<F> {
}
}

fn error(status: Status) -> Self {
fn status(status: Status) -> Self {
Self {
kind: Kind::Error(Some(status)),
kind: Kind::Status(Some(status)),
}
}
}
Expand All @@ -211,7 +216,7 @@ impl<F> ResponseFuture<F> {
#[derive(Debug)]
enum Kind<F> {
Future(#[pin] F),
Error(Option<Status>),
Status(Option<Status>),
}

impl<F, E, B> Future for ResponseFuture<F>
Expand All @@ -221,14 +226,20 @@ where
B: Default + http_body::Body<Data = Bytes> + Send + 'static,
B::Error: Into<crate::Error>,
{
type Output = Result<http::Response<B>, crate::Error>;
type Output = Result<http::Response<BoxBody>, E>;

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match self.project().kind.project() {
KindProj::Future(future) => future.poll(cx).map_err(Into::into),
KindProj::Error(status) => {
let response = status.take().unwrap().to_http().map(|_| B::default());

KindProj::Future(future) => future
.poll(cx)
.map(|result| result.map(|res| res.map(boxed))),
KindProj::Status(status) => {
let response = status
.take()
.unwrap()
.to_http()
.map(|_| B::default())
.map(boxed);
Poll::Ready(Ok(response))
}
}
Expand Down

0 comments on commit 6dfc20e

Please sign in to comment.