diff --git a/mobile/docs/root/intro/version_history.rst b/mobile/docs/root/intro/version_history.rst index ece69bf8ca8c..b9c964bdb2fc 100644 --- a/mobile/docs/root/intro/version_history.rst +++ b/mobile/docs/root/intro/version_history.rst @@ -7,6 +7,7 @@ Pending Release Breaking changes: - api: replace the `drainConnections()` method with a broader `resetConnectivityState()`. (:issue:`#2225 <2225>`). +- api: disallow setting 'host' header directly (:issue:`#2275 <2275>`) - net: enable happy eyeballs by default (:issue:`#2272 <2272>`) Bugfixes: diff --git a/mobile/library/kotlin/io/envoyproxy/envoymobile/HeadersBuilder.kt b/mobile/library/kotlin/io/envoyproxy/envoymobile/HeadersBuilder.kt index c51f814fa00c..184b2885ac66 100644 --- a/mobile/library/kotlin/io/envoyproxy/envoymobile/HeadersBuilder.kt +++ b/mobile/library/kotlin/io/envoyproxy/envoymobile/HeadersBuilder.kt @@ -77,5 +77,5 @@ open class HeadersBuilder { } private fun isRestrictedHeader(name: String) = name.startsWith(":") || - name.startsWith("x-envoy-mobile") + name.startsWith("x-envoy-mobile") || name == "host" } diff --git a/mobile/library/swift/HeadersBuilder.swift b/mobile/library/swift/HeadersBuilder.swift index 5cbb15288dc3..0217597bd000 100644 --- a/mobile/library/swift/HeadersBuilder.swift +++ b/mobile/library/swift/HeadersBuilder.swift @@ -3,7 +3,7 @@ import Foundation private let kRestrictedPrefixes = [":", "x-envoy-mobile"] private func isRestrictedHeader(name: String) -> Bool { - return kRestrictedPrefixes.contains { name.hasPrefix($0) } + return name == "host" || kRestrictedPrefixes.contains { name.hasPrefix($0) } } /// Base builder class used to construct `Headers` instances. diff --git a/mobile/test/kotlin/io/envoyproxy/envoymobile/RequestHeadersBuilderTest.kt b/mobile/test/kotlin/io/envoyproxy/envoymobile/RequestHeadersBuilderTest.kt index 17a3a44f1159..7fb43c3c59aa 100644 --- a/mobile/test/kotlin/io/envoyproxy/envoymobile/RequestHeadersBuilderTest.kt +++ b/mobile/test/kotlin/io/envoyproxy/envoymobile/RequestHeadersBuilderTest.kt @@ -99,10 +99,12 @@ class RequestHeadersBuilderTest { ) .add(":x-foo", "123") .add("x-envoy-mobile-foo", "abc") + .add("host", "example.com") .build() assertThat(headers.allHeaders()).doesNotContainKey(":x-foo") assertThat(headers.allHeaders()).doesNotContainKey("x-envoy-mobile-foo") + assertThat(headers.allHeaders()).doesNotContainKey("host") } @Test diff --git a/mobile/test/swift/HeadersBuilderTests.swift b/mobile/test/swift/HeadersBuilderTests.swift index 69af7c7cc68f..bf8990026b5a 100644 --- a/mobile/test/swift/HeadersBuilderTests.swift +++ b/mobile/test/swift/HeadersBuilderTests.swift @@ -40,6 +40,21 @@ final class HeadersBuilderTests: XCTestCase { XCTAssertEqual(["x-foo": ["abc"]], headers) } + func testRestrictedHeadersAreNotSettable() { + let headers = RequestHeadersBuilder(method: .get, authority: "example.com", path: "/") + .add(name: "host", value: "example.com") + .set(name: ":scheme", value: ["http"]) + .set(name: ":path", value: ["/nope"]) + .headers + let expected = [ + ":authority": ["example.com"], + ":path": ["/"], + ":method": ["GET"], + ":scheme": ["https"], + ] + XCTAssertEqual(expected, headers) + } + func testBuildersAreEqualIfUnderlyingHeadersAreEqual() { let builder1 = RequestHeadersBuilder(headers: ["x-foo": ["123"], "x-bar": ["abc"]]) let builder2 = RequestHeadersBuilder(headers: ["x-foo": ["123"], "x-bar": ["abc"]])