From 3c5e928bd3e4a7c61193ba67db6195f9f021f369 Mon Sep 17 00:00:00 2001 From: Gus Cairo Date: Mon, 29 Apr 2024 17:25:07 +0100 Subject: [PATCH 1/3] Disable SETTINGS_ENABLE_PUSH HTTP/2 setting --- .../ConnectionPool/HTTP2/HTTP2Connection.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sources/AsyncHTTPClient/ConnectionPool/HTTP2/HTTP2Connection.swift b/Sources/AsyncHTTPClient/ConnectionPool/HTTP2/HTTP2Connection.swift index 2c3c3cc0a..61a030a8b 100644 --- a/Sources/AsyncHTTPClient/ConnectionPool/HTTP2/HTTP2Connection.swift +++ b/Sources/AsyncHTTPClient/ConnectionPool/HTTP2/HTTP2Connection.swift @@ -29,6 +29,8 @@ struct HTTP2PushNotSupportedError: Error {} struct HTTP2ReceivedGoAwayBeforeSettingsError: Error {} final class HTTP2Connection { + private static let defaultSettings = nioDefaultSettings + [HTTP2Setting(parameter: .enablePush, value: 0)] + let channel: Channel let multiplexer: HTTP2StreamMultiplexer let logger: Logger @@ -196,7 +198,7 @@ final class HTTP2Connection { // can be scheduled on this connection. let sync = self.channel.pipeline.syncOperations - let http2Handler = NIOHTTP2Handler(mode: .client, initialSettings: nioDefaultSettings) + let http2Handler = NIOHTTP2Handler(mode: .client, initialSettings: Self.defaultSettings) let idleHandler = HTTP2IdleHandler(delegate: self, logger: self.logger, maximumConnectionUses: self.maximumConnectionUses) try sync.addHandler(http2Handler, position: .last) From 77b34c84d2183128809f7d0949e507e5e0c0b97f Mon Sep 17 00:00:00 2001 From: Gus Cairo Date: Tue, 30 Apr 2024 12:16:41 +0100 Subject: [PATCH 2/3] Add test --- .../HTTP2/HTTP2Connection.swift | 2 +- .../HTTP2ConnectionTests.swift | 23 +++++++++++++++++++ .../HTTPClientTestUtils.swift | 7 ++---- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Sources/AsyncHTTPClient/ConnectionPool/HTTP2/HTTP2Connection.swift b/Sources/AsyncHTTPClient/ConnectionPool/HTTP2/HTTP2Connection.swift index 61a030a8b..ab43558c0 100644 --- a/Sources/AsyncHTTPClient/ConnectionPool/HTTP2/HTTP2Connection.swift +++ b/Sources/AsyncHTTPClient/ConnectionPool/HTTP2/HTTP2Connection.swift @@ -29,7 +29,7 @@ struct HTTP2PushNotSupportedError: Error {} struct HTTP2ReceivedGoAwayBeforeSettingsError: Error {} final class HTTP2Connection { - private static let defaultSettings = nioDefaultSettings + [HTTP2Setting(parameter: .enablePush, value: 0)] + internal static let defaultSettings = nioDefaultSettings + [HTTP2Setting(parameter: .enablePush, value: 0)] let channel: Channel let multiplexer: HTTP2StreamMultiplexer diff --git a/Tests/AsyncHTTPClientTests/HTTP2ConnectionTests.swift b/Tests/AsyncHTTPClientTests/HTTP2ConnectionTests.swift index 15e5cdff2..afce6749f 100644 --- a/Tests/AsyncHTTPClientTests/HTTP2ConnectionTests.swift +++ b/Tests/AsyncHTTPClientTests/HTTP2ConnectionTests.swift @@ -18,6 +18,7 @@ import NIOConcurrencyHelpers import NIOCore import NIOEmbedded import NIOHTTP1 +import NIOHTTP2 import NIOPosix import NIOSSL import NIOTestUtils @@ -338,6 +339,28 @@ class HTTP2ConnectionTests: XCTestCase { } XCTAssertLessThan(retryCount, maxRetries) } + + func testServerPushIsDisabled() { + let embedded = EmbeddedChannel() + let logger = Logger(label: "test.http2.connection") + let connection = HTTP2Connection( + channel: embedded, + connectionID: 0, + decompression: .disabled, + maximumConnectionUses: nil, + delegate: TestHTTP2ConnectionDelegate(), + logger: logger + ) + _ = connection._start0() + + let settingsFrame = HTTP2Frame(streamID: 0, payload: .settings(.settings([]))) + XCTAssertNoThrow(try connection.channel.writeAndFlush(settingsFrame).wait()) + + let pushPromiseFrame = HTTP2Frame(streamID: 0, payload: .pushPromise(.init(pushedStreamID: 1, headers: [:]))) + XCTAssertThrowsError(try connection.channel.writeAndFlush(pushPromiseFrame).wait()) { error in + XCTAssertNotNil(error as? NIOHTTP2Errors.PushInViolationOfSetting) + } + } } class TestConnectionCreator { diff --git a/Tests/AsyncHTTPClientTests/HTTPClientTestUtils.swift b/Tests/AsyncHTTPClientTests/HTTPClientTestUtils.swift index 2d37b1387..7f28040c2 100644 --- a/Tests/AsyncHTTPClientTests/HTTPClientTestUtils.swift +++ b/Tests/AsyncHTTPClientTests/HTTPClientTestUtils.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -import AsyncHTTPClient +@testable import AsyncHTTPClient import Atomics import Foundation import Logging @@ -361,10 +361,7 @@ internal final class HTTPBin where var httpSettings: HTTP2Settings { switch self { case .http1_1, .http2(_, _, nil), .refuse: - return [ - HTTP2Setting(parameter: .maxConcurrentStreams, value: 10), - HTTP2Setting(parameter: .maxHeaderListSize, value: HPACKDecoder.defaultMaxHeaderListSize), - ] + return HTTP2Connection.defaultSettings case .http2(_, _, .some(let customSettings)): return customSettings } From 4e9619dbcac6dbdfb7df27e209f4cb4c63543938 Mon Sep 17 00:00:00 2001 From: Gus Cairo Date: Wed, 1 May 2024 12:40:56 +0100 Subject: [PATCH 3/3] Formatting --- Tests/AsyncHTTPClientTests/HTTP2ConnectionTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/AsyncHTTPClientTests/HTTP2ConnectionTests.swift b/Tests/AsyncHTTPClientTests/HTTP2ConnectionTests.swift index afce6749f..2e82fafba 100644 --- a/Tests/AsyncHTTPClientTests/HTTP2ConnectionTests.swift +++ b/Tests/AsyncHTTPClientTests/HTTP2ConnectionTests.swift @@ -339,7 +339,7 @@ class HTTP2ConnectionTests: XCTestCase { } XCTAssertLessThan(retryCount, maxRetries) } - + func testServerPushIsDisabled() { let embedded = EmbeddedChannel() let logger = Logger(label: "test.http2.connection") @@ -352,7 +352,7 @@ class HTTP2ConnectionTests: XCTestCase { logger: logger ) _ = connection._start0() - + let settingsFrame = HTTP2Frame(streamID: 0, payload: .settings(.settings([]))) XCTAssertNoThrow(try connection.channel.writeAndFlush(settingsFrame).wait())