diff --git a/CHANGELOG.md b/CHANGELOG.md index 6987d87..929bd29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Other +- Changed endpoint construction to set origin for compatibility with SNI based servers. + ## [0.9.0](https://github.com/TrueLayer/ginepro/compare/ginepro-v0.8.2...ginepro-v0.8.1) - 2025-07-24 ### Breaking changes diff --git a/ginepro/src/service_definition.rs b/ginepro/src/service_definition.rs index 0850d85..1c659d4 100644 --- a/ginepro/src/service_definition.rs +++ b/ginepro/src/service_definition.rs @@ -8,6 +8,8 @@ pub struct ServiceDefinition { hostname: String, /// The service port. port: u16, + /// Authority + authority: http::uri::Authority, } impl ServiceDefinition { @@ -21,7 +23,15 @@ impl ServiceDefinition { .map_err(anyhow::Error::from) .context("invalid 'hostname'")?; - Ok(Self { hostname, port }) + let authority = format!("{}:{}", hostname, port) + .parse() + .context("invalid 'hostname'")?; + + Ok(Self { + hostname, + port, + authority, + }) } /// Get the `hostname` part of a `ServiceDefinition`. @@ -29,6 +39,10 @@ impl ServiceDefinition { &self.hostname } + pub(crate) fn authority(&self) -> &http::uri::Authority { + &self.authority + } + /// Get the `port` part of a `ServiceDefinition`. pub fn port(&self) -> u16 { self.port diff --git a/ginepro/src/service_probe.rs b/ginepro/src/service_probe.rs index 0e65708..3def8bc 100644 --- a/ginepro/src/service_probe.rs +++ b/ginepro/src/service_probe.rs @@ -34,6 +34,7 @@ where Lookup: LookupService, { service_definition: ServiceDefinition, + origin: http::uri::Uri, scheme: http::uri::Scheme, dns_lookup: Lookup, probe_interval: tokio::time::Duration, @@ -70,8 +71,10 @@ impl GrpcServiceProbe { config: GrpcServiceProbeConfig, endpoint_reporter: Sender>, ) -> GrpcServiceProbe { + let origin = create_origin(config.service_definition.authority().clone()); Self { service_definition: config.service_definition, + origin, dns_lookup: config.dns_lookup, probe_interval: config.probe_interval, endpoint_timeout: config.endpoint_timeout, @@ -85,9 +88,15 @@ impl GrpcServiceProbe { /// Enable tls for all endpoints. pub fn with_tls(self, tls_config: ClientTlsConfig) -> GrpcServiceProbe { + let mut parts = self.origin.into_parts(); + parts.scheme = Some(http::uri::Scheme::HTTPS); + let origin = parts + .try_into() + .expect("Invalid URI. Impossible as all parts are present"); Self { tls_config: Some(tls_config), scheme: http::uri::Scheme::HTTPS, + origin, ..self } } @@ -215,7 +224,8 @@ impl GrpcServiceProbe { .map_err(|err| { tracing::warn!("endpoint creation error: {:?}", err); }) - .ok()?; + .ok()? + .origin(self.origin.clone()); if let Some(ref tls_config) = self.tls_config { endpoint = endpoint @@ -237,3 +247,13 @@ impl GrpcServiceProbe { Some(endpoint) } } + +fn create_origin(authority: http::uri::Authority) -> http::uri::Uri { + let mut parts = http::uri::Parts::default(); + parts.scheme = Some(http::uri::Scheme::HTTP); + parts.authority = Some(authority); + parts.path_and_query = Some(http::uri::PathAndQuery::from_static("/")); + parts + .try_into() + .expect("Invalid URI. Impossible as all parts are present") +}