Damian Kołakowski 9 年 前
コミット
c92f8d1b8d

+ 0 - 1
Sources/DemoServer.swift

@@ -18,7 +18,6 @@ public func demoServer(_ publicDir: String) -> HttpServer {
     let server = HttpServer()
     
     server["/public/:path"] = shareFilesFromDirectory(publicDir)
-    server["/public/"] = shareFilesFromDirectory(publicDir)    // needed to serve index file at root level
 
     server["/files/:path"] = directoryBrowser("/")
 

+ 0 - 154
Sources/File.swift

@@ -1,154 +0,0 @@
-//
-//  File.swift
-//  Swifter
-//
-//  Copyright (c) 2014-2016 Damian Kołakowski. All rights reserved.
-//
-
-#if os(Linux)
-    import Glibc
-#else
-    import Foundation
-#endif
-
-public enum FileError: Error {
-    case openFailed(String)
-    case writeFailed(String)
-    case readFailed(String)
-    case seekFailed(String)
-    case getCurrentWorkingDirectoryFailed(String)
-    case isDirectoryFailed(String)
-    case openDirFailed(String)
-}
-
-public class File {
-    
-    public static func openNewForWriting(_ path: String) throws -> File {
-        return try openFileForMode(path, "wb")
-    }
-    
-    public static func openForReading(_ path: String) throws -> File {
-        return try openFileForMode(path, "rb")
-    }
-    
-    public static func openForWritingAndReading(_ path: String) throws -> File {
-        return try openFileForMode(path, "r+b")
-    }
-    
-    public static func openFileForMode(_ path: String, _ mode: String) throws -> File {
-        guard let file = path.withCString({ pathPointer in mode.withCString({ fopen(pathPointer, $0) }) }) else {
-            throw FileError.openFailed(Errno.description())
-        }
-        return File(file)
-    }
-    
-    public static func isDirectory(_ path: String) throws -> Bool {
-        var s = stat()
-        guard path.withCString({ stat($0, &s) }) == 0 else {
-            throw FileError.isDirectoryFailed(Errno.description())
-        }
-        return s.st_mode & S_IFMT == S_IFDIR
-    }
-    
-    public static func currentWorkingDirectory() throws -> String {
-        guard let path = getcwd(nil, 0) else {
-            throw FileError.getCurrentWorkingDirectoryFailed(Errno.description())
-        }
-        return String(cString: path)
-    }
-    
-    public static func exists(_ path: String) throws -> Bool {
-        var buffer = stat()
-        return path.withCString({ stat($0, &buffer) == 0 })
-    }
-    
-    public static func list(_ path: String) throws -> [String] {
-        guard let dir = path.withCString({ opendir($0) }) else {
-            throw FileError.openDirFailed(Errno.description())
-        }
-        defer { closedir(dir) }
-        var results = [String]()
-        while let ent = readdir(dir) {
-            var name = ent.pointee.d_name
-            let fileName = withUnsafePointer(to: &name) { (ptr) -> String? in
-                #if os(Linux)
-                    return String.fromCString([CChar](UnsafeBufferPointer<CChar>(start: UnsafePointer(unsafeBitCast(ptr, UnsafePointer<CChar>.self)), count: 256)))
-                #else
-                    var buffer = [CChar](UnsafeBufferPointer(start: unsafeBitCast(ptr, to: UnsafePointer<CChar>.self), count: Int(ent.pointee.d_namlen)))
-                    buffer.append(0)
-                    return String(validatingUTF8: buffer)
-                #endif
-            }
-            if let fileName = fileName {
-                results.append(fileName)
-            }
-        }
-        return results
-    }
-    
-    let pointer: UnsafeMutablePointer<FILE>
-    
-    public init(_ pointer: UnsafeMutablePointer<FILE>) {
-        self.pointer = pointer
-    }
-    
-    public func close() -> Void {
-        fclose(pointer)
-    }
-    
-    public func read( data: inout [UInt8]) throws -> Int {
-        if data.count <= 0 {
-            return data.count
-        }
-        let count = fread(&data, 1, data.count, self.pointer)
-        if count == data.count {
-            return count
-        }
-        if feof(self.pointer) != 0 {
-            return count
-        }
-        if ferror(self.pointer) != 0 {
-            throw FileError.readFailed(Errno.description())
-        }
-        throw FileError.readFailed("Unknown file read error occured.")
-    }
-
-    public func write(data: [UInt8]) throws -> Void {
-        if data.count <= 0 {
-            return
-        }
-        try data.withUnsafeBufferPointer {
-            if fwrite($0.baseAddress, 1, data.count, self.pointer) != data.count {
-                throw FileError.writeFailed(Errno.description())
-            }
-        }
-    }
-    
-    public func seek(offset: Int) throws -> Void {
-        if fseek(self.pointer, offset, SEEK_SET) != 0 {
-            throw FileError.seekFailed(Errno.description())
-        }
-    }
-
-}
-
-public func withNewFileOpenedForWriting<Result>(_ path: String, _ f: (File) throws -> Result) throws -> Result {
-    return try withFileOpenedForMode(path, mode: "wb", f)
-}
-
-public func withFileOpenedForReading<Result>(_ path: String, _ f: (File) throws -> Result) throws -> Result {
-    return try withFileOpenedForMode(path, mode: "rb", f)
-}
-
-public func withFileOpenedForWritingAndReading<Result>(_ path: String, _ f: (File) throws -> Result) throws -> Result {
-    return try withFileOpenedForMode(path, mode: "r+b", f)
-}
-
-public func withFileOpenedForMode<Result>(_ path: String, mode: String, _ f: (File) throws -> Result) throws -> Result {
-    let file = try File.openFileForMode(path, mode)
-    defer {
-        file.close()
-    }
-    return try f(file)
-}
-

+ 27 - 17
Sources/Files.swift

@@ -11,19 +11,29 @@
     import Foundation
 #endif
 
-public func shareFilesFromDirectory(_ directoryPath: String) -> ((HttpRequest) -> HttpResponse) {
+
+public func shareFilesFromDirectory(_ directoryPath: String, defaults: [String] = ["index.html", "default.html"]) -> ((HttpRequest) -> HttpResponse) {
     return { r in
         guard let fileRelativePath = r.params.first else {
             return .notFound
         }
-        let absolutePath = directoryPath + "/" + fileRelativePath.1
-        guard let file = try? File.openForReading(absolutePath) else {
-            return .notFound
+        if fileRelativePath.value.isEmpty {
+            for path in defaults {
+                if let file = try? (directoryPath + String.pathSeparator + path).openForReading() {
+                    return .raw(200, "OK", [:], { writer in
+                        try? writer.write(file)
+                        file.close()
+                    })
+                }
+            }
+        }
+        if let file = try? (directoryPath + String.pathSeparator + fileRelativePath.value).openForReading() {
+            return .raw(200, "OK", [:], { writer in
+                try? writer.write(file)
+                file.close()
+            })
         }
-        return .raw(200, "OK", [:], { writer in
-            defer { file.close() }
-            try writer.write(file)
-        })
+        return .notFound
     }
 }
 
@@ -32,13 +42,13 @@ public func directoryBrowser(_ dir: String) -> ((HttpRequest) -> HttpResponse) {
         guard let (_, value) = r.params.first else {
             return HttpResponse.notFound
         }
-        let filePath = dir + "/" + value
+        let filePath = dir + String.pathSeparator + value
         do {
-            guard try File.exists(filePath) else {
-                return HttpResponse.notFound
+            guard try filePath.exists() else {
+                return .notFound
             }
-            if try File.isDirectory(filePath) {
-                let files = try File.list(filePath)
+            if try filePath.directory() {
+                let files = try filePath.files()
                 return scopes {
                     html {
                         body {
@@ -54,14 +64,14 @@ public func directoryBrowser(_ dir: String) -> ((HttpRequest) -> HttpResponse) {
                             }
                         }
                     }
-                }(r)
+                    }(r)
             } else {
-                guard let file = try? File.openForReading(filePath) else {
+                guard let file = try? filePath.openForReading() else {
                     return .notFound
                 }
                 return .raw(200, "OK", [:], { writer in
-                    defer { file.close() }
-                    try writer.write(file)
+                    try? writer.write(file)
+                    file.close()
                 })
             }
         } catch {

+ 1 - 1
Sources/HttpResponse.swift

@@ -17,7 +17,7 @@ public enum SerializationError: Error {
 }
 
 public protocol HttpResponseBodyWriter {
-    func write(_ file: File) throws
+    func write(_ file: String.File) throws
     func write(_ data: [UInt8]) throws
     func write(_ data: ArraySlice<UInt8>) throws
     func write(_ data: NSData) throws

+ 1 - 1
Sources/HttpServerIO.swift

@@ -114,7 +114,7 @@ public class HttpServerIO {
         
         let socket: Socket
 
-        func write(_ file: File) throws {
+        func write(_ file: String.File) throws {
             try socket.writeFile(file)
         }
 

+ 1 - 1
Sources/Socket+File.swift

@@ -38,7 +38,7 @@
 
 extension Socket {
     
-    public func writeFile(_ file: File) throws -> Void {
+    public func writeFile(_ file: String.File) throws -> Void {
         var offset: off_t = 0
         var sf: sf_hdtr = sf_hdtr()
         let result = sendfileImpl(fileno(file.pointer), self.socketFileDescriptor, 0, &offset, &sf

+ 139 - 0
Sources/String+File.swift

@@ -0,0 +1,139 @@
+//
+//  String+File.swift
+//  Swifter
+//
+//  Copyright © 2016 Damian Kołakowski. All rights reserved.
+//
+
+import Foundation
+
+extension String {
+    
+    public enum FileError: Error {
+        case error(Int32)
+    }
+    
+    public class File {
+        
+        internal let pointer: UnsafeMutablePointer<FILE>
+        
+        public init(_ pointer: UnsafeMutablePointer<FILE>) {
+            self.pointer = pointer
+        }
+        
+        public func close() -> Void {
+            fclose(pointer)
+        }
+        
+        public func read(_ data: inout [UInt8]) throws -> Int {
+            if data.count <= 0 {
+                return data.count
+            }
+            let count = fread(&data, 1, data.count, self.pointer)
+            if count == data.count {
+                return count
+            }
+            if feof(self.pointer) != 0 {
+                return count
+            }
+            if ferror(self.pointer) != 0 {
+                throw FileError.error(errno)
+            }
+            throw FileError.error(0)
+        }
+        
+        public func write(_ data: [UInt8]) throws -> Void {
+            if data.count <= 0 {
+                return
+            }
+            try data.withUnsafeBufferPointer {
+                if fwrite($0.baseAddress, 1, data.count, self.pointer) != data.count {
+                    throw FileError.error(errno)
+                }
+            }
+        }
+        
+        public static func currentWorkingDirectory() throws -> String {
+            guard let path = getcwd(nil, 0) else {
+                throw FileError.error(errno)
+            }
+            return String(cString: path)
+        }
+    }
+    
+    public static var pathSeparator = "/"
+    
+    public func openNewForWriting() throws -> File {
+        return try openFileForMode(self, "wb")
+    }
+    
+    public func openForReading() throws -> File {
+        return try openFileForMode(self, "rb")
+    }
+    
+    public func openForWritingAndReading() throws -> File {
+        return try openFileForMode(self, "r+b")
+    }
+    
+    public func openFileForMode(_ path: String, _ mode: String) throws -> File {
+        guard let file = path.withCString({ pathPointer in mode.withCString({ fopen(pathPointer, $0) }) }) else {
+            throw FileError.error(errno)
+        }
+        return File(file)
+    }
+    
+    public func exists() throws -> Bool {
+        return try self.withStat {
+            if let _ = $0 {
+                return true
+            }
+            return false
+        }
+    }
+    
+    public func directory() throws -> Bool {
+        return try self.withStat {
+            if let stat = $0 {
+                return stat.st_mode & S_IFMT == S_IFDIR
+            }
+            return false
+        }
+    }
+    
+    public func files() throws -> [String] {
+        guard let dir = self.withCString({ opendir($0) }) else {
+            throw FileError.error(errno)
+        }
+        defer { closedir(dir) }
+        var results = [String]()
+        while let ent = readdir(dir) {
+            var name = ent.pointee.d_name
+            let fileName = withUnsafePointer(to: &name) { (ptr) -> String? in
+                #if os(Linux)
+                    return String.fromCString([CChar](UnsafeBufferPointer<CChar>(start: UnsafePointer(unsafeBitCast(ptr, UnsafePointer<CChar>.self)), count: 256)))
+                #else
+                    var buffer = [CChar](UnsafeBufferPointer(start: unsafeBitCast(ptr, to: UnsafePointer<CChar>.self), count: Int(ent.pointee.d_namlen)))
+                    buffer.append(0)
+                    return String(validatingUTF8: buffer)
+                #endif
+            }
+            if let fileName = fileName {
+                results.append(fileName)
+            }
+        }
+        return results
+    }
+    
+    private func withStat<T>(_ closure: ((stat?) throws -> T)) throws -> T {
+        return try self.withCString({
+            var statBuffer = stat()
+            if stat($0, &statBuffer) == 0 {
+                return try closure(statBuffer)
+            }
+            if errno == ENOENT {
+                return try closure(nil)
+            }
+            throw FileError.error(errno)
+        })
+    }
+}

+ 6 - 10
XCode/Swifter.xcodeproj/project.pbxproj

@@ -21,7 +21,6 @@
 		269B478E1D3AAAE20042D137 /* HttpServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B6F11D2C44F30030FC98 /* HttpServer.swift */; };
 		269B478F1D3AAAE20042D137 /* HttpRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B6EE1D2C44F30030FC98 /* HttpRequest.swift */; };
 		269B47901D3AAAE20042D137 /* DemoServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B6EA1D2C44F30030FC98 /* DemoServer.swift */; };
-		269B47911D3AAAE20042D137 /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B6EB1D2C44F30030FC98 /* File.swift */; };
 		269B47921D3AAAE20042D137 /* Socket+File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B29E1D369BEC00D35BFB /* Socket+File.swift */; };
 		269B47931D3AAAE20042D137 /* Socket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B6F51D2C44F30030FC98 /* Socket.swift */; };
 		269B47941D3AAAE20042D137 /* HttpServerIO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B6F21D2C44F30030FC98 /* HttpServerIO.swift */; };
@@ -34,6 +33,8 @@
 		7AE893EA1C05127900A29F63 /* SwifteriOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AE893E91C05127900A29F63 /* SwifteriOS.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		7AE893FE1C0512C400A29F63 /* SwifterMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AE893FD1C0512C400A29F63 /* SwifterMac.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		7AE8940D1C05151100A29F63 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7AE8940C1C05151100A29F63 /* Launch Screen.storyboard */; };
+		7C377E181D964B96009C6148 /* String+File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C377E161D964B6A009C6148 /* String+File.swift */; };
+		7C377E191D964B9F009C6148 /* String+File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C377E161D964B6A009C6148 /* String+File.swift */; };
 		7C458EFC1D4A7526006A68E5 /* Socket+Server.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C458EFB1D4A7526006A68E5 /* Socket+Server.swift */; };
 		7C458EFD1D4A7526006A68E5 /* Socket+Server.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C458EFB1D4A7526006A68E5 /* Socket+Server.swift */; };
 		7C458EFE1D4A7526006A68E5 /* Socket+Server.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C458EFB1D4A7526006A68E5 /* Socket+Server.swift */; };
@@ -47,8 +48,6 @@
 		7C76B2A31D369C9D00D35BFB /* Errno.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B2A11D369C9D00D35BFB /* Errno.swift */; };
 		7C76B70D1D2C456A0030FC98 /* DemoServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B6EA1D2C44F30030FC98 /* DemoServer.swift */; };
 		7C76B70E1D2C456B0030FC98 /* DemoServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B6EA1D2C44F30030FC98 /* DemoServer.swift */; };
-		7C76B70F1D2C456D0030FC98 /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B6EB1D2C44F30030FC98 /* File.swift */; };
-		7C76B7101D2C456D0030FC98 /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B6EB1D2C44F30030FC98 /* File.swift */; };
 		7C76B7111D2C45710030FC98 /* Files.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B6EC1D2C44F30030FC98 /* Files.swift */; };
 		7C76B7121D2C45710030FC98 /* Files.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B6EC1D2C44F30030FC98 /* Files.swift */; };
 		7C76B7131D2C45730030FC98 /* HttpParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B6ED1D2C44F30030FC98 /* HttpParser.swift */; };
@@ -87,7 +86,6 @@
 		7CDAB8131BE2A1D400C8A977 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7CDAB80D1BE2A1D400C8A977 /* Main.storyboard */; };
 		7CDAB8141BE2A1D400C8A977 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7CDAB80F1BE2A1D400C8A977 /* Images.xcassets */; };
 		7CDAB8161BE2A1D400C8A977 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CDAB8111BE2A1D400C8A977 /* ViewController.swift */; };
-		7CEBB86E1D94612D00370A6B /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B6EB1D2C44F30030FC98 /* File.swift */; };
 		7CEBB86F1D94612D00370A6B /* Files.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B6EC1D2C44F30030FC98 /* Files.swift */; };
 		7CEBB8701D94612D00370A6B /* HttpParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B6ED1D2C44F30030FC98 /* HttpParser.swift */; };
 		7CEBB8711D94612D00370A6B /* HttpRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C76B6EE1D2C44F30030FC98 /* HttpRequest.swift */; };
@@ -159,12 +157,12 @@
 		7AE893FD1C0512C400A29F63 /* SwifterMac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwifterMac.h; sourceTree = "<group>"; };
 		7AE893FF1C0512C400A29F63 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		7AE8940C1C05151100A29F63 /* Launch Screen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = "<group>"; };
+		7C377E161D964B6A009C6148 /* String+File.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+File.swift"; sourceTree = "<group>"; };
 		7C458EFB1D4A7526006A68E5 /* Socket+Server.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Socket+Server.swift"; sourceTree = "<group>"; };
 		7C4785E81C71D15600A9FE73 /* SwifterTestsWebSocketSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwifterTestsWebSocketSession.swift; sourceTree = "<group>"; };
 		7C76B29E1D369BEC00D35BFB /* Socket+File.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Socket+File.swift"; sourceTree = "<group>"; };
 		7C76B2A11D369C9D00D35BFB /* Errno.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Errno.swift; sourceTree = "<group>"; };
 		7C76B6EA1D2C44F30030FC98 /* DemoServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DemoServer.swift; sourceTree = "<group>"; };
-		7C76B6EB1D2C44F30030FC98 /* File.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = File.swift; sourceTree = "<group>"; };
 		7C76B6EC1D2C44F30030FC98 /* Files.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Files.swift; sourceTree = "<group>"; };
 		7C76B6ED1D2C44F30030FC98 /* HttpParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HttpParser.swift; sourceTree = "<group>"; };
 		7C76B6EE1D2C44F30030FC98 /* HttpRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HttpRequest.swift; sourceTree = "<group>"; };
@@ -282,7 +280,6 @@
 			isa = PBXGroup;
 			children = (
 				7C76B6EA1D2C44F30030FC98 /* DemoServer.swift */,
-				7C76B6EB1D2C44F30030FC98 /* File.swift */,
 				7C76B6EC1D2C44F30030FC98 /* Files.swift */,
 				7C76B6ED1D2C44F30030FC98 /* HttpParser.swift */,
 				7C76B6EE1D2C44F30030FC98 /* HttpRequest.swift */,
@@ -300,6 +297,7 @@
 				7C76B6F81D2C44F30030FC98 /* String+SHA1.swift */,
 				7C76B6F91D2C44F30030FC98 /* WebSockets.swift */,
 				7C76B2A11D369C9D00D35BFB /* Errno.swift */,
+				7C377E161D964B6A009C6148 /* String+File.swift */,
 			);
 			name = Sources;
 			path = ../Sources;
@@ -667,7 +665,6 @@
 				269B478E1D3AAAE20042D137 /* HttpServer.swift in Sources */,
 				269B478F1D3AAAE20042D137 /* HttpRequest.swift in Sources */,
 				269B47901D3AAAE20042D137 /* DemoServer.swift in Sources */,
-				269B47911D3AAAE20042D137 /* File.swift in Sources */,
 				269B47921D3AAAE20042D137 /* Socket+File.swift in Sources */,
 				269B47931D3AAAE20042D137 /* Socket.swift in Sources */,
 				269B47941D3AAAE20042D137 /* HttpServerIO.swift in Sources */,
@@ -684,6 +681,7 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				7C377E191D964B9F009C6148 /* String+File.swift in Sources */,
 				7C76B7171D2C45780030FC98 /* HttpResponse.swift in Sources */,
 				7C76B7211D2C45870030FC98 /* Scopes.swift in Sources */,
 				7C76B71F1D2C45840030FC98 /* Process.swift in Sources */,
@@ -693,7 +691,6 @@
 				7C76B71B1D2C457E0030FC98 /* HttpServer.swift in Sources */,
 				7C76B7151D2C45760030FC98 /* HttpRequest.swift in Sources */,
 				7C76B70D1D2C456A0030FC98 /* DemoServer.swift in Sources */,
-				7C76B70F1D2C456D0030FC98 /* File.swift in Sources */,
 				7C76B29F1D369BEC00D35BFB /* Socket+File.swift in Sources */,
 				7C76B7231D2C45890030FC98 /* Socket.swift in Sources */,
 				7C76B71D1D2C45820030FC98 /* HttpServerIO.swift in Sources */,
@@ -710,6 +707,7 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				7C377E181D964B96009C6148 /* String+File.swift in Sources */,
 				7C76B7181D2C45790030FC98 /* HttpResponse.swift in Sources */,
 				7C76B7221D2C45870030FC98 /* Scopes.swift in Sources */,
 				7C76B7201D2C45840030FC98 /* Process.swift in Sources */,
@@ -719,7 +717,6 @@
 				7C76B71C1D2C457E0030FC98 /* HttpServer.swift in Sources */,
 				7C76B7161D2C45760030FC98 /* HttpRequest.swift in Sources */,
 				7C76B70E1D2C456B0030FC98 /* DemoServer.swift in Sources */,
-				7C76B7101D2C456D0030FC98 /* File.swift in Sources */,
 				7C76B2A01D369BEC00D35BFB /* Socket+File.swift in Sources */,
 				7C76B7241D2C458A0030FC98 /* Socket.swift in Sources */,
 				7C76B71E1D2C45820030FC98 /* HttpServerIO.swift in Sources */,
@@ -767,7 +764,6 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				7CEBB86E1D94612D00370A6B /* File.swift in Sources */,
 				7CEBB86F1D94612D00370A6B /* Files.swift in Sources */,
 				7CEBB8701D94612D00370A6B /* HttpParser.swift in Sources */,
 				7CEBB8711D94612D00370A6B /* HttpRequest.swift in Sources */,

+ 1 - 1
XCode/SwifterSampleOSX/main.swift

@@ -8,7 +8,7 @@ import Foundation
 import Swifter
 
 do {
-    let server = demoServer(try File.currentWorkingDirectory())
+    let server = demoServer(try String.File.currentWorkingDirectory())
     server["/testAfterBaseRoute"] = { request in
         return .ok(.html("ok !"))
     }