Skip to content

Commit

Permalink
header values are be expected to be W3C baggage encoded (#6164)
Browse files Browse the repository at this point in the history
Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com>
Co-authored-by: Jack Berg <jberg@newrelic.com>
  • Loading branch information
3 people committed Feb 1, 2024
1 parent 8684882 commit ecbd1f9
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Locale;
import java.util.Map;
Expand Down Expand Up @@ -89,7 +91,17 @@ public static void configureOtlpExporterBuilder(
if (headers.isEmpty()) {
headers = config.getMap("otel.exporter.otlp.headers");
}
headers.forEach(addHeader);
for (Map.Entry<String, String> entry : headers.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
try {
// headers are encoded as URL - see
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#specifying-headers-via-environment-variables
addHeader.accept(key, URLDecoder.decode(value, StandardCharsets.UTF_8.displayName()));
} catch (Exception e) {
throw new ConfigurationException("Cannot decode header value: " + value, e);
}
}

String compression = config.getString("otel.exporter.otlp." + dataType + ".compression");
if (compression == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand Down Expand Up @@ -219,7 +220,8 @@ void createExporter_HttpWithGeneralConfiguration() throws CertificateEncodingExc
config.put("otel.exporter.otlp.certificate", certificatePath);
config.put("otel.exporter.otlp.client.key", clientKeyPath);
config.put("otel.exporter.otlp.client.certificate", clientCertificatePath);
config.put("otel.exporter.otlp.headers", "header-key=header-value");
config.put(
"otel.exporter.otlp.headers", "header-key1=header%20value1,header-key2=header value2");
config.put("otel.exporter.otlp.compression", "gzip");
config.put("otel.exporter.otlp.timeout", "15s");
config.put("otel.experimental.exporter.otlp.retry.enabled", "true");
Expand All @@ -229,7 +231,8 @@ void createExporter_HttpWithGeneralConfiguration() throws CertificateEncodingExc
assertThat(exporter).isInstanceOf(OtlpHttpSpanExporter.class);
verify(httpBuilder, times(1)).build();
verify(httpBuilder).setEndpoint("https://localhost:443/v1/traces");
verify(httpBuilder).addHeader("header-key", "header-value");
verify(httpBuilder).addHeader("header-key1", "header value1");
verify(httpBuilder).addHeader("header-key2", "header value2");
verify(httpBuilder).setCompression("gzip");
verify(httpBuilder).setTimeout(Duration.ofSeconds(15));
verify(httpBuilder).setTrustedCertificates(serverTls.certificate().getEncoded());
Expand Down Expand Up @@ -274,4 +277,16 @@ void createExporter_HttpWithSignalConfiguration() throws CertificateEncodingExce
}
Mockito.verifyNoInteractions(grpcBuilder);
}

@Test
void createExporter_decodingError() {
Assertions.assertThatThrownBy(
() -> {
provider.createExporter(
DefaultConfigProperties.createFromMap(
Collections.singletonMap("otel.exporter.otlp.headers", "header-key=%-1")));
})
.isInstanceOf(ConfigurationException.class)
.hasMessage("Cannot decode header value: %-1");
}
}

0 comments on commit ecbd1f9

Please sign in to comment.