1
0

Files.swift 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. //
  2. // HttpHandlers+Files.swift
  3. // Swifter
  4. //
  5. // Copyright (c) 2014-2016 Damian Kołakowski. All rights reserved.
  6. //
  7. import Foundation
  8. /*
  9. public func shareFile(_ path: String) {
  10. return { r in
  11. if let file = try? path.openForReading() {
  12. return .raw(200, "OK", [:], { writer in
  13. try? writer.write(file)
  14. file.close()
  15. })
  16. }
  17. return .notFound
  18. }
  19. }*/
  20. #if os(iOS) || os(Linux)
  21. func fileZeroCopy(from: Int32, to: Int32) {
  22. var buffer = [UInt8](repeating: 0, count: 1024)
  23. while true {
  24. let readResult = read(source, &buffer, buffer.count)
  25. guard readResult > 0 else {
  26. return Int32(readResult)
  27. }
  28. var writeCounter = 0
  29. while writeCounter < readResult {
  30. let writeResult = write(target, &buffer + writeCounter, readResult - writeCounter)
  31. guard writeResult > 0 else {
  32. return Int32(writeResult)
  33. }
  34. writeCounter = writeCounter + writeResult
  35. }
  36. }
  37. }
  38. #else
  39. func fileZeroCopy(from: Int32, to: Int32) {
  40. var offset: off_t = 0
  41. var sf: sf_hdtr = sf_hdtr()
  42. sendfile(from, to, 0, &offset, &sf, 0)
  43. }
  44. #endif
  45. @available(OSXApplicationExtension 10.10, *)
  46. public func share(filesAtPath path: String, defaults: [String] = ["index.html", "default.html"]) -> (([String: String], Request, @escaping ((Response) -> Void)) -> Void) {
  47. return { (params, request, responder) in
  48. DispatchQueue.global(qos: .background).async {
  49. guard let fileRelativePath = params.first else {
  50. return responder(404)
  51. }
  52. if fileRelativePath.value.isEmpty {
  53. for path in defaults {
  54. if let file = try? (path + String.pathSeparator + path).openFile(forMode: "r+b") {
  55. fileZeroCopy(from: fileno(file.pointer), to: 0)
  56. file.close()
  57. }
  58. }
  59. }
  60. if let file = try? (path + String.pathSeparator + fileRelativePath.value).openFile(forMode: "r+b") {
  61. fileZeroCopy(from: fileno(file.pointer), to: 0)
  62. file.close()
  63. }
  64. return responder(404)
  65. }
  66. }
  67. }
  68. /*
  69. public func directoryBrowser(_ dir: String) -> (([String: String], Request, @escaping ((Response) -> Void)) -> Void) {
  70. return { r in
  71. guard let (_, value) = r.params.first else {
  72. return HttpResponse.notFound
  73. }
  74. let filePath = dir + String.pathSeparator + value
  75. do {
  76. guard try filePath.exists() else {
  77. return .notFound
  78. }
  79. if try filePath.directory() {
  80. let files = try filePath.files()
  81. return scopes {
  82. html {
  83. body {
  84. table(files) { file in
  85. tr {
  86. td {
  87. a {
  88. href = r.path + "/" + file
  89. inner = file
  90. }
  91. }
  92. }
  93. }
  94. }
  95. }
  96. }(r)
  97. } else {
  98. guard let file = try? filePath.openForReading() else {
  99. return .notFound
  100. }
  101. return .raw(200, "OK", [:], { writer in
  102. try? writer.write(file)
  103. file.close()
  104. })
  105. }
  106. } catch {
  107. return HttpResponse.internalServerError
  108. }
  109. }
  110. }*/