diff --git a/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/Element.java b/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/Element.java index f6bdaec9eb3..cc1791e80f0 100644 --- a/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/Element.java +++ b/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/Element.java @@ -31,6 +31,8 @@ class Element { } private final BitSet excluded; + private final boolean allowEmpty; + private boolean seenWhitespace; private boolean leadingSpace; private boolean readingValue; @@ -40,11 +42,11 @@ class Element { @Nullable private String value; static Element createKeyElement() { - return new Element(EXCLUDED_KEY_CHARS); + return new Element(EXCLUDED_KEY_CHARS, /* allowEmpty= */ false); } static Element createValueElement() { - return new Element(EXCLUDED_VALUE_CHARS); + return new Element(EXCLUDED_VALUE_CHARS, /* allowEmpty= */ true); } /** @@ -52,8 +54,9 @@ static Element createValueElement() { * * @param excluded characters that are not allowed for this type of an element */ - private Element(BitSet excluded) { + private Element(BitSet excluded, boolean allowEmpty) { this.excluded = excluded; + this.allowEmpty = allowEmpty; reset(0); } @@ -68,6 +71,7 @@ void reset(int start) { readingValue = false; trailingSpace = false; value = null; + seenWhitespace = false; } boolean tryTerminating(int index, String header) { @@ -77,6 +81,9 @@ boolean tryTerminating(int index, String header) { if (this.trailingSpace) { setValue(header); return true; + } else if (allowEmpty && !seenWhitespace) { + this.value = ""; + return true; } else { // leading spaces - no content, invalid return false; @@ -110,6 +117,8 @@ private static boolean isWhitespace(char character) { private boolean tryNextWhitespace(int index) { if (readingValue) { markEnd(index); + } else { + seenWhitespace = true; } return true; } diff --git a/api/all/src/test/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagatorTest.java b/api/all/src/test/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagatorTest.java index 93f4e25f1a6..c030a258446 100644 --- a/api/all/src/test/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagatorTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagatorTest.java @@ -208,7 +208,8 @@ void extract_value_empty() { Context result = propagator.extract(Context.root(), ImmutableMap.of("baggage", "key1="), getter); - assertThat(Baggage.fromContext(result)).isEqualTo(Baggage.empty()); + Baggage expectedBaggage = Baggage.builder().put("key1", "").build(); + assertThat(Baggage.fromContext(result)).isEqualTo(expectedBaggage); } @Test @@ -219,7 +220,9 @@ void extract_value_empty_withMetadata() { propagator.extract( Context.root(), ImmutableMap.of("baggage", "key1=;metakey=metaval"), getter); - assertThat(Baggage.fromContext(result)).isEqualTo(Baggage.empty()); + Baggage expectedBaggage = + Baggage.builder().put("key1", "", BaggageEntryMetadata.create("metakey=metaval")).build(); + assertThat(Baggage.fromContext(result)).isEqualTo(expectedBaggage); } @Test