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
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
: ErrorType { 0038 case SocketCreationFailed
Socket.swift:61
            throw SocketError.SocketCreationFailed(Socket.descriptionOfLastError())
(String) 0039 case SocketSettingReUseAddrFailed
Socket.swift:68
            throw SocketError.SocketSettingReUseAddrFailed(details)
(String) 0040 case BindFailed
Socket.swift:93
            throw SocketError.BindFailed(details)
(String) 0041 case ListenFailed
Socket.swift:99
            throw SocketError.ListenFailed(details)
(String) 0042 case WriteFailed
Socket.swift:145
                    throw SocketError.WriteFailed(Socket.descriptionOfLastError())
(String) 0043 case GetPeerNameFailed
Socket.swift:184
            throw SocketError.GetPeerNameFailed(Socket.descriptionOfLastError())
(String) 0044 case ConvertingPeerNameFailed
Socket.swift:191
            throw SocketError.ConvertingPeerNameFailed
0045 case GetNameInfoFailed
Socket.swift:188
            throw SocketError.GetNameInfoFailed(Socket.descriptionOfLastError())
(String) 0046 case AcceptFailed
Socket.swift:125
            throw SocketError.AcceptFailed(Socket.descriptionOfLastError())
(String) 0047 case RecvFailed
Socket.swift:156
            throw SocketError.RecvFailed(Socket.descriptionOfLastError())
(String) 0048 } 0049 0050 public class Socket
Response.swift:50
    public typealias Writer = Socket throws -> Void
Socket.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.NL
Socket.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 {
: Hashable, Equatable { 0051 0052 public class func tcpSocketForListen
SocketServer.swift:26
        self.listenSocket = try Socket.tcpSocketForListen(UInt16(port))
(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
Socket.swift:107
        self.socketFileDescriptor = socketFileDescriptor
Socket.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.socketFileDescriptor
Socket.swift:241
    return socket1.socketFileDescriptor == socket2.socketFileDescriptor
: Int32 0105 0106 init
Socket.swift:101
        return Socket(socketFileDescriptor: socketFileDescriptor)
Socket.swift:128
        return Socket(socketFileDescriptor: clientSocket)
SocketServer.swift:74
    private var listenSocket: Socket = Socket(socketFileDescriptor: -1)
(socketFileDescriptor: Int32) { 0107 self.socketFileDescriptor = socketFileDescriptor 0108 } 0109 0110 public var hashValue: Int { return Int(self.socketFileDescriptor) } 0111 0112 public func release
SocketServer.swift:62
        self.listenSocket.release()
SocketServer.swift:89
            socket.release()
() { 0113 Socket.release(self.socketFileDescriptor) 0114 } 0115 0116 public func shutdwn
SocketServer.swift:67
                socket.shutdwn()
() { 0117 Socket.shutdwn(self.socketFileDescriptor) 0118 } 0119 0120 func acceptClientSocket
SocketServer.swift:31
            while let socket = try? self.listenSocket.acceptClientSocket() {
() 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: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")
(string: String) throws { 0132 try writeUInt8([UInt8](string.utf8)) 0133 } 0134 0135 public func writeUInt8
Socket.swift:132
        try writeUInt8([UInt8](string.utf8))
SocketServer.swift:154
            try socket.writeUInt8(response.data)
(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:168
            n = try self.read()
SocketParser.swift:72
            body.append(try socket.read())
() 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:169
            if n > Socket.CR { characters.append(Character(UnicodeScalar(n))) }
= UInt8(13) 0162 private static let NL
Socket.swift:170
        } while n != Socket.NL
= UInt8(10) 0163 0164 public func readLine
SocketParser.swift:41
        let requestLine = try RequestLine(string: socket.readLine())
SocketParser.swift:86
            let headerLine = try socket.readLine()
() 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
Socket.swift:177
        if let name = self.cachedPeerName {
Socket.swift:194
        self.cachedPeerName = name
: String? 0175 0176 public func peername
SocketParser.swift:47
        let address = try? socket.peername()
() 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
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())
() -> String { 0199 return String.fromCString(UnsafePointer(strerror(errno))) ?? "Error: \(errno)" 0200 } 0201 0202 private class func setNoSigPipe
Socket.swift:70
        Socket.setNoSigPipe(socketFileDescriptor)
Socket.swift:127
        Socket.setNoSigPipe(clientSocket)
(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:117
        Socket.shutdwn(self.socketFileDescriptor)
(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:67
            Socket.release(socketFileDescriptor)
Socket.swift:92
            Socket.release(socketFileDescriptor)
Socket.swift:98
            Socket.release(socketFileDescriptor)
Socket.swift:113
        Socket.release(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:82
            addr.sin_port = Socket.htonsPort(port)
(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