Skip to content

Commit e2203ca

Browse files
committed
add promise to ProxyConnectHandler init, misc.
- Add missing `context.fireChannelActive()`,`context.fireChannelInactive()` to pass along events down the pipeline. - Make some members private
1 parent 014dbdb commit e2203ca

File tree

2 files changed

+32
-26
lines changed

2 files changed

+32
-26
lines changed

Sources/NIOExtras/HTTP1ProxyConnectHandler.swift

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
import NIOCore
1616
import NIOHTTP1
1717

18-
public final class HTTP1ProxyConnectHandler: ChannelDuplexHandler, RemovableChannelHandler {
18+
public final class NIOHTTP1ProxyConnectHandler: ChannelDuplexHandler, RemovableChannelHandler {
1919
public typealias OutboundIn = Never
2020
public typealias OutboundOut = HTTPClientRequestPart
2121
public typealias InboundIn = HTTPClientResponsePart
2222

23-
enum State {
23+
private enum State {
2424
// transitions to `.connectSent` or `.failed`
2525
case initialized
2626
// transitions to `.headReceived` or `.failed`
@@ -39,25 +39,29 @@ public final class HTTP1ProxyConnectHandler: ChannelDuplexHandler, RemovableChan
3939
private let targetPort: Int
4040
private let headers: HTTPHeaders
4141
private let deadline: NIODeadline
42-
43-
private var proxyEstablishedPromise: EventLoopPromise<Void>?
44-
var proxyEstablishedFuture: EventLoopFuture<Void>? {
45-
return self.proxyEstablishedPromise?.futureResult
46-
}
47-
48-
init(targetHost: String,
42+
private let promise: EventLoopPromise<Void>?
43+
44+
/// Creates a new ``NIOHTTP1ProxyConnectHandler`` that issues a CONNECT request to a proxy server
45+
/// and instructs the server to connect to `targetHost`.
46+
/// - Parameters:
47+
/// - targetHost: The desired end point host
48+
/// - targetPort: The port to be used when connecting to `targetHost`
49+
/// - headers: Headers to supply to the proxy server as part of the CONNECT request
50+
/// - deadline: Deadline for the CONNECT request
51+
/// - promise: Promise with which the result of the connect operation is communicated
52+
public init(targetHost: String,
4953
targetPort: Int,
5054
headers: HTTPHeaders,
51-
deadline: NIODeadline) {
55+
deadline: NIODeadline,
56+
promise: EventLoopPromise<Void>?) {
5257
self.targetHost = targetHost
5358
self.targetPort = targetPort
5459
self.headers = headers
5560
self.deadline = deadline
61+
self.promise = promise
5662
}
5763

5864
public func handlerAdded(context: ChannelHandlerContext) {
59-
self.proxyEstablishedPromise = context.eventLoop.makePromise(of: Void.self)
60-
6165
self.sendConnect(context: context)
6266
}
6367

@@ -67,12 +71,13 @@ public final class HTTP1ProxyConnectHandler: ChannelDuplexHandler, RemovableChan
6771
break
6872
case .initialized, .connectSent, .headReceived:
6973
self.state = .failed(Error.noResult)
70-
self.proxyEstablishedPromise?.fail(Error.noResult)
74+
self.promise?.fail(Error.noResult)
7175
}
7276
}
7377

7478
public func channelActive(context: ChannelHandlerContext) {
7579
self.sendConnect(context: context)
80+
context.fireChannelActive()
7681
}
7782

7883
public func channelInactive(context: ChannelHandlerContext) {
@@ -86,6 +91,7 @@ public final class HTTP1ProxyConnectHandler: ChannelDuplexHandler, RemovableChan
8691
case .failed, .completed:
8792
break
8893
}
94+
context.fireChannelInactive()
8995
}
9096

9197
public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise<Void>?) {
@@ -176,7 +182,7 @@ public final class HTTP1ProxyConnectHandler: ChannelDuplexHandler, RemovableChan
176182
case .headReceived(let timeout):
177183
timeout.cancel()
178184
self.state = .completed
179-
self.proxyEstablishedPromise?.succeed(())
185+
self.promise?.succeed(())
180186

181187
case .failed:
182188
// ran into an error before... ignore this one
@@ -188,7 +194,7 @@ public final class HTTP1ProxyConnectHandler: ChannelDuplexHandler, RemovableChan
188194

189195
private func failWithError(_ error: Error, context: ChannelHandlerContext, closeConnection: Bool = true) {
190196
self.state = .failed(error)
191-
self.proxyEstablishedPromise?.fail(error)
197+
self.promise?.fail(error)
192198
context.fireErrorCaught(error)
193199
if closeConnection {
194200
context.close(mode: .all, promise: nil)

Tests/NIOExtrasTests/HTTP1ProxyConnectHandlerTests.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class HTTP1ProxyConnectHandlerTests: XCTestCase {
2626
let socketAddress = try! SocketAddress.makeAddressResolvingHost("localhost", port: 0)
2727
XCTAssertNoThrow(try embedded.connect(to: socketAddress).wait())
2828

29-
let proxyConnectHandler = HTTP1ProxyConnectHandler(
29+
let proxyConnectHandler = NIOHTTP1ProxyConnectHandler(
3030
targetHost: "swift.org",
3131
targetPort: 443,
3232
headers: [:],
@@ -59,7 +59,7 @@ class HTTP1ProxyConnectHandlerTests: XCTestCase {
5959
let socketAddress = try! SocketAddress.makeAddressResolvingHost("localhost", port: 0)
6060
XCTAssertNoThrow(try embedded.connect(to: socketAddress).wait())
6161

62-
let proxyConnectHandler = HTTP1ProxyConnectHandler(
62+
let proxyConnectHandler = NIOHTTP1ProxyConnectHandler(
6363
targetHost: "swift.org",
6464
targetPort: 443,
6565
headers: ["proxy-authorization" : "Basic abc123"],
@@ -92,7 +92,7 @@ class HTTP1ProxyConnectHandlerTests: XCTestCase {
9292
let socketAddress = try! SocketAddress.makeAddressResolvingHost("localhost", port: 0)
9393
XCTAssertNoThrow(try embedded.connect(to: socketAddress).wait())
9494

95-
let proxyConnectHandler = HTTP1ProxyConnectHandler(
95+
let proxyConnectHandler = NIOHTTP1ProxyConnectHandler(
9696
targetHost: "swift.org",
9797
targetPort: 443,
9898
headers: [:],
@@ -115,13 +115,13 @@ class HTTP1ProxyConnectHandlerTests: XCTestCase {
115115
let responseHead = HTTPResponseHead(version: .http1_1, status: .internalServerError)
116116
// answering with 500 should lead to a triggered error in pipeline
117117
XCTAssertThrowsError(try embedded.writeInbound(HTTPClientResponsePart.head(responseHead))) {
118-
XCTAssertEqual($0 as? HTTP1ProxyConnectHandler.Error, .invalidProxyResponse)
118+
XCTAssertEqual($0 as? NIOHTTP1ProxyConnectHandler.Error, .invalidProxyResponse)
119119
}
120120
XCTAssertFalse(embedded.isActive, "Channel should be closed in response to the error")
121121
XCTAssertNoThrow(try embedded.writeInbound(HTTPClientResponsePart.end(nil)))
122122

123123
XCTAssertThrowsError(try XCTUnwrap(proxyConnectHandler.proxyEstablishedFuture).wait()) {
124-
XCTAssertEqual($0 as? HTTP1ProxyConnectHandler.Error, .invalidProxyResponse)
124+
XCTAssertEqual($0 as? NIOHTTP1ProxyConnectHandler.Error, .invalidProxyResponse)
125125
}
126126
}
127127

@@ -131,7 +131,7 @@ class HTTP1ProxyConnectHandlerTests: XCTestCase {
131131
let socketAddress = try! SocketAddress.makeAddressResolvingHost("localhost", port: 0)
132132
XCTAssertNoThrow(try embedded.connect(to: socketAddress).wait())
133133

134-
let proxyConnectHandler = HTTP1ProxyConnectHandler(
134+
let proxyConnectHandler = NIOHTTP1ProxyConnectHandler(
135135
targetHost: "swift.org",
136136
targetPort: 443,
137137
headers: [:],
@@ -154,13 +154,13 @@ class HTTP1ProxyConnectHandlerTests: XCTestCase {
154154
let responseHead = HTTPResponseHead(version: .http1_1, status: .proxyAuthenticationRequired)
155155
// answering with 500 should lead to a triggered error in pipeline
156156
XCTAssertThrowsError(try embedded.writeInbound(HTTPClientResponsePart.head(responseHead))) {
157-
XCTAssertEqual($0 as? HTTP1ProxyConnectHandler.Error, .proxyAuthenticationRequired)
157+
XCTAssertEqual($0 as? NIOHTTP1ProxyConnectHandler.Error, .proxyAuthenticationRequired)
158158
}
159159
XCTAssertFalse(embedded.isActive, "Channel should be closed in response to the error")
160160
XCTAssertNoThrow(try embedded.writeInbound(HTTPClientResponsePart.end(nil)))
161161

162162
XCTAssertThrowsError(try XCTUnwrap(proxyConnectHandler.proxyEstablishedFuture).wait()) {
163-
XCTAssertEqual($0 as? HTTP1ProxyConnectHandler.Error, .proxyAuthenticationRequired)
163+
XCTAssertEqual($0 as? NIOHTTP1ProxyConnectHandler.Error, .proxyAuthenticationRequired)
164164
}
165165
}
166166

@@ -170,7 +170,7 @@ class HTTP1ProxyConnectHandlerTests: XCTestCase {
170170
let socketAddress = try! SocketAddress.makeAddressResolvingHost("localhost", port: 0)
171171
XCTAssertNoThrow(try embedded.connect(to: socketAddress).wait())
172172

173-
let proxyConnectHandler = HTTP1ProxyConnectHandler(
173+
let proxyConnectHandler = NIOHTTP1ProxyConnectHandler(
174174
targetHost: "swift.org",
175175
targetPort: 443,
176176
headers: [:],
@@ -193,13 +193,13 @@ class HTTP1ProxyConnectHandlerTests: XCTestCase {
193193
XCTAssertNoThrow(try embedded.writeInbound(HTTPClientResponsePart.head(responseHead)))
194194
// answering with a body should lead to a triggered error in pipeline
195195
XCTAssertThrowsError(try embedded.writeInbound(HTTPClientResponsePart.body(ByteBuffer(bytes: [0, 1, 2, 3])))) {
196-
XCTAssertEqual($0 as? HTTP1ProxyConnectHandler.Error, .invalidProxyResponse)
196+
XCTAssertEqual($0 as? NIOHTTP1ProxyConnectHandler.Error, .invalidProxyResponse)
197197
}
198198
XCTAssertEqual(embedded.isActive, false)
199199
XCTAssertNoThrow(try embedded.writeInbound(HTTPClientResponsePart.end(nil)))
200200

201201
XCTAssertThrowsError(try XCTUnwrap(proxyConnectHandler.proxyEstablishedFuture).wait()) {
202-
XCTAssertEqual($0 as? HTTP1ProxyConnectHandler.Error, .invalidProxyResponse)
202+
XCTAssertEqual($0 as? NIOHTTP1ProxyConnectHandler.Error, .invalidProxyResponse)
203203
}
204204
}
205205
}

0 commit comments

Comments
 (0)