0001 import Foundation 0002 0003 #if os(Linux) 0004 import Glibc 0005 #endif 0006 0007 public class SocketServer: ServerDriver { 0008 0009 /// Turns received `Request`s into a `Response`s 0010 public var delegate
Application.swift:60 public init(router: RouterDriver = BranchRouter(), server: ServerDriver = SocketServer()) {: ServerDriverDelegate? 0011 0012 init
SocketServer.swift:92 guard let delegate = self.delegate else {() { 0013 0014 } 0015 0016 /** 0017 Starts the server on a given port. 0018 0019 - parameter port: The port to listen on. 0020 */ 0021 public func boot(port port: Int) throws { 0022 //stop the server if it's running 0023 self.halt() 0024 0025 //open a socket, might fail 0026 self.listenSocket = try Socket.tcpSocketForListen(UInt16(port)) 0027 0028 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) { 0029 0030 //creates the infinite loop that will wait for client connections 0031 while let socket = try? self.listenSocket.acceptClientSocket() { 0032 0033 //wait for lock to notify a new connection 0034 self.lock(self.clientSocketsLock) { 0035 //keep track of open sockets 0036 self.clientSockets.insert(socket) 0037 } 0038 0039 //handle connection in background thread 0040 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), { 0041 self.handleConnection(socket) 0042 0043 //set lock to wait for another connection 0044 self.lock(self.clientSocketsLock) { 0045 self.clientSockets.remove(socket) 0046 } 0047 }) 0048 } 0049 0050 //stop the server in case something didn't work 0051 self.halt() 0052 } 0053 0054 } 0055 0056 /** 0057 Stops the server by closing all connected 0058 client `Socket`s 0059 */ 0060 public func halt
Application.swift:60 public init(router: RouterDriver = BranchRouter(), server: ServerDriver = SocketServer()) {() { 0061 //free the port 0062 self.listenSocket.release() 0063 0064 //shutdown all client sockets 0065 self.lock(self.clientSocketsLock) { 0066 for socket in self.clientSockets { 0067 socket.shutdwn() 0068 } 0069 self.clientSockets.removeAll(keepCapacity: true) 0070 } 0071 } 0072 0073 ///A `Socket` open to the port the server is listening on. Usually 80. 0074 private var listenSocket
SocketServer.swift:23 self.halt()SocketServer.swift:51 self.halt(): Socket = Socket(socketFileDescriptor: -1) 0075 0076 ///A set of connected client `Socket`s. 0077 private var clientSockets
SocketServer.swift:26 self.listenSocket = try Socket.tcpSocketForListen(UInt16(port))SocketServer.swift:31 while let socket = try? self.listenSocket.acceptClientSocket() {SocketServer.swift:62 self.listenSocket.release(): Set<Socket> = [] 0078 0079 ///The shared lock for notifying new connections. 0080 private let clientSocketsLock
SocketServer.swift:36 self.clientSockets.insert(socket)SocketServer.swift:45 self.clientSockets.remove(socket)SocketServer.swift:66 for socket in self.clientSockets {SocketServer.swift:69 self.clientSockets.removeAll(keepCapacity: true)= NSLock() 0081 0082 /** 0083 Handles incoming `Socket` connections by parsing 0084 the HTTP request into a `Request` and writing 0085 a `Response` back to the `Socket`. 0086 */ 0087 func handleConnection
SocketServer.swift:34 self.lock(self.clientSocketsLock) {SocketServer.swift:44 self.lock(self.clientSocketsLock) {SocketServer.swift:65 self.lock(self.clientSocketsLock) {(socket: Socket) { 0088 defer { 0089 socket.release() 0090 } 0091 0092 guard let delegate = self.delegate else { 0093 print("No server delegate") 0094 return 0095 } 0096 0097 let parser = SocketParser() 0098 0099 while let request = try? parser.readHttpRequest(socket) { 0100 let response = delegate.serverDriverDidReceiveRequest(request) 0101 0102 var keepConnection = request.supportsKeepAlive 0103 do { 0104 keepConnection = try self.respond(socket, response: response, keepAlive: keepConnection) 0105 } catch { 0106 print("Failed to send response: \(error)") 0107 break 0108 } 0109 if !keepConnection { break } 0110 } 0111 0112 } 0113 0114 0115 0116 /** 0117 Locking mechanism for holding thread until a 0118 new socket connection is ready. 0119 0120 - parameter handle: NSLock 0121 - parameter closure: Code that will run when the lock has been altered. 0122 */ 0123 private func lock
SocketServer.swift:41 self.handleConnection(socket)(handle: NSLock, closure: () -> ()) { 0124 handle.lock() 0125 closure() 0126 handle.unlock(); 0127 } 0128 0129 /** 0130 Writes the `Response` to the client `Socket`. 0131 */ 0132 private func respond
SocketServer.swift:34 self.lock(self.clientSocketsLock) {SocketServer.swift:44 self.lock(self.clientSocketsLock) {SocketServer.swift:65 self.lock(self.clientSocketsLock) {(socket: Socket, response: Response, keepAlive: Bool) throws -> Bool { 0133 if let response = response as? AsyncResponse { 0134 try response.writer(socket) 0135 } else { 0136 try socket.writeUTF8("HTTP/1.1 \(response.status.code) \(response.reasonPhrase)\r\n") 0137 0138 var headers = response.headers 0139 0140 if response.data.count >= 0 { 0141 headers["Content-Length"] = "\(response.data.count)" 0142 } 0143 0144 if keepAlive && response.data.count != -1 { 0145 headers["Connection"] = "keep-alive" 0146 } 0147 0148 for (name, value) in headers { 0149 try socket.writeUTF8("\(name): \(value)\r\n") 0150 } 0151 0152 try socket.writeUTF8("\r\n") 0153 0154 try socket.writeUInt8(response.data) 0155 } 0156 0157 return keepAlive && response.data.count != -1; 0158 } 0159 } 0160
SocketServer.swift:104 keepConnection = try self.respond(socket, response: response, keepAlive: keepConnection)