1
0

HttpServer.swift 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. //
  2. // HttpServer.swift
  3. //
  4. // Created by Damian Kolakowski on 05/06/14.
  5. // Copyright (c) 2014 Damian Kołakowski. All rights reserved.
  6. //
  7. import Foundation
  8. /* HTTP server */
  9. class HttpServer
  10. {
  11. enum Statuses {
  12. static let OK = 200
  13. static let NOT_FOUND = 404
  14. }
  15. var handlers: Dictionary<String, (Void -> (Int, String))> = Dictionary()
  16. var acceptSocket: CInt = -1
  17. subscript (path: String) -> ((Void -> (Int, String))) {
  18. get {
  19. return handlers[path]!
  20. }
  21. set ( newValue ) {
  22. self.handlers.updateValue(newValue, forKey: path)
  23. }
  24. }
  25. func start(listenPort: in_port_t) -> (Bool, String?) {
  26. releaseAcceptSocket()
  27. let (socket, error) = Socket.tcpForListen(listenPort)
  28. if ( socket == -1 ) {
  29. return (false, error)
  30. }
  31. acceptSocket = socket
  32. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), { () -> Void in
  33. while ( self.acceptSocket != -1 ) {
  34. var addr = sockaddr(sa_len: 0, sa_family: 0, sa_data: (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), len: socklen_t = 0
  35. let socket = accept(self.acceptSocket, &addr, &len)
  36. if ( socket == -1 ) {
  37. self.releaseAcceptSocket();
  38. return
  39. }
  40. Socket.nosigpipe(socket)
  41. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), { () -> Void in
  42. let parser = HttpParser()
  43. while let (path, headers) = parser.parseHttpHeader(socket) {
  44. if let handler = self.handlers[path] {
  45. let (status, response) = handler()
  46. Socket.writeStringUTF8(socket, string: "HTTP/1.1 \(status)\r\n")
  47. let nsdata = response.bridgeToObjectiveC().dataUsingEncoding(NSUTF8StringEncoding)
  48. Socket.writeStringUTF8(socket, string: "Content-Length: \(nsdata.length)\r\n")
  49. if parser.supportsKeepAlive(headers) {
  50. Socket.writeStringUTF8(socket, string: "Connection: keep-alive\r\n")
  51. }
  52. Socket.writeStringUTF8(socket, string: "\r\n")
  53. Socket.writeStringUTF8(socket, string: response)
  54. } else {
  55. Socket.writeStringUTF8(socket, string: "HTTP/1.1 \(Statuses.NOT_FOUND)\r\n")
  56. Socket.writeStringUTF8(socket, string: "Content-Length: 0\r\n")
  57. if parser.supportsKeepAlive(headers) {
  58. Socket.writeStringUTF8(socket, string: "Connection: keep-alive\r\n")
  59. }
  60. Socket.writeStringUTF8(socket, string: "\r\n")
  61. }
  62. if !parser.supportsKeepAlive(headers) {
  63. break
  64. }
  65. }
  66. Socket.release(socket)
  67. });
  68. }
  69. });
  70. return (true, nil)
  71. }
  72. func stop() {
  73. releaseAcceptSocket()
  74. }
  75. func releaseAcceptSocket() {
  76. if ( acceptSocket != -1 ) {
  77. Socket.release(acceptSocket)
  78. acceptSocket = -1
  79. }
  80. }
  81. }