Преглед на файлове

Swifter takes advantage of sendfile system call (OSX).

Damian Kołakowski преди 10 години
родител
ревизия
a27de6a59d

+ 1 - 1
Sources/Swifter/File.swift

@@ -56,7 +56,7 @@ public class File {
         return String(cString: path)
     }
     
-    private let pointer: UnsafeMutablePointer<FILE>
+    internal let pointer: UnsafeMutablePointer<FILE>
     
     public init(_ pointer: UnsafeMutablePointer<FILE>) {
         self.pointer = pointer

+ 1 - 4
Sources/Swifter/HttpHandlers+Files.swift

@@ -19,10 +19,7 @@ extension HttpHandlers {
                 return .NotFound
             }
             return .RAW(200, "OK", [:], { writer in
-                var buffer = [UInt8](repeating: 0, count: 64)
-                while let count = try? file.read(&buffer) where count > 0 {
-                    writer.write(buffer[0..<count])
-                }
+                writer.write(file)
                 file.close()
             })
         }

+ 1 - 1
Sources/Swifter/HttpRequest.swift

@@ -108,7 +108,7 @@ public class HttpRequest {
                 return nil
             }
         } else {
-            nextMultiPartLine(&generator)
+            let /* ignore */ _ = nextMultiPartLine(&generator)
         }
         var headers = [String: String]()
         while let line = nextMultiPartLine(&generator) where !line.isEmpty {

+ 1 - 0
Sources/Swifter/HttpResponse.swift

@@ -13,6 +13,7 @@ public enum SerializationError: ErrorProtocol {
 }
 
 public protocol HttpResponseBodyWriter {
+    func write(_ file: File)
     func write(_ data: [UInt8])
     func write(_ data: ArraySlice<UInt8>)
 }

+ 30 - 5
Sources/Swifter/HttpServerIO.swift

@@ -17,10 +17,8 @@ public class HttpServerIO {
     private var listenSocket: Socket = Socket(socketFileDescriptor: -1)
     private var clientSockets: Set<Socket> = []
     private let clientSocketsLock = Lock()
-    
-    public typealias MiddlewareCallback = (HttpRequest) -> HttpResponse?
-    
-    public var middleware = [MiddlewareCallback]()
+        
+    public var middleware = Array<(HttpRequest) -> HttpResponse?>()
     
     @available(OSX 10.10, *)
     public func start(_ listenPort: in_port_t = 8080, forceIPv4: Bool = false) throws {
@@ -100,9 +98,16 @@ public class HttpServerIO {
     
     private struct InnerWriteContext: HttpResponseBodyWriter {
         let socket: Socket
+        
+        func write(_ file: File) {
+            var offset: off_t = 0
+            let _ = sendfile(fileno(file.pointer), socket.socketFileDescriptor, 0, &offset, nil, 0)
+        }
+        
         func write(_ data: [UInt8]) {
             write(ArraySlice(data))
         }
+        
         func write(_ data: ArraySlice<UInt8>) {
             do {
                 try socket.writeUInt8(data)
@@ -143,9 +148,29 @@ public class HttpServerIO {
 #if os(Linux)
     
 import Glibc
+    
+struct sf_hdtr { }
+    
+func sendfile(_ source: Int32, _ target: Int32, _: off_t, _: UnsafeMutablePointer<off_t>!, _: UnsafeMutablePointer<sf_hdtr>!, _: Int32) -> Int32 {
+    var buffer = [UInt8](repeating: 0, count: 1024)
+    while true {
+        let readResult = read(source, &buffer, buffer.count)
+        guard readResult > 0 else {
+            return Int32(readResult)
+        }
+        var writeCounter = 0
+        while writeCounter < readResult {
+            let writeResult = write(target, &buffer + writeCounter, readResult - writeCounter)
+            guard writeResult > 0 else {
+                return Int32(writeResult)
+            }
+            writeCounter = writeCounter + writeResult
+        }
+    }
+}
 
 public class Lock {
-    
+
     private var mutex = pthread_mutex_t()
     
     init() { pthread_mutex_init(&mutex, nil) }