0001 // 0002 // HttpServer.swift 0003 // Swifter 0004 // 0005 // Copyright (c) 2014-2016 Damian KoĊakowski. All rights reserved. 0006 // 0007 0008 import Foundation 0009 0010 #if os(Linux) 0011 import Glibc 0012 import NSLinux 0013 #endif 0014 0015 public class HttpServerIO{ 0016 0017 private var listenSocket
HttpServer.swift:10 public class HttpServer: HttpServerIO {: Socket = Socket(socketFileDescriptor: -1) 0018 private var clientSockets
HttpServerIO.swift:23 listenSocket = try Socket.tcpSocketForListen(listenPort)HttpServerIO.swift:25 while let socket = try? self.listenSocket.acceptClientSocket() {HttpServerIO.swift:41 listenSocket.release(): Set<Socket> = [] 0019 private let clientSocketsLock
HttpServerIO.swift:27 self.clientSockets.insert(socket)HttpServerIO.swift:32 self.clientSockets.remove(socket)HttpServerIO.swift:43 for socket in self.clientSockets {HttpServerIO.swift:46 self.clientSockets.removeAll(keepCapacity: true)= NSLock() 0020 0021 public func start(listenPort: in_port_t = 8080) throws { 0022 stop() 0023 listenSocket = try Socket.tcpSocketForListen(listenPort) 0024 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) { 0025 while let socket = try? self.listenSocket.acceptClientSocket() { 0026 self.lock(self.clientSocketsLock) { 0027 self.clientSockets.insert(socket) 0028 } 0029 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), { 0030 self.handleConnection(socket) 0031 self.lock(self.clientSocketsLock) { 0032 self.clientSockets.remove(socket) 0033 } 0034 }) 0035 } 0036 self.stop() 0037 } 0038 } 0039 0040 public func stop
HttpServerIO.swift:26 self.lock(self.clientSocketsLock) {HttpServerIO.swift:31 self.lock(self.clientSocketsLock) {HttpServerIO.swift:42 lock(self.clientSocketsLock) {() { 0041 listenSocket.release() 0042 lock(self.clientSocketsLock) { 0043 for socket in self.clientSockets { 0044 socket.shutdwn() 0045 } 0046 self.clientSockets.removeAll(keepCapacity: true) 0047 } 0048 } 0049 0050 public func dispatch
HttpServerIO.swift:22 stop()HttpServerIO.swift:36 self.stop()(method: String, path: String) -> ([String: String], HttpRequest -> HttpResponse) { 0051 return ([:], { _ in HttpResponse.NotFound }) 0052 } 0053 0054 private func handleConnection
HttpServer.swift:50 return super.dispatch(method, path: path)HttpServerIO.swift:59 let (params, handler) = self.dispatch(request.method, path: request.path)(socket: Socket) { 0055 let address = try? socket.peername() 0056 let parser = HttpParser() 0057 while let request = try? parser.readHttpRequest(socket) { 0058 let request = request 0059 let (params, handler) = self.dispatch(request.method, path: request.path) 0060 request.address = address 0061 request.params = params; 0062 let response = handler(request) 0063 var keepConnection = parser.supportsKeepAlive(request.headers) 0064 do { 0065 keepConnection = try self.respond(socket, response: response, keepAlive: keepConnection) 0066 } catch { 0067 print("Failed to send response: \(error)") 0068 break 0069 } 0070 if let session = response.socketSession() { 0071 session(socket) 0072 break 0073 } 0074 if !keepConnection { break } 0075 } 0076 socket.release() 0077 } 0078 0079 private func lock
HttpServerIO.swift:30 self.handleConnection(socket)(handle: NSLock, closure: () -> ()) { 0080 handle.lock() 0081 closure() 0082 handle.unlock(); 0083 } 0084 0085 private struct InnerWriteContext
HttpServerIO.swift:26 self.lock(self.clientSocketsLock) {HttpServerIO.swift:31 self.lock(self.clientSocketsLock) {HttpServerIO.swift:42 lock(self.clientSocketsLock) {: HttpResponseBodyWriter { 0086 let socket
HttpServerIO.swift:119 let context = InnerWriteContext(socket: socket): Socket 0087 func write(data: [UInt8]) { 0088 write(ArraySlice(data)) 0089 } 0090 func write
HttpServerIO.swift:92 try socket.writeUInt8(data)(data: ArraySlice<UInt8>) { 0091 do { 0092 try socket.writeUInt8(data) 0093 } catch { 0094 print("\(error)") 0095 } 0096 } 0097 } 0098 0099 private func respond
HttpServerIO.swift:88 write(ArraySlice(data))(socket: Socket, response: HttpResponse, keepAlive: Bool) throws -> Bool { 0100 try socket.writeUTF8("HTTP/1.1 \(response.statusCode()) \(response.reasonPhrase())\r\n") 0101 0102 let content = response.content() 0103 0104 if content.length >= 0 { 0105 try socket.writeUTF8("Content-Length: \(content.length)\r\n") 0106 } 0107 0108 if keepAlive && content.length != -1 { 0109 try socket.writeUTF8("Connection: keep-alive\r\n") 0110 } 0111 0112 for (name, value) in response.headers() { 0113 try socket.writeUTF8("\(name): \(value)\r\n") 0114 } 0115 0116 try socket.writeUTF8("\r\n") 0117 0118 if let writeClosure = content.write { 0119 let context = InnerWriteContext(socket: socket) 0120 try writeClosure(context) 0121 } 0122 0123 return keepAlive && content.length != -1; 0124 } 0125 } 0126
HttpServerIO.swift:65 keepConnection = try self.respond(socket, response: response, keepAlive: keepConnection)