-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Kitura/Kitura#33 Initial push. Basic connect support
- Loading branch information
Showing
11 changed files
with
429 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
.build | ||
build | ||
.vagrant | ||
Packages | ||
*.pkg | ||
Kitura-WebSocket.xcodeproj | ||
*.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/** | ||
* Copyright IBM Corporation 2016 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
**/ | ||
|
||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "Kitura-WebSocket", | ||
dependencies: [ | ||
.Package(url: "https://github.com/IBM-Swift/Kitura.git", majorVersion: 1, minor: 0), | ||
.Package(url: "https://github.com/IBM-Swift/BlueCryptor.git", majorVersion: 0, minor: 7), | ||
] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
* Copyright IBM Corporation 2015 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import Foundation | ||
|
||
import Cryptor | ||
import KituraNet | ||
|
||
public class WSConnectionUpgradeFactory: ConnectionUpgradeFactory { | ||
private var registry = Dictionary<String, WebSocketService>() | ||
|
||
private let wsGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" | ||
|
||
/// The name of the protocol supported by this `ConnectionUpgradeFactory`. A case insensitive compare is made with this name. | ||
public let name = "websocket" | ||
|
||
init() { | ||
ConnectionUpgrader.register(factory: self) | ||
} | ||
|
||
/// "Upgrade" a connection to the protocol supported by this `ConnectionUpgradeFactory`. | ||
/// | ||
/// - Parameter handler: The `IncomingSocketHandler` that is handling the connection being upgraded. | ||
/// - Parameter request: The `ServerRequest` object of the incoming "upgrade" request. | ||
/// - Parameter response: The `ServerResponse` object that will be used to send the response of the "upgrade" request. | ||
/// | ||
/// - Returns: A tuple of the created `IncomingSocketProcessor` and a message to send as the body of the response to | ||
/// the upgrade request. The `IncomingSocketProcessor` should be nil if the upgrade request wasn't successful. | ||
/// If the message is nil, the response will not contain a body. | ||
/// | ||
/// - Note: The `ConnectionUpgradeFactory` instance doesn't need to work with the `ServerResponse` unless it | ||
/// needs to add special headers to the response. | ||
public func upgrade(handler: IncomingSocketHandler, request: ServerRequest, response: ServerResponse) -> (IncomingSocketProcessor?, String?) { | ||
|
||
var processor: IncomingSocketProcessor? | ||
|
||
if let securityKey = request.headers["Sec-WebSocket-Key"] { | ||
let sha1 = Digest(using: .sha1) | ||
let sha1Bytes = sha1.update(string: securityKey[0] + wsGUID)!.final() | ||
let sha1Data = NSData(bytes: sha1Bytes, length: sha1Bytes.count) | ||
response.headers["Sec-WebSocket-Accept"] = | ||
[sha1Data.base64EncodedString(options: .lineLength64Characters)] | ||
response.headers["Sec-WebSocket-Protocol"] = request.headers["Sec-WebSocket-Protocol"] | ||
|
||
processor = WSSocketProcessor() | ||
} | ||
|
||
return (processor, nil) | ||
} | ||
|
||
func register(service: WebSocketService, onPath: String) { | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
* Copyright IBM Corporation 2015 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import Foundation | ||
|
||
import KituraNet | ||
|
||
class WSSocketProcessor: IncomingSocketProcessor { | ||
/// A back reference to the `IncomingSocketHandler` processing the socket that | ||
/// this `IncomingDataProcessor` is processing. | ||
public weak var handler: IncomingSocketHandler? | ||
|
||
/// The socket if idle will be kept alive until... | ||
public var keepAliveUntil: TimeInterval = 500.0 | ||
|
||
/// A flag to indicate that the socket has a request in progress | ||
public var inProgress = true | ||
|
||
/// Process data read from the socket. | ||
/// | ||
/// - Parameter buffer: An NSData object containing the data that was read in | ||
/// and needs to be processed. | ||
/// | ||
/// - Returns: true if the data was processed, false if it needs to be processed later. | ||
public func process(_ buffer: NSData) -> Bool { | ||
return true | ||
} | ||
|
||
/// Write data to the socket | ||
/// | ||
/// - Parameter from: An NSData object containing the bytes to be written to the socket. | ||
public func write(from data: NSData) { | ||
handler?.write(from: data) | ||
} | ||
|
||
/// Write a sequence of bytes in an array to the socket | ||
/// | ||
/// - Parameter from: An UnsafeRawPointer to the sequence of bytes to be written to the socket. | ||
/// - Parameter length: The number of bytes to write to the socket. | ||
public func write(from bytes: UnsafeRawPointer, length: Int) { | ||
handler?.write(from: bytes, length: length) | ||
} | ||
|
||
/// Close the socket and mark this handler as no longer in progress. | ||
public func close() { | ||
handler?.prepareToClose() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* | ||
* Copyright IBM Corporation 2015 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import KituraNet | ||
|
||
public class WebSocket { | ||
private static let factory = WSConnectionUpgradeFactory() | ||
|
||
public static func register(service: WebSocketService, onPath path: String) { | ||
factory.register(service: service, onPath: path.lowercased()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* | ||
* Copyright IBM Corporation 2015 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import Foundation | ||
|
||
public class WebSocketClient { | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
* Copyright IBM Corporation 2015 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import Foundation | ||
|
||
public protocol WebSocketService { | ||
func connected(client: WebSocketClient) | ||
func disconnected(client: WebSocketClient) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// | ||
// BasicTests.swift | ||
// Kitura-WebSocket | ||
// | ||
// Created by Samuel Kallner on 26/10/2016. | ||
// | ||
// | ||
|
||
import Foundation/** | ||
* Copyright IBM Corporation 2016 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
**/ | ||
|
||
import XCTest | ||
import Foundation | ||
|
||
@testable import Kitura | ||
@testable import KituraNet | ||
@testable import KituraWebSocket | ||
|
||
class BasicTests: XCTestCase { | ||
|
||
static var allTests: [(String, (BasicTests) -> () throws -> Void)] { | ||
return [ | ||
("testPing", testPing) | ||
] | ||
} | ||
|
||
override func setUp() { | ||
doSetUp() | ||
} | ||
|
||
override func tearDown() { | ||
doTearDown() | ||
} | ||
|
||
func testPing() { | ||
WebSocket.register(service: TestWebSocketService(), onPath: "/wstester") | ||
|
||
performServerTest(TestServerDelegate()) { (expectation: XCTestExpectation) in | ||
} | ||
} | ||
|
||
class TestWebSocketService: WebSocketService { | ||
public func connected(client: WebSocketClient) { | ||
print("Connected") | ||
} | ||
|
||
public func disconnected(client: WebSocketClient){ | ||
print("disconnected") | ||
} | ||
} | ||
|
||
class TestServerDelegate : ServerDelegate { | ||
func handle(request: ServerRequest, response: ServerResponse) { | ||
XCTFail("Server delegate invoked in an Upgrade scenario") | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/** | ||
* Copyright IBM Corporation 2016 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
**/ | ||
|
||
import XCTest | ||
import Kitura | ||
|
||
@testable import KituraNet | ||
|
||
import Foundation | ||
import Dispatch | ||
|
||
protocol KituraTest { | ||
func expectation(_ index: Int) -> XCTestExpectation | ||
func waitExpectation(timeout t: TimeInterval, handler: XCWaitCompletionHandler?) | ||
} | ||
|
||
extension KituraTest { | ||
|
||
func doSetUp() { | ||
PrintLogger.use() | ||
} | ||
|
||
func doTearDown() { | ||
// sleep(10) | ||
} | ||
|
||
func performServerTest(_ router: ServerDelegate, | ||
asyncTasks: @escaping (XCTestExpectation) -> Void...) { | ||
Kitura.addHTTPServer(onPort: 8090, with: router) | ||
Kitura.start() | ||
sleep(1) | ||
let requestQueue = DispatchQueue(label: "Request queue") | ||
|
||
for (index, asyncTask) in asyncTasks.enumerated() { | ||
let expectation = self.expectation(index) | ||
requestQueue.async() { | ||
asyncTask(expectation) | ||
} | ||
} | ||
|
||
waitExpectation(timeout: 100) { error in | ||
// blocks test until request completes | ||
Kitura.stop() | ||
XCTAssertNil(error) | ||
} | ||
} | ||
} | ||
|
||
extension XCTestCase: KituraTest { | ||
func expectation(_ index: Int) -> XCTestExpectation { | ||
let expectationDescription = "\(type(of: self))-\(index)" | ||
return self.expectation(description: expectationDescription) | ||
} | ||
|
||
func waitExpectation(timeout t: TimeInterval, handler: XCWaitCompletionHandler?) { | ||
self.waitForExpectations(timeout: t, handler: handler) | ||
} | ||
} | ||
|
Oops, something went wrong.