0001 /** 0002 Copyright (c) 2014, Damian KoĊakowski 0003 All rights reserved. 0004 0005 Redistribution and use in source and binary forms, with or without 0006 modification, are permitted provided that the following conditions are met: 0007 0008 * Redistributions of source code must retain the above copyright notice, this 0009 list of conditions and the following disclaimer. 0010 0011 * Redistributions in binary form must reproduce the above copyright notice, 0012 this list of conditions and the following disclaimer in the documentation 0013 and/or other materials provided with the distribution. 0014 0015 * Neither the name of the {organization} nor the names of its 0016 contributors may be used to endorse or promote products derived from 0017 this software without specific prior written permission. 0018 0019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 0020 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0021 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 0022 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 0023 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 0024 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 0025 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 0026 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 0027 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 0028 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0029 */ 0030 0031 #if os(Linux) 0032 import Glibc 0033 #else 0034 import Foundation 0035 #endif 0036 0037 public enum SocketError: ErrorType { 0038 case SocketCreationFailed
Socket.swift:61 throw SocketError.SocketCreationFailed(Socket.descriptionOfLastError())Socket.swift:68 throw SocketError.SocketSettingReUseAddrFailed(details)Socket.swift:93 throw SocketError.BindFailed(details)Socket.swift:99 throw SocketError.ListenFailed(details)Socket.swift:125 throw SocketError.AcceptFailed(Socket.descriptionOfLastError())Socket.swift:145 throw SocketError.WriteFailed(Socket.descriptionOfLastError())Socket.swift:156 throw SocketError.RecvFailed(Socket.descriptionOfLastError())Socket.swift:184 throw SocketError.GetPeerNameFailed(Socket.descriptionOfLastError())Socket.swift:188 throw SocketError.GetNameInfoFailed(Socket.descriptionOfLastError())Socket.swift:191 throw SocketError.ConvertingPeerNameFailed(String) 0039 case SocketSettingReUseAddrFailed
Socket.swift:61 throw SocketError.SocketCreationFailed(Socket.descriptionOfLastError())(String) 0040 case BindFailed
Socket.swift:68 throw SocketError.SocketSettingReUseAddrFailed(details)(String) 0041 case ListenFailed
Socket.swift:93 throw SocketError.BindFailed(details)(String) 0042 case WriteFailed
Socket.swift:99 throw SocketError.ListenFailed(details)(String) 0043 case GetPeerNameFailed
Socket.swift:145 throw SocketError.WriteFailed(Socket.descriptionOfLastError())(String) 0044 case ConvertingPeerNameFailed
Socket.swift:184 throw SocketError.GetPeerNameFailed(Socket.descriptionOfLastError())0045 case GetNameInfoFailed
Socket.swift:191 throw SocketError.ConvertingPeerNameFailed(String) 0046 case AcceptFailed
Socket.swift:188 throw SocketError.GetNameInfoFailed(Socket.descriptionOfLastError())(String) 0047 case RecvFailed
Socket.swift:125 throw SocketError.AcceptFailed(Socket.descriptionOfLastError())(String) 0048 } 0049 0050 public class Socket
Socket.swift:156 throw SocketError.RecvFailed(Socket.descriptionOfLastError()): Hashable, Equatable { 0051 0052 public class func tcpSocketForListen
Response.swift:50 public typealias Writer = Socket throws -> VoidSocket.swift:52 public class func tcpSocketForListen(port: in_port_t, maxPendingConnection: Int32 = SOMAXCONN) throws -> Socket {Socket.swift:61 throw SocketError.SocketCreationFailed(Socket.descriptionOfLastError())Socket.swift:66 let details = Socket.descriptionOfLastError()Socket.swift:67 Socket.release(socketFileDescriptor)Socket.swift:70 Socket.setNoSigPipe(socketFileDescriptor)Socket.swift:82 addr.sin_port = Socket.htonsPort(port)Socket.swift:91 let details = Socket.descriptionOfLastError()Socket.swift:92 Socket.release(socketFileDescriptor)Socket.swift:97 let details = Socket.descriptionOfLastError()Socket.swift:98 Socket.release(socketFileDescriptor)Socket.swift:101 return Socket(socketFileDescriptor: socketFileDescriptor)Socket.swift:113 Socket.release(self.socketFileDescriptor)Socket.swift:117 Socket.shutdwn(self.socketFileDescriptor)Socket.swift:120 func acceptClientSocket() throws -> Socket {Socket.swift:125 throw SocketError.AcceptFailed(Socket.descriptionOfLastError())Socket.swift:127 Socket.setNoSigPipe(clientSocket)Socket.swift:128 return Socket(socketFileDescriptor: clientSocket)Socket.swift:145 throw SocketError.WriteFailed(Socket.descriptionOfLastError())Socket.swift:156 throw SocketError.RecvFailed(Socket.descriptionOfLastError())Socket.swift:169 if n > Socket.CR { characters.append(Character(UnicodeScalar(n))) }Socket.swift:170 } while n != Socket.NLSocket.swift:184 throw SocketError.GetPeerNameFailed(Socket.descriptionOfLastError())Socket.swift:188 throw SocketError.GetNameInfoFailed(Socket.descriptionOfLastError())Socket.swift:240 public func ==(socket1: Socket, socket2: Socket) -> Bool {Socket.swift:240 public func ==(socket1: Socket, socket2: Socket) -> Bool {SocketParser.swift:40 func readHttpRequest(socket: Socket) throws -> Request {SocketParser.swift:67 private func readBody(socket: Socket, size: Int) throws -> [UInt8] {SocketParser.swift:82 private func readHeaders(socket: Socket) throws -> [String: String] {SocketServer.swift:26 self.listenSocket = try Socket.tcpSocketForListen(UInt16(port))SocketServer.swift:74 private var listenSocket: Socket = Socket(socketFileDescriptor: -1)SocketServer.swift:74 private var listenSocket: Socket = Socket(socketFileDescriptor: -1)SocketServer.swift:77 private var clientSockets: Set<Socket> = []SocketServer.swift:87 func handleConnection(socket: Socket) {SocketServer.swift:132 private func respond(socket: Socket, response: Response, keepAlive: Bool) throws -> Bool {(port: in_port_t, maxPendingConnection: Int32 = SOMAXCONN) throws -> Socket { 0053 0054 #if os(Linux) 0055 let socketFileDescriptor = socket(AF_INET, Int32(SOCK_STREAM.rawValue), 0) 0056 #else 0057 let socketFileDescriptor = socket(AF_INET, SOCK_STREAM, 0) 0058 #endif 0059 0060 if socketFileDescriptor == -1 { 0061 throw SocketError.SocketCreationFailed(Socket.descriptionOfLastError()) 0062 } 0063 0064 var value: Int32 = 1 0065 if setsockopt(socketFileDescriptor, SOL_SOCKET, SO_REUSEADDR, &value, socklen_t(sizeof(Int32))) == -1 { 0066 let details = Socket.descriptionOfLastError() 0067 Socket.release(socketFileDescriptor) 0068 throw SocketError.SocketSettingReUseAddrFailed(details) 0069 } 0070 Socket.setNoSigPipe(socketFileDescriptor) 0071 0072 #if os(Linux) 0073 var addr = sockaddr_in() 0074 addr.sin_family = sa_family_t(AF_INET) 0075 addr.sin_port = Socket.htonsPort(port) 0076 addr.sin_addr = in_addr(s_addr: in_addr_t(0)) 0077 addr.sin_zero = (0, 0, 0, 0, 0, 0, 0, 0) 0078 #else 0079 var addr = sockaddr_in() 0080 addr.sin_len = __uint8_t(sizeof(sockaddr_in)) 0081 addr.sin_family = sa_family_t(AF_INET) 0082 addr.sin_port = Socket.htonsPort(port) 0083 addr.sin_addr = in_addr(s_addr: inet_addr("0.0.0.0")) 0084 addr.sin_zero = (0, 0, 0, 0, 0, 0, 0, 0) 0085 #endif 0086 0087 var bind_addr = sockaddr() 0088 memcpy(&bind_addr, &addr, Int(sizeof(sockaddr_in))) 0089 0090 if bind(socketFileDescriptor, &bind_addr, socklen_t(sizeof(sockaddr_in))) == -1 { 0091 let details = Socket.descriptionOfLastError() 0092 Socket.release(socketFileDescriptor) 0093 throw SocketError.BindFailed(details) 0094 } 0095 0096 if listen(socketFileDescriptor, maxPendingConnection ) == -1 { 0097 let details = Socket.descriptionOfLastError() 0098 Socket.release(socketFileDescriptor) 0099 throw SocketError.ListenFailed(details) 0100 } 0101 return Socket(socketFileDescriptor: socketFileDescriptor) 0102 } 0103 0104 private let socketFileDescriptor
SocketServer.swift:26 self.listenSocket = try Socket.tcpSocketForListen(UInt16(port)): Int32 0105 0106 init
Socket.swift:107 self.socketFileDescriptor = socketFileDescriptorSocket.swift:110 public var hashValue: Int { return Int(self.socketFileDescriptor) }Socket.swift:113 Socket.release(self.socketFileDescriptor)Socket.swift:117 Socket.shutdwn(self.socketFileDescriptor)Socket.swift:123 let clientSocket = accept(self.socketFileDescriptor, &addr, &len)Socket.swift:142 let s = write(self.socketFileDescriptor, $0.baseAddress + sent, Int(data.count - sent))Socket.swift:154 let next = recv(self.socketFileDescriptor as Int32, &buffer, Int(buffer.count), 0)Socket.swift:183 if getpeername(self.socketFileDescriptor, &addr, &len) != 0 {Socket.swift:241 return socket1.socketFileDescriptor == socket2.socketFileDescriptorSocket.swift:241 return socket1.socketFileDescriptor == socket2.socketFileDescriptor(socketFileDescriptor: Int32) { 0107 self.socketFileDescriptor = socketFileDescriptor 0108 } 0109 0110 public var hashValue: Int { return Int(self.socketFileDescriptor) } 0111 0112 public func release
Socket.swift:101 return Socket(socketFileDescriptor: socketFileDescriptor)Socket.swift:128 return Socket(socketFileDescriptor: clientSocket)SocketServer.swift:74 private var listenSocket: Socket = Socket(socketFileDescriptor: -1)() { 0113 Socket.release(self.socketFileDescriptor) 0114 } 0115 0116 public func shutdwn
SocketServer.swift:62 self.listenSocket.release()SocketServer.swift:89 socket.release()() { 0117 Socket.shutdwn(self.socketFileDescriptor) 0118 } 0119 0120 func acceptClientSocket
SocketServer.swift:67 socket.shutdwn()() throws -> Socket { 0121 var addr = sockaddr() 0122 var len: socklen_t = 0 0123 let clientSocket = accept(self.socketFileDescriptor, &addr, &len) 0124 if clientSocket == -1 { 0125 throw SocketError.AcceptFailed(Socket.descriptionOfLastError()) 0126 } 0127 Socket.setNoSigPipe(clientSocket) 0128 return Socket(socketFileDescriptor: clientSocket) 0129 } 0130 0131 public func writeUTF8
SocketServer.swift:31 while let socket = try? self.listenSocket.acceptClientSocket() {(string: String) throws { 0132 try writeUInt8([UInt8](string.utf8)) 0133 } 0134 0135 public func writeUInt8
SocketServer.swift:136 try socket.writeUTF8("HTTP/1.1 \(response.status.code) \(response.reasonPhrase)\r\n")SocketServer.swift:149 try socket.writeUTF8("\(name): \(value)\r\n")SocketServer.swift:152 try socket.writeUTF8("\r\n")(data: [UInt8]) throws { 0136 try data.withUnsafeBufferPointer { 0137 var sent = 0 0138 while sent < data.count { 0139 #if os(Linux) 0140 let s = send(self.socketFileDescriptor, $0.baseAddress + sent, Int(data.count - sent), Int32(MSG_NOSIGNAL)) 0141 #else 0142 let s = write(self.socketFileDescriptor, $0.baseAddress + sent, Int(data.count - sent)) 0143 #endif 0144 if s <= 0 { 0145 throw SocketError.WriteFailed(Socket.descriptionOfLastError()) 0146 } 0147 sent += s 0148 } 0149 } 0150 } 0151 0152 public func read
Socket.swift:132 try writeUInt8([UInt8](string.utf8))SocketServer.swift:154 try socket.writeUInt8(response.data)() throws -> UInt8 { 0153 var buffer = [UInt8](count: 1, repeatedValue: 0) 0154 let next = recv(self.socketFileDescriptor as Int32, &buffer, Int(buffer.count), 0) 0155 if next <= 0 { 0156 throw SocketError.RecvFailed(Socket.descriptionOfLastError()) 0157 } 0158 return buffer[0] 0159 } 0160 0161 private static let CR
Socket.swift:168 n = try self.read()SocketParser.swift:72 body.append(try socket.read())= UInt8(13) 0162 private static let NL
Socket.swift:169 if n > Socket.CR { characters.append(Character(UnicodeScalar(n))) }= UInt8(10) 0163 0164 public func readLine
Socket.swift:170 } while n != Socket.NL() throws -> String { 0165 var characters: String = "" 0166 var n: UInt8 = 0 0167 repeat { 0168 n = try self.read() 0169 if n > Socket.CR { characters.append(Character(UnicodeScalar(n))) } 0170 } while n != Socket.NL 0171 return characters 0172 } 0173 0174 var cachedPeerName
SocketParser.swift:41 let requestLine = try RequestLine(string: socket.readLine())SocketParser.swift:86 let headerLine = try socket.readLine(): String? 0175 0176 public func peername
Socket.swift:177 if let name = self.cachedPeerName {Socket.swift:194 self.cachedPeerName = name() throws -> String { 0177 if let name = self.cachedPeerName { 0178 return name 0179 } 0180 0181 0182 var addr = sockaddr(), len: socklen_t = socklen_t(sizeof(sockaddr)) 0183 if getpeername(self.socketFileDescriptor, &addr, &len) != 0 { 0184 throw SocketError.GetPeerNameFailed(Socket.descriptionOfLastError()) 0185 } 0186 var hostBuffer = [CChar](count: Int(NI_MAXHOST), repeatedValue: 0) 0187 if getnameinfo(&addr, len, &hostBuffer, socklen_t(hostBuffer.count), nil, 0, NI_NUMERICHOST) != 0 { 0188 throw SocketError.GetNameInfoFailed(Socket.descriptionOfLastError()) 0189 } 0190 guard let name = String.fromCString(hostBuffer) else { 0191 throw SocketError.ConvertingPeerNameFailed 0192 } 0193 0194 self.cachedPeerName = name 0195 return name 0196 } 0197 0198 private class func descriptionOfLastError
SocketParser.swift:47 let address = try? socket.peername()() -> String { 0199 return String.fromCString(UnsafePointer(strerror(errno))) ?? "Error: \(errno)" 0200 } 0201 0202 private class func setNoSigPipe
Socket.swift:61 throw SocketError.SocketCreationFailed(Socket.descriptionOfLastError())Socket.swift:66 let details = Socket.descriptionOfLastError()Socket.swift:91 let details = Socket.descriptionOfLastError()Socket.swift:97 let details = Socket.descriptionOfLastError()Socket.swift:125 throw SocketError.AcceptFailed(Socket.descriptionOfLastError())Socket.swift:145 throw SocketError.WriteFailed(Socket.descriptionOfLastError())Socket.swift:156 throw SocketError.RecvFailed(Socket.descriptionOfLastError())Socket.swift:184 throw SocketError.GetPeerNameFailed(Socket.descriptionOfLastError())Socket.swift:188 throw SocketError.GetNameInfoFailed(Socket.descriptionOfLastError())(socket: Int32) { 0203 #if os(Linux) 0204 // There is no SO_NOSIGPIPE in Linux (nor some other systems). You can instead use the MSG_NOSIGNAL flag when calling send(), 0205 // or use signal(SIGPIPE, SIG_IGN) to make your entire application ignore SIGPIPE. 0206 #else 0207 // Prevents crashes when blocking calls are pending and the app is paused ( via Home button ). 0208 var no_sig_pipe: Int32 = 1 0209 setsockopt(socket, SOL_SOCKET, SO_NOSIGPIPE, &no_sig_pipe, socklen_t(sizeof(Int32))) 0210 #endif 0211 } 0212 0213 private class func shutdwn
Socket.swift:70 Socket.setNoSigPipe(socketFileDescriptor)Socket.swift:127 Socket.setNoSigPipe(clientSocket)(socket: Int32) { 0214 #if os(Linux) 0215 shutdown(socket, Int32(SHUT_RDWR)) 0216 #else 0217 Darwin.shutdown(socket, SHUT_RDWR) 0218 #endif 0219 } 0220 0221 public class func release
Socket.swift:117 Socket.shutdwn(self.socketFileDescriptor)(socket: Int32) { 0222 #if os(Linux) 0223 shutdown(socket, Int32(SHUT_RDWR)) 0224 #else 0225 Darwin.shutdown(socket, SHUT_RDWR) 0226 #endif 0227 close(socket) 0228 } 0229 0230 private class func htonsPort
Socket.swift:67 Socket.release(socketFileDescriptor)Socket.swift:92 Socket.release(socketFileDescriptor)Socket.swift:98 Socket.release(socketFileDescriptor)Socket.swift:113 Socket.release(self.socketFileDescriptor)(port: in_port_t) -> in_port_t { 0231 #if os(Linux) 0232 return port.bigEndian //use htons() when llvm stops crashing 0233 #else 0234 let isLittleEndian = Int(OSHostByteOrder()) == OSLittleEndian 0235 return isLittleEndian ? _OSSwapInt16(port) : port 0236 #endif 0237 } 0238 } 0239 0240 public func ==(socket1: Socket, socket2: Socket) -> Bool { 0241 return socket1.socketFileDescriptor == socket2.socketFileDescriptor 0242 } 0243
Socket.swift:82 addr.sin_port = Socket.htonsPort(port)