Просмотр исходного кода

class-powered socket used

Socket is now a class with the power of it. It holds the socketId
inside, so we can juste use write method without to know the id.
The read line and int8 is moved into the socket (the socket read the
data, not the httpparser, which is used just for http !)
in the httpServer subscript, I re-change set (newValue) : why is that
???, newValue is the default name, so you don’t have to name it that
way, except if you want a different name

I use deinit to release the socket. I test with Instrument with deinit
and release, and I don’t see any difference, but you can change if you
want, the release is still in comment.
nonn 10 лет назад
Родитель
Сommit
59f0196ccb
8 измененных файлов с 161 добавлено и 313 удалено
  1. 10 33
      Common/HttpParser.swift
  2. 22 23
      Common/HttpServer.swift
  3. 128 66
      Common/Socket.swift
  4. 0 27
      Common/TestSocket.swift
  5. 0 22
      Resources/chat.html
  6. 0 119
      Swifter.xcodeproj/project.pbxproj
  7. 0 19
      SwifterOSX/chat.swift
  8. 1 4
      SwifterOSX/main.swift

+ 10 - 33
Common/HttpParser.swift

@@ -8,15 +8,14 @@ import Foundation
 
 
 
 
 enum HttpParserError : ErrorType {
 enum HttpParserError : ErrorType {
-    case RecvFailed(String?)
-    case ReadBodyFailed(String?)
+    case ReadBodyFailed(String)
     case InvalidStatusLine(String)
     case InvalidStatusLine(String)
 }
 }
 
 
 class HttpParser {
 class HttpParser {
     
     
-    func nextHttpRequest(socket: CInt) throws -> HttpRequest {
-        let statusLine = try nextLine(socket)
+    func nextHttpRequest(socket: Socket) throws -> HttpRequest {
+        let statusLine = try socket.nextLine()
         let statusLineTokens = statusLine.componentsSeparatedByString(" ")
         let statusLineTokens = statusLine.componentsSeparatedByString(" ")
         print(statusLineTokens)
         print(statusLineTokens)
         if statusLineTokens.count < 3 {
         if statusLineTokens.count < 3 {
@@ -25,9 +24,9 @@ class HttpParser {
         let method = statusLineTokens[0]
         let method = statusLineTokens[0]
         let path = statusLineTokens[1]
         let path = statusLineTokens[1]
         let urlParams = extractUrlParams(path)
         let urlParams = extractUrlParams(path)
-        let headers = try nextHeaders(socket)
+        let headers = try self.nextHeaders(socket)
         if let contentLength = headers["content-length"], let contentLengthValue = Int(contentLength) {
         if let contentLength = headers["content-length"], let contentLengthValue = Int(contentLength) {
-            let body = try nextBody(socket, size: contentLengthValue)
+            let body = try self.nextBody(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: body, capturedUrlGroups: [], address: nil)
         }
         }
         return HttpRequest(url: path, urlParams: urlParams, method: method, headers: headers, body: nil, capturedUrlGroups: [], address: nil)
         return HttpRequest(url: path, urlParams: urlParams, method: method, headers: headers, body: nil, capturedUrlGroups: [], address: nil)
@@ -49,13 +48,13 @@ class HttpParser {
         }
         }
     }
     }
     
     
-    private func nextBody(socket: CInt, size: Int) throws -> String {
+    private func nextBody(socket: Socket, size: Int) throws -> String {
         var body = ""
         var body = ""
         var counter = 0;
         var counter = 0;
         while counter < size {
         while counter < size {
-            let c = nextInt8(socket)
+            let c = socket.nextInt8()
             if c < 0 {
             if c < 0 {
-                throw HttpParserError.ReadBodyFailed(String.fromCString(UnsafePointer(strerror(errno))))
+                throw HttpParserError.ReadBodyFailed(ErrorHandle.errorText)
             }
             }
             body.append(UnicodeScalar(c))
             body.append(UnicodeScalar(c))
             counter++;
             counter++;
@@ -63,10 +62,10 @@ class HttpParser {
         return body
         return body
     }
     }
     
     
-    private func nextHeaders(socket: CInt) throws -> [String: String] {
+    private func nextHeaders(socket: Socket) throws -> [String: String] {
         var requestHeaders = [String: String]()
         var requestHeaders = [String: String]()
         repeat {
         repeat {
-            let headerLine = try nextLine(socket)
+            let headerLine = try socket.nextLine()
             if headerLine.isEmpty {
             if headerLine.isEmpty {
                 return requestHeaders
                 return requestHeaders
             }
             }
@@ -83,28 +82,6 @@ class HttpParser {
             }
             }
         } while true
         } while true
     }
     }
-
-    private func nextInt8(socket: CInt) -> Int {
-        var buffer = [UInt8](count: 1, repeatedValue: 0);
-        let next = recv(socket as Int32, &buffer, Int(buffer.count), 0)
-        if next <= 0 {
-            return next
-        }
-        return Int(buffer[0])
-    }
-    
-    private func nextLine(socket: CInt) throws -> String {
-        var characters: String = ""
-        var n = 0
-        repeat {
-            n = nextInt8(socket)
-            if ( n > 13 /* CR */ ) { characters.append(Character(UnicodeScalar(n))) }
-        } while n > 0 && n != 10 /* NL */
-        if n == -1 {
-            throw HttpParserError.RecvFailed(String.fromCString(UnsafePointer(strerror(errno))))
-        }
-        return characters
-    }
     
     
     func supportsKeepAlive(headers: [String: String]) -> Bool {
     func supportsKeepAlive(headers: [String: String]) -> Bool {
         if let value = headers["connection"] {
         if let value = headers["connection"] {

+ 22 - 23
Common/HttpServer.swift

@@ -13,8 +13,8 @@ public class HttpServer
     public typealias Handler = HttpRequest -> HttpResponse
     public typealias Handler = HttpRequest -> HttpResponse
     
     
     private(set) var handlers: [(expression: NSRegularExpression, handler: Handler)] = []
     private(set) var handlers: [(expression: NSRegularExpression, handler: Handler)] = []
-    private(set) var acceptSocket: CInt = -1
-    private(set) var clientSockets: Set<CInt> = []
+    private(set) var acceptSocket: Socket!
+    private(set) var clientSockets: Set<Socket> = []
     private let clientSocketsLock = 0
     private let clientSocketsLock = 0
 
 
     
     
@@ -27,11 +27,12 @@ public class HttpServer
         get {
         get {
             return nil
             return nil
         }
         }
-        set ( newValue ) {
+        
+        set {
             do {
             do {
-                let regex = try NSRegularExpression(pattern: path, options: expressionOptions)
+                let regex = try NSRegularExpression(pattern: path, options: self.expressionOptions)
                 if let newHandler = newValue {
                 if let newHandler = newValue {
-                    handlers.append(expression: regex, handler: newHandler)
+                    self.handlers.append(expression: regex, handler: newHandler)
                 }
                 }
             } catch  {
             } catch  {
                 print("Could not register handler for: \(path), error: \(error)")
                 print("Could not register handler for: \(path), error: \(error)")
@@ -40,19 +41,18 @@ public class HttpServer
     }
     }
     
     
     public var routes:[String] {
     public var routes:[String] {
-        return self.handlers.map { $0.0.pattern }
+        return self.handlers.map { $0.expression.pattern }
     }
     }
     
     
     public func start(listenPort: in_port_t = 8080) throws {
     public func start(listenPort: in_port_t = 8080) throws {
         self.stop()
         self.stop()
-        self.acceptSocket = try Socket.tcpForListen(listenPort)
+        self.acceptSocket = try Socket(port:listenPort)
         dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
         dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
-            while let socket = try? Socket.acceptClientSocket(self.acceptSocket) {
+            while let socket = try? self.acceptSocket.acceptClientSocket() {
                 HttpServer.lock(self.clientSocketsLock) {
                 HttpServer.lock(self.clientSocketsLock) {
                     self.clientSockets.insert(socket)
                     self.clientSockets.insert(socket)
                 }
                 }
-                if self.acceptSocket == -1 { return }
-                let socketAddress = try? Socket.peername(socket)!
+                let socketAddress = try? self.acceptSocket.peername()
                 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
                 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
                     let parser = HttpParser()
                     let parser = HttpParser()
                     while let request = try? parser.nextHttpRequest(socket) {
                     while let request = try? parser.nextHttpRequest(socket) {
@@ -73,7 +73,6 @@ public class HttpServer
                         }
                         }
                         if !keepAlive { break }
                         if !keepAlive { break }
                     }
                     }
-                    Socket.release(socket)
                     HttpServer.lock(self.clientSocketsLock) {
                     HttpServer.lock(self.clientSocketsLock) {
                         self.clientSockets.remove(socket)
                         self.clientSockets.remove(socket)
                     }
                     }
@@ -112,12 +111,12 @@ public class HttpServer
     }
     }
     
     
     public func stop() {
     public func stop() {
-        Socket.release(acceptSocket)
-        self.acceptSocket = -1
+//        self.acceptSocket?.release()
+        self.acceptSocket = nil
         HttpServer.lock(self.clientSocketsLock) {
         HttpServer.lock(self.clientSocketsLock) {
-            for clientSocket in self.clientSockets {
-                Socket.release(clientSocket)
-            }
+//            for clientSocket in self.clientSockets {
+//                clientSocket.release()
+//            }
             self.clientSockets.removeAll(keepCapacity: true)
             self.clientSockets.removeAll(keepCapacity: true)
         }
         }
     }
     }
@@ -132,21 +131,21 @@ public class HttpServer
         objc_sync_exit(handle)
         objc_sync_exit(handle)
     }
     }
     
     
-    private class func respond(socket: CInt, response: HttpResponse, keepAlive: Bool) throws {
-        try Socket.writeUTF8(socket, string: "HTTP/1.1 \(response.statusCode()) \(response.reasonPhrase())\r\n")
+    private class func respond(socket: Socket, response: HttpResponse, keepAlive: Bool) throws {
+        try socket.writeUTF8("HTTP/1.1 \(response.statusCode()) \(response.reasonPhrase())\r\n")
         
         
         let length = response.body()?.length ?? 0
         let length = response.body()?.length ?? 0
-        try Socket.writeASCII(socket, string: "Content-Length: \(length)\r\n")
+        try socket.writeASCII("Content-Length: \(length)\r\n")
         
         
         if keepAlive {
         if keepAlive {
-            try Socket.writeASCII(socket, string: "Connection: keep-alive\r\n")
+            try socket.writeASCII("Connection: keep-alive\r\n")
         }
         }
         for (name, value) in response.headers() {
         for (name, value) in response.headers() {
-            try Socket.writeASCII(socket, string: "\(name): \(value)\r\n")
+            try socket.writeASCII("\(name): \(value)\r\n")
         }
         }
-        try Socket.writeASCII(socket, string: "\r\n")
+        try socket.writeASCII("\r\n")
         if let body = response.body() {
         if let body = response.body() {
-            try Socket.writeData(socket, data: body)
+            try socket.writeData(body)
         }
         }
     }
     }
 }
 }

+ 128 - 66
Common/Socket.swift

@@ -9,121 +9,183 @@ import Foundation
 /* Low level routines for POSIX sockets */
 /* Low level routines for POSIX sockets */
 
 
 enum SocketError: ErrorType {
 enum SocketError: ErrorType {
-    case SocketInitializationFailed(String?)
-    case SocketOptionInitializationFailed(String?)
-    case BindFailed(String?)
-    case ListenFailed(String?)
-    case WriteFailed(String?)
-    case GetPeerNameFailed(String?)
-    case GetNameInfoFailed(String?)
-    case AcceptFailed(String?)
+    case SocketInitializationFailed(String)
+    case SocketOptionInitializationFailed(String)
+    case BindFailed(String)
+    case ListenFailed(String)
+    case WriteFailed(String)
+    case GetPeerNameFailed(String)
+    case ConvertingPeerNameFailed
+    case GetNameInfoFailed(String)
+    case AcceptFailed(String)
+    case RecvFailed(String)
+
 }
 }
 
 
 let maxPendingConnection: Int32 = 20
 let maxPendingConnection: Int32 = 20
 
 
-struct Socket {
+class Socket : Hashable {
+    let socketId: CInt
+    
+    var hashValue: Int {
+        return Int(self.socketId)
+    }
     
     
-    static func tcpForListen(port: in_port_t = 8080) throws -> CInt {
-        let s = socket(AF_INET, SOCK_STREAM, 0)
-        if s == -1 {
-            throw SocketError.SocketInitializationFailed(String.fromCString(UnsafePointer(strerror(errno))))
+    init(port: in_port_t = 8080) throws {
+        self.socketId = socket(AF_INET, SOCK_STREAM, 0)
+        if self.socketId == -1 {
+            throw SocketError.SocketInitializationFailed(ErrorHandle.errorText)
         }
         }
         
         
         var value: Int32 = 1
         var value: Int32 = 1
-        if setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &value, socklen_t(sizeof(Int32))) == -1 {
-            let details = String.fromCString(UnsafePointer(strerror(errno)))
-            release(s)
+        if setsockopt(self.socketId, SOL_SOCKET, SO_REUSEADDR, &value, socklen_t(sizeof(Int32))) == -1 {
+            let details = ErrorHandle.errorText
+//            self.release()
             throw SocketError.SocketOptionInitializationFailed(details)
             throw SocketError.SocketOptionInitializationFailed(details)
         }
         }
         
         
-        nosigpipe(s)
+        self.nosigpipe()
         
         
         var addr = sockaddr_in(sin_len: __uint8_t(sizeof(sockaddr_in)),
         var addr = sockaddr_in(sin_len: __uint8_t(sizeof(sockaddr_in)),
-            sin_family: sa_family_t(AF_INET),
-            sin_port: 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))
+                               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 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))
         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)))
         memcpy(&sock_addr, &addr, Int(sizeof(sockaddr_in)))
         
         
-        if bind(s, &sock_addr, socklen_t(sizeof(sockaddr_in))) == -1 {
-            let details = String.fromCString(UnsafePointer(strerror(errno)))
-            release(s)
+        if bind(self.socketId, &sock_addr, socklen_t(sizeof(sockaddr_in))) == -1 {
+            let details = ErrorHandle.errorText
+//            self.release()
             throw SocketError.BindFailed(details)
             throw SocketError.BindFailed(details)
         }
         }
         
         
-        if listen(s, maxPendingConnection ) == -1 {
-            let details = String.fromCString(UnsafePointer(strerror(errno)))
-            release(s)
+        if listen(self.socketId, maxPendingConnection ) == -1 {
+            let details = ErrorHandle.errorText
+//            self.release()
             throw SocketError.ListenFailed(details)
             throw SocketError.ListenFailed(details)
         }
         }
-        return s
     }
     }
     
     
-    static func writeUTF8(socket: CInt, string: String) throws {
-        if let nsdata = string.dataUsingEncoding(NSUTF8StringEncoding) {
-            try writeData(socket, data: nsdata)
-        } else {
-            throw SocketError.WriteFailed("dataUsingEncoding(NSUTF8StringEncoding) failed")
-        }
+    private init(socketId: CInt) {
+        self.socketId = socketId
+    }
+    
+    deinit {
+        print("deinit socket")
+        shutdown(self.socketId, SHUT_RDWR)
+        close(self.socketId)
+    }
+    
+    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)));
     }
     }
     
     
-    static func writeASCII(socket: CInt, string: String) throws {
-        if let nsdata = string.dataUsingEncoding(NSASCIIStringEncoding) {
-            try writeData(socket, data: nsdata)
+    class func port_htons(port: in_port_t) -> in_port_t {
+        let isLittleEndian = Int(OSHostByteOrder()) == OSLittleEndian
+        return isLittleEndian ? _OSSwapInt16(port) : port
+    }
+    
+    
+    // MARK: - write methods
+    
+    func writeUTF8(string: String) throws {
+        try self.writeString(string, withEncoding: NSUTF8StringEncoding)
+    }
+    
+    func writeASCII(string: String) throws {
+        try self.writeString(string, withEncoding: NSASCIIStringEncoding)
+    }
+    
+    private func writeString(string: String, withEncoding encoding: NSStringEncoding) throws {
+        if let nsdata = string.dataUsingEncoding(encoding) {
+            try self.writeData(nsdata)
         } else {
         } else {
-            throw SocketError.WriteFailed("dataUsingEncoding(NSASCIIStringEncoding) failed")
+            throw SocketError.WriteFailed("dataUsingEncoding(\(encoding)) failed")
         }
         }
     }
     }
     
     
-    static func writeData(socket: CInt, data: NSData) throws {
+    func writeData(data: NSData) throws {
         var sent = 0
         var sent = 0
         let unsafePointer = UnsafePointer<UInt8>(data.bytes)
         let unsafePointer = UnsafePointer<UInt8>(data.bytes)
         while sent < data.length {
         while sent < data.length {
-            let s = write(socket, unsafePointer + sent, Int(data.length - sent))
+            let s = write(self.socketId, unsafePointer + sent, Int(data.length - sent))
             if s <= 0 {
             if s <= 0 {
-                throw SocketError.WriteFailed(String.fromCString(UnsafePointer(strerror(errno))))
+                throw SocketError.WriteFailed(ErrorHandle.errorText)
             }
             }
             sent += s
             sent += s
         }
         }
     }
     }
     
     
-    static func acceptClientSocket(socket: CInt) throws -> CInt {
+    // MARK: -
+    
+    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 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
         var len: socklen_t = 0
-        let clientSocket = accept(socket, &addr, &len)
+        let clientSocket = accept(self.socketId, &addr, &len)
         if clientSocket == -1 {
         if clientSocket == -1 {
-            throw SocketError.AcceptFailed(String.fromCString(UnsafePointer(strerror(errno))))
+            throw SocketError.AcceptFailed(ErrorHandle.errorText)
         }
         }
-        Socket.nosigpipe(clientSocket)
-        return clientSocket
+        self.nosigpipe()
+        return Socket(socketId: clientSocket)
     }
     }
     
     
-    static func nosigpipe(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 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)
+        }
+        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)
+        }
+        
+        guard let name = String.fromCString(hostBuffer) else {
+            throw SocketError.ConvertingPeerNameFailed
+        }
+        
+        return name
     }
     }
+
+//    func release() {
+//        print("release")
+//        shutdown(self.socketId, SHUT_RDWR)
+//        close(self.socketId)
+//    }
     
     
-    static func port_htons(port: in_port_t) -> in_port_t {
-        let isLittleEndian = Int(OSHostByteOrder()) == OSLittleEndian
-        return isLittleEndian ? _OSSwapInt16(port) : port
-    }
+    // MARK: - basic receiving
     
     
-    static func release(socket: CInt) {
-        shutdown(socket, SHUT_RDWR)
-        close(socket)
+    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])
     }
     }
     
     
-    static func peername(socket: CInt) throws -> String? {
-        var addr = sockaddr(), len: socklen_t = socklen_t(sizeof(sockaddr))
-        if getpeername(socket, &addr, &len) != 0 {
-            throw SocketError.GetPeerNameFailed(String.fromCString(UnsafePointer(strerror(errno))))
+    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)
         }
         }
-        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(String.fromCString(UnsafePointer(strerror(errno))))
-        }
-        return String.fromCString(hostBuffer)
+        return characters
     }
     }
 }
 }
+
+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"
+    }
+}

+ 0 - 27
Common/TestSocket.swift

@@ -1,27 +0,0 @@
-//
-//  TestSocket.swift
-//  Swifter
-//
-//  Created by Clément Nonn on 16/10/2015.
-//  Copyright © 2015 Damian Kołakowski. All rights reserved.
-//
-
-import Foundation
-
-//http://socket.io/get-started/chat/
-
-func testSocket(publicDir: String) -> HttpServer {
-    let server = HttpServer()
-
-    server["/resources/(.+)"] = HttpHandlers.directory(publicDir)
-    
-    server["/"] = { request in
-        if let html = NSData(contentsOfFile:"\(publicDir)/chat.html") {
-            return HttpResponse.RAW(200, "OK", nil, html)
-        } else {
-            return .NotFound
-        }
-    }
-    
-    return server
-}

+ 0 - 22
Resources/chat.html

@@ -1,22 +0,0 @@
-<!doctype html>
-<html>
-    <head>
-        <title>SwiftyIO chat</title>
-        <style>
-            * { margin: 0; padding: 0; box-sizing: border-box; }
-            body { font: 13px Helvetica, Arial; }
-            form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
-            form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
-            form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
-            #messages { list-style-type: none; margin: 0; padding: 0; }
-            #messages li { padding: 5px 10px; }
-            #messages li:nth-child(odd) { background: #eee; }
-            </style>
-    </head>
-    <body>
-        <ul id="messages"></ul>
-        <form action="">
-            <input id="m" autocomplete="off" /><button>Send</button>
-        </form>
-    </body>
-</html>

+ 0 - 119
Swifter.xcodeproj/project.pbxproj

@@ -7,7 +7,6 @@
 	objects = {
 	objects = {
 
 
 /* Begin PBXBuildFile section */
 /* Begin PBXBuildFile section */
-		18447C3F1BD14CF50011C707 /* TestSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18447C3E1BD14CF50011C707 /* TestSocket.swift */; settings = {ASSET_TAGS = (); }; };
 		7C71C5B01A1D52F800682BF0 /* login.html in CopyFiles */ = {isa = PBXBuildFile; fileRef = 98630C061A1C9A9D00478D08 /* login.html */; };
 		7C71C5B01A1D52F800682BF0 /* login.html in CopyFiles */ = {isa = PBXBuildFile; fileRef = 98630C061A1C9A9D00478D08 /* login.html */; };
 		7C71C5B11A1EC49B00682BF0 /* logo.png in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7CB102DF1A17381D00CBA3B4 /* logo.png */; };
 		7C71C5B11A1EC49B00682BF0 /* logo.png in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7CB102DF1A17381D00CBA3B4 /* logo.png */; };
 		7C839B7419422CFF003A6950 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C839B7319422CFF003A6950 /* AppDelegate.swift */; };
 		7C839B7419422CFF003A6950 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C839B7319422CFF003A6950 /* AppDelegate.swift */; };
@@ -32,19 +31,6 @@
 		7CB102DD1A167FFA00CBA3B4 /* DemoServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CB102DC1A167FFA00CBA3B4 /* DemoServer.swift */; };
 		7CB102DD1A167FFA00CBA3B4 /* DemoServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CB102DC1A167FFA00CBA3B4 /* DemoServer.swift */; };
 		7CB102DE1A1680EA00CBA3B4 /* DemoServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CB102DC1A167FFA00CBA3B4 /* DemoServer.swift */; };
 		7CB102DE1A1680EA00CBA3B4 /* DemoServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CB102DC1A167FFA00CBA3B4 /* DemoServer.swift */; };
 		7CB102E01A17381D00CBA3B4 /* logo.png in Resources */ = {isa = PBXBuildFile; fileRef = 7CB102DF1A17381D00CBA3B4 /* logo.png */; };
 		7CB102E01A17381D00CBA3B4 /* logo.png in Resources */ = {isa = PBXBuildFile; fileRef = 7CB102DF1A17381D00CBA3B4 /* logo.png */; };
-		7CEA69AA1BD270F10009F783 /* chat.html in Resources */ = {isa = PBXBuildFile; fileRef = 7CEA69A91BD270F10009F783 /* chat.html */; settings = {ASSET_TAGS = (); }; };
-		7CEA69AF1BD271920009F783 /* HttpResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CA4814B19A2EED00030B30D /* HttpResponse.swift */; };
-		7CEA69B11BD271920009F783 /* HttpParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CA4814A19A2EED00030B30D /* HttpParser.swift */; };
-		7CEA69B21BD271920009F783 /* Socket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CA4814D19A2EED00030B30D /* Socket.swift */; };
-		7CEA69B31BD271920009F783 /* HttpServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CA4814C19A2EED00030B30D /* HttpServer.swift */; };
-		7CEA69B41BD271920009F783 /* chat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CEA69AB1BD271160009F783 /* chat.swift */; settings = {ASSET_TAGS = (); }; };
-		7CEA69B61BD271920009F783 /* TestSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18447C3E1BD14CF50011C707 /* TestSocket.swift */; settings = {ASSET_TAGS = (); }; };
-		7CEA69B71BD271920009F783 /* HttpHandlers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CB102D91A1664B200CBA3B4 /* HttpHandlers.swift */; };
-		7CEA69B81BD271920009F783 /* HttpRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CA4815A19A2F6A60030B30D /* HttpRequest.swift */; };
-		7CEA69BB1BD271920009F783 /* logo.png in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7CB102DF1A17381D00CBA3B4 /* logo.png */; };
-		7CEA69BC1BD271920009F783 /* login.html in CopyFiles */ = {isa = PBXBuildFile; fileRef = 98630C061A1C9A9D00478D08 /* login.html */; };
-		7CEA69BD1BD271920009F783 /* test.json in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7CA4815719A2EF2B0030B30D /* test.json */; };
-		7CEA69C21BD271B20009F783 /* chat.html in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7CEA69A91BD270F10009F783 /* chat.html */; };
 		98630C071A1C9A9D00478D08 /* login.html in Resources */ = {isa = PBXBuildFile; fileRef = 98630C061A1C9A9D00478D08 /* login.html */; };
 		98630C071A1C9A9D00478D08 /* login.html in Resources */ = {isa = PBXBuildFile; fileRef = 98630C061A1C9A9D00478D08 /* login.html */; };
 /* End PBXBuildFile section */
 /* End PBXBuildFile section */
 
 
@@ -61,23 +47,9 @@
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};
-		7CEA69BA1BD271920009F783 /* CopyFiles */ = {
-			isa = PBXCopyFilesBuildPhase;
-			buildActionMask = 12;
-			dstPath = "";
-			dstSubfolderSpec = 7;
-			files = (
-				7CEA69C21BD271B20009F783 /* chat.html in CopyFiles */,
-				7CEA69BB1BD271920009F783 /* logo.png in CopyFiles */,
-				7CEA69BC1BD271920009F783 /* login.html in CopyFiles */,
-				7CEA69BD1BD271920009F783 /* test.json in CopyFiles */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
 /* End PBXCopyFilesBuildPhase section */
 /* End PBXCopyFilesBuildPhase section */
 
 
 /* Begin PBXFileReference section */
 /* Begin PBXFileReference section */
-		18447C3E1BD14CF50011C707 /* TestSocket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestSocket.swift; sourceTree = "<group>"; };
 		7C839B6E19422CFF003A6950 /* Swifter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Swifter.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		7C839B6E19422CFF003A6950 /* Swifter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Swifter.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		7C839B7219422CFF003A6950 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		7C839B7219422CFF003A6950 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		7C839B7319422CFF003A6950 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
 		7C839B7319422CFF003A6950 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@@ -95,9 +67,6 @@
 		7CB102D91A1664B200CBA3B4 /* HttpHandlers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HttpHandlers.swift; sourceTree = "<group>"; };
 		7CB102D91A1664B200CBA3B4 /* HttpHandlers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HttpHandlers.swift; sourceTree = "<group>"; };
 		7CB102DC1A167FFA00CBA3B4 /* DemoServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DemoServer.swift; sourceTree = "<group>"; };
 		7CB102DC1A167FFA00CBA3B4 /* DemoServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DemoServer.swift; sourceTree = "<group>"; };
 		7CB102DF1A17381D00CBA3B4 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = "<group>"; };
 		7CB102DF1A17381D00CBA3B4 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = "<group>"; };
-		7CEA69A91BD270F10009F783 /* chat.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = chat.html; sourceTree = "<group>"; };
-		7CEA69AB1BD271160009F783 /* chat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = chat.swift; sourceTree = "<group>"; };
-		7CEA69C11BD271920009F783 /* SwifterOSXChat */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SwifterOSXChat; sourceTree = BUILT_PRODUCTS_DIR; };
 		98630C061A1C9A9D00478D08 /* login.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = login.html; sourceTree = "<group>"; };
 		98630C061A1C9A9D00478D08 /* login.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = login.html; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 /* End PBXFileReference section */
 
 
@@ -116,13 +85,6 @@
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};
-		7CEA69B91BD271920009F783 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
 /* End PBXFrameworksBuildPhase section */
 /* End PBXFrameworksBuildPhase section */
 
 
 /* Begin PBXGroup section */
 /* Begin PBXGroup section */
@@ -142,7 +104,6 @@
 			children = (
 			children = (
 				7C839B6E19422CFF003A6950 /* Swifter.app */,
 				7C839B6E19422CFF003A6950 /* Swifter.app */,
 				7CA4813B19A2EA8D0030B30D /* SwifterOSX */,
 				7CA4813B19A2EA8D0030B30D /* SwifterOSX */,
-				7CEA69C11BD271920009F783 /* SwifterOSXChat */,
 			);
 			);
 			name = Products;
 			name = Products;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -171,7 +132,6 @@
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
 				7CA4813D19A2EA8D0030B30D /* main.swift */,
 				7CA4813D19A2EA8D0030B30D /* main.swift */,
-				7CEA69AB1BD271160009F783 /* chat.swift */,
 			);
 			);
 			path = SwifterOSX;
 			path = SwifterOSX;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -186,7 +146,6 @@
 				7CA4814C19A2EED00030B30D /* HttpServer.swift */,
 				7CA4814C19A2EED00030B30D /* HttpServer.swift */,
 				7CA4814D19A2EED00030B30D /* Socket.swift */,
 				7CA4814D19A2EED00030B30D /* Socket.swift */,
 				7CB102DC1A167FFA00CBA3B4 /* DemoServer.swift */,
 				7CB102DC1A167FFA00CBA3B4 /* DemoServer.swift */,
-				18447C3E1BD14CF50011C707 /* TestSocket.swift */,
 			);
 			);
 			path = Common;
 			path = Common;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -194,7 +153,6 @@
 		7CA4815619A2EF2B0030B30D /* Resources */ = {
 		7CA4815619A2EF2B0030B30D /* Resources */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
-				7CEA69A91BD270F10009F783 /* chat.html */,
 				98630C061A1C9A9D00478D08 /* login.html */,
 				98630C061A1C9A9D00478D08 /* login.html */,
 				7CB102DF1A17381D00CBA3B4 /* logo.png */,
 				7CB102DF1A17381D00CBA3B4 /* logo.png */,
 				7CA4815719A2EF2B0030B30D /* test.json */,
 				7CA4815719A2EF2B0030B30D /* test.json */,
@@ -239,23 +197,6 @@
 			productReference = 7CA4813B19A2EA8D0030B30D /* SwifterOSX */;
 			productReference = 7CA4813B19A2EA8D0030B30D /* SwifterOSX */;
 			productType = "com.apple.product-type.tool";
 			productType = "com.apple.product-type.tool";
 		};
 		};
-		7CEA69AD1BD271920009F783 /* SwifterOSXChat */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 7CEA69BE1BD271920009F783 /* Build configuration list for PBXNativeTarget "SwifterOSXChat" */;
-			buildPhases = (
-				7CEA69AE1BD271920009F783 /* Sources */,
-				7CEA69B91BD271920009F783 /* Frameworks */,
-				7CEA69BA1BD271920009F783 /* CopyFiles */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = SwifterOSXChat;
-			productName = SwifterOSX;
-			productReference = 7CEA69C11BD271920009F783 /* SwifterOSXChat */;
-			productType = "com.apple.product-type.tool";
-		};
 /* End PBXNativeTarget section */
 /* End PBXNativeTarget section */
 
 
 /* Begin PBXProject section */
 /* Begin PBXProject section */
@@ -289,7 +230,6 @@
 			targets = (
 			targets = (
 				7C839B6D19422CFF003A6950 /* Swifter */,
 				7C839B6D19422CFF003A6950 /* Swifter */,
 				7CA4813A19A2EA8D0030B30D /* SwifterOSX */,
 				7CA4813A19A2EA8D0030B30D /* SwifterOSX */,
-				7CEA69AD1BD271920009F783 /* SwifterOSXChat */,
 			);
 			);
 		};
 		};
 /* End PBXProject section */
 /* End PBXProject section */
@@ -299,7 +239,6 @@
 			isa = PBXResourcesBuildPhase;
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
 			files = (
 			files = (
-				7CEA69AA1BD270F10009F783 /* chat.html in Resources */,
 				7CB102E01A17381D00CBA3B4 /* logo.png in Resources */,
 				7CB102E01A17381D00CBA3B4 /* logo.png in Resources */,
 				7C839B7919422CFF003A6950 /* Main.storyboard in Resources */,
 				7C839B7919422CFF003A6950 /* Main.storyboard in Resources */,
 				98630C071A1C9A9D00478D08 /* login.html in Resources */,
 				98630C071A1C9A9D00478D08 /* login.html in Resources */,
@@ -319,7 +258,6 @@
 				7CB102DA1A1664B200CBA3B4 /* HttpHandlers.swift in Sources */,
 				7CB102DA1A1664B200CBA3B4 /* HttpHandlers.swift in Sources */,
 				7CB102DD1A167FFA00CBA3B4 /* DemoServer.swift in Sources */,
 				7CB102DD1A167FFA00CBA3B4 /* DemoServer.swift in Sources */,
 				7C839B7619422CFF003A6950 /* ViewController.swift in Sources */,
 				7C839B7619422CFF003A6950 /* ViewController.swift in Sources */,
-				18447C3F1BD14CF50011C707 /* TestSocket.swift in Sources */,
 				7CA4815419A2EED00030B30D /* Socket.swift in Sources */,
 				7CA4815419A2EED00030B30D /* Socket.swift in Sources */,
 				7CA4815219A2EED00030B30D /* HttpServer.swift in Sources */,
 				7CA4815219A2EED00030B30D /* HttpServer.swift in Sources */,
 				7CA4814E19A2EED00030B30D /* HttpParser.swift in Sources */,
 				7CA4814E19A2EED00030B30D /* HttpParser.swift in Sources */,
@@ -343,21 +281,6 @@
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};
-		7CEA69AE1BD271920009F783 /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				7CEA69AF1BD271920009F783 /* HttpResponse.swift in Sources */,
-				7CEA69B11BD271920009F783 /* HttpParser.swift in Sources */,
-				7CEA69B21BD271920009F783 /* Socket.swift in Sources */,
-				7CEA69B31BD271920009F783 /* HttpServer.swift in Sources */,
-				7CEA69B41BD271920009F783 /* chat.swift in Sources */,
-				7CEA69B61BD271920009F783 /* TestSocket.swift in Sources */,
-				7CEA69B71BD271920009F783 /* HttpHandlers.swift in Sources */,
-				7CEA69B81BD271920009F783 /* HttpRequest.swift in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
 /* End PBXSourcesBuildPhase section */
 /* End PBXSourcesBuildPhase section */
 
 
 /* Begin PBXVariantGroup section */
 /* Begin PBXVariantGroup section */
@@ -515,39 +438,6 @@
 			};
 			};
 			name = Release;
 			name = Release;
 		};
 		};
-		7CEA69BF1BD271920009F783 /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				CLANG_ENABLE_MODULES = YES;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"DEBUG=1",
-					"$(inherited)",
-				);
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
-				MACOSX_DEPLOYMENT_TARGET = 10.9;
-				MTL_ENABLE_DEBUG_INFO = YES;
-				ONLY_ACTIVE_ARCH = YES;
-				PRODUCT_NAME = "$(TARGET_NAME)";
-				SDKROOT = macosx;
-				SWIFT_OBJC_BRIDGING_HEADER = "";
-				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
-			};
-			name = Debug;
-		};
-		7CEA69C01BD271920009F783 /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				CLANG_ENABLE_MODULES = YES;
-				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
-				MACOSX_DEPLOYMENT_TARGET = 10.9;
-				MTL_ENABLE_DEBUG_INFO = NO;
-				PRODUCT_NAME = "$(TARGET_NAME)";
-				SDKROOT = macosx;
-				SWIFT_OBJC_BRIDGING_HEADER = "";
-			};
-			name = Release;
-		};
 /* End XCBuildConfiguration section */
 /* End XCBuildConfiguration section */
 
 
 /* Begin XCConfigurationList section */
 /* Begin XCConfigurationList section */
@@ -578,15 +468,6 @@
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 			defaultConfigurationName = Release;
 		};
 		};
-		7CEA69BE1BD271920009F783 /* Build configuration list for PBXNativeTarget "SwifterOSXChat" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				7CEA69BF1BD271920009F783 /* Debug */,
-				7CEA69C01BD271920009F783 /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
 /* End XCConfigurationList section */
 /* End XCConfigurationList section */
 	};
 	};
 	rootObject = 7C839B6619422CFF003A6950 /* Project object */;
 	rootObject = 7C839B6619422CFF003A6950 /* Project object */;

+ 0 - 19
SwifterOSX/chat.swift

@@ -1,19 +0,0 @@
-//
-//  chat.swift
-//  Swifter
-//
-//  Created by Damian Kolakowski on 17/10/15.
-//  Copyright © 2015 Damian Kołakowski. All rights reserved.
-//
-
-import Foundation
-
-let server = testSocket(NSBundle.mainBundle().resourcePath!)
-
-do {
-    try server.start(9080)
-    print("Server has started ( port = 9080 ). Try to connect now...")
-    NSRunLoop.mainRunLoop().run()
-} catch {
-    print("Server start error: \(error)")
-}

+ 1 - 4
SwifterOSX/main.swift

@@ -14,7 +14,4 @@ do {
     NSRunLoop.mainRunLoop().run()
     NSRunLoop.mainRunLoop().run()
 } catch {
 } catch {
     print("Server start error: \(error)")
     print("Server start error: \(error)")
-}
-
-
-
+}