Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Safer endpoint Uri construction #1553

Merged
merged 2 commits into from Feb 18, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 28 additions & 5 deletions opentelemetry-otlp/src/exporter/http/mod.rs
Expand Up @@ -270,6 +270,15 @@ impl OtlpHttpClient {
}
}

fn build_endpoint_uri(endpoint: &str, path: &str) -> Result<Uri, crate::Error> {
let path = if endpoint.ends_with('/') && path.starts_with('/') {
path.strip_prefix('/').unwrap()
} else {
path
};
format!("{endpoint}{path}").parse().map_err(From::from)
}

// see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#endpoint-urls-for-otlphttp
fn resolve_endpoint(
signal_endpoint_var: &str,
Expand All @@ -287,15 +296,13 @@ fn resolve_endpoint(
// if signal env var is not set, then we check if the OTEL_EXPORTER_OTLP_ENDPOINT is set
if let Some(endpoint) = env::var(OTEL_EXPORTER_OTLP_ENDPOINT)
.ok()
.and_then(|s| format!("{s}{signal_endpoint_path}").parse().ok())
.and_then(|s| build_endpoint_uri(&s, signal_endpoint_path).ok())
{
return Ok(endpoint);
}

// if neither works, we use the one provided in pipeline. If user never provide one, we will use the default one
format!("{provided_or_default_endpoint}{signal_endpoint_path}")
.parse()
.map_err(From::from)
// if neither works, we use the one provided in pipeline. If user never provides one, we will use the default one
build_endpoint_uri(provided_or_default_endpoint, signal_endpoint_path)
}

#[allow(clippy::mutable_key_type)] // http headers are not mutated
Expand All @@ -313,6 +320,8 @@ mod tests {
use crate::exporter::tests::run_env_test;
use crate::{OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT};

use super::build_endpoint_uri;

#[test]
fn test_append_signal_path_to_generic_env() {
run_env_test(
Expand Down Expand Up @@ -374,6 +383,20 @@ mod tests {
});
}

#[test]
fn test_build_endpoint_uri() {
let uri = build_endpoint_uri("https://example.com", "/v1/traces").unwrap();
assert_eq!(uri, "https://example.com/v1/traces");

// Should be no duplicate slahes:
let uri = build_endpoint_uri("https://example.com/", "/v1/traces").unwrap();
assert_eq!(uri, "https://example.com/v1/traces");

// Append paths properly:
let uri = build_endpoint_uri("https://example.com/additional/path/", "/v1/traces").unwrap();
assert_eq!(uri, "https://example.com/additional/path/v1/traces");
}

#[test]
fn test_invalid_uri_in_signal_env_falls_back_to_generic_env() {
run_env_test(
Expand Down