Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ let package = Package(
dependencies: [
.package(url: "https://github.com/apple/swift-nio.git", from: "2.30.0"),
.package(url: "https://github.com/apple/swift-nio-ssl.git", from: "2.14.0"),
.package(url: "https://github.com/apple/swift-nio-http2.git", from: "1.18.0"),
.package(url: "https://github.com/apple/swift-nio-extras.git", from: "1.10.0"),
.package(url: "https://github.com/apple/swift-nio-transport-services.git", from: "1.11.0"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.4.0"),
Expand All @@ -48,6 +49,7 @@ let package = Package(
.product(name: "NIO", package: "swift-nio"),
.product(name: "NIOConcurrencyHelpers", package: "swift-nio"),
.product(name: "NIOSSL", package: "swift-nio-ssl"),
.product(name: "NIOHTTP2", package: "swift-nio-http2"),
"AsyncHTTPClient",
.product(name: "NIOFoundationCompat", package: "swift-nio"),
.product(name: "NIOTestUtils", package: "swift-nio"),
Expand Down
2 changes: 1 addition & 1 deletion Tests/AsyncHTTPClientTests/HTTPClient+SOCKSTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class HTTPClientSOCKSTests: XCTestCase {

var clientGroup: EventLoopGroup!
var serverGroup: EventLoopGroup!
var defaultHTTPBin: HTTPBin!
var defaultHTTPBin: HTTPBin<HTTPBinHandler>!
var defaultClient: HTTPClient!
var backgroundLogStore: CollectEverythingLogHandler.LogStore!

Expand Down
63 changes: 48 additions & 15 deletions Tests/AsyncHTTPClientTests/HTTPClientInternalTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -368,11 +368,49 @@ class HTTPClientInternalTests: XCTestCase {
func didFinishRequest(task: HTTPClient.Task<Response>) throws {}
}

final class WriteAfterFutureSucceedsHandler: ChannelInboundHandler {
typealias InboundIn = HTTPServerRequestPart
typealias OutboundOut = HTTPServerResponsePart

let bodyFuture: EventLoopFuture<Void>
let endFuture: EventLoopFuture<Void>

init(bodyFuture: EventLoopFuture<Void>, endFuture: EventLoopFuture<Void>) {
self.bodyFuture = bodyFuture
self.endFuture = endFuture
}

func channelRead(context: ChannelHandlerContext, data: NIOAny) {
switch self.unwrapInboundIn(data) {
case .head:
let head = HTTPResponseHead(version: HTTPVersion(major: 1, minor: 1), status: .ok)
context.writeAndFlush(wrapOutboundOut(.head(head)), promise: nil)
case .body:
// ignore
break
case .end:
self.bodyFuture.hop(to: context.eventLoop).whenSuccess {
let buffer = context.channel.allocator.buffer(string: "1234")
context.writeAndFlush(self.wrapOutboundOut(.body(.byteBuffer(buffer))), promise: nil)
}

self.endFuture.hop(to: context.eventLoop).whenSuccess {
context.writeAndFlush(self.wrapOutboundOut(.end(nil)), promise: nil)
}
}
}
}

// cannot test with NIOTS as `maxMessagesPerRead` is not supported
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let httpClient = HTTPClient(eventLoopGroupProvider: .shared(eventLoopGroup))
let promise = httpClient.eventLoopGroup.next().makePromise(of: Channel.self)
let httpBin = HTTPBin(channelPromise: promise)
let delegate = BackpressureTestDelegate(eventLoop: httpClient.eventLoopGroup.next())
let httpBin = HTTPBin { _ in
WriteAfterFutureSucceedsHandler(
bodyFuture: delegate.optionsApplied.futureResult,
endFuture: delegate.backpressurePromise.futureResult
)
}

defer {
XCTAssertNoThrow(try httpClient.syncShutdown(requiresCleanClose: true))
Expand All @@ -381,27 +419,22 @@ class HTTPClientInternalTests: XCTestCase {
}

let request = try Request(url: "http://localhost:\(httpBin.port)/custom")
let delegate = BackpressureTestDelegate(eventLoop: httpClient.eventLoopGroup.next())
let future = httpClient.execute(request: request, delegate: delegate).futureResult

let channel = try promise.futureResult.wait()
let requestFuture = httpClient.execute(request: request, delegate: delegate).futureResult

// We need to wait for channel options that limit NIO to sending only one byte at a time.
try delegate.optionsApplied.futureResult.wait()

//
// Send 4 bytes, but only one should be received until the backpressure promise is succeeded.
let buffer = channel.allocator.buffer(string: "1234")
try channel.writeAndFlush(HTTPServerResponsePart.body(.byteBuffer(buffer))).wait()

// Now we wait until message is delivered to client channel pipeline
try delegate.messageReceived.futureResult.wait()
XCTAssertEqual(delegate.reads, 1)

// Succeed the backpressure promise.
delegate.backpressurePromise.succeed(())

try channel.writeAndFlush(HTTPServerResponsePart.end(nil)).wait()
try future.wait()
try requestFuture.wait()

// At this point all other bytes should be delivered.
XCTAssertEqual(delegate.reads, 4)
Expand Down Expand Up @@ -602,7 +635,7 @@ class HTTPClientInternalTests: XCTestCase {
}

func testResponseConnectionCloseGet() throws {
let httpBin = HTTPBin(ssl: false)
let httpBin = HTTPBin(.http1_1())
let httpClient = HTTPClient(eventLoopGroupProvider: .shared(self.clientGroup),
configuration: HTTPClient.Configuration(certificateVerification: .none))
defer {
Expand Down Expand Up @@ -756,14 +789,14 @@ class HTTPClientInternalTests: XCTestCase {
struct NoChannelError: Error {}

let client = HTTPClient(eventLoopGroupProvider: .shared(self.clientGroup))
var maybeServersAndChannels: [(HTTPBin, Channel)]?
var maybeServersAndChannels: [(HTTPBin<HTTPBinHandler>, Channel)]?
XCTAssertNoThrow(maybeServersAndChannels = try (0..<10).map { _ in
let web = HTTPBin()
defer {
XCTAssertNoThrow(try web.shutdown())
}

let req = try! HTTPClient.Request(url: "http://localhost:\(web.serverChannel.localAddress!.port!)/get",
let req = try! HTTPClient.Request(url: "http://localhost:\(web.port)/get",
method: .GET,
body: nil)
var maybeConnection: Connection?
Expand Down Expand Up @@ -847,7 +880,7 @@ class HTTPClientInternalTests: XCTestCase {
XCTAssertNoThrow(try client.syncShutdown())
}

let req = try! HTTPClient.Request(url: "http://localhost:\(web.serverChannel.localAddress!.port!)/get",
let req = try! HTTPClient.Request(url: "http://localhost:\(web.port)/get",
method: .GET,
body: nil)

Expand Down Expand Up @@ -1083,7 +1116,7 @@ class HTTPClientInternalTests: XCTestCase {
let el1 = elg.next()
let el2 = elg.next()

let httpBin = HTTPBin(refusesConnections: true)
let httpBin = HTTPBin(.refuse)
let client = HTTPClient(eventLoopGroupProvider: .shared(elg))

defer {
Expand Down
6 changes: 3 additions & 3 deletions Tests/AsyncHTTPClientTests/HTTPClientNIOTSTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class HTTPClientNIOTSTests: XCTestCase {
func testTLSFailError() {
guard isTestingNIOTS() else { return }

let httpBin = HTTPBin(ssl: true)
let httpBin = HTTPBin(.http1_1(ssl: true))
let httpClient = HTTPClient(eventLoopGroupProvider: .shared(self.clientGroup))
defer {
XCTAssertNoThrow(try httpClient.syncShutdown(requiresCleanClose: true))
Expand All @@ -76,7 +76,7 @@ class HTTPClientNIOTSTests: XCTestCase {

func testConnectionFailError() {
guard isTestingNIOTS() else { return }
let httpBin = HTTPBin(ssl: true)
let httpBin = HTTPBin(.http1_1(ssl: true))
let httpClient = HTTPClient(eventLoopGroupProvider: .shared(self.clientGroup),
configuration: .init(timeout: .init(connect: .milliseconds(100),
read: .milliseconds(100))))
Expand All @@ -96,7 +96,7 @@ class HTTPClientNIOTSTests: XCTestCase {
func testTLSVersionError() {
guard isTestingNIOTS() else { return }
#if canImport(Network)
let httpBin = HTTPBin(ssl: true)
let httpBin = HTTPBin(.http1_1(ssl: true))
var tlsConfig = TLSConfiguration.makeClientConfiguration()
tlsConfig.certificateVerification = .none
tlsConfig.minimumTLSVersion = .tlsv11
Expand Down
Loading