Files.swift 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. //
  2. // HttpHandlers+Files.swift
  3. // Swifter
  4. //
  5. // Copyright (c) 2014-2016 Damian Kołakowski. All rights reserved.
  6. //
  7. import Foundation
  8. public func shareFile(_ path: String) -> ((HttpRequest) -> HttpResponse) {
  9. return { _ in
  10. if let file = try? path.openForReading() {
  11. let mimeType = path.mimeType()
  12. var responseHeader: [String: String] = ["Content-Type": mimeType]
  13. if let attr = try? FileManager.default.attributesOfItem(atPath: path),
  14. let fileSize = attr[FileAttributeKey.size] as? UInt64 {
  15. responseHeader["Content-Length"] = String(fileSize)
  16. }
  17. return .raw(200, "OK", responseHeader, { writer in
  18. try? writer.write(file)
  19. file.close()
  20. })
  21. }
  22. return .notFound()
  23. }
  24. }
  25. public func shareFilesFromDirectory(_ directoryPath: String, defaults: [String] = ["index.html", "default.html"]) -> ((HttpRequest) -> HttpResponse) {
  26. return { request in
  27. guard let fileRelativePath = request.params.first else {
  28. return .notFound()
  29. }
  30. if fileRelativePath.value.isEmpty {
  31. for path in defaults {
  32. if let file = try? (directoryPath + String.pathSeparator + path).openForReading() {
  33. return .raw(200, "OK", [:], { writer in
  34. try? writer.write(file)
  35. file.close()
  36. })
  37. }
  38. }
  39. }
  40. let filePath = directoryPath + String.pathSeparator + fileRelativePath.value
  41. if let file = try? filePath.openForReading() {
  42. let mimeType = fileRelativePath.value.mimeType()
  43. var responseHeader: [String: String] = ["Content-Type": mimeType]
  44. if let attr = try? FileManager.default.attributesOfItem(atPath: filePath),
  45. let fileSize = attr[FileAttributeKey.size] as? UInt64 {
  46. responseHeader["Content-Length"] = String(fileSize)
  47. }
  48. return .raw(200, "OK", responseHeader, { writer in
  49. try? writer.write(file)
  50. file.close()
  51. })
  52. }
  53. return .notFound()
  54. }
  55. }
  56. public func directoryBrowser(_ dir: String) -> ((HttpRequest) -> HttpResponse) {
  57. return { request in
  58. guard let (_, value) = request.params.first else {
  59. return .notFound()
  60. }
  61. let filePath = dir + String.pathSeparator + value
  62. do {
  63. guard try filePath.exists() else {
  64. return .notFound()
  65. }
  66. if try filePath.directory() {
  67. var files = try filePath.files()
  68. files.sort(by: {$0.lowercased() < $1.lowercased()})
  69. return scopes {
  70. html {
  71. body {
  72. table(files) { file in
  73. tr {
  74. td {
  75. a {
  76. href = request.path + "/" + file
  77. inner = file
  78. }
  79. }
  80. }
  81. }
  82. }
  83. }
  84. }(request)
  85. } else {
  86. guard let file = try? filePath.openForReading() else {
  87. return .notFound()
  88. }
  89. return .raw(200, "OK", [:], { writer in
  90. try? writer.write(file)
  91. file.close()
  92. })
  93. }
  94. } catch {
  95. return HttpResponse.internalServerError(.text("Internal Server Error"))
  96. }
  97. }
  98. }