Skip to content

Commit 10f6d2f

Browse files
authoredJun 20, 2022
feat: Add Grpc::with_origin for clients (#1017)
1 parent 4388d82 commit 10f6d2f

File tree

3 files changed

+32
-23
lines changed

3 files changed

+32
-23
lines changed
 

‎examples/src/tls/client_rustls.rs

+3-23
Original file line numberDiff line numberDiff line change
@@ -48,30 +48,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
4848

4949
let client = hyper::Client::builder().build(connector);
5050

51-
// Hyper expects an absolute `Uri` to allow it to know which server to connect too.
52-
// Currently, tonic's generated code only sets the `path_and_query` section so we
53-
// are going to write a custom tower layer in front of the hyper client to add the
54-
// scheme and authority.
55-
//
56-
// Again, this Uri is `example.com` because our tls certs is signed with this SNI but above
57-
// we actually map this back to `[::1]:50051` before the `Uri` is passed to hyper's `HttpConnector`
58-
// to allow it to correctly establish the tcp connection to the local `tls-server`.
51+
// Using `with_origin` will let the codegenerated client set the `scheme` and
52+
// `authority` from the porvided `Uri`.
5953
let uri = Uri::from_static("https://example.com");
60-
let svc = tower::ServiceBuilder::new()
61-
.map_request(move |mut req: http::Request<tonic::body::BoxBody>| {
62-
let uri = Uri::builder()
63-
.scheme(uri.scheme().unwrap().clone())
64-
.authority(uri.authority().unwrap().clone())
65-
.path_and_query(req.uri().path_and_query().unwrap().clone())
66-
.build()
67-
.unwrap();
68-
69-
*req.uri_mut() = uri;
70-
req
71-
})
72-
.service(client);
73-
74-
let mut client = EchoClient::new(svc);
54+
let mut client = EchoClient::with_origin(client, uri);
7555

7656
let request = tonic::Request::new(EchoRequest {
7757
message: "hello".into(),

‎tonic-build/src/client.rs

+6
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ pub fn generate<T: Service>(
4444
clippy::let_unit_value,
4545
)]
4646
use tonic::codegen::*;
47+
use tonic::codegen::http::Uri;
4748

4849
#service_doc
4950
#(#struct_attributes)*
@@ -66,6 +67,11 @@ pub fn generate<T: Service>(
6667
Self { inner }
6768
}
6869

70+
pub fn with_origin(inner: T, origin: Uri) -> Self {
71+
let inner = tonic::client::Grpc::with_origin(inner, origin);
72+
Self { inner }
73+
}
74+
6975
pub fn with_interceptor<F>(inner: T, interceptor: F) -> #service_ident<InterceptedService<T, F>>
7076
where
7177
F: tonic::service::Interceptor,

‎tonic/src/client/grpc.rs

+23
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use std::fmt;
3030
/// [gRPC protocol definition]: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests
3131
pub struct Grpc<T> {
3232
inner: T,
33+
origin: Uri,
3334
/// Which compression encodings does the client accept?
3435
accept_compression_encodings: EnabledCompressionEncodings,
3536
/// The compression encoding that will be applied to requests.
@@ -41,6 +42,20 @@ impl<T> Grpc<T> {
4142
pub fn new(inner: T) -> Self {
4243
Self {
4344
inner,
45+
origin: Uri::default(),
46+
send_compression_encodings: None,
47+
accept_compression_encodings: EnabledCompressionEncodings::default(),
48+
}
49+
}
50+
51+
/// Creates a new gRPC client with the provided [`GrpcService`] and `Uri`.
52+
///
53+
/// The provided Uri will use only the scheme and authority parts as the
54+
/// path_and_query portion will be set for each method.
55+
pub fn with_origin(inner: T, origin: Uri) -> Self {
56+
Self {
57+
inner,
58+
origin,
4459
send_compression_encodings: None,
4560
accept_compression_encodings: EnabledCompressionEncodings::default(),
4661
}
@@ -211,8 +226,13 @@ impl<T> Grpc<T> {
211226
M1: Send + Sync + 'static,
212227
M2: Send + Sync + 'static,
213228
{
229+
let scheme = self.origin.scheme().cloned();
230+
let authority = self.origin.authority().cloned();
231+
214232
let mut parts = Parts::default();
215233
parts.path_and_query = Some(path);
234+
parts.scheme = scheme;
235+
parts.authority = authority;
216236

217237
let uri = Uri::from_parts(parts).expect("path_and_query only is valid Uri");
218238

@@ -296,6 +316,7 @@ impl<T: Clone> Clone for Grpc<T> {
296316
fn clone(&self) -> Self {
297317
Self {
298318
inner: self.inner.clone(),
319+
origin: self.origin.clone(),
299320
send_compression_encodings: self.send_compression_encodings,
300321
accept_compression_encodings: self.accept_compression_encodings,
301322
}
@@ -308,6 +329,8 @@ impl<T: fmt::Debug> fmt::Debug for Grpc<T> {
308329

309330
f.field("inner", &self.inner);
310331

332+
f.field("origin", &self.origin);
333+
311334
f.field("compression_encoding", &self.send_compression_encodings);
312335

313336
f.field(

0 commit comments

Comments
 (0)
Please sign in to comment.