HttpHandlers.swift 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. //
  2. // Handlers.swift
  3. // Swifter
  4. // Copyright (c) 2014 Damian Kołakowski. All rights reserved.
  5. //
  6. import Foundation
  7. public class HttpHandlers {
  8. private static let rangePrefix = "bytes="
  9. public class func directory(dir: String) -> (HttpRequest -> HttpResponse) {
  10. return { request in
  11. guard let localPath = request.params.first else {
  12. return HttpResponse.NotFound
  13. }
  14. let filesPath = dir + "/" + localPath.1
  15. guard let fileBody = NSData(contentsOfFile: filesPath) else {
  16. return HttpResponse.NotFound
  17. }
  18. if let rangeHeader = request.headers["range"] {
  19. guard rangeHeader.hasPrefix(HttpHandlers.rangePrefix) else {
  20. return HttpResponse.BadRequest
  21. }
  22. #if os(Linux)
  23. let rangeString = rangeHeader.substringFromIndex(HttpHandlers.rangePrefix.characters.count)
  24. #else
  25. let rangeString = rangeHeader.substringFromIndex(rangeHeader.startIndex.advancedBy(HttpHandlers.rangePrefix.characters.count))
  26. #endif
  27. let rangeStringExploded = rangeString.split("-")
  28. guard rangeStringExploded.count == 2 else {
  29. return HttpResponse.BadRequest
  30. }
  31. let startStr = rangeStringExploded[0]
  32. let endStr = rangeStringExploded[1]
  33. guard let start = Int(startStr), end = Int(endStr) else {
  34. var array = [UInt8](count: fileBody.length, repeatedValue: 0)
  35. fileBody.getBytes(&array, length: fileBody.length)
  36. return HttpResponse.RAW(200, "OK", nil, { $0.write(array) })
  37. }
  38. let length = end - start
  39. let range = NSRange(location: start, length: length + 1)
  40. guard range.location + range.length <= fileBody.length else {
  41. return HttpResponse.RAW(416, "Requested range not satisfiable", nil, nil)
  42. }
  43. let subData = fileBody.subdataWithRange(range)
  44. let headers = [
  45. "Content-Range" : "bytes \(startStr)-\(endStr)/\(fileBody.length)"
  46. ]
  47. var array = [UInt8](count: subData.length, repeatedValue: 0)
  48. subData.getBytes(&array, length: subData.length)
  49. return HttpResponse.RAW(206, "Partial Content", headers, { $0.write(array) })
  50. }
  51. else {
  52. var array = [UInt8](count: fileBody.length, repeatedValue: 0)
  53. fileBody.getBytes(&array, length: fileBody.length)
  54. return HttpResponse.RAW(200, "OK", nil, { $0.write(array) })
  55. }
  56. }
  57. }
  58. public class func directoryBrowser(dir: String) -> ( HttpRequest -> HttpResponse ) {
  59. return { r in
  60. if let (_, value) = r.params.first {
  61. let filePath = dir + "/" + value
  62. let fileManager = NSFileManager.defaultManager()
  63. var isDir: ObjCBool = false
  64. if fileManager.fileExistsAtPath(filePath, isDirectory: &isDir) {
  65. if isDir {
  66. do {
  67. let files = try fileManager.contentsOfDirectoryAtPath(filePath)
  68. var response = "<h3>\(filePath)</h3></br><table>"
  69. response += files.map({ "<tr><td><a href=\"\(r.path)/\($0)\">\($0)</a></td></tr>"}).joinWithSeparator("")
  70. response += "</table>"
  71. return HttpResponse.OK(.Html(response))
  72. } catch {
  73. return HttpResponse.NotFound
  74. }
  75. } else {
  76. if let fileBody = NSData(contentsOfFile: filePath) {
  77. var array = [UInt8](count: fileBody.length, repeatedValue: 0)
  78. fileBody.getBytes(&array, length: fileBody.length)
  79. return HttpResponse.RAW(200, "OK", nil, { $0.write(array) })
  80. }
  81. }
  82. }
  83. }
  84. return HttpResponse.NotFound
  85. }
  86. }
  87. }