@@ -33,7 +33,7 @@ use crate::{
33
33
workflow_handle:: UntypedWorkflowHandle ,
34
34
} ;
35
35
use backoff:: { exponential, ExponentialBackoff , SystemClock } ;
36
- use http:: uri:: InvalidUri ;
36
+ use http:: { uri:: InvalidUri , Uri } ;
37
37
use once_cell:: sync:: OnceCell ;
38
38
use parking_lot:: RwLock ;
39
39
use std:: {
@@ -114,6 +114,14 @@ pub struct ClientOptions {
114
114
/// Retry configuration for the server client. Default is [RetryConfig::default]
115
115
#[ builder( default ) ]
116
116
pub retry_config : RetryConfig ,
117
+
118
+ /// If set, override the origin used when connecting. May be useful in rare situations where tls
119
+ /// verification needs to use a different name from what should be set as the `:authority`
120
+ /// header. If [TlsConfig::domain] is set, and this is not, this will be set to
121
+ /// `https://<domain>`, effectively making the `:authority` header consistent with the domain
122
+ /// override.
123
+ #[ builder( default ) ]
124
+ pub override_origin : Option < Uri > ,
117
125
}
118
126
119
127
/// Configuration options for TLS
@@ -310,6 +318,11 @@ impl ClientOptions {
310
318
{
311
319
let channel = Channel :: from_shared ( self . target_url . to_string ( ) ) ?;
312
320
let channel = self . add_tls_to_channel ( channel) . await ?;
321
+ let channel = if let Some ( origin) = self . override_origin . clone ( ) {
322
+ channel. origin ( origin)
323
+ } else {
324
+ channel
325
+ } ;
313
326
let channel = channel. connect ( ) . await ?;
314
327
let service = ServiceBuilder :: new ( )
315
328
. layer_fn ( |channel| GrpcMetricSvc {
@@ -347,10 +360,7 @@ impl ClientOptions {
347
360
348
361
/// If TLS is configured, set the appropriate options on the provided channel and return it.
349
362
/// Passes it through if TLS options not set.
350
- async fn add_tls_to_channel (
351
- & self ,
352
- channel : Endpoint ,
353
- ) -> Result < Endpoint , tonic:: transport:: Error > {
363
+ async fn add_tls_to_channel ( & self , mut channel : Endpoint ) -> Result < Endpoint , ClientInitError > {
354
364
if let Some ( tls_cfg) = & self . tls_cfg {
355
365
let mut tls = tonic:: transport:: ClientTlsConfig :: new ( ) ;
356
366
@@ -361,6 +371,13 @@ impl ClientOptions {
361
371
362
372
if let Some ( domain) = & tls_cfg. domain {
363
373
tls = tls. domain_name ( domain) ;
374
+
375
+ // This song and dance ultimately is just to make sure the `:authority` header ends
376
+ // up correct on requests while we use TLS. Setting the header directly in our
377
+ // interceptor doesn't work since seemingly it is overridden at some point by
378
+ // something lower level.
379
+ let uri: Uri = format ! ( "https://{}" , domain) . parse ( ) ?;
380
+ channel = channel. origin ( uri) ;
364
381
}
365
382
366
383
if let Some ( client_opts) = & tls_cfg. client_tls_config {
@@ -369,7 +386,7 @@ impl ClientOptions {
369
386
tls = tls. identity ( client_identity) ;
370
387
}
371
388
372
- return channel. tls_config ( tls) ;
389
+ return channel. tls_config ( tls) . map_err ( Into :: into ) ;
373
390
}
374
391
Ok ( channel)
375
392
}
0 commit comments