0001    //
0002    //  Document.swift
0003    //  Dynamo
0004    //
0005    //  Created by John Holdsworth on 11/07/2015.
0006    //  Copyright (c) 2015 John Holdsworth. All rights reserved.
0007    //
0008    //  $Id: //depot/Dynamo/Sources/Document.swift#6 $
0009    //
0010    //  Repo: https://github.com/johnno1962/Dynamo
0011    //
0012    
0013    import Foundation
0014    
0015    // MARK: Logging Swiftlet
0016    
0017    /**
0018        Null swiftlet to log each request as it is presented to the processing chain.
0019    */
0020    
0021    public class LoggingSwiftlet: _NSObject_, DynamoSwiftlet {
0022    
0023        let logger
Document.swift:27
        self.logger = logger
Document.swift:32
        logger( "\(httpClient.method) \(httpClient.path) \(httpClient.version) - \(httpClient.remoteAddr)" )
: (String) -> Void 0024 0025 /** default initialiser for logging Swiftlet */ 0026 public init( logger: ((String) -> Void) = dynamoTrace ) { 0027 self.logger = logger 0028 } 0029 0030 /** log current request */ 0031 public func present( httpClient: DynamoHTTPConnection ) -> DynamoProcessed { 0032 logger( "\(httpClient.method) \(httpClient.path) \(httpClient.version) - \(httpClient.remoteAddr)" ) 0033 return .NotProcessed 0034 } 0035 0036 } 0037 0038 // MARK: Default document Swiftlet 0039 0040 /** 0041 Default document mime type/charset 0042 */ 0043 0044 public var dynamoHtmlMimeType
Connection.swift:354
            contentType = dynamoHtmlMimeType
Document.swift:61
    "htm": dynamoHtmlMimeType,
Document.swift:62
    "html":dynamoHtmlMimeType,
Document.swift:145
            httpClient.contentType = (ext != nil ? dynamoMimeTypeMapping[ext!] : nil) ?? dynamoHtmlMimeType
Swiftlets.swift:187
            out.contentType = dynamoHtmlMimeType
= "text/html; charset=utf-8" 0045 0046 /** 0047 Supported mime types by document extension. 0048 */ 0049 0050 public var dynamoMimeTypeMapping
Connection.swift:418
                contentType = dynamoMimeTypeMapping["json"] ?? "application/json"
Document.swift:145
            httpClient.contentType = (ext != nil ? dynamoMimeTypeMapping[ext!] : nil) ?? dynamoHtmlMimeType
= [ 0051 "ico": "image/x-icon", 0052 "jpeg":"image/jpeg", 0053 "jpe": "image/jpeg", 0054 "jpg": "image/jpeg", 0055 "tiff":"image/tiff", 0056 "tif": "image/tiff", 0057 "gif": "image/gif", 0058 "png": "image/png", 0059 "bmp": "image/bmp", 0060 "css": "text/css", 0061 "htm": dynamoHtmlMimeType, 0062 "html":dynamoHtmlMimeType, 0063 "java":"text/plain", 0064 "json":"application/json", 0065 "doc": "application/msword", 0066 "xls": "application/vnd.ms-excel", 0067 "ppt": "application/vnd.ms-powerpoint", 0068 "pps": "application/vnd.ms-powerpoint", 0069 "js": "application/x-javascript", 0070 "jse": "application/x-javascript", 0071 "reg": "application/octet-stream", 0072 "eps": "application/postscript", 0073 "ps": "application/postscript", 0074 "gz": "application/x-gzip", 0075 "hta": "application/hta", 0076 "jar": "application/zip", 0077 "zip": "application/zip", 0078 "pdf": "application/pdf", 0079 "qt": "video/quicktime", 0080 "mov": "video/quicktime", 0081 "avi": "video/x-msvideo", 0082 "wav": "audio/x-wav", 0083 "snd": "audio/basic", 0084 "mid": "audio/basic", 0085 "au": "audio/basic", 0086 "mpeg":"video/mpeg", 0087 "mpe": "video/mpeg", 0088 "mpg": "video/mpeg", 0089 ] 0090 0091 /** 0092 Default swiftlet, generally last in the swiftlet chain to serve static documents from the file system. 0093 This is either from the app resources directory for iOS apps or ~/Sites/hostname:port/... on OSX. 0094 */ 0095 0096 public class DocumentSwiftlet: _NSObject_, DynamoSwiftlet { 0097 0098 let fileManager
Document.swift:136
            if fileManager.fileExistsAtPath( fullPath, isDirectory: &isDir ) && isDir {
Document.swift:148
            if fileManager.fileExistsAtPath( zippedPath ) {
Document.swift:153
            if let attrs = try? fileManager.attributesOfItemAtPath( fullPath ),
= NSFileManager.defaultManager() 0099 let documentRoot
Document.swift:116
        self.documentRoot = documentRoot
Document.swift:133
            var fullPath = "\(documentRoot)/\(siteHost)"+(httpClient.url.path ?? "/")
: String 0100 let report404
Document.swift:117
        self.report404 = report404
Document.swift:169
            if report404 {
: Bool 0101 0102 /** 0103 Convenience initialiser taking document root from the resources directory/localhost:port 0104 */ 0105 0106 public convenience override init() { 0107 self.init( documentRoot: NSBundle.mainBundle().resourcePath! ) 0108 } 0109 0110 /** 0111 Initialiser pecifying documentRoot an whether this is the last Swiftlet and it should report 404 0112 if a document is not found. 0113 */ 0114 0115 public init
Document.swift:107
        self.init( documentRoot: NSBundle.mainBundle().resourcePath! )
( documentRoot: String, report404: Bool = true ) { 0116 self.documentRoot = documentRoot 0117 self.report404 = report404 0118 } 0119 0120 private func webDate
Document.swift:156
                let lastModified = webDate( lastModifiedDate )
( date: NSDate ) -> String { 0121 return webDateFormatter.stringFromDate( date ) 0122 } 0123 0124 /** 0125 Look for static documents in directory named affter host(:port) used in url 0126 */ 0127 0128 public func present( httpClient: DynamoHTTPConnection ) -> DynamoProcessed { 0129 0130 if httpClient.method == "GET" { 0131 0132 let siteHost = httpClient.requestHeaders["Host"] ?? "localhost" 0133 var fullPath = "\(documentRoot)/\(siteHost)"+(httpClient.url.path ?? "/") 0134 0135 var isDir: ObjCBool = false 0136 if fileManager.fileExistsAtPath( fullPath, isDirectory: &isDir ) && isDir { 0137 #if os(Linux) 0138 fullPath = NSURL( fileURLWithPath: fullPath ).URLByAppendingPathComponent( "index.html" )!.path! 0139 #else 0140 fullPath = NSURL( fileURLWithPath: fullPath ).URLByAppendingPathComponent( "index.html" ).path! 0141 #endif 0142 } 0143 0144 let ext = NSURL( fileURLWithPath: fullPath ).pathExtension 0145 httpClient.contentType = (ext != nil ? dynamoMimeTypeMapping[ext!] : nil) ?? dynamoHtmlMimeType 0146 0147 let zippedPath = fullPath+".gz" 0148 if fileManager.fileExistsAtPath( zippedPath ) { 0149 httpClient.addResponseHeader( "Content-Encoding", value: "gzip" ) 0150 fullPath = zippedPath 0151 } 0152 0153 if let attrs = try? fileManager.attributesOfItemAtPath( fullPath ), 0154 lastModifiedDate = attrs[NSFileModificationDate] as? NSDate { 0155 0156 let lastModified = webDate( lastModifiedDate ) 0157 httpClient.addResponseHeader( "Last-Modified", value: lastModified ) 0158 0159 if let since = httpClient.requestHeaders["If-Modified-Since"] 0160 where since == lastModified { 0161 return httpClient.sendResponse( .Status( status: 304, text: "" ) ) 0162 } 0163 0164 if let data = NSData( contentsOfFile: fullPath ) { 0165 return httpClient.sendResponse( .Data( data: data ) ) 0166 } 0167 } 0168 0169 if report404 { 0170 dynamoLog( "404 File not Found: \(fullPath)" ) 0171 return httpClient.sendResponse( .Status( status: 404, text: "<b>File not found:</b> \(fullPath)" ) ) 0172 } 0173 } 0174 0175 return .NotProcessed 0176 } 0177 0178 } 0179