0001 https://github.com/johnno1962/Dynamo
0013 import Foundation
0014
0015 #if os(Linux)
0016 import NSLinux
0017 #endif
0018
0019
0021
0025
0026 public class ApplicationSwiftlet| Generated.swift:32 | public class HTMLApplicationSwiftlet: ApplicationSwiftlet { |
| Swiftlets.swift:143 | public class SessionSwiftlet: ApplicationSwiftlet { |
| Swiftlets.swift:146 | var sessions = [String:ApplicationSwiftlet]() |
| Swiftlets.swift:345 | public class ServerPagesSwiftlet: ApplicationSwiftlet { |
: _NSObject_, DynamoBrowserSwiftlet {
0027
0028 let pathPrefix| Swiftlets.swift:35 | self.pathPrefix = pathPrefix |
| Swiftlets.swift:40 | if let pathInfo = httpClient.url.path where pathInfo.hasPrefix( pathPrefix ) { |
| Swiftlets.swift:41 | let endIndex = pathInfo.rangeOfString( pathPrefix )!.endIndex |
| Swiftlets.swift:186 | out.setCookie( cookieName, value: sessionKey!, path: pathPrefix ) |
: String
0029
0030
0033
0034 public init| Swiftlets.swift:158 | super.init( pathPrefix: pathPrefix ) |
| Swiftlets.swift:357 | super.init( pathPrefix: "/**.ssp" ) |
( pathPrefix: String ) {
0035 self.pathPrefix = pathPrefix
0036 }
0037
0038 public func present| Swiftlets.swift:396 | return reloader.present( httpClient ) |
( httpClient: DynamoHTTPConnection ) -> DynamoProcessed {
0039
0040 if let pathInfo = httpClient.url.path where pathInfo.hasPrefix( pathPrefix ) {
0041 let endIndex = pathInfo.rangeOfString( pathPrefix )!.endIndex
0042 return process( httpClient, pathInfo: pathInfo.substringToIndex( endIndex ) )
0043 }
0044
0045 return .NotProcessed
0046 }
0047
0048
0052
0053 public func process| Swiftlets.swift:42 | return process( httpClient, pathInfo: pathInfo.substringToIndex( endIndex ) ) |
( httpClient: DynamoHTTPConnection, pathInfo: String ) -> DynamoProcessed {
0054
0055 var cookies = [String:String]()
0056 if let cookieHeader = httpClient.requestHeaders["Cookie"] {
0057 addParameters( &cookies, from: cookieHeader, delimeter: "; " )
0058 }
0059
0060 var parameters = [String:String]()
0061 if let queryString = httpClient.url.query {
0062 addParameters( ¶meters, from: queryString )
0063 }
0064
0065 if httpClient.method == "POST" {
0066 if httpClient.contentType == "application/json" {
0067 #if !os(Linux)
0068 if let json = httpClient.postJSON() {
0069 processJSON( httpClient,
0070 pathInfo: pathInfo,
0071 parameters: parameters,
0072 cookies: cookies,
0073 json: json )
0074 }
0075 #endif
0076 return httpClient.knowsResponseLength ? .ProcessedAndReusable : .Processed
0077 }
0078
0079 if httpClient.contentType == "application/x-www-form-urlencoded" {
0080 if let postString = httpClient.postString() {
0081 addParameters( ¶meters, from: postString )
0082 }
0083 else {
0084 dynamoLog( "POST data not available" )
0085 }
0086 }
0087 }
0088
0089 processRequest( httpClient, pathInfo: pathInfo, parameters: parameters, cookies: cookies )
0090
0091 return httpClient.knowsResponseLength ? .ProcessedAndReusable : .Processed
0092 }
0093
0094 private func addParameters| Swiftlets.swift:57 | addParameters( &cookies, from: cookieHeader, delimeter: "; " ) |
| Swiftlets.swift:62 | addParameters( ¶meters, from: queryString ) |
| Swiftlets.swift:81 | addParameters( ¶meters, from: postString ) |
( inout parameters: [String:String], from queryString: String, delimeter: String = "&" ) {
0095 for nameValue in queryString.componentsSeparatedByString( delimeter ) {
0096 if let divider = nameValue.rangeOfString( "=" )?.startIndex {
0097 let value = nameValue.substringFromIndex( divider.advancedBy( 1 ) )
0098 if let value = value
0099 .stringByReplacingOccurrencesOfString( "+", withString: " " )
0100 .stringByRemovingPercentEncoding {
0101 parameters[nameValue.substringToIndex( divider )] = value
0102 }
0103 }
0104 else {
0105 parameters[nameValue] = ""
0106 }
0107 }
0108 }
0109
0110
0114
0115 public func processRequest| Swiftlets.swift:89 | processRequest( httpClient, pathInfo: pathInfo, parameters: parameters, cookies: cookies ) |
| Swiftlets.swift:124 | processRequest( out, pathInfo: pathInfo, parameters: parameters, cookies: cookies ) |
| Swiftlets.swift:192 | sessionApp.processRequest( out, pathInfo: pathInfo, parameters: parameters, cookies: cookies ) |
( out: DynamoHTTPConnection, pathInfo: String, parameters: [String:String], cookies: [String:String] ) {
0116 dynamoLog( "DynamoApplicationSwiftlet.processRequest(): Subclass responsibility" )
0117 }
0118
0119
0122
0123 public func processJSON| Swiftlets.swift:69 | processJSON( httpClient, |
( out: DynamoHTTPConnection, pathInfo: String, parameters: [String:String], cookies: [String:String], json: AnyObject ) {
0124 processRequest( out, pathInfo: pathInfo, parameters: parameters, cookies: cookies )
0125 }
0126
0127 }
0128
0129
0131
0134
0135 public var dynanmoDefaultSessionExpiry| Swiftlets.swift:226 | self.expiry = NSDate().timeIntervalSinceReferenceDate + dynanmoDefaultSessionExpiry |
: NSTimeInterval = 15*60
0136 private var sessionExpiryCheckInterval| Swiftlets.swift:172 | let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(sessionExpiryCheckInterval * Double(NSEC_PER_SEC))) |
: NSTimeInterval = 60
0137
0138
0142
0143 public class SessionSwiftlet| Swiftlets.swift:208 | let manager: SessionSwiftlet |
| Swiftlets.swift:223 | required public init( manager: SessionSwiftlet, sessionKey: String ) { |
| Swiftlets.swift:249 | public class BundleSwiftlet: SessionSwiftlet { |
: ApplicationSwiftlet {
0144
0145 var appClass| Swiftlets.swift:156 | self.appClass = appClass |
| Swiftlets.swift:185 | sessions[sessionKey!] = appClass.init( manager: self, sessionKey: sessionKey! ) |
: SessionApplication.Type
0146 var sessions| Swiftlets.swift:163 | for (key, session) in sessions { |
| Swiftlets.swift:167 | sessions.removeValueForKey( key ) |
| Swiftlets.swift:183 | if sessionKey == nil || sessions[sessionKey!] == nil { |
| Swiftlets.swift:185 | sessions[sessionKey!] = appClass.init( manager: self, sessionKey: sessionKey! ) |
| Swiftlets.swift:191 | if let sessionApp = sessions[sessionKey!] { |
| Swiftlets.swift:216 | manager.sessions.removeValueForKey( sessionKey ) |
= [String:ApplicationSwiftlet]()
0147
0148 private var sessionLock| Swiftlets.swift:166 | sessionLock.lock() |
| Swiftlets.swift:168 | sessionLock.unlock() |
| Swiftlets.swift:181 | sessionLock.lock() |
| Swiftlets.swift:189 | sessionLock.unlock() |
= NSLock()
0149 private let cookieName| Swiftlets.swift:157 | self.cookieName = cookieName |
| Swiftlets.swift:182 | var sessionKey = cookies[cookieName] |
| Swiftlets.swift:186 | out.setCookie( cookieName, value: sessionKey!, path: pathPrefix ) |
: String
0150
0151
0154
0155 public init| Swiftlets.swift:281 | super.init( pathPrefix: pathPrefix, appClass: appClass ) |
| Swiftlets.swift:290 | super.init( pathPrefix: pathPrefix, appClass: SessionApplication.self ) |
( pathPrefix: String, appClass: SessionApplication.Type, cookieName: String = "DynamoSession" ) {
0156 self.appClass = appClass
0157 self.cookieName = cookieName
0158 super.init( pathPrefix: pathPrefix )
0159 cleanupSessions()
0160 }
0161
0162 private func cleanupSessions| Swiftlets.swift:159 | cleanupSessions() |
| Swiftlets.swift:173 | dispatch_after( delayTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), cleanupSessions ) |
() {
0163 for (key, session) in sessions {
0164 if let session = session as? SessionApplication
0165 where session.expiry < NSDate().timeIntervalSinceReferenceDate {
0166 sessionLock.lock()
0167 sessions.removeValueForKey( key )
0168 sessionLock.unlock()
0169 }
0170 }
0171
0172 let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(sessionExpiryCheckInterval * Double(NSEC_PER_SEC)))
0173 dispatch_after( delayTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), cleanupSessions )
0174 }
0175
0178
0179 public override func processRequest| Swiftlets.swift:330 | super.processRequest( out, pathInfo: pathInfo, parameters: parameters, cookies: cookies ) |
( out: DynamoHTTPConnection, pathInfo: String, parameters: [String : String], cookies: [String : String] ) {
0180
0181 sessionLock.lock()
0182 var sessionKey = cookies[cookieName]
0183 if sessionKey == nil || sessions[sessionKey!] == nil {
0184 sessionKey = NSUUID().UUIDString
0185 sessions[sessionKey!] = appClass.init( manager: self, sessionKey: sessionKey! )
0186 out.setCookie( cookieName, value: sessionKey!, path: pathPrefix )
0187 out.contentType = dynamoHtmlMimeType
0188 }
0189 sessionLock.unlock()
0190
0191 if let sessionApp = sessions[sessionKey!] {
0192 sessionApp.processRequest( out, pathInfo: pathInfo, parameters: parameters, cookies: cookies )
0193 }
0194 else {
0195 dynamoLog( "Missing app for session \(sessionKey)" )
0196 }
0197 }
0198
0199 }
0200
0201
0204
0205 public class SessionApplication| Swiftlets.swift:145 | var appClass: SessionApplication.Type |
| Swiftlets.swift:155 | public init( pathPrefix: String, appClass: SessionApplication.Type, cookieName: String = "DynamoSession" ) { |
| Swiftlets.swift:164 | if let session = session as? SessionApplication |
| Swiftlets.swift:280 | if let appClass = bundle.classNamed( "\(bundleName)Swiftlet" ) as? SessionApplication.Type { |
| Swiftlets.swift:290 | super.init( pathPrefix: pathPrefix, appClass: SessionApplication.self ) |
: HTMLApplicationSwiftlet {
0206
0207 let sessionKey| Swiftlets.swift:216 | manager.sessions.removeValueForKey( sessionKey ) |
| Swiftlets.swift:225 | self.sessionKey = sessionKey |
: String
0208 let manager| Swiftlets.swift:216 | manager.sessions.removeValueForKey( sessionKey ) |
| Swiftlets.swift:224 | self.manager = manager |
: SessionSwiftlet
0209 var expiry| Swiftlets.swift:165 | where session.expiry < NSDate().timeIntervalSinceReferenceDate { |
| Swiftlets.swift:226 | self.expiry = NSDate().timeIntervalSinceReferenceDate + dynanmoDefaultSessionExpiry |
: NSTimeInterval
0210
0211
0214
0215 public func clearSession() {
0216 manager.sessions.removeValueForKey( sessionKey )
0217 }
0218
0219
0222
0223 required public init| Swiftlets.swift:185 | sessions[sessionKey!] = appClass.init( manager: self, sessionKey: sessionKey! ) |
( manager: SessionSwiftlet, sessionKey: String ) {
0224 self.manager = manager
0225 self.sessionKey = sessionKey
0226 self.expiry = NSDate().timeIntervalSinceReferenceDate + dynanmoDefaultSessionExpiry
0227 super.init( pathPrefix: "N/A" )
0228 }
0229
0230
0233
0234 public override func processRequest( out: DynamoHTTPConnection, pathInfo: String, parameters: [String : String], cookies: [String : String] ) {
0235 dynamoLog( "DynamoSessionApplication.processRequest(): Subclass responsibility" )
0236 }
0237
0238 }
0239
0240
0242
0248
0249 public class BundleSwiftlet| Swiftlets.swift:348 | var reloaders = [String:BundleSwiftlet]() |
| Swiftlets.swift:384 | if let reloader = BundleSwiftlet( pathPrefix: sspPath, |
: SessionSwiftlet {
0250
0251 let bundleName| Swiftlets.swift:274 | self.bundleName = bundleName |
| Swiftlets.swift:305 | let nextPath = "/tmp/\(bundleName)V\(loadNumber).ssp" |
: String
0252 let bundlePath| Swiftlets.swift:275 | self.bundlePath = bundlePath |
| Swiftlets.swift:314 | try fileManager.copyItemAtPath( bundlePath, toPath: nextPath ) |
: String
0253 let binaryPath| Swiftlets.swift:276 | self.binaryPath = "\(bundlePath)/Contents/MacOS/\(bundleName)" |
| Swiftlets.swift:302 | if let attrs = try? fileManager.attributesOfItemAtPath( binaryPath), |
: String
0254 var loaded| Swiftlets.swift:277 | self.loaded = NSDate().timeIntervalSinceReferenceDate |
| Swiftlets.swift:304 | where lastModified > loaded { |
| Swiftlets.swift:319 | self.loaded = lastModified |
: NSTimeInterval
0255 let fileManager| Swiftlets.swift:302 | if let attrs = try? fileManager.attributesOfItemAtPath( binaryPath), |
| Swiftlets.swift:309 | try fileManager.removeItemAtPath( nextPath ) |
| Swiftlets.swift:314 | try fileManager.copyItemAtPath( bundlePath, toPath: nextPath ) |
= NSFileManager.defaultManager()
0256 var loadNumber| Swiftlets.swift:305 | let nextPath = "/tmp/\(bundleName)V\(loadNumber).ssp" |
| Swiftlets.swift:306 | loadNumber += 1 |
= 0
0257
0258
0261
0262 public convenience init?( pathPrefix: String, bundleName: String ) {
0263 let bundlePath = NSBundle.mainBundle().pathForResource( bundleName, ofType: "ssp" )!
0264 self.init( pathPrefix: pathPrefix, bundleName: bundleName, bundlePath: bundlePath )
0265 }
0266
0267
0271
0272 public init| Swiftlets.swift:264 | self.init( pathPrefix: pathPrefix, bundleName: bundleName, bundlePath: bundlePath ) |
| Swiftlets.swift:384 | if let reloader = BundleSwiftlet( pathPrefix: sspPath, |
?( pathPrefix: String, bundleName: String, bundlePath: String ) {
0273
0274 self.bundleName = bundleName
0275 self.bundlePath = bundlePath
0276 self.binaryPath = "\(bundlePath)/Contents/MacOS/\(bundleName)"
0277 self.loaded = NSDate().timeIntervalSinceReferenceDate
0278
0279 if let bundle = NSBundle( path: bundlePath ) where bundle.load() {
0280 if let appClass = bundle.classNamed( "\(bundleName)Swiftlet" ) as? SessionApplication.Type {
0281 super.init( pathPrefix: pathPrefix, appClass: appClass )
0282 return
0283 }
0284 else {
0285 dynamoLog( "Could not locate class with @objc name \(bundleName)Swiftlet in \(bundlePath)")
0286 }
0287 }
0288
0289 dynamoLog( "Could not find/load swiftlet for bundle \(bundlePath)" )
0290 super.init( pathPrefix: pathPrefix, appClass: SessionApplication.self )
0291 return nil
0292 }
0293
0294
0299
0300 public override func processRequest( out: DynamoHTTPConnection, pathInfo: String, parameters: [String : String], cookies: [String : String] ) {
0301
0302 if let attrs = try? fileManager.attributesOfItemAtPath( binaryPath),
0303 lastModified = (attrs[NSFileModificationDate] as? NSDate)?.timeIntervalSinceReferenceDate
0304 where lastModified > loaded {
0305 let nextPath = "/tmp/\(bundleName)V\(loadNumber).ssp"
0306 loadNumber += 1
0307
0308 do {
0309 try fileManager.removeItemAtPath( nextPath )
0310 } catch _ {
0311 }
0312
0313 do {
0314 try fileManager.copyItemAtPath( bundlePath, toPath: nextPath )
0315
0316 if let bundle = NSBundle( path: nextPath ) {
0317 if bundle.load() {
0318 self.loaded = lastModified
0320 }
0321 else {
0322 dynamoLog( "Could not reload bundle \(nextPath)" )
0323 }
0324 }
0325 } catch let error as NSError {
0326 dynamoLog( "Could not copy bundle to \(nextPath) \(error)" )
0327 }
0328 }
0329
0330 super.processRequest( out, pathInfo: pathInfo, parameters: parameters, cookies: cookies )
0331 }
0332
0333 }
0334
0335
0337
0342
0343 #if !os(Linux)
0344
0345 public class ServerPagesSwiftlet: ApplicationSwiftlet {
0346
0347 let documentRoot| Swiftlets.swift:356 | self.documentRoot = documentRoot |
| Swiftlets.swift:372 | if sspPath != path && fileManager.fileExistsAtPath( "\(documentRoot)/\(host)\(path)") { |
| Swiftlets.swift:376 | let sspFullPath = "\(documentRoot)/\(host)\(sspPath)" |
: String
0348 var reloaders| Swiftlets.swift:377 | let reloader = reloaders[sspPath] |
| Swiftlets.swift:386 | reloaders[sspPath] = reloader |
| Swiftlets.swift:395 | if let reloader = reloaders[sspPath] { |
= [String:BundleSwiftlet]()
0349 let fileManager| Swiftlets.swift:372 | if sspPath != path && fileManager.fileExistsAtPath( "\(documentRoot)/\(host)\(path)") { |
| Swiftlets.swift:379 | if reloader == nil && fileManager.fileExistsAtPath( sspFullPath ) { |
= NSFileManager.defaultManager()
0350
0351
0354
0355 public init( documentRoot: String ) {
0356 self.documentRoot = documentRoot
0357 super.init( pathPrefix: "/**.ssp" )
0358 }
0359
0360
0364
0365 override public func present( httpClient: DynamoHTTPConnection ) -> DynamoProcessed {
0366
0367 let path = httpClient.path
0368
0369 if let sspMatch = path.rangeOfString( ".ssp" )?.endIndex, host = httpClient.requestHeaders["Host"] {
0370 let sspPath = path.substringToIndex( sspMatch )
0371
0372 if sspPath != path && fileManager.fileExistsAtPath( "\(documentRoot)/\(host)\(path)") {
0373 return .NotProcessed
0374 }
0375
0376 let sspFullPath = "\(documentRoot)/\(host)\(sspPath)"
0377 let reloader = reloaders[sspPath]
0378
0379 if reloader == nil && fileManager.fileExistsAtPath( sspFullPath ) {
0380 if let nameStart = sspPath.rangeOfString( "/",
0381 options: NSStringCompareOptions.BackwardsSearch )?.endIndex {
0382 let nameEnd = sspPath.endIndex.advancedBy(-4 )
0383 let bundleName = sspPath.substringWithRange( Range( start: nameStart, end: nameEnd ) )
0384 if let reloader = BundleSwiftlet( pathPrefix: sspPath,
0385 bundleName: bundleName, bundlePath: sspFullPath ) {
0386 reloaders[sspPath] = reloader
0387 }
0388 }
0389 else {
0390 dynamoLog( "Unable to parse .ssp path: \(sspPath)" )
0391 return .NotProcessed
0392 }
0393 }
0394
0395 if let reloader = reloaders[sspPath] {
0396 return reloader.present( httpClient )
0397 }
0398 else {
0399 dynamoLog( "Missing .ssp bundle for path \(path)" )
0400 }
0401 }
0402
0403 return .NotProcessed
0404 }
0405 }
0406
0407 #endif
0408