diff --git a/Source/WebSocket.swift b/Source/WebSocket.swift index d8006c3..f01db7a 100644 --- a/Source/WebSocket.swift +++ b/Source/WebSocket.swift @@ -10,6 +10,31 @@ import Foundation import CoreFoundation import Security +////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Websocket.swift +// +// Created by Dalton Cherry on 7/16/14. +// Copyright (c) 2014-2015 Dalton Cherry. +// +// 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 CoreFoundation +import Security + public protocol WebSocketDelegate: class { func websocketDidConnect(socket: WebSocket) func websocketDidDisconnect(socket: WebSocket, error: NSError?) @@ -421,6 +446,33 @@ public class WebSocket : NSObject, NSStreamDelegate { return false } + ///read a 16 bit big endian value from a buffer + private static func readUint16(buffer: UnsafePointer, offset: Int) -> UInt16 { + return (UInt16(buffer[offset + 0]) << 8) | UInt16(buffer[offset + 1]) + } + + ///read a 64 bit big endian value from a buffer + private static func readUint64(buffer: UnsafePointer, offset: Int) -> UInt64 { + var value = UInt64(0) + for i in 0...7 { + value = (value << 8) | UInt64(buffer[offset + i]) + } + return value + } + + ///write a 16 bit big endian value to a buffer + private static func writeUint16(buffer: UnsafeMutablePointer, offset: Int, value: UInt16) { + buffer[offset + 0] = UInt8(value >> 8) + buffer[offset + 1] = UInt8(value & 0xff) + } + + ///write a 64 bit big endian value to a buffer + private static func writeUint64(buffer: UnsafeMutablePointer, offset: Int, value: UInt64) { + for i in 0...7 { + buffer[offset + i] = UInt8((value >> (8*UInt64(7 - i))) & 0xff) + } + } + ///process the websocket data private func processRawMessage(buffer: UnsafePointer, bufferLen: Int) { let response = readStack.last @@ -474,8 +526,7 @@ public class WebSocket : NSObject, NSStreamDelegate { if payloadLen == 1 { code = CloseCode.ProtocolError.rawValue } else if payloadLen > 1 { - let codeBuffer = UnsafePointer((buffer+offset)) - code = codeBuffer[0].bigEndian + code = WebSocket.readUint16(buffer, offset: offset) if code < 1000 || (code > 1003 && code < 1007) || (code > 1011 && code < 3000) { code = CloseCode.ProtocolError.rawValue } @@ -501,12 +552,10 @@ public class WebSocket : NSObject, NSStreamDelegate { } var dataLength = UInt64(payloadLen) if dataLength == 127 { - let bytes = UnsafePointer((buffer+offset)) - dataLength = bytes[0].bigEndian + dataLength = WebSocket.readUint64(buffer, offset: offset) offset += sizeof(UInt64) } else if dataLength == 126 { - let bytes = UnsafePointer((buffer+offset)) - dataLength = UInt64(bytes[0].bigEndian) + dataLength = UInt64(WebSocket.readUint16(buffer, offset: offset)) offset += sizeof(UInt16) } if bufferLen < offset || UInt64(bufferLen - offset) < dataLength { @@ -644,8 +693,8 @@ public class WebSocket : NSObject, NSStreamDelegate { ///write a an error to the socket private func writeError(code: UInt16) { let buf = NSMutableData(capacity: sizeof(UInt16)) - let buffer = UnsafeMutablePointer(buf!.bytes) - buffer[0] = code.bigEndian + let buffer = UnsafeMutablePointer(buf!.bytes) + WebSocket.writeUint16(buffer, offset: 0, value: code) dequeueWrite(NSData(bytes: buffer, length: sizeof(UInt16)), code: .ConnectionClose) } ///used to write things to the stream @@ -665,13 +714,11 @@ public class WebSocket : NSObject, NSStreamDelegate { buffer[1] = CUnsignedChar(dataLength) } else if dataLength <= Int(UInt16.max) { buffer[1] = 126 - let sizeBuffer = UnsafeMutablePointer((buffer+offset)) - sizeBuffer[0] = UInt16(dataLength).bigEndian + WebSocket.writeUint16(buffer, offset: offset, value: UInt16(dataLength)) offset += sizeof(UInt16) } else { buffer[1] = 127 - let sizeBuffer = UnsafeMutablePointer((buffer+offset)) - sizeBuffer[0] = UInt64(dataLength).bigEndian + WebSocket.writeUint64(buffer, offset: offset, value: UInt64(dataLength)) offset += sizeof(UInt64) } buffer[1] |= s.MaskMask @@ -725,6 +772,7 @@ public class WebSocket : NSObject, NSStreamDelegate { } } + private class SSLCert { var certData: NSData? var key: SecKeyRef?