Skip to content

Commit 721ede5

Browse files
authored
Handle mixed case cloud propagator headers (#112)
* Handle mixed case cloud propagator headers * update CHANGELOG
1 parent 561c1a3 commit 721ede5

4 files changed

Lines changed: 46 additions & 5 deletions

File tree

docs-requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ Sphinx
33
sphinx-autodoc-typehints
44
opentelemetry-api
55
opentelemetry-sdk
6-
./opentelemetry-exporter-google-cloud
7-
./opentelemetry-tools-google-cloud
6+
-e ./opentelemetry-exporter-google-cloud
7+
-e ./opentelemetry-tools-google-cloud

opentelemetry-tools-google-cloud/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
## Unreleased
44

5+
- Handle mixed case cloud propagator headers
6+
([#112](https://github.com/GoogleCloudPlatform/opentelemetry-operations-python/pull/112))
7+
58
## Version 0.17b0
69

710
Released 2021-02-04

opentelemetry-tools-google-cloud/src/opentelemetry/tools/cloud_trace_propagator.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
get_hexadecimal_trace_id,
2626
)
2727

28-
_TRACE_CONTEXT_HEADER_NAME = "X-Cloud-Trace-Context"
28+
_TRACE_CONTEXT_HEADER_NAME = "x-cloud-trace-context"
2929
_TRACE_CONTEXT_HEADER_FORMAT = r"(?P<trace_id>[0-9a-f]{32})\/(?P<span_id>[\d]{1,20});o=(?P<trace_flags>\d+)"
3030
_TRACE_CONTEXT_HEADER_RE = re.compile(_TRACE_CONTEXT_HEADER_FORMAT)
3131
_FIELDS = {_TRACE_CONTEXT_HEADER_NAME}
@@ -37,18 +37,36 @@ class CloudTraceFormatPropagator(textmap.TextMapPropagator):
3737
Cloud format.
3838
"""
3939

40+
@staticmethod
41+
def _get_header_value(
42+
getter: textmap.Getter[textmap.TextMapPropagatorT],
43+
carrier: textmap.TextMapPropagatorT,
44+
) -> typing.Optional[str]:
45+
# first try all lowercase header
46+
header = getter.get(carrier, _TRACE_CONTEXT_HEADER_NAME)
47+
if header:
48+
return header[0]
49+
50+
# otherwise try to find in keys for mixed case
51+
for key in getter.keys(carrier):
52+
if key.lower() == _TRACE_CONTEXT_HEADER_NAME:
53+
header = getter.get(carrier, key)
54+
if header:
55+
return header[0]
56+
return None
57+
4058
def extract(
4159
self,
4260
getter: textmap.Getter[textmap.TextMapPropagatorT],
4361
carrier: textmap.TextMapPropagatorT,
4462
context: typing.Optional[Context] = None,
4563
) -> Context:
46-
header = getter.get(carrier, _TRACE_CONTEXT_HEADER_NAME)
64+
header = self._get_header_value(getter, carrier)
4765

4866
if not header:
4967
return trace.set_span_in_context(trace.INVALID_SPAN, context)
5068

51-
match = re.fullmatch(_TRACE_CONTEXT_HEADER_RE, header[0])
69+
match = re.fullmatch(_TRACE_CONTEXT_HEADER_RE, header)
5270
if match is None:
5371
return trace.set_span_in_context(trace.INVALID_SPAN, context)
5472

opentelemetry-tools-google-cloud/tests/test_cloud_trace_propagator.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,26 @@ def test_valid_header(self):
105105
self.assertEqual(new_span_context.trace_flags, TraceFlags(0))
106106
self.assertTrue(new_span_context.is_remote)
107107

108+
def test_mixed_case_header_key(self):
109+
header_value = "{}/{};o=1".format(
110+
get_hexadecimal_trace_id(self.valid_trace_id), self.valid_span_id
111+
)
112+
113+
for header_key in (
114+
"X-Cloud-Trace-Context",
115+
"X-ClOuD-tRace-ConTeXt",
116+
"X-CLOUD-TRACE-CONTEXT",
117+
):
118+
header_map = {header_key: [header_value]}
119+
new_context = self.propagator.extract(dict_getter, header_map)
120+
new_span_context = trace.get_current_span(
121+
new_context
122+
).get_span_context()
123+
self.assertEqual(new_span_context.trace_id, self.valid_trace_id)
124+
self.assertEqual(new_span_context.span_id, self.valid_span_id)
125+
self.assertEqual(new_span_context.trace_flags, TraceFlags(1))
126+
self.assertTrue(new_span_context.is_remote)
127+
108128
def test_invalid_header_format(self):
109129
header = "invalid_header"
110130
self.assertEqual(

0 commit comments

Comments
 (0)