From 85ef18f8b7f91047ca5bcfe5fc90e3c510c7936a Mon Sep 17 00:00:00 2001 From: Juan Alvarez Date: Mon, 11 Nov 2019 08:27:40 -0600 Subject: [PATCH] fix(transport): Update builders to move self (#132) --- tonic-examples/src/gcp/client.rs | 5 +- tonic-examples/src/tls/client.rs | 5 +- tonic-examples/src/tls/server.rs | 1 - tonic-examples/src/tls_client_auth/client.rs | 5 +- tonic-examples/src/tls_client_auth/server.rs | 5 +- tonic-interop/src/bin/client.rs | 9 +- tonic-interop/src/bin/server.rs | 54 +++++------ tonic/src/transport/endpoint.rs | 99 ++++++++++++-------- tonic/src/transport/server.rs | 73 +++++++++------ 9 files changed, 144 insertions(+), 112 deletions(-) diff --git a/tonic-examples/src/gcp/client.rs b/tonic-examples/src/gcp/client.rs index 3d0e0afd8..c698ba8b0 100644 --- a/tonic-examples/src/gcp/client.rs +++ b/tonic-examples/src/gcp/client.rs @@ -29,14 +29,13 @@ async fn main() -> Result<(), Box> { let tls_config = ClientTlsConfig::with_rustls() .ca_certificate(Certificate::from_pem(certs.as_slice())) - .domain_name("pubsub.googleapis.com") - .clone(); + .domain_name("pubsub.googleapis.com"); let channel = Channel::from_static(ENDPOINT) .intercept_headers(move |headers| { headers.insert("authorization", header_value.clone()); }) - .tls_config(&tls_config) + .tls_config(tls_config) .connect() .await?; diff --git a/tonic-examples/src/tls/client.rs b/tonic-examples/src/tls/client.rs index 02c614cb9..f7060e70a 100644 --- a/tonic-examples/src/tls/client.rs +++ b/tonic-examples/src/tls/client.rs @@ -12,11 +12,10 @@ async fn main() -> Result<(), Box> { let tls = ClientTlsConfig::with_rustls() .ca_certificate(ca) - .domain_name("example.com") - .clone(); + .domain_name("example.com"); let channel = Channel::from_static("http://[::1]:50051") - .tls_config(&tls) + .tls_config(tls) .connect() .await?; diff --git a/tonic-examples/src/tls/server.rs b/tonic-examples/src/tls/server.rs index 79b85451b..2643fd419 100644 --- a/tonic-examples/src/tls/server.rs +++ b/tonic-examples/src/tls/server.rs @@ -60,7 +60,6 @@ async fn main() -> Result<(), Box> { Server::builder() .tls_config(ServerTlsConfig::with_rustls().identity(identity)) - .clone() .add_service(pb::server::EchoServer::new(server)) .serve(addr) .await?; diff --git a/tonic-examples/src/tls_client_auth/client.rs b/tonic-examples/src/tls_client_auth/client.rs index 1a1335a88..a77212a57 100644 --- a/tonic-examples/src/tls_client_auth/client.rs +++ b/tonic-examples/src/tls_client_auth/client.rs @@ -16,11 +16,10 @@ async fn main() -> Result<(), Box> { let tls = ClientTlsConfig::with_rustls() .domain_name("localhost") .ca_certificate(server_root_ca_cert) - .identity(client_identity) - .clone(); + .identity(client_identity); let channel = Channel::from_static("http://[::1]:50051") - .tls_config(&tls) + .tls_config(tls) .connect() .await?; diff --git a/tonic-examples/src/tls_client_auth/server.rs b/tonic-examples/src/tls_client_auth/server.rs index bff58ca26..7ee7f2dd0 100644 --- a/tonic-examples/src/tls_client_auth/server.rs +++ b/tonic-examples/src/tls_client_auth/server.rs @@ -39,11 +39,10 @@ async fn main() -> Result<(), Box> { let tls = ServerTlsConfig::with_rustls() .identity(server_identity) - .client_ca_root(client_ca_cert) - .clone(); + .client_ca_root(client_ca_cert); Server::builder() - .tls_config(&tls) + .tls_config(tls) .add_service(pb::server::EchoServer::new(server)) .serve(addr) .await?; diff --git a/tonic-interop/src/bin/client.rs b/tonic-interop/src/bin/client.rs index a2c5e6af9..3572d32c5 100644 --- a/tonic-interop/src/bin/client.rs +++ b/tonic-interop/src/bin/client.rs @@ -30,20 +30,19 @@ async fn main() -> Result<(), Box> { #[allow(unused_mut)] let mut endpoint = Endpoint::from_static("http://localhost:10000") .timeout(Duration::from_secs(5)) - .concurrency_limit(30) - .clone(); + .concurrency_limit(30); if matches.use_tls { #[cfg(not(any(feature = "tls_rustls", feature = "tls_openssl")))] { - panic!("No TLS libary feature selected"); + panic!("No TLS library feature selected"); } #[cfg(feature = "tls_rustls")] { let pem = tokio::fs::read("tonic-interop/data/ca.pem").await?; let ca = Certificate::from_pem(pem); - endpoint.tls_config( + endpoint = endpoint.tls_config( ClientTlsConfig::with_rustls() .ca_certificate(ca) .domain_name("foo.test.google.fr"), @@ -54,7 +53,7 @@ async fn main() -> Result<(), Box> { { let pem = tokio::fs::read("tonic-interop/data/ca.pem").await?; let ca = Certificate::from_pem(pem); - endpoint.tls_config( + endpoint = endpoint.tls_config( ClientTlsConfig::with_openssl() .ca_certificate(ca) .domain_name("foo.test.google.fr"), diff --git a/tonic-interop/src/bin/server.rs b/tonic-interop/src/bin/server.rs index 3871c249a..427e91985 100644 --- a/tonic-interop/src/bin/server.rs +++ b/tonic-interop/src/bin/server.rs @@ -21,34 +21,7 @@ async fn main() -> std::result::Result<(), Box> { let addr = "127.0.0.1:10000".parse().unwrap(); - let mut builder = Server::builder(); - - if matches.use_tls { - #[cfg(not(any(feature = "tls_rustls", feature = "tls_openssl")))] - { - panic!("No TLS libary feature selected"); - } - - #[cfg(feature = "tls_rustls")] - { - let cert = tokio::fs::read("tonic-interop/data/server1.pem").await?; - let key = tokio::fs::read("tonic-interop/data/server1.key").await?; - let identity = Identity::from_pem(cert, key); - - builder.tls_config(ServerTlsConfig::with_rustls().identity(identity)); - } - - #[cfg(feature = "tls_openssl")] - { - let cert = tokio::fs::read("tonic-interop/data/server1.pem").await?; - let key = tokio::fs::read("tonic-interop/data/server1.key").await?; - let identity = Identity::from_pem(cert, key); - - builder.tls_config(ServerTlsConfig::with_openssl().identity(identity)); - } - } - - builder.interceptor_fn(|svc, req| { + let mut builder = Server::builder().interceptor_fn(|svc, req| { let echo_header = req .headers() .get("x-grpc-test-echo-initial") @@ -76,6 +49,31 @@ async fn main() -> std::result::Result<(), Box> { } }); + if matches.use_tls { + #[cfg(not(any(feature = "tls_rustls", feature = "tls_openssl")))] + { + panic!("No TLS library feature selected"); + } + + #[cfg(feature = "tls_rustls")] + { + let cert = tokio::fs::read("tonic-interop/data/server1.pem").await?; + let key = tokio::fs::read("tonic-interop/data/server1.key").await?; + let identity = Identity::from_pem(cert, key); + + builder = builder.tls_config(ServerTlsConfig::with_rustls().identity(identity)); + } + + #[cfg(feature = "tls_openssl")] + { + let cert = tokio::fs::read("tonic-interop/data/server1.pem").await?; + let key = tokio::fs::read("tonic-interop/data/server1.key").await?; + let identity = Identity::from_pem(cert, key); + + builder = builder.tls_config(ServerTlsConfig::with_openssl().identity(identity)); + } + } + let test_service = server::TestServiceServer::new(server::TestService::default()); let unimplemented_service = server::UnimplementedServiceServer::new(server::UnimplementedService::default()); diff --git a/tonic/src/transport/endpoint.rs b/tonic/src/transport/endpoint.rs index 832830059..a79cc2481 100644 --- a/tonic/src/transport/endpoint.rs +++ b/tonic/src/transport/endpoint.rs @@ -76,9 +76,11 @@ impl Endpoint { /// # let mut builder = Endpoint::from_static("https://example.com"); /// builder.timeout(Duration::from_secs(5)); /// ``` - pub fn timeout(&mut self, dur: Duration) -> &mut Self { - self.timeout = Some(dur); - self + pub fn timeout(self, dur: Duration) -> Self { + Endpoint { + timeout: Some(dur), + ..self + } } /// Apply a concurrency limit to each request. @@ -88,9 +90,11 @@ impl Endpoint { /// # let mut builder = Endpoint::from_static("https://example.com"); /// builder.concurrency_limit(256); /// ``` - pub fn concurrency_limit(&mut self, limit: usize) -> &mut Self { - self.concurrency_limit = Some(limit); - self + pub fn concurrency_limit(self, limit: usize) -> Self { + Endpoint { + concurrency_limit: Some(limit), + ..self + } } /// Apply a rate limit to each request. @@ -101,9 +105,11 @@ impl Endpoint { /// # let mut builder = Endpoint::from_static("https://example.com"); /// builder.rate_limit(32, Duration::from_secs(1)); /// ``` - pub fn rate_limit(&mut self, limit: u64, duration: Duration) -> &mut Self { - self.rate_limit = Some((limit, duration)); - self + pub fn rate_limit(self, limit: u64, duration: Duration) -> Self { + Endpoint { + rate_limit: Some((limit, duration)), + ..self + } } /// Sets the [`SETTINGS_INITIAL_WINDOW_SIZE`][spec] option for HTTP2 @@ -112,33 +118,41 @@ impl Endpoint { /// Default is 65,535 /// /// [spec]: https://http2.github.io/http2-spec/#SETTINGS_INITIAL_WINDOW_SIZE - pub fn initial_stream_window_size(&mut self, sz: impl Into>) -> &mut Self { - self.init_stream_window_size = sz.into(); - self + pub fn initial_stream_window_size(self, sz: impl Into>) -> Self { + Endpoint { + init_stream_window_size: sz.into(), + ..self + } } /// Sets the max connection-level flow control for HTTP2 /// /// Default is 65,535 - pub fn initial_connection_window_size(&mut self, sz: impl Into>) -> &mut Self { - self.init_connection_window_size = sz.into(); - self + pub fn initial_connection_window_size(self, sz: impl Into>) -> Self { + Endpoint { + init_connection_window_size: sz.into(), + ..self + } } /// Intercept outbound HTTP Request headers; - pub fn intercept_headers(&mut self, f: F) -> &mut Self + pub fn intercept_headers(self, f: F) -> Self where F: Fn(&mut http::HeaderMap) + Send + Sync + 'static, { - self.interceptor_headers = Some(Arc::new(f)); - self + Endpoint { + interceptor_headers: Some(Arc::new(f)), + ..self + } } /// Configures TLS for the endpoint. #[cfg(feature = "tls")] - pub fn tls_config(&mut self, tls_config: &ClientTlsConfig) -> &mut Self { - self.tls = Some(tls_config.tls_connector(self.uri.clone()).unwrap()); - self + pub fn tls_config(self, tls_config: ClientTlsConfig) -> Self { + Endpoint { + tls: Some(tls_config.tls_connector(self.uri.clone()).unwrap()), + ..self + } } /// Create a channel from this config. @@ -262,48 +276,55 @@ impl ClientTlsConfig { /// /// This has no effect if `rustls_client_config` or `openssl_connector` is used to configure /// Rustls or OpenSSL respectively. - pub fn domain_name(&mut self, domain_name: impl Into) -> &mut Self { - self.domain = Some(domain_name.into()); - self + pub fn domain_name(self, domain_name: impl Into) -> Self { + ClientTlsConfig { + domain: Some(domain_name.into()), + ..self + } } /// Sets the CA Certificate against which to verify the server's TLS certificate. /// /// This has no effect if `rustls_client_config` or `openssl_connector` is used to configure /// Rustls or OpenSSL respectively. - pub fn ca_certificate(&mut self, ca_certificate: Certificate) -> &mut Self { - self.cert = Some(ca_certificate); - self + pub fn ca_certificate(self, ca_certificate: Certificate) -> Self { + ClientTlsConfig { + cert: Some(ca_certificate), + ..self + } } /// Sets the client identity to present to the server. /// /// This has no effect if `rustls_client_config` or `openssl_connector` is used to configure /// Rustls or OpenSSL respectively. - pub fn identity(&mut self, identity: Identity) -> &mut Self { - self.identity = Some(identity); - self + pub fn identity(self, identity: Identity) -> Self { + ClientTlsConfig { + identity: Some(identity), + ..self + } } /// Use options specified by the given `SslConnector` to configure TLS. /// /// This overrides all other TLS options set via other means. #[cfg(feature = "openssl")] - pub fn openssl_connector(&mut self, connector: openssl1::ssl::SslConnector) -> &mut Self { - self.openssl_raw = Some(connector); - self + pub fn openssl_connector(self, connector: openssl1::ssl::SslConnector) -> Self { + ClientTlsConfig { + openssl_raw: Some(connector), + ..self + } } /// Use options specified by the given `ClientConfig` to configure TLS. /// /// This overrides all other TLS options set via other means. #[cfg(feature = "rustls")] - pub fn rustls_client_config( - &mut self, - config: tokio_rustls::rustls::ClientConfig, - ) -> &mut Self { - self.rustls_raw = Some(config); - self + pub fn rustls_client_config(self, config: tokio_rustls::rustls::ClientConfig) -> Self { + ClientTlsConfig { + rustls_raw: Some(config), + ..self + } } fn tls_connector(&self, uri: Uri) -> Result { diff --git a/tonic/src/transport/server.rs b/tonic/src/transport/server.rs index 9d1da6076..c86ea3da4 100644 --- a/tonic/src/transport/server.rs +++ b/tonic/src/transport/server.rs @@ -83,9 +83,11 @@ impl Server { impl Server { /// Configure TLS for this server. #[cfg(feature = "tls")] - pub fn tls_config(&mut self, tls_config: &ServerTlsConfig) -> &mut Self { - self.tls = Some(tls_config.tls_acceptor().unwrap()); - self + pub fn tls_config(self, tls_config: ServerTlsConfig) -> Self { + Server { + tls: Some(tls_config.tls_acceptor().unwrap()), + ..self + } } /// Set the concurrency limit applied to on requests inbound per connection. @@ -96,9 +98,11 @@ impl Server { /// # let mut builder = Server::builder(); /// builder.concurrency_limit_per_connection(32); /// ``` - pub fn concurrency_limit_per_connection(&mut self, limit: usize) -> &mut Self { - self.concurrency_limit = Some(limit); - self + pub fn concurrency_limit_per_connection(self, limit: usize) -> Self { + Server { + concurrency_limit: Some(limit), + ..self + } } // FIXME: tower-timeout currentlly uses `From` instead of `Into` for the error @@ -114,17 +118,21 @@ impl Server { /// Default is 65,535 /// /// [spec]: https://http2.github.io/http2-spec/#SETTINGS_INITIAL_WINDOW_SIZE - pub fn initial_stream_window_size(&mut self, sz: impl Into>) -> &mut Self { - self.init_stream_window_size = sz.into(); - self + pub fn initial_stream_window_size(self, sz: impl Into>) -> Self { + Server { + init_stream_window_size: sz.into(), + ..self + } } /// Sets the max connection-level flow control for HTTP2 /// /// Default is 65,535 - pub fn initial_connection_window_size(&mut self, sz: impl Into>) -> &mut Self { - self.init_connection_window_size = sz.into(); - self + pub fn initial_connection_window_size(self, sz: impl Into>) -> Self { + Server { + init_connection_window_size: sz.into(), + ..self + } } /// Sets the [`SETTINGS_MAX_CONCURRENT_STREAMS`][spec] option for HTTP2 @@ -133,9 +141,11 @@ impl Server { /// Default is no limit (`None`). /// /// [spec]: https://http2.github.io/http2-spec/#SETTINGS_MAX_CONCURRENT_STREAMS - pub fn max_concurrent_streams(&mut self, max: impl Into>) -> &mut Self { - self.max_concurrent_streams = max.into(); - self + pub fn max_concurrent_streams(self, max: impl Into>) -> Self { + Server { + max_concurrent_streams: max.into(), + ..self + } } /// Intercept the execution of gRPC methods. @@ -149,7 +159,7 @@ impl Server { /// svc.call(req) /// }); /// ``` - pub fn interceptor_fn(&mut self, f: F) -> &mut Self + pub fn interceptor_fn(self, f: F) -> Self where F: Fn(&mut BoxService, Request) -> Out + Send + Sync + 'static, Out: Future, crate::Error>> + Send + 'static, @@ -160,8 +170,11 @@ impl Server { tower::service_fn(move |req| f(&mut s, req)) }); let layer = Stack::new(interceptor, layer_fn(BoxService::new)); - self.interceptor = Some(Arc::new(layer)); - self + + Server { + interceptor: Some(Arc::new(layer)), + ..self + } } /// Create a router with the `S` typed service as the first service. @@ -366,24 +379,30 @@ impl ServerTlsConfig { } /// Sets the [`Identity`] of the server. - pub fn identity(&mut self, identity: Identity) -> &mut Self { - self.identity = Some(identity); - self + pub fn identity(self, identity: Identity) -> Self { + ServerTlsConfig { + identity: Some(identity), + ..self + } } /// Sets a certificate against which to validate client TLS certificates. - pub fn client_ca_root(&mut self, cert: Certificate) -> &mut Self { - self.client_ca_root = Some(cert); - self + pub fn client_ca_root(self, cert: Certificate) -> Self { + ServerTlsConfig { + client_ca_root: Some(cert), + ..self + } } /// Use options specified by the given `SslAcceptor` to configure TLS. /// /// This overrides all other TLS options set via other means. #[cfg(feature = "openssl")] - pub fn openssl_connector(&mut self, acceptor: openssl1::ssl::SslAcceptor) -> &mut Self { - self.openssl_raw = Some(acceptor); - self + pub fn openssl_connector(self, acceptor: openssl1::ssl::SslAcceptor) -> Self { + ServerTlsConfig { + openssl_raw: Some(acceptor), + ..self + } } /// Use options specified by the given `ServerConfig` to configure TLS.