0001 https://github.com/johnno1962/Dynamo
0013 import Foundation
0014
0015 #if os(Linux)
0016 import Glibc
0017 import NSLinux
0018 #endif
0019
0020
0022 let dynamoRequestQueue| Servers.swift:109 | dispatch_async( dynamoRequestQueue, { |
= dispatch_queue_create( "DynamoRequestThread", DISPATCH_QUEUE_CONCURRENT )
0023
0024
0026
0030
0031 public class DynamoWebServer| Servers.swift:190 | public class DynamoSSLWebServer: DynamoWebServer { |
: _NSObject_ {
0032
0033 private let swiftlets| Servers.swift:55 | self.swiftlets = swiftlets |
| Servers.swift:130 | for swiftlet in swiftlets { |
: [DynamoSwiftlet]
0034 private let serverSocket| Servers.swift:70 | serverSocket = socket( Int32(ip4addr.sin_family), sockType, 0 ) |
| Servers.swift:77 | if serverSocket < 0 { |
| Servers.swift:80 | else if setsockopt( serverSocket, SOL_SOCKET, SO_REUSEADDR, &yes, yeslen ) < 0 { |
| Servers.swift:83 | else if bind( serverSocket, sockaddr_cast(&ip4addr), addrLen ) < 0 { |
| Servers.swift:86 | else if listen( serverSocket, 100 ) < 0 { |
| Servers.swift:89 | else if getsockname( serverSocket, sockaddr_cast(&ip4addr), &addrLen ) == 0 { |
| Servers.swift:104 | while self.serverSocket >= 0 { |
| Servers.swift:106 | let clientSocket = accept( self.serverSocket, nil, nil ) |
: Int32
0035
0036
0037 public var serverPort| Servers.swift:90 | serverPort = ntohs( ip4addr.sin_port ) |
| Servers.swift:96 | dynamoLog( "Server available on http\(s)://localhost:\(serverPort)" ) |
: UInt16 = 0
0038
0039
0040 public convenience init?( portNumber: UInt16, swiftlets: [DynamoSwiftlet], localhostOnly: Bool = false ) {
0041
0042 self.init( portNumber, swiftlets: swiftlets, localhostOnly: localhostOnly )
0043
0044 dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), {
0045 self.runConnectionHandler( self.httpConnectionHandler )
0046 } )
0047 }
0048
0049 init| Servers.swift:42 | self.init( portNumber, swiftlets: swiftlets, localhostOnly: localhostOnly ) |
| Servers.swift:201 | super.init( portNumber, swiftlets: swiftlets, localhostOnly: false ) |
?( _ portNumber: UInt16, swiftlets: [DynamoSwiftlet], localhostOnly: Bool ) {
0050
0051 #if os(Linux)
0052 signal( SIGPIPE, SIG_IGN )
0053 #endif
0054
0055 self.swiftlets = swiftlets
0056
0057 var ip4addr = sockaddr_in()
0058
0059 #if !os(Linux)
0060 ip4addr.sin_len = UInt8(sizeof(sockaddr_in))
0061 #endif
0062 ip4addr.sin_family = sa_family_t(AF_INET)
0063 ip4addr.sin_port = htons( portNumber )
0064 ip4addr.sin_addr = in_addr( s_addr: INADDR_ANY )
0065
0066 if localhostOnly {
0067 inet_aton( "127.0.0.1", &ip4addr.sin_addr )
0068 }
0069
0070 serverSocket = socket( Int32(ip4addr.sin_family), sockType, 0 )
0071
0072 var yes: u_int = 1, yeslen = socklen_t(sizeof(yes.dynamicType))
0073 var addrLen = socklen_t(sizeof(ip4addr.dynamicType))
0074
0075 super.init()
0076
0077 if serverSocket < 0 {
0078 dynamoStrerror( "Could not get server socket" )
0079 }
0080 else if setsockopt( serverSocket, SOL_SOCKET, SO_REUSEADDR, &yes, yeslen ) < 0 {
0081 dynamoStrerror( "Could not set SO_REUSEADDR" )
0082 }
0083 else if bind( serverSocket, sockaddr_cast(&ip4addr), addrLen ) < 0 {
0084 dynamoStrerror( "Could not bind service socket on port \(portNumber)" )
0085 }
0086 else if listen( serverSocket, 100 ) < 0 {
0087 dynamoStrerror( "Server socket would not listen" )
0088 }
0089 else if getsockname( serverSocket, sockaddr_cast(&ip4addr), &addrLen ) == 0 {
0090 serverPort = ntohs( ip4addr.sin_port )
0091 #if os(Linux)
0092 let s = ""
0093 #else
0094 let s = self.dynamicType === DynamoSSLWebServer.self ? "s" : ""
0095 #endif
0096 dynamoLog( "Server available on http\(s)://localhost:\(serverPort)" )
0097 return
0098 }
0099
0100 return nil
0101 }
0102
0103 func runConnectionHandler| Servers.swift:45 | self.runConnectionHandler( self.httpConnectionHandler ) |
| Servers.swift:205 | self.runConnectionHandler( self.httpConnectionHandler ) |
| Servers.swift:209 | runConnectionHandler( { |
( connectionHandler: (Int32) -> Void ) {
0104 while self.serverSocket >= 0 {
0105
0106 let clientSocket = accept( self.serverSocket, nil, nil )
0107
0108 if clientSocket >= 0 {
0109 dispatch_async( dynamoRequestQueue, {
0110 connectionHandler( clientSocket )
0111 } )
0112 }
0113 else {
0114 NSThread.sleepForTimeInterval( 0.5 )
0115 }
0116 }
0117 }
0118
0119 func wrapConnection| Servers.swift:125 | if let httpClient = self.wrapConnection( clientSocket ) { |
( clientSocket: Int32 ) -> DynamoHTTPConnection? {
0120 return DynamoHTTPConnection( clientSocket: clientSocket )
0121 }
0122
0123 public func httpConnectionHandler| Servers.swift:45 | self.runConnectionHandler( self.httpConnectionHandler ) |
| Servers.swift:205 | self.runConnectionHandler( self.httpConnectionHandler ) |
( clientSocket: Int32 ) {
0124
0125 if let httpClient = self.wrapConnection( clientSocket ) {
0126
0127 while httpClient.readHeaders() {
0128 var processed = false
0129
0130 for swiftlet in swiftlets {
0131
0132 switch swiftlet.present( httpClient ) {
0133 case .NotProcessed:
0134 continue
0135 case .Processed:
0136 return
0137 case .ProcessedAndReusable:
0138 httpClient.flush()
0139 processed = true
0140 break
0141 }
0142
0143 break
0144 }
0145
0146 if !processed {
0147 httpClient.status = 400
0148 httpClient.response( "Invalid request: \(httpClient.method) \(httpClient.path) \(httpClient.version)" )
0149 return
0150 }
0151 }
0152 }
0153 }
0154
0155 }
0156
0157 #if os(Linux)
0158
0161
0162 public class DynamoWorkerServer : DynamoWebServer {
0163
0164 public init?( portNumber: UInt16, swiftlets: [DynamoSwiftlet], workers: Int, localhostOnly: Bool = false ) {
0165
0166 super.init( portNumber, swiftlets: swiftlets, localhostOnly: localhostOnly )
0167
0168 dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), {
0169 var wcount = 0
0170 while true {
0171 let status = __WAIT_STATUS()
0172 if (wcount < workers || wait( status ) != 0) && fork() == 0 {
0173 self.runConnectionHandler( self.httpConnectionHandler )
0174 }
0175 wcount += 1
0176 }
0177 } )
0178 }
0179
0180 }
0181 #else
0182
0183
0185
0189
0190 public class DynamoSSLWebServer| Servers.swift:94 | let s = self.dynamicType === DynamoSSLWebServer.self ? "s" : "" |
: DynamoWebServer {
0191
0192 private let certs| Servers.swift:199 | self.certs = certs |
| Servers.swift:223 | return DynamoSSLConnection( sslSocket: clientSocket, certs: certs ) |
: [AnyObject]
0193
0194
0197 public init?( portNumber: UInt16, swiftlets: [DynamoSwiftlet] = [], certs: [AnyObject], surrogate: String? = nil ) {
0198
0199 self.certs = certs
0200
0201 super.init( portNumber, swiftlets: swiftlets, localhostOnly: false )
0202
0203 if surrogate == nil {
0204 dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), {
0205 self.runConnectionHandler( self.httpConnectionHandler )
0206 } )
0207 }
0208 else if let surrogateURL = NSURL( string: surrogate! ) {
0209 runConnectionHandler( {
0210 (clientSocket: Int32) in
0211 if let sslConnection = self.wrapConnection( clientSocket ),
0212 surrogateConnection = DynamoHTTPConnection( url: surrogateURL ) {
0213 DynamoSelector.relay( "surrogate", from: sslConnection, to: surrogateConnection, dynamoTrace )
0214 }
0215 } )
0216 }
0217 else {
0218 dynamoLog( "Invalid surrogate URL: \(surrogate)" )
0219 }
0220 }
0221
0222 override func wrapConnection| Servers.swift:211 | if let sslConnection = self.wrapConnection( clientSocket ), |
( clientSocket: Int32 ) -> DynamoHTTPConnection? {
0223 return DynamoSSLConnection( sslSocket: clientSocket, certs: certs )
0224 }
0225
0226 }
0227
0228 class DynamoSSLConnection| Servers.swift:223 | return DynamoSSLConnection( sslSocket: clientSocket, certs: certs ) |
: DynamoHTTPConnection {
0229
0230 let inputStream| Servers.swift:240 | inputStream = readStream!.takeRetainedValue() |
| Servers.swift:245 | inputStream.open() |
| Servers.swift:255 | CFReadStreamSetProperty( inputStream, kCFStreamPropertySSLSettings, sslSettings ) |
| Servers.swift:261 | return inputStream.hasBytesAvailable |
| Servers.swift:265 | return inputStream.read( UnsafeMutablePointer<UInt8>(buffer), maxLength: count ) |
| Servers.swift:273 | return inputStream.hasBytesAvailable ? _read( buffer, count: count ) : nil |
| Servers.swift:283 | inputStream.close() |
: NSInputStream
0231 let outputStream| Servers.swift:241 | outputStream = writeStream!.takeRetainedValue() |
| Servers.swift:246 | outputStream.open() |
| Servers.swift:256 | CFWriteStreamSetProperty( outputStream, kCFStreamPropertySSLSettings, sslSettings ) |
| Servers.swift:269 | return outputStream.write( UnsafePointer<UInt8>(buffer), maxLength: count ) |
| Servers.swift:277 | return outputStream.hasSpaceAvailable ? _write( buffer, count: count ) : nil |
| Servers.swift:282 | outputStream.close() |
: NSOutputStream
0232
0233 init| Servers.swift:223 | return DynamoSSLConnection( sslSocket: clientSocket, certs: certs ) |
?( sslSocket: Int32, certs: [AnyObject]? ) {
0234
0235 var readStream: Unmanaged<CFReadStream>?
0236 var writeStream: Unmanaged<CFWriteStream>?
0237
0238 CFStreamCreatePairWithSocket( nil, sslSocket, &readStream, &writeStream )
0239
0240 inputStream = readStream!.takeRetainedValue()
0241 outputStream = writeStream!.takeRetainedValue()
0242
0243 super.init( clientSocket: sslSocket )
0244
0245 inputStream.open()
0246 outputStream.open()
0247
0248 if certs != nil {
0249 let sslSettings: [NSString:AnyObject] = [
0250 kCFStreamSSLIsServer: NSNumber( bool: true ),
0251 kCFStreamSSLLevel: kCFStreamSSLLevel,
0252 kCFStreamSSLCertificates: certs!
0253 ]
0254
0255 CFReadStreamSetProperty( inputStream, kCFStreamPropertySSLSettings, sslSettings )
0256 CFWriteStreamSetProperty( outputStream, kCFStreamPropertySSLSettings, sslSettings )
0257 }
0258 }
0259
0260 override var hasBytesAvailable: Bool {
0261 return inputStream.hasBytesAvailable
0262 }
0263
0264 override func _read| Servers.swift:273 | return inputStream.hasBytesAvailable ? _read( buffer, count: count ) : nil |
( buffer: UnsafeMutablePointer<Void>, count: Int ) -> Int {
0265 return inputStream.read( UnsafeMutablePointer<UInt8>(buffer), maxLength: count )
0266 }
0267
0268 override func _write| Servers.swift:277 | return outputStream.hasSpaceAvailable ? _write( buffer, count: count ) : nil |
( buffer: UnsafePointer<Void>, count: Int ) -> Int {
0269 return outputStream.write( UnsafePointer<UInt8>(buffer), maxLength: count )
0270 }
0271
0272 override func receive( buffer: UnsafeMutablePointer<Void>, count: Int ) -> Int? {
0273 return inputStream.hasBytesAvailable ? _read( buffer, count: count ) : nil
0274 }
0275
0276 override func forward( buffer: UnsafePointer<Void>, count: Int ) -> Int? {
0277 return outputStream.hasSpaceAvailable ? _write( buffer, count: count ) : nil
0278 }
0279
0280 deinit {
0281 flush()
0282 outputStream.close()
0283 inputStream.close()
0284 }
0285
0286 }
0287
0288 #endif
0289
0290