HttpRouter.swift 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. //
  2. // HttpRouter.swift
  3. // Swifter
  4. // Copyright (c) 2015 Damian Kołakowski. All rights reserved.
  5. //
  6. import Foundation
  7. public class HttpRouter {
  8. private var handlers: [(method: HttpRequest.Method?, pattern: [String],
  9. handler: HttpServer.Handler)] = []
  10. public func routes() -> [(method: HttpRequest.Method?, path: String)] {
  11. return handlers.map { ($0.method, "/" + $0.pattern.joinWithSeparator("/")) }
  12. }
  13. public func register(path: String, handler: HttpServer.Handler) {
  14. register(nil, path: path, handler: handler)
  15. }
  16. public func register(method: HttpRequest.Method?, path: String, handler: HttpServer.Handler) {
  17. handlers.append((method, path.split("/"), handler))
  18. handlers.sortInPlace { $0.0.pattern.count < $0.1.pattern.count }
  19. }
  20. public func unregister(path: String) {
  21. unregister(nil, path: path)
  22. }
  23. public func unregister(method: HttpRequest.Method?, path: String) {
  24. let p = path.split("/")
  25. handlers = handlers.filter { (meth, pattern, _) -> Bool in
  26. return meth != method || pattern != p
  27. }
  28. }
  29. public func select(method: HttpRequest.Method, url: String)
  30. -> ([String: String], HttpServer.Handler)? {
  31. let urlTokens = url.split("/")
  32. for (meth, pattern, handler) in handlers {
  33. if meth == nil || meth! == method {
  34. if let params = matchParams(pattern, valueTokens: urlTokens) {
  35. return (params, handler)
  36. }
  37. }
  38. }
  39. return nil
  40. }
  41. public func matchParams(patternTokens: [String], valueTokens: [String]) -> [String: String]? {
  42. var params = [String: String]()
  43. for index in 0..<valueTokens.count {
  44. if index >= patternTokens.count {
  45. return nil
  46. }
  47. let patternToken = patternTokens[index]
  48. let valueToken = valueTokens[index]
  49. if patternToken.isEmpty {
  50. if patternToken != valueToken {
  51. return nil
  52. }
  53. }
  54. if patternToken.characters.first == ":" {
  55. #if os(Linux)
  56. params[patternToken.substringFromIndex(1)] = valueToken
  57. #else
  58. params[patternToken.substringFromIndex(patternToken.characters.startIndex.successor())] = valueToken
  59. #endif
  60. } else {
  61. if patternToken != valueToken {
  62. return nil
  63. }
  64. }
  65. }
  66. return params
  67. }
  68. }