Skip to content

Commit d3da369

Browse files
authored
feat(web): Relax GrpcWebService request body type (#2016)
1 parent 0846e6e commit d3da369

File tree

2 files changed

+28
-10
lines changed

2 files changed

+28
-10
lines changed

tonic-web/src/lib.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,9 @@ const DEFAULT_ALLOW_HEADERS: [HeaderName; 4] = [
141141
since = "0.12.4",
142142
note = "compose the `GrpcWebLayer` with the cors layer of your choice"
143143
)]
144-
pub fn enable<S>(service: S) -> CorsGrpcWeb<S>
144+
pub fn enable<S, B>(service: S) -> CorsGrpcWeb<S>
145145
where
146-
S: Service<http::Request<BoxBody>, Response = http::Response<BoxBody>>,
146+
S: Service<B>,
147147
{
148148
let cors = CorsLayer::new()
149149
.allow_origin(AllowOrigin::mirror_request())
@@ -160,19 +160,24 @@ where
160160
#[derive(Debug, Clone)]
161161
pub struct CorsGrpcWeb<S>(tower_http::cors::Cors<GrpcWebService<S>>);
162162

163-
impl<S> Service<http::Request<BoxBody>> for CorsGrpcWeb<S>
163+
impl<S, B> Service<http::Request<B>> for CorsGrpcWeb<S>
164164
where
165165
S: Service<http::Request<BoxBody>, Response = http::Response<BoxBody>>,
166+
B: http_body::Body<Data = bytes::Bytes> + Send + 'static,
167+
B::Error: Into<BoxError> + std::fmt::Display,
166168
{
167169
type Response = S::Response;
168170
type Error = S::Error;
169171
type Future = CorsGrpcWebResponseFuture<S::Future>;
170172

171173
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
172-
self.0.poll_ready(cx)
174+
<tower_http::cors::Cors<GrpcWebService<S>> as Service<http::Request<B>>>::poll_ready(
175+
&mut self.0,
176+
cx,
177+
)
173178
}
174179

175-
fn call(&mut self, req: http::Request<BoxBody>) -> Self::Future {
180+
fn call(&mut self, req: http::Request<B>) -> Self::Future {
176181
CorsGrpcWebResponseFuture(self.0.call(req))
177182
}
178183
}
@@ -207,6 +212,8 @@ where
207212
const NAME: &'static str = S::NAME;
208213
}
209214

215+
type BoxError = Box<dyn std::error::Error + Send + Sync>;
216+
210217
pub(crate) mod util {
211218
pub(crate) mod base64 {
212219
use base64::{

tonic-web/src/service.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use core::fmt;
12
use std::future::Future;
23
use std::pin::Pin;
34
use std::task::{ready, Context, Poll};
@@ -61,9 +62,11 @@ where
6162
}
6263
}
6364

64-
impl<S> Service<Request<BoxBody>> for GrpcWebService<S>
65+
impl<S, B> Service<Request<B>> for GrpcWebService<S>
6566
where
6667
S: Service<Request<BoxBody>, Response = Response<BoxBody>>,
68+
B: http_body::Body<Data = bytes::Bytes> + Send + 'static,
69+
B::Error: Into<crate::BoxError> + fmt::Display,
6770
{
6871
type Response = S::Response;
6972
type Error = S::Error;
@@ -73,7 +76,7 @@ where
7376
self.inner.poll_ready(cx)
7477
}
7578

76-
fn call(&mut self, req: Request<BoxBody>) -> Self::Future {
79+
fn call(&mut self, req: Request<B>) -> Self::Future {
7780
match RequestKind::new(req.headers(), req.method(), req.version()) {
7881
// A valid grpc-web request, regardless of HTTP version.
7982
//
@@ -113,7 +116,7 @@ where
113116
debug!(kind = "other h2", content_type = ?req.headers().get(header::CONTENT_TYPE));
114117
ResponseFuture {
115118
case: Case::Other {
116-
future: self.inner.call(req),
119+
future: self.inner.call(req.map(tonic::body::boxed)),
117120
},
118121
}
119122
}
@@ -194,7 +197,11 @@ impl<'a> RequestKind<'a> {
194197
// Mutating request headers to conform to a gRPC request is not really
195198
// necessary for us at this point. We could remove most of these except
196199
// maybe for inserting `header::TE`, which tonic should check?
197-
fn coerce_request(mut req: Request<BoxBody>, encoding: Encoding) -> Request<BoxBody> {
200+
fn coerce_request<B>(mut req: Request<B>, encoding: Encoding) -> Request<BoxBody>
201+
where
202+
B: http_body::Body<Data = bytes::Bytes> + Send + 'static,
203+
B::Error: Into<crate::BoxError> + fmt::Display,
204+
{
198205
req.headers_mut().remove(header::CONTENT_LENGTH);
199206

200207
req.headers_mut()
@@ -211,7 +218,11 @@ fn coerce_request(mut req: Request<BoxBody>, encoding: Encoding) -> Request<BoxB
211218
req.map(|b| GrpcWebCall::request(b, encoding).boxed_unsync())
212219
}
213220

214-
fn coerce_response(res: Response<BoxBody>, encoding: Encoding) -> Response<BoxBody> {
221+
fn coerce_response<B>(res: Response<B>, encoding: Encoding) -> Response<BoxBody>
222+
where
223+
B: http_body::Body<Data = bytes::Bytes> + Send + 'static,
224+
B::Error: Into<crate::BoxError> + fmt::Display,
225+
{
215226
let mut res = res
216227
.map(|b| GrpcWebCall::response(b, encoding))
217228
.map(BoxBody::new);

0 commit comments

Comments
 (0)