diff --git a/Sources/KituraNet/ClientRequest.swift b/Sources/KituraNet/ClientRequest.swift index d484123a..e4fabc4d 100644 --- a/Sources/KituraNet/ClientRequest.swift +++ b/Sources/KituraNet/ClientRequest.swift @@ -440,8 +440,13 @@ public class ClientRequest { private func initializeClientBootstrapWithSSL(eventLoopGroup: EventLoopGroup) { if let sslConfig = self.sslConfig { - sslContext = try! SSLContext(configuration: sslConfig) + do { + sslContext = try SSLContext(configuration: sslConfig) + } catch let error { + Log.error("Failed to create SSLContext. Error: \(error)") + } } + bootstrap = ClientBootstrap(group: eventLoopGroup) .channelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEADDR), value: 1) .channelInitializer { channel in diff --git a/Sources/KituraNet/HTTP/HTTPServer.swift b/Sources/KituraNet/HTTP/HTTPServer.swift index 09ae2b5a..f1ab0dd7 100644 --- a/Sources/KituraNet/HTTP/HTTPServer.swift +++ b/Sources/KituraNet/HTTP/HTTPServer.swift @@ -147,7 +147,11 @@ public class HTTPServer : Server { self.port = port if let tlsConfig = tlsConfig { - self.sslContext = try! SSLContext(configuration: tlsConfig) + do { + self.sslContext = try SSLContext(configuration: tlsConfig) + } catch let error { + Log.error("Failed to create SSLContext. Error: \(error)") + } } var upgraders: [HTTPProtocolUpgrader] = [] @@ -256,14 +260,22 @@ public class HTTPServer : Server { return server } - deinit { - try! eventLoopGroup.syncShutdownGracefully() + deinit { + do { + try eventLoopGroup.syncShutdownGracefully() + } catch { + Log.error("Failed to shutdown eventLoopGroup") + } } /// Stop listening for new connections. public func stop() { guard serverChannel != nil else { return } - try! serverChannel.close().wait() + do { + try serverChannel.close().wait() + } catch let error { + Log.error("Failed to close the server channel. Error: \(error)") + } self.state = .stopped } diff --git a/Tests/KituraNetTests/PipeliningTests.swift b/Tests/KituraNetTests/PipeliningTests.swift index 85fb35a2..6a49c07e 100644 --- a/Tests/KituraNetTests/PipeliningTests.swift +++ b/Tests/KituraNetTests/PipeliningTests.swift @@ -18,6 +18,7 @@ import NIO import NIOHTTP1 import Dispatch import XCTest +import LoggerAPI @testable import KituraNet func randomNumber(limit: Int) -> Int { @@ -45,10 +46,16 @@ class PipeliningTests : KituraNetTest { func testPipelining() { let server = HTTPServer() server.delegate = Delegate() - try! server.listen(on: 0) + do { + try server.listen(on: 0) + } catch let error { + Log.error("Server failed to listen. Error: \(error)") + } + let expectation = self.expectation(description: "test pipelining") let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) - let clientChannel = try! ClientBootstrap(group: group) + do { + let clientChannel = try ClientBootstrap(group: group) .channelInitializer { channel in channel.pipeline.addHTTPClientHandlers().then { channel.pipeline.add(handler: PipelinedRequestsHandler(with: expectation)) @@ -56,13 +63,16 @@ class PipeliningTests : KituraNetTest { } .channelOption(ChannelOptions.socket(IPPROTO_TCP, TCP_NODELAY), value: 1) .connect(host: "localhost", port: server.port!).wait() - let request = HTTPRequestHead(version: HTTPVersion(major: 1, minor:1), method: .GET, uri: "/") - for _ in 0...4 { + let request = HTTPRequestHead(version: HTTPVersion(major: 1, minor:1), method: .GET, uri: "/") + for _ in 0...4 { + clientChannel.write(NIOAny(HTTPClientRequestPart.head(request)), promise: nil) + _ = clientChannel.write(NIOAny(HTTPClientRequestPart.end(nil))) + } clientChannel.write(NIOAny(HTTPClientRequestPart.head(request)), promise: nil) - _ = clientChannel.write(NIOAny(HTTPClientRequestPart.end(nil))) + try clientChannel.writeAndFlush(NIOAny(HTTPClientRequestPart.end(nil))).wait() + } catch let error { + Log.error("Error: \(error)") } - clientChannel.write(NIOAny(HTTPClientRequestPart.head(request)), promise: nil) - try! clientChannel.writeAndFlush(NIOAny(HTTPClientRequestPart.end(nil))).wait() waitForExpectations(timeout: 10) } @@ -73,25 +83,35 @@ class PipeliningTests : KituraNetTest { func testPipeliningSpanningPackets() { let server = HTTPServer() server.delegate = Delegate() - try! server.listen(on: 0) + server.delegate = Delegate() + do { + try server.listen(on: 0) + } catch let error { + Log.error("Server failed to listen. Error: \(error)") + } + let expectation = self.expectation(description: "test pipelining spanning packets") let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) - let clientChannel = try! ClientBootstrap(group: group) - .channelInitializer { channel in - channel.pipeline.addHTTPClientHandlers().then { - channel.pipeline.add(handler: PipelinedRequestsHandler(with: expectation)) + do { + let clientChannel = try ClientBootstrap(group: group) + .channelInitializer { channel in + channel.pipeline.addHTTPClientHandlers().then { + channel.pipeline.add(handler: PipelinedRequestsHandler(with: expectation)) + } } + .channelOption(ChannelOptions.socket(IPPROTO_TCP, TCP_NODELAY), value: 1) + .connect(host: "localhost", port: server.port!).wait() + let request = HTTPRequestHead(version: HTTPVersion(major: 1, minor:1), method: .POST, uri: "/") + for _ in 0...5 { + clientChannel.write(NIOAny(HTTPClientRequestPart.head(request)), promise: nil) + let buffer = BufferList() + buffer.append(data: Data(count: randomNumber(limit: 8*1024))) + clientChannel.write(NIOAny(HTTPClientRequestPart.body(.byteBuffer(buffer.byteBuffer))), promise: nil) + _ = clientChannel.writeAndFlush(NIOAny(HTTPClientRequestPart.end(nil))) + usleep(100) } - .channelOption(ChannelOptions.socket(IPPROTO_TCP, TCP_NODELAY), value: 1) - .connect(host: "localhost", port: server.port!).wait() - let request = HTTPRequestHead(version: HTTPVersion(major: 1, minor:1), method: .POST, uri: "/") - for _ in 0...5 { - clientChannel.write(NIOAny(HTTPClientRequestPart.head(request)), promise: nil) - let buffer = BufferList() - buffer.append(data: Data(count: randomNumber(limit: 8*1024))) - clientChannel.write(NIOAny(HTTPClientRequestPart.body(.byteBuffer(buffer.byteBuffer))), promise: nil) - _ = clientChannel.writeAndFlush(NIOAny(HTTPClientRequestPart.end(nil))) - usleep(100) + } catch let error { + Log.error("Error: \(error)") } waitForExpectations(timeout: 10) } @@ -102,7 +122,11 @@ private class Delegate: ServerDelegate { var count = 0 func handle(request: ServerRequest, response: ServerResponse) { response.statusCode = .OK - try! response.end(text: "\(count)") + do { + try response.end(text: "\(count)") + } catch let error { + Log.error("Error: \(error)") + } count += 1 } } diff --git a/Tests/KituraNetTests/RegressionTests.swift b/Tests/KituraNetTests/RegressionTests.swift index 5a97a51f..7117d50f 100644 --- a/Tests/KituraNetTests/RegressionTests.swift +++ b/Tests/KituraNetTests/RegressionTests.swift @@ -21,6 +21,7 @@ import Foundation import NIO import NIOHTTP1 import NIOOpenSSL +import LoggerAPI class RegressionTests: KituraNetTest { @@ -152,7 +153,11 @@ class RegressionTests: KituraNetTest { XCTAssertTrue(serverPort != 0, "Ephemeral server port not set") var goodClient = GoodClient(with: HTTPClient(with: self.expectation(description: "Bad request error"))) - try! goodClient.makeBadRequest(serverPort) + do { + try goodClient.makeBadRequest(serverPort) + } catch { + Log.error("Failed to make bad request") + } waitForExpectations(timeout: 10) } catch { @@ -179,7 +184,11 @@ class RegressionTests: KituraNetTest { } XCTAssertTrue(serverPort != 0, "Ephemeral server port not set") var goodClient = GoodClient(with: HTTPClient(with: self.expectation(description: "Bad request error"))) - try! goodClient.makeGoodRequestFollowedByBadRequest(serverPort) + do { + try goodClient.makeGoodRequestFollowedByBadRequest(serverPort) + } catch { + Log.error("Failed to make request") + } waitForExpectations(timeout: 10) } catch { XCTFail("Couldn't start server") @@ -205,7 +214,11 @@ class RegressionTests: KituraNetTest { } mutating func connect(_ port: Int, expectation: XCTestExpectation) throws { - channel = try! clientBootstrap.connect(host: "localhost", port: port).wait() + do { + channel = try clientBootstrap.connect(host: "localhost", port: port).wait() + } catch { + Log.error("Failed to connect to port \(port)") + } if channel.remoteAddress != nil { expectation.fulfill() } @@ -225,14 +238,24 @@ class RegressionTests: KituraNetTest { } init() throws { - let sslConfig = TLSConfiguration.forClient(certificateVerification: .none) - let sslContext = try! SSLContext(configuration: sslConfig) + var openSSLClientHandler: OpenSSLHandler? { + let sslConfig = TLSConfiguration.forClient(certificateVerification: .none) + do { + let sslContext = try SSLContext(configuration: sslConfig) + return try OpenSSLClientHandler(context: sslContext) + } catch let error { + Log.error("Failed to create OpenSSLClientHandler. Error: \(error)") + return nil + } + } + clientBootstrap = ClientBootstrap(group: MultiThreadedEventLoopGroup(numberOfThreads: 1)) .channelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEADDR), value: 1) .channelInitializer { channel in - channel.pipeline.add(handler: try! OpenSSLClientHandler(context: sslContext)).then { - channel.pipeline.addHTTPClientHandlers() + if let openSSLClientHandler = openSSLClientHandler { + _ = channel.pipeline.add(handler: openSSLClientHandler) } + return channel.pipeline.addHTTPClientHandlers() } } @@ -247,21 +270,33 @@ class RegressionTests: KituraNetTest { } mutating func connect(_ port: Int, expectation: XCTestExpectation) throws { - channel = try! clientBootstrap.connect(host: "localhost", port: port).wait() + do { + channel = try clientBootstrap.connect(host: "localhost", port: port).wait() + } catch { + Log.error("Failed to connect to port \(port)") + } if channel.remoteAddress != nil { expectation.fulfill() } } mutating func makeBadRequest(_ port: Int) throws { - channel = try! clientBootstrap.connect(host: "localhost", port: port).wait() + do { + channel = try clientBootstrap.connect(host: "localhost", port: port).wait() + } catch { + Log.error("Failed to connect to port \(port)") + } let request = HTTPRequestHead(version: HTTPVersion(major: 1, minor:1), method: .GET, uri: "#/") _ = channel.write(NIOAny(HTTPClientRequestPart.head(request))) _ = channel.writeAndFlush(NIOAny(HTTPClientRequestPart.end(nil))) } mutating func makeGoodRequestFollowedByBadRequest(_ port: Int) throws { - channel = try! clientBootstrap.connect(host: "localhost", port: port).wait() + do { + channel = try clientBootstrap.connect(host: "localhost", port: port).wait() + } catch { + Log.error("Failed to connect to port \(port)") + } let request = HTTPRequestHead(version: HTTPVersion(major: 1, minor:1), method: .GET, uri: "/") var httpHeaders = HTTPHeaders() httpHeaders.add(name: "Connection", value: "Keep-Alive")