Skip to content

Commit fa3265f

Browse files
authored
Merge pull request #146 from slashmo/feature/http-headers-extractor-multiple-values
Join multiple header values in HTTPHeadersExtractor
2 parents a0a55b4 + efa2bea commit fa3265f

File tree

4 files changed

+102
-1
lines changed

4 files changed

+102
-1
lines changed

Sources/NIOInstrumentation/HTTPHeadersCarrier.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,24 @@
1414
import Instrumentation
1515
import NIOHTTP1
1616

17+
/// Extracts header values from `NIOHTTP1.HTTPHeaders`.
18+
///
19+
/// If multiple entries exist for a given key, their values will be joined according to
20+
/// [HTTP RFC 7230: Field Order](https://httpwg.org/specs/rfc7230.html#rfc.section.3.2.2), returning a comma-separated list
21+
/// of the values.
1722
public struct HTTPHeadersExtractor: ExtractorProtocol {
1823
public init() {}
1924

2025
public func extract(key: String, from headers: HTTPHeaders) -> String? {
21-
return headers.first(name: key)
26+
return headers
27+
.lazy
28+
.filter { $0.name == key }
29+
.map { $0.value }
30+
.joined(separator: ",")
2231
}
2332
}
2433

34+
/// Injects values into `NIOHTTP1.HTTPHeaders`.
2535
public struct HTTPHeadersInjector: InjectorProtocol {
2636
public init() {}
2737

Tests/LinuxMain.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class LinuxMainRunnerImpl: LinuxMainRunner {
3737
XCTMain([
3838
testCase(BaggageContextInboundHTTPHandlerTests.allTests),
3939
testCase(BaggageContextOutboundHTTPHandlerTests.allTests),
40+
testCase(HTTPHeadersCarrierTests.allTests),
4041
testCase(InstrumentTests.allTests),
4142
testCase(InstrumentationSystemTests.allTests),
4243
testCase(SpanAttributeSemanticsTests.allTests),
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift Distributed Tracing open source project
4+
//
5+
// Copyright (c) 2020 Moritz Lang and the Swift Tracing project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
//
10+
// SPDX-License-Identifier: Apache-2.0
11+
//
12+
//===----------------------------------------------------------------------===//
13+
//
14+
// HTTPHeadersCarrierTests+XCTest.swift
15+
//
16+
import XCTest
17+
///
18+
/// NOTE: This file was generated by generate_linux_tests.rb
19+
///
20+
/// Do NOT edit this file directly as it will be regenerated automatically when needed.
21+
///
22+
23+
extension HTTPHeadersCarrierTests {
24+
25+
@available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings")
26+
static var allTests : [(String, (HTTPHeadersCarrierTests) -> () throws -> Void)] {
27+
return [
28+
("testExtractSingleHeader", testExtractSingleHeader),
29+
("testExtractMultipleHeadersOfSameName", testExtractMultipleHeadersOfSameName),
30+
]
31+
}
32+
}
33+
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift Distributed Tracing open source project
4+
//
5+
// Copyright (c) 2020 Moritz Lang and the Swift Tracing project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
//
10+
// SPDX-License-Identifier: Apache-2.0
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
import NIOHTTP1
15+
import NIOInstrumentation
16+
import XCTest
17+
18+
final class HTTPHeadersCarrierTests: XCTestCase {
19+
func testExtractSingleHeader() {
20+
let headers: HTTPHeaders = [
21+
"tracestate": "vendorname1=opaqueValue1,vendorname2=opaqueValue2",
22+
"traceparent": "00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01",
23+
]
24+
25+
let extractor = HTTPHeadersExtractor()
26+
27+
XCTAssertEqual(
28+
extractor.extract(key: "tracestate", from: headers),
29+
"vendorname1=opaqueValue1,vendorname2=opaqueValue2"
30+
)
31+
32+
XCTAssertEqual(
33+
extractor.extract(key: "traceparent", from: headers),
34+
"00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01"
35+
)
36+
}
37+
38+
func testExtractMultipleHeadersOfSameName() {
39+
let headers: HTTPHeaders = [
40+
"tracestate": "vendorname1=opaqueValue1",
41+
"traceparent": "00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01",
42+
"tracestate": "vendorname2=opaqueValue2",
43+
]
44+
45+
let extractor = HTTPHeadersExtractor()
46+
47+
XCTAssertEqual(
48+
extractor.extract(key: "tracestate", from: headers),
49+
"vendorname1=opaqueValue1,vendorname2=opaqueValue2"
50+
)
51+
52+
XCTAssertEqual(
53+
extractor.extract(key: "traceparent", from: headers),
54+
"00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01"
55+
)
56+
}
57+
}

0 commit comments

Comments
 (0)