Переглянути джерело

Code cleanup for Socket class.

Damian Kołakowski 10 роки тому
батько
коміт
831853b0b9

+ 9 - 9
Common/HttpParser.swift

@@ -14,8 +14,8 @@ enum HttpParserError : ErrorType {
 
 class HttpParser {
     
-    func nextHttpRequest(socket: Socket) throws -> HttpRequest {
-        let statusLine = try socket.nextLine()
+    func readHttpRequest(socket: Socket) throws -> HttpRequest {
+        let statusLine = try socket.readLine()
         let statusLineTokens = statusLine.componentsSeparatedByString(" ")
         print(statusLineTokens)
         if statusLineTokens.count < 3 {
@@ -24,9 +24,9 @@ class HttpParser {
         let method = statusLineTokens[0]
         let path = statusLineTokens[1]
         let urlParams = extractUrlParams(path)
-        let headers = try self.nextHeaders(socket)
+        let headers = try readHeaders(socket)
         if let contentLength = headers["content-length"], let contentLengthValue = Int(contentLength) {
-            let body = try self.nextBody(socket, size: contentLengthValue)
+            let body = try readBody(socket, size: contentLengthValue)
             return HttpRequest(url: path, urlParams: urlParams, method: method, headers: headers, body: body, capturedUrlGroups: [], address: nil)
         }
         return HttpRequest(url: path, urlParams: urlParams, method: method, headers: headers, body: nil, capturedUrlGroups: [], address: nil)
@@ -48,13 +48,13 @@ class HttpParser {
         }
     }
     
-    private func nextBody(socket: Socket, size: Int) throws -> String {
+    private func readBody(socket: Socket, size: Int) throws -> String {
         var body = ""
         var counter = 0;
         while counter < size {
-            let c = socket.nextInt8()
+            let c = socket.read()
             if c < 0 {
-                throw HttpParserError.ReadBodyFailed(ErrorHandle.errorText)
+                throw HttpParserError.ReadBodyFailed(String.fromCString(UnsafePointer(strerror(errno))) ?? "Error: \(errno)")
             }
             body.append(UnicodeScalar(c))
             counter++;
@@ -62,10 +62,10 @@ class HttpParser {
         return body
     }
     
-    private func nextHeaders(socket: Socket) throws -> [String: String] {
+    private func readHeaders(socket: Socket) throws -> [String: String] {
         var requestHeaders = [String: String]()
         repeat {
-            let headerLine = try socket.nextLine()
+            let headerLine = try socket.readLine()
             if headerLine.isEmpty {
                 return requestHeaders
             }

+ 29 - 32
Common/HttpServer.swift

@@ -12,22 +12,14 @@ public class HttpServer
     
     public typealias Handler = HttpRequest -> HttpResponse
     
-    private(set) var handlers: [(expression: NSRegularExpression, handler: Handler)] = []
-    private(set) var acceptSocket: Socket!
-    private(set) var clientSockets: Set<Socket> = []
+    private var handlers: [(expression: NSRegularExpression, handler: Handler)] = []
+    private var listenSocket: Socket = Socket(socketFileDescriptor: -1)
+    private var clientSockets: Set<Socket> = []
     private let clientSocketsLock = 0
-
-    
-    let matchingOptions = NSMatchingOptions(rawValue: 0)
-    let expressionOptions = NSRegularExpressionOptions(rawValue: 0)
     
     public init() { }
     
     public subscript (path: String) -> Handler? {
-        get {
-            return nil
-        }
-        
         set {
             do {
                 let regex = try NSRegularExpression(pattern: path, options: self.expressionOptions)
@@ -38,6 +30,9 @@ public class HttpServer
                 print("Could not register handler for: \(path), error: \(error)")
             }
         }
+        get {
+            return nil
+        }
     }
     
     public var routes:[String] {
@@ -46,17 +41,17 @@ public class HttpServer
     
     public func start(listenPort: in_port_t = 8080) throws {
         self.stop()
-        self.acceptSocket = try Socket(port:listenPort)
+        self.listenSocket = try Socket.tcpSocketForListen(listenPort)
         dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
-            while let socket = try? self.acceptSocket.acceptClientSocket() {
+            while let socket = try? self.listenSocket.acceptClientSocket() {
                 HttpServer.lock(self.clientSocketsLock) {
                     self.clientSockets.insert(socket)
                 }
-                let socketAddress = try? self.acceptSocket.peername()
                 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
-                    let parser = HttpParser()
-                    while let request = try? parser.nextHttpRequest(socket) {
-                        let keepAlive = parser.supportsKeepAlive(request.headers)
+                    let socketAddress = try? socket.peername()
+                    let httpParser = HttpParser()
+                    while let request = try? httpParser.readHttpRequest(socket) {
+                        let keepAlive = httpParser.supportsKeepAlive(request.headers)
                         let response: HttpResponse
                         if let (expression, handler) = self.findHandler(request.url) {
                             let capturedUrlsGroups = self.captureExpressionGroups(expression, value: request.url)
@@ -73,6 +68,7 @@ public class HttpServer
                         }
                         if !keepAlive { break }
                     }
+                    socket.release()
                     HttpServer.lock(self.clientSocketsLock) {
                         self.clientSockets.remove(socket)
                     }
@@ -82,7 +78,20 @@ public class HttpServer
         }
     }
     
-    func findHandler(url:String) -> (NSRegularExpression, Handler)? {
+    public func stop() {
+        self.listenSocket.release()
+        HttpServer.lock(self.clientSocketsLock) {
+            for socket in self.clientSockets {
+                socket.release()
+            }
+            self.clientSockets.removeAll(keepCapacity: true)
+        }
+    }
+    
+    private let matchingOptions = NSMatchingOptions(rawValue: 0)
+    private let expressionOptions = NSRegularExpressionOptions(rawValue: 0)
+    
+    private func findHandler(url:String) -> (NSRegularExpression, Handler)? {
         if let u = NSURL(string: url), path = u.path {
             for handler in self.handlers {
                 if handler.expression.numberOfMatchesInString(path, options: self.matchingOptions, range: HttpServer.asciiRange(path)) > 0 {
@@ -93,11 +102,10 @@ public class HttpServer
 		return nil
     }
     
-    func captureExpressionGroups(expression: NSRegularExpression, value: String) -> [String] {
+    private func captureExpressionGroups(expression: NSRegularExpression, value: String) -> [String] {
         guard let u = NSURL(string: value), path = u.path else {
             return []
         }
-        
         var capturedGroups = [String]()
         if let result = expression.firstMatchInString(path, options: matchingOptions, range: HttpServer.asciiRange(path)) {
             let nsValue: NSString = path
@@ -110,17 +118,6 @@ public class HttpServer
         return capturedGroups
     }
     
-    public func stop() {
-//        self.acceptSocket?.release()
-        self.acceptSocket = nil
-        HttpServer.lock(self.clientSocketsLock) {
-//            for clientSocket in self.clientSockets {
-//                clientSocket.release()
-//            }
-            self.clientSockets.removeAll(keepCapacity: true)
-        }
-    }
-    
     private class func asciiRange(value: String) -> NSRange {
         return NSMakeRange(0, value.lengthOfBytesUsingEncoding(NSASCIIStringEncoding))
     }
@@ -132,7 +129,7 @@ public class HttpServer
     }
     
     private class func respond(socket: Socket, response: HttpResponse, keepAlive: Bool) throws {
-        try socket.writeUTF8("HTTP/1.1 \(response.statusCode()) \(response.reasonPhrase())\r\n")
+        try socket.writeASCII("HTTP/1.1 \(response.statusCode()) \(response.reasonPhrase())\r\n")
         
         let length = response.body()?.length ?? 0
         try socket.writeASCII("Content-Length: \(length)\r\n")

+ 86 - 102
Common/Socket.swift

@@ -9,8 +9,8 @@ import Foundation
 /* Low level routines for POSIX sockets */
 
 enum SocketError: ErrorType {
-    case SocketInitializationFailed(String)
-    case SocketOptionInitializationFailed(String)
+    case SocketCreationFailed(String)
+    case SocketSettingReUseAddrFailed(String)
     case BindFailed(String)
     case ListenFailed(String)
     case WriteFailed(String)
@@ -19,87 +19,79 @@ enum SocketError: ErrorType {
     case GetNameInfoFailed(String)
     case AcceptFailed(String)
     case RecvFailed(String)
-
 }
 
-let maxPendingConnection: Int32 = 20
-
-class Socket : Hashable {
-    let socketId: CInt
-    
-    var hashValue: Int {
-        return Int(self.socketId)
-    }
+public class Socket : Hashable {
     
-    init(port: in_port_t = 8080) throws {
-        self.socketId = socket(AF_INET, SOCK_STREAM, 0)
-        if self.socketId == -1 {
-            throw SocketError.SocketInitializationFailed(ErrorHandle.errorText)
+    public class func tcpSocketForListen(port: in_port_t = 8080, maxPendingConnection: Int32 = SOMAXCONN) throws -> Socket {
+        let socketFileDescriptor = socket(AF_INET, SOCK_STREAM, 0)
+        if socketFileDescriptor == -1 {
+            throw SocketError.SocketCreationFailed(Socket.descriptionOfLastError())
         }
         
         var value: Int32 = 1
-        if setsockopt(self.socketId, SOL_SOCKET, SO_REUSEADDR, &value, socklen_t(sizeof(Int32))) == -1 {
-            let details = ErrorHandle.errorText
-//            self.release()
-            throw SocketError.SocketOptionInitializationFailed(details)
+        if setsockopt(socketFileDescriptor, SOL_SOCKET, SO_REUSEADDR, &value, socklen_t(sizeof(Int32))) == -1 {
+            let details = Socket.descriptionOfLastError()
+            Socket.release(socketFileDescriptor)
+            throw SocketError.SocketSettingReUseAddrFailed(details)
         }
+        Socket.setNoSigPipe(socketFileDescriptor)
         
-        self.nosigpipe()
-        
-        var addr = sockaddr_in(sin_len: __uint8_t(sizeof(sockaddr_in)),
-                               sin_family: sa_family_t(AF_INET),
-                               sin_port: Socket.port_htons(port),
-                               sin_addr: in_addr(s_addr: inet_addr("0.0.0.0")),
-                               sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
+        var addr = sockaddr_in(
+            sin_len: __uint8_t(sizeof(sockaddr_in)),
+            sin_family: sa_family_t(AF_INET),
+            sin_port: Socket.htonsPort(port),
+            sin_addr: in_addr(s_addr: inet_addr("0.0.0.0")),
+            sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
         var sock_addr = sockaddr(sa_len: 0, sa_family: 0, sa_data: (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
         memcpy(&sock_addr, &addr, Int(sizeof(sockaddr_in)))
         
-        if bind(self.socketId, &sock_addr, socklen_t(sizeof(sockaddr_in))) == -1 {
-            let details = ErrorHandle.errorText
-//            self.release()
+        if bind(socketFileDescriptor, &sock_addr, socklen_t(sizeof(sockaddr_in))) == -1 {
+            let details = Socket.descriptionOfLastError()
+            Socket.release(socketFileDescriptor)
             throw SocketError.BindFailed(details)
         }
         
-        if listen(self.socketId, maxPendingConnection ) == -1 {
-            let details = ErrorHandle.errorText
-//            self.release()
+        if listen(socketFileDescriptor, maxPendingConnection ) == -1 {
+            let details = Socket.descriptionOfLastError()
+            Socket.release(socketFileDescriptor)
             throw SocketError.ListenFailed(details)
         }
+        return Socket(socketFileDescriptor: socketFileDescriptor)
     }
     
-    private init(socketId: CInt) {
-        self.socketId = socketId
-    }
+    private let socketFileDescriptor: CInt
     
-    deinit {
-        print("deinit socket")
-        shutdown(self.socketId, SHUT_RDWR)
-        close(self.socketId)
+    init(socketFileDescriptor: CInt) {
+        self.socketFileDescriptor = socketFileDescriptor
     }
     
-    func nosigpipe() {
-        // prevents crashes when blocking calls are pending and the app is paused ( via Home button )
-        var no_sig_pipe: Int32 = 1;
-        setsockopt(self.socketId, SOL_SOCKET, SO_NOSIGPIPE, &no_sig_pipe, socklen_t(sizeof(Int32)));
-    }
+    public var hashValue: Int { return Int(self.socketFileDescriptor) }
     
-    class func port_htons(port: in_port_t) -> in_port_t {
-        let isLittleEndian = Int(OSHostByteOrder()) == OSLittleEndian
-        return isLittleEndian ? _OSSwapInt16(port) : port
+    public func release() {
+        Socket.release(self.socketFileDescriptor)
     }
     
+    public func acceptClientSocket() throws -> Socket {
+        var addr = sockaddr(sa_len: 0, sa_family: 0, sa_data: (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
+        var len: socklen_t = 0
+        let clientSocket = accept(self.socketFileDescriptor, &addr, &len)
+        if clientSocket == -1 {
+            throw SocketError.AcceptFailed(Socket.descriptionOfLastError())
+        }
+        Socket.setNoSigPipe(clientSocket)
+        return Socket(socketFileDescriptor: clientSocket)
+    }
     
-    // MARK: - write methods
-    
-    func writeUTF8(string: String) throws {
+    public func writeUTF8(string: String) throws {
         try self.writeString(string, withEncoding: NSUTF8StringEncoding)
     }
     
-    func writeASCII(string: String) throws {
+    public func writeASCII(string: String) throws {
         try self.writeString(string, withEncoding: NSASCIIStringEncoding)
     }
     
-    private func writeString(string: String, withEncoding encoding: NSStringEncoding) throws {
+    public func writeString(string: String, withEncoding encoding: NSStringEncoding) throws {
         if let nsdata = string.dataUsingEncoding(encoding) {
             try self.writeData(nsdata)
         } else {
@@ -107,85 +99,77 @@ class Socket : Hashable {
         }
     }
     
-    func writeData(data: NSData) throws {
+    public func writeData(data: NSData) throws {
         var sent = 0
         let unsafePointer = UnsafePointer<UInt8>(data.bytes)
         while sent < data.length {
-            let s = write(self.socketId, unsafePointer + sent, Int(data.length - sent))
+            let s = write(self.socketFileDescriptor, unsafePointer + sent, Int(data.length - sent))
             if s <= 0 {
-                throw SocketError.WriteFailed(ErrorHandle.errorText)
+                throw SocketError.WriteFailed(Socket.descriptionOfLastError())
             }
             sent += s
         }
     }
     
-    // MARK: -
+    public func read() -> Int {
+        var buffer = [UInt8](count: 1, repeatedValue: 0);
+        let next = recv(self.socketFileDescriptor as Int32, &buffer, Int(buffer.count), 0)
+        if next <= 0 {
+            return next
+        }
+        return Int(buffer[0])
+    }
     
-    func acceptClientSocket() throws -> Socket {
-        var addr = sockaddr(sa_len: 0, sa_family: 0, sa_data: (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
-        var len: socklen_t = 0
-        let clientSocket = accept(self.socketId, &addr, &len)
-        if clientSocket == -1 {
-            throw SocketError.AcceptFailed(ErrorHandle.errorText)
+    public func readLine() throws -> String {
+        var characters: String = ""
+        var n = 0
+        repeat {
+            n = self.read()
+            if ( n > 13 /* CR */ ) { characters.append(Character(UnicodeScalar(n))) }
+        } while n > 0 && n != 10 /* NL */
+        if n == -1 {
+            throw SocketError.RecvFailed(Socket.descriptionOfLastError())
         }
-        self.nosigpipe()
-        return Socket(socketId: clientSocket)
+        return characters
     }
     
-    func peername() throws -> String {
+    public func peername() throws -> String {
         var addr = sockaddr(), len: socklen_t = socklen_t(sizeof(sockaddr))
-        if getpeername(self.socketId, &addr, &len) != 0 {
-            throw SocketError.GetPeerNameFailed(ErrorHandle.errorText)
+        if getpeername(self.socketFileDescriptor, &addr, &len) != 0 {
+            throw SocketError.GetPeerNameFailed(Socket.descriptionOfLastError())
         }
         var hostBuffer = [CChar](count: Int(NI_MAXHOST), repeatedValue: 0)
         if getnameinfo(&addr, len, &hostBuffer, socklen_t(hostBuffer.count), nil, 0, NI_NUMERICHOST) != 0 {
-            throw SocketError.GetNameInfoFailed(ErrorHandle.errorText)
+            throw SocketError.GetNameInfoFailed(Socket.descriptionOfLastError())
         }
-        
         guard let name = String.fromCString(hostBuffer) else {
             throw SocketError.ConvertingPeerNameFailed
         }
-        
         return name
     }
-
-//    func release() {
-//        print("release")
-//        shutdown(self.socketId, SHUT_RDWR)
-//        close(self.socketId)
-//    }
     
-    // MARK: - basic receiving
+    private class func descriptionOfLastError() -> String {
+        return String.fromCString(UnsafePointer(strerror(errno))) ?? "Error: \(errno)"
+    }
     
-    func nextInt8() -> Int {
-        var buffer = [UInt8](count: 1, repeatedValue: 0);
-        let next = recv(self.socketId as Int32, &buffer, Int(buffer.count), 0)
-        if next <= 0 {
-            return next
-        }
-        return Int(buffer[0])
+    private class func setNoSigPipe(socket: CInt) {
+        // prevents crashes when blocking calls are pending and the app is paused ( via Home button )
+        var no_sig_pipe: Int32 = 1;
+        setsockopt(socket, SOL_SOCKET, SO_NOSIGPIPE, &no_sig_pipe, socklen_t(sizeof(Int32)));
     }
     
-    func nextLine() throws -> String {
-        var characters: String = ""
-        var n = 0
-        repeat {
-            n = self.nextInt8()
-            if ( n > 13 /* CR */ ) { characters.append(Character(UnicodeScalar(n))) }
-        } while n > 0 && n != 10 /* NL */
-        if n == -1 {
-            throw SocketError.RecvFailed(ErrorHandle.errorText)
-        }
-        return characters
+    private class func release(socket: CInt) {
+        shutdown(socket, SHUT_RDWR)
+        close(socket)
+    }
+    
+    private class func htonsPort(port: in_port_t) -> in_port_t {
+        let isLittleEndian = Int(OSHostByteOrder()) == OSLittleEndian
+        return isLittleEndian ? _OSSwapInt16(port) : port
     }
 }
 
-func ==(socket1: Socket, socket2: Socket) -> Bool {
-    return socket1.socketId == socket2.socketId
-}
 
-class ErrorHandle {
-    class var errorText: String {
-        return String.fromCString(UnsafePointer(strerror(errno))) ?? "error converting error text from C String"
-    }
+public func ==(socket1: Socket, socket2: Socket) -> Bool {
+    return socket1.hashValue == socket2.hashValue
 }

BIN
Swifter.xcodeproj/project.xcworkspace/xcuserdata/damiankolakowski.xcuserdatad/UserInterfaceState.xcuserstate


+ 30 - 94
Swifter.xcodeproj/xcuserdata/damiankolakowski.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -202,11 +202,11 @@
             ignoreCount = "0"
             continueAfterRunningActions = "No"
             filePath = "Common/HttpServer.swift"
-            timestampString = "466774667.297767"
+            timestampString = "466971590.533081"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "45"
-            endingLineNumber = "45"
+            startingLineNumber = "40"
+            endingLineNumber = "40"
             landmarkName = "HttpServer"
             landmarkType = "3">
          </BreakpointContent>
@@ -218,11 +218,11 @@
             ignoreCount = "0"
             continueAfterRunningActions = "No"
             filePath = "Common/HttpServer.swift"
-            timestampString = "466774667.297767"
+            timestampString = "466971590.533081"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "47"
-            endingLineNumber = "47"
+            startingLineNumber = "42"
+            endingLineNumber = "42"
             landmarkName = "start(_:)"
             landmarkType = "5">
          </BreakpointContent>
@@ -234,11 +234,11 @@
             ignoreCount = "0"
             continueAfterRunningActions = "No"
             filePath = "Common/HttpServer.swift"
-            timestampString = "466774667.297767"
+            timestampString = "466971590.533081"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "48"
-            endingLineNumber = "48"
+            startingLineNumber = "43"
+            endingLineNumber = "43"
             landmarkName = "start(_:)"
             landmarkType = "5">
          </BreakpointContent>
@@ -319,7 +319,7 @@
             endingColumnNumber = "9223372036854775807"
             startingLineNumber = "19"
             endingLineNumber = "19"
-            landmarkName = "nextHttpRequest(_:)"
+            landmarkName = "readHttpRequest(_:)"
             landmarkType = "5">
          </BreakpointContent>
       </BreakpointProxy>
@@ -335,7 +335,7 @@
             endingColumnNumber = "9223372036854775807"
             startingLineNumber = "18"
             endingLineNumber = "18"
-            landmarkName = "nextHttpRequest(_:)"
+            landmarkName = "readHttpRequest(_:)"
             landmarkType = "5">
          </BreakpointContent>
       </BreakpointProxy>
@@ -362,11 +362,11 @@
             ignoreCount = "0"
             continueAfterRunningActions = "No"
             filePath = "Common/HttpServer.swift"
-            timestampString = "466775670.320344"
+            timestampString = "466972257.459384"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "105"
-            endingLineNumber = "105"
+            startingLineNumber = "113"
+            endingLineNumber = "113"
             landmarkName = "captureExpressionGroups(_:value:)"
             landmarkType = "5">
          </BreakpointContent>
@@ -378,11 +378,11 @@
             ignoreCount = "0"
             continueAfterRunningActions = "No"
             filePath = "Common/HttpServer.swift"
-            timestampString = "466775670.320344"
+            timestampString = "466972257.459384"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "106"
-            endingLineNumber = "106"
+            startingLineNumber = "114"
+            endingLineNumber = "114"
             landmarkName = "captureExpressionGroups(_:value:)"
             landmarkType = "5">
          </BreakpointContent>
@@ -403,22 +403,6 @@
             landmarkType = "5">
          </BreakpointContent>
       </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            shouldBeEnabled = "No"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "Common/Socket.swift"
-            timestampString = "466776889.884253"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "28"
-            endingLineNumber = "28"
-            landmarkName = "tcpForListen(_:)"
-            landmarkType = "5">
-         </BreakpointContent>
-      </BreakpointProxy>
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
@@ -692,61 +676,13 @@
             shouldBeEnabled = "No"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
-            filePath = "Common/Socket.swift"
-            timestampString = "466776889.884253"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "80"
-            endingLineNumber = "80"
-            landmarkName = "writeData(_:data:)"
-            landmarkType = "5">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            shouldBeEnabled = "No"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "Common/Socket.swift"
-            timestampString = "466776889.884253"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "87"
-            endingLineNumber = "87"
-            landmarkName = "Socket"
-            landmarkType = "3">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            shouldBeEnabled = "No"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "Common/Socket.swift"
-            timestampString = "466776889.884253"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "89"
-            endingLineNumber = "89"
-            landmarkName = "acceptClientSocket(_:)"
-            landmarkType = "5">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            shouldBeEnabled = "No"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "Common/HttpServer.swift"
-            timestampString = "466775670.320344"
+            filePath = "Common/HttpRequest.swift"
+            timestampString = "466766967.614148"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "117"
-            endingLineNumber = "117"
-            landmarkName = "stop()"
+            startingLineNumber = "20"
+            endingLineNumber = "20"
+            landmarkName = "parseForm()"
             landmarkType = "5">
          </BreakpointContent>
       </BreakpointProxy>
@@ -757,11 +693,11 @@
             ignoreCount = "0"
             continueAfterRunningActions = "No"
             filePath = "Common/HttpRequest.swift"
-            timestampString = "466766967.614148"
+            timestampString = "466767025.146182"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "20"
-            endingLineNumber = "20"
+            startingLineNumber = "22"
+            endingLineNumber = "22"
             landmarkName = "parseForm()"
             landmarkType = "5">
          </BreakpointContent>
@@ -772,13 +708,13 @@
             shouldBeEnabled = "No"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
-            filePath = "Common/HttpRequest.swift"
-            timestampString = "466767025.146182"
+            filePath = "Common/Socket.swift"
+            timestampString = "466971590.533081"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "22"
-            endingLineNumber = "22"
-            landmarkName = "parseForm()"
+            startingLineNumber = "65"
+            endingLineNumber = "65"
+            landmarkName = "init(socketFileDescriptor:)"
             landmarkType = "5">
          </BreakpointContent>
       </BreakpointProxy>

+ 3 - 2
Swifter/ViewController.swift

@@ -12,12 +12,13 @@ class ViewController: UIViewController {
     
     override func viewDidLoad() {
         super.viewDidLoad()
-        self.server = demoServer(NSBundle.mainBundle().resourcePath)
+        let server = demoServer(NSBundle.mainBundle().resourcePath)
         do {
-            try self.server.start()
+            try server.start()
         } catch {
             print("Server start error: \(error)")
         }
+        self.server = server
     }
 
     override func didReceiveMemoryWarning() {


BIN
github_code.png