Line data Source code
1 : #include "source/extensions/tracers/datadog/dict_util.h" 2 : 3 : #include <cstddef> 4 : 5 : #include "envoy/http/header_map.h" 6 : #include "envoy/tracing/trace_context.h" 7 : 8 : #include "absl/strings/str_join.h" 9 : 10 : namespace Envoy { 11 : namespace Extensions { 12 : namespace Tracers { 13 : namespace Datadog { 14 : 15 0 : RequestHeaderWriter::RequestHeaderWriter(Http::RequestHeaderMap& headers) : headers_(headers) {} 16 : 17 : void RequestHeaderWriter::set(datadog::tracing::StringView key, 18 0 : datadog::tracing::StringView value) { 19 0 : headers_.setCopy(Http::LowerCaseString{key}, value); 20 0 : } 21 : 22 : ResponseHeaderReader::ResponseHeaderReader(const Http::ResponseHeaderMap& headers) 23 0 : : headers_(headers) {} 24 : 25 : datadog::tracing::Optional<datadog::tracing::StringView> 26 0 : ResponseHeaderReader::lookup(datadog::tracing::StringView key) const { 27 0 : auto result = headers_.get(Http::LowerCaseString{key}); 28 0 : if (result.empty()) { 29 : // `headers_.get` can return multiple header entries. It conveys 30 : // "not found" by returning zero header entries. 31 0 : return datadog::tracing::nullopt; 32 0 : } 33 : 34 0 : if (result.size() == 1) { 35 0 : return result[0]->value().getStringView(); 36 0 : } 37 : 38 : // There's more than one matching header entry. 39 : // Per RFC 2616, this is the same as if there were only one entry whose 40 : // value is the comma-separated concatenation of the multiple values. 41 : // I don't expect the Agent to repeat response headers, and we don't even 42 : // examine the Agent's response headers, but here's a solution anyway. 43 0 : std::vector<absl::string_view> values; 44 0 : values.reserve(result.size()); 45 0 : for (std::size_t i = 0; i < result.size(); ++i) { 46 0 : values.push_back(result[i]->value().getStringView()); 47 0 : } 48 0 : buffer_ = absl::StrJoin(values, ", "); 49 0 : return buffer_; 50 0 : } 51 : 52 : void ResponseHeaderReader::visit( 53 : const std::function<void(datadog::tracing::StringView key, datadog::tracing::StringView value)>& 54 0 : visitor) const { 55 0 : headers_.iterate([&](const Http::HeaderEntry& entry) { 56 0 : visitor(entry.key().getStringView(), entry.value().getStringView()); 57 0 : return Http::ResponseHeaderMap::Iterate::Continue; 58 0 : }); 59 0 : } 60 : 61 0 : TraceContextReader::TraceContextReader(const Tracing::TraceContext& context) : context_(context) {} 62 : 63 : datadog::tracing::Optional<datadog::tracing::StringView> 64 0 : TraceContextReader::lookup(datadog::tracing::StringView key) const { 65 0 : return context_.get(key); 66 0 : } 67 : 68 : void TraceContextReader::visit( 69 : const std::function<void(datadog::tracing::StringView key, datadog::tracing::StringView value)>& 70 0 : visitor) const { 71 0 : context_.forEach([&](absl::string_view key, absl::string_view value) { 72 0 : visitor(key, value); 73 0 : const bool continue_iterating = true; 74 0 : return continue_iterating; 75 0 : }); 76 0 : } 77 : 78 : } // namespace Datadog 79 : } // namespace Tracers 80 : } // namespace Extensions 81 : } // namespace Envoy