1
0

SwifterTestsHttpParser.swift 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. //
  2. // SwifterTests.swift
  3. // SwifterTests
  4. //
  5. // Copyright © 2016 Damian Kołakowski. All rights reserved.
  6. //
  7. import XCTest
  8. class SwifterTestsHttpParser: XCTestCase {
  9. class TestSocket: Socket {
  10. var content = [UInt8]()
  11. var offset = 0
  12. init(_ content: String) {
  13. super.init(socketFileDescriptor: -1)
  14. self.content.append(contentsOf: [UInt8](content.utf8))
  15. }
  16. override func read() throws -> UInt8 {
  17. if offset < content.count {
  18. let value = self.content[offset]
  19. offset = offset + 1
  20. return value
  21. }
  22. throw SocketError.recvFailed("")
  23. }
  24. }
  25. func testParser() {
  26. let parser = HttpParser()
  27. do {
  28. let _ = try parser.readHttpRequest(TestSocket(""))
  29. XCTAssert(false, "Parser should throw an error if socket is empty.")
  30. } catch { }
  31. do {
  32. let _ = try parser.readHttpRequest(TestSocket("12345678"))
  33. XCTAssert(false, "Parser should throw an error if status line has single token.")
  34. } catch { }
  35. do {
  36. let _ = try parser.readHttpRequest(TestSocket("GET HTTP/1.0"))
  37. XCTAssert(false, "Parser should throw an error if status line has not enough tokens.")
  38. } catch { }
  39. do {
  40. let _ = try parser.readHttpRequest(TestSocket("GET / HTTP/1.0"))
  41. XCTAssert(false, "Parser should throw an error if there is no next line symbol.")
  42. } catch { }
  43. do {
  44. let _ = try parser.readHttpRequest(TestSocket("GET / HTTP/1.0"))
  45. XCTAssert(false, "Parser should throw an error if there is no next line symbol.")
  46. } catch { }
  47. do {
  48. let _ = try parser.readHttpRequest(TestSocket("GET / HTTP/1.0\r"))
  49. XCTAssert(false, "Parser should throw an error if there is no next line symbol.")
  50. } catch { }
  51. do {
  52. let _ = try parser.readHttpRequest(TestSocket("GET / HTTP/1.0\n"))
  53. XCTAssert(false, "Parser should throw an error if there is no 'Content-Length' header.")
  54. } catch { }
  55. do {
  56. let _ = try parser.readHttpRequest(TestSocket("GET / HTTP/1.0\r\nContent-Length: 0\r\n\r\n"))
  57. } catch {
  58. XCTAssert(false, "Parser should not throw any errors if there is a valid 'Content-Length' header.")
  59. }
  60. do {
  61. let _ = try parser.readHttpRequest(TestSocket("GET / HTTP/1.0\nContent-Length: 0\r\n\n"))
  62. } catch {
  63. XCTAssert(false, "Parser should not throw any errors if there is a valid 'Content-Length' header.")
  64. }
  65. do {
  66. let _ = try parser.readHttpRequest(TestSocket("GET / HTTP/1.0\nContent-Length: 5\n\n12345"))
  67. } catch {
  68. XCTAssert(false, "Parser should not throw any errors if there is a valid 'Content-Length' header.")
  69. }
  70. do {
  71. let _ = try parser.readHttpRequest(TestSocket("GET / HTTP/1.0\nContent-Length: 10\r\n\n"))
  72. XCTAssert(false, "Parser should throw an error if request' body is too short.")
  73. } catch { }
  74. var r = try? parser.readHttpRequest(TestSocket("GET /open?link=https://www.youtube.com/watch?v=D2cUBG4PnOA HTTP/1.0\nContent-Length: 10\n\n1234567890"))
  75. XCTAssertEqual(r?.queryParams.filter({ $0.0 == "link"}).first?.1, "https://www.youtube.com/watch?v=D2cUBG4PnOA")
  76. XCTAssertEqual(r?.method, "GET", "Parser should extract HTTP method name from the status line.")
  77. XCTAssertEqual(r?.path, "/open?link=https://www.youtube.com/watch?v=D2cUBG4PnOA", "Parser should extract HTTP path value from the status line.")
  78. XCTAssertEqual(r?.headers["content-length"], "10", "Parser should extract Content-Length header value.")
  79. r = try? parser.readHttpRequest(TestSocket("POST / HTTP/1.0\nContent-Length: 10\n\n1234567890"))
  80. XCTAssertEqual(r?.method, "POST", "Parser should extract HTTP method name from the status line.")
  81. r = try? parser.readHttpRequest(TestSocket("GET / HTTP/1.0\nHeader1: 1:1:34\nHeader2: 12345\nContent-Length: 0\n\n"))
  82. XCTAssertEqual(r?.headers["header1"], "1:1:34", "Parser should properly extract header name and value in case the value has ':' character.")
  83. r = try? parser.readHttpRequest(TestSocket("GET / HTTP/1.0\nHeader1: 1\nHeader2: 2\nContent-Length: 0\n\n"))
  84. XCTAssertEqual(r?.headers["header1"], "1", "Parser should extract multiple headers from the request.")
  85. XCTAssertEqual(r?.headers["header2"], "2", "Parser should extract multiple headers from the request.")
  86. }
  87. }