diff --git a/Package.swift b/Package.swift index 16e3ffa..61055c2 100644 --- a/Package.swift +++ b/Package.swift @@ -31,6 +31,7 @@ let package = Package( // Dependencies declare other packages that this package depends on. .package(url: "https://github.com/IBM-Swift/Kitura-NIO.git", from: "2.0.0"), .package(url: "https://github.com/IBM-Swift/BlueCryptor.git", from: "1.0.0"), + .package(url: "https://github.com/IBM-Swift/BlueSSLService.git", from: "1.0.0"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. @@ -47,6 +48,6 @@ let package = Package( dependencies: ["CZlib", "KituraNet"]), .testTarget( name: "KituraWebSocketTests", - dependencies: ["KituraWebSocket", "Cryptor"]) + dependencies: ["KituraWebSocket", "Cryptor", "SSLService"]) ] ) diff --git a/Tests/KituraWebSocketTests/KituraTest.swift b/Tests/KituraWebSocketTests/KituraTest.swift index 17676a6..6c3b11a 100644 --- a/Tests/KituraWebSocketTests/KituraTest.swift +++ b/Tests/KituraWebSocketTests/KituraTest.swift @@ -26,9 +26,28 @@ import NIOWebSocket import Foundation import Dispatch import LoggerAPI +import NIOSSL +import SSLService class KituraTest: XCTestCase { + // SSL Configuration for WSS tests + static let sslConfig: SSLService.Configuration = { + let sslConfigDir = URL(fileURLWithPath: #file).appendingPathComponent("../SSLConfig") + + #if os(Linux) + let certificatePath = sslConfigDir.appendingPathComponent("certificate.pem").standardized.path + let keyPath = sslConfigDir.appendingPathComponent("key.pem").standardized.path + return SSLService.Configuration(withCACertificateDirectory: nil, usingCertificateFile: certificatePath, + withKeyFile: keyPath, usingSelfSignedCerts: true, cipherSuite: nil) + + #else + let chainFilePath = sslConfigDir.appendingPathComponent("certificateChain.pfx").standardized.path + return SSLService.Configuration(withChainFilePath: chainFilePath, withPassword: "kitura", + usingSelfSignedCerts: true, cipherSuite: nil) + #endif + }() + private static let initOnce: () = { PrintLogger.use(colored: true) }() @@ -52,9 +71,16 @@ class KituraTest: XCTestCase { var httpHandler: HTTPResponseHandler? - func performServerTest(line: Int = #line, asyncTasks: (XCTestExpectation) -> Void...) { + var isSecure: Bool = true + + func performServerTest(line: Int = #line, isSecure: Bool = true, asyncTasks: (XCTestExpectation) -> Void...) { + self.isSecure = isSecure let server = HTTP.createServer() server.allowPortReuse = true + if isSecure { + server.sslConfig = KituraTest.sslConfig + } + do { try server.listen(on: 8080) @@ -87,7 +113,7 @@ class KituraTest: XCTestCase { _ = try channel.pipeline.removeHandler(httpRequestEncoder!).wait() _ = try channel.pipeline.removeHandler(httpResponseDecoder!).wait() _ = try channel.pipeline.removeHandler(httpHandler!).wait() - try channel.pipeline.addHandler(WebSocketClientHandler(expectedFrames: expectedFrames, expectation: expectation, compressed: compressed), position: .first).wait() + try channel.pipeline.addHandler(WebSocketClientHandler(expectedFrames: expectedFrames, expectation: expectation, compressed: compressed)).wait() } catch let error { Log.error("Error: \(error)") } @@ -106,9 +132,23 @@ class KituraTest: XCTestCase { func clientChannelInitializer(channel: Channel) -> EventLoopFuture { self.httpRequestEncoder = HTTPRequestEncoder() self.httpResponseDecoder = ByteToMessageHandler(HTTPResponseDecoder(leftOverBytesStrategy: .dropBytes)) - return channel.pipeline.addHandlers(self.httpRequestEncoder!, self.httpResponseDecoder!, position: .last).flatMap { + let httpHandlersAddedFuture = channel.pipeline.addHandlers(self.httpRequestEncoder!, self.httpResponseDecoder!, position: .last).flatMap { channel.pipeline.addHandler(self.httpHandler!) } + + if self.isSecure { + do { + let sslConfig = TLSConfiguration.forClient(certificateVerification: .none) + let sslContext = try NIOSSLContext(configuration: sslConfig) + let sslHandler = try NIOSSLClientHandler(context: sslContext, serverHostname: nil) + return httpHandlersAddedFuture.flatMap { + channel.pipeline.addHandler(sslHandler, position: .first) + } + } catch let error { + Log.error("Failed to create client SSLContext. Error: \(error)") + } + } + return httpHandlersAddedFuture } func sendUpgradeRequest(forProtocolVersion: String? = "13", toPath: String, usingKey: String?, semaphore: DispatchSemaphore, errorMessage: String? = nil, compressed: Bool = false) -> Channel? {