66//
77
88import Foundation
9+
910/*
10- public func shareFile(_ path: String) -> ((HttpRequest) -> HttpResponse) {
11+ public func shareFile(_ path: String) {
1112 return { r in
1213 if let file = try? path.openForReading() {
1314 return .raw(200, "OK", [:], { writer in
@@ -17,34 +18,65 @@ public func shareFile(_ path: String) -> ((HttpRequest) -> HttpResponse) {
1718 }
1819 return .notFound
1920 }
20- }
21+ }*/
2122
22- public func shareFilesFromDirectory(_ directoryPath: String, defaults: [String] = ["index.html", "default.html"]) -> ((HttpRequest) -> HttpResponse) {
23- return { r in
24- guard let fileRelativePath = r.params.first else {
25- return .notFound
23+ #if os(iOS) || os(Linux)
24+
25+ func fileZeroCopy( from: Int32 , to: Int32 ) {
26+ var buffer = [ UInt8] ( repeating: 0 , count: 1024 )
27+ while true {
28+ let readResult = read ( source, & buffer, buffer. count)
29+ guard readResult > 0 else {
30+ return Int32 ( readResult)
2631 }
27- if fileRelativePath.value.isEmpty {
28- for path in defaults {
29- if let file = try? (directoryPath + String.pathSeparator + path).openForReading() {
30- return .raw(200, "OK", [:], { writer in
31- try? writer.write(file)
32- file.close()
33- })
34- }
32+ var writeCounter = 0
33+ while writeCounter < readResult {
34+ let writeResult = write ( target, & buffer + writeCounter, readResult - writeCounter)
35+ guard writeResult > 0 else {
36+ return Int32 ( writeResult)
3537 }
38+ writeCounter = writeCounter + writeResult
3639 }
37- if let file = try? (directoryPath + String.pathSeparator + fileRelativePath.value).openForReading() {
38- return .raw(200, "OK", [:], { writer in
39- try? writer.write(file)
40- file.close()
41- })
42- }
43- return .notFound
4440 }
4541}
4642
47- public func directoryBrowser(_ dir: String) -> ((HttpRequest) -> HttpResponse) {
43+ #else
44+
45+ func fileZeroCopy( from: Int32 , to: Int32 ) {
46+ var offset : off_t = 0
47+ var sf : sf_hdtr = sf_hdtr ( )
48+ sendfile ( from, to, 0 , & offset, & sf, 0 )
49+ }
50+
51+ #endif
52+
53+ @available ( OSXApplicationExtension 10 . 10 , * )
54+ public func share( filesAtPath path: String , defaults: [ String ] = [ " index.html " , " default.html " ] ) -> ( ( [ String : String ] , Request , @escaping ( ( Response ) -> Void ) ) -> Void ) {
55+ return { ( params, request, responder) in
56+ DispatchQueue . global ( qos: . background) . async {
57+ guard let fileRelativePath = params. first else {
58+ return responder ( 404 )
59+ }
60+ if fileRelativePath. value. isEmpty {
61+ for path in defaults {
62+ if let file = try ? ( path + String. pathSeparator + path) . openFile ( forMode: " r+b " ) {
63+ fileZeroCopy ( from: fileno ( file. pointer) , to: 0 )
64+ file. close ( )
65+ }
66+ }
67+ }
68+ if let file = try ? ( path + String. pathSeparator + fileRelativePath. value) . openFile ( forMode: " r+b " ) {
69+ fileZeroCopy ( from: fileno ( file. pointer) , to: 0 )
70+ file. close ( )
71+ }
72+ return responder ( 404 )
73+ }
74+ }
75+ }
76+
77+ /*
78+
79+ public func directoryBrowser(_ dir: String) -> (([String: String], Request, @escaping ((Response) -> Void)) -> Void) {
4880 return { r in
4981 guard let (_, value) = r.params.first else {
5082 return HttpResponse.notFound
0 commit comments