Skip to content

Commit 14e61b5

Browse files
Router & HttpParser tests migration to 2.0.
1 parent d4b1e64 commit 14e61b5

File tree

7 files changed

+200
-104
lines changed

7 files changed

+200
-104
lines changed

Sources/WebSockets.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public class WebsocketResponse: Response {
2323
public init(_ request: Request, _ closure: @escaping ((WebsocketEvent) -> Void)) {
2424

2525
super.init()
26-
26+
2727
guard request.hasToken("websocket", forHeader: "upgrade") else {
2828
self.status = Status.badRequest.rawValue
2929
self.body = [UInt8](("Invalid value of 'Upgrade' header.").utf8)

XCode/Swifter.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
7C0324491E51D36900325E4F /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C0324461E51D36900325E4F /* Error.swift */; };
6060
7C03244A1E51D36900325E4F /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C0324461E51D36900325E4F /* Error.swift */; };
6161
7C03244B1E51D36900325E4F /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C0324461E51D36900325E4F /* Error.swift */; };
62+
7C2F837C1E61D0D8001B744C /* Http+Misc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C4965311E6098C50043503A /* Http+Misc.swift */; };
63+
7C2F837D1E61D0D8001B744C /* Http+Misc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C4965311E6098C50043503A /* Http+Misc.swift */; };
6264
7C377E181D964B96009C6148 /* String+File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C377E161D964B6A009C6148 /* String+File.swift */; };
6365
7C377E191D964B9F009C6148 /* String+File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C377E161D964B6A009C6148 /* String+File.swift */; };
6466
7C4785E91C71D15600A9FE73 /* SwifterTestsWebSocketSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C4785E81C71D15600A9FE73 /* SwifterTestsWebSocketSession.swift */; };
@@ -754,6 +756,7 @@
754756
7C03243F1E51D21D00325E4F /* MacOS.swift in Sources */,
755757
7C4785E91C71D15600A9FE73 /* SwifterTestsWebSocketSession.swift in Sources */,
756758
7CCD87721C660B250068099B /* SwifterTestsStringExtensions.swift in Sources */,
759+
7C2F837C1E61D0D8001B744C /* Http+Misc.swift in Sources */,
757760
7C0324431E51D24A00325E4F /* Html.swift in Sources */,
758761
);
759762
runOnlyForDeploymentPostprocessing = 0;
@@ -781,6 +784,7 @@
781784
7C4785EA1C71D15600A9FE73 /* SwifterTestsWebSocketSession.swift in Sources */,
782785
7C0324331E51D21100325E4F /* Server.swift in Sources */,
783786
7C03243E1E51D21C00325E4F /* MacOS.swift in Sources */,
787+
7C2F837D1E61D0D8001B744C /* Http+Misc.swift in Sources */,
784788
7C03244B1E51D36900325E4F /* Error.swift in Sources */,
785789
7CCD87851C660ED60068099B /* SwifterTestsStringExtensions.swift in Sources */,
786790
);

XCode/SwifterTestsCommon/IOSafetyTests.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
import XCTest
1010

1111
class IOSafetyTests: XCTestCase {
12+
13+
14+
/*
1215
var server: HttpServer!
1316

1417
override func setUp() {
@@ -40,4 +43,6 @@ class IOSafetyTests: XCTestCase {
4043
}
4144
}
4245
}
46+
47+
*/
4348
}

XCode/SwifterTestsCommon/PingServer.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
import Foundation
1010

1111
// Server
12-
extension HttpServer {
13-
class func pingServer() -> HttpServer {
14-
let server = HttpServer()
15-
server.GET["/ping"] = { request in
16-
return HttpResponse.ok(.text("pong!"))
12+
extension Swifter {
13+
14+
class func pingServer() throws -> Swifter {
15+
let server = try Swifter()
16+
server.get("/ping") { _, request, responder in
17+
responder(TextResponse(200, "pong!"))
1718
}
1819
return server
1920
}

XCode/SwifterTestsCommon/SwifterTestsHttpParser.swift

Lines changed: 167 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -9,96 +9,192 @@ import XCTest
99

1010
class SwifterTestsHttpParser: XCTestCase {
1111

12-
class TestSocket: Socket {
13-
var content = [UInt8]()
14-
var offset = 0
15-
16-
init(_ content: String) {
17-
super.init(socketFileDescriptor: -1)
18-
self.content.append(contentsOf: [UInt8](content.utf8))
19-
}
20-
21-
override func read() throws -> UInt8 {
22-
if offset < content.count {
23-
let value = self.content[offset]
24-
offset = offset + 1
25-
return value
26-
}
27-
throw SocketError.recvFailed("")
12+
func testRandomStuff() {
13+
do {
14+
let data = [UInt8]("1231245".utf8)
15+
try HttpIncomingDataPorcessor(0, { item in
16+
XCTAssert(false, "Http processor should not return a request object for invalid data .")
17+
}).process(data[0..<data.count])
18+
} catch {
19+
XCTAssert(false, "No exception")
2820
}
2921
}
3022

31-
func testParser() {
32-
let parser = HttpParser()
33-
23+
func testInvalidStatusLineChunk() {
3424
do {
35-
let _ = try parser.readHttpRequest(TestSocket(""))
36-
XCTAssert(false, "Parser should throw an error if socket is empty.")
37-
} catch { }
38-
25+
let data = [UInt8]("GET HTTP/1.0".utf8)
26+
try HttpIncomingDataPorcessor(0, { item in
27+
XCTAssert(false, "Http processor should not return a request object for invalid status line.")
28+
}).process(data[0..<data.count])
29+
} catch {
30+
XCTAssert(false, "No exception")
31+
}
32+
}
33+
34+
func testValidStatusLineChunk() {
3935
do {
40-
let _ = try parser.readHttpRequest(TestSocket("12345678"))
41-
XCTAssert(false, "Parser should throw an error if status line has single token.")
42-
} catch { }
43-
36+
let data = [UInt8]("GET / HTTP/1.0".utf8)
37+
try HttpIncomingDataPorcessor(0, { item in
38+
XCTAssert(false, "Http processor should not return a request object for valid status line only.")
39+
}).process(data[0..<data.count])
40+
} catch {
41+
XCTAssert(false, "No exception")
42+
}
43+
}
44+
45+
func testStatusLineWithSingleNextLine() {
4446
do {
45-
let _ = try parser.readHttpRequest(TestSocket("GET HTTP/1.0"))
46-
XCTAssert(false, "Parser should throw an error if status line has not enough tokens.")
47-
} catch { }
48-
47+
let data = [UInt8]("GET / HTTP/1.0\r\n".utf8)
48+
try HttpIncomingDataPorcessor(0, { item in
49+
XCTAssert(false, "Http processor should not return if there is no double next line symbol.")
50+
}).process(data[0..<data.count])
51+
} catch {
52+
XCTAssert(false, "No exception")
53+
}
54+
}
55+
56+
func testStatusLineWithDoubleNextLine() {
4957
do {
50-
let _ = try parser.readHttpRequest(TestSocket("GET / HTTP/1.0"))
51-
XCTAssert(false, "Parser should throw an error if there is no next line symbol.")
52-
} catch { }
53-
58+
var request: Request? = nil
59+
let data = [UInt8]("GET / HTTP/1.0\r\n\r\n".utf8)
60+
try HttpIncomingDataPorcessor(0, { item in
61+
request = item
62+
}).process(data[0..<data.count])
63+
XCTAssertEqual(request?.path, "/")
64+
XCTAssertEqual(request?.method, "GET")
65+
XCTAssertEqual(request?.httpVersion, .http10)
66+
} catch {
67+
XCTAssert(false, "There should be no crash for valid http request.")
68+
}
69+
}
70+
71+
func testContentLengthZero() {
5472
do {
55-
let _ = try parser.readHttpRequest(TestSocket("GET / HTTP/1.0"))
56-
XCTAssert(false, "Parser should throw an error if there is no next line symbol.")
57-
} catch { }
58-
73+
var request: Request? = nil
74+
let data = [UInt8]("GET / HTTP/1.0\r\nContent-Length: 0\r\n\r\n".utf8)
75+
try HttpIncomingDataPorcessor(0, { item in
76+
request = item
77+
}).process(data[0..<data.count])
78+
XCTAssertEqual(request?.path, "/")
79+
XCTAssertEqual(request?.method, "GET")
80+
XCTAssertEqual(request?.body.count, 0)
81+
XCTAssertEqual(request?.httpVersion, .http10)
82+
} catch {
83+
XCTAssert(false, "No exception")
84+
}
85+
}
86+
87+
func testContentLengthNonZero() {
5988
do {
60-
let _ = try parser.readHttpRequest(TestSocket("GET / HTTP/1.0\r"))
61-
XCTAssert(false, "Parser should throw an error if there is no next line symbol.")
62-
} catch { }
63-
89+
var request: Request? = nil
90+
let data = [UInt8]("GET / HTTP/1.0\r\nContent-Length: 5\r\n\r\n12345".utf8)
91+
try HttpIncomingDataPorcessor(0, { item in
92+
request = item
93+
}).process(data[0..<data.count])
94+
XCTAssertEqual(request?.path, "/")
95+
XCTAssertEqual(request?.method, "GET")
96+
XCTAssertEqual(request?.body.count, 5)
97+
XCTAssertEqual((request?.body)!, [49, 50, 51, 52, 53])
98+
XCTAssertEqual(request?.httpVersion, .http10)
99+
} catch {
100+
XCTAssert(false, "No exception")
101+
}
102+
}
103+
104+
func testContentLengthWithBodyChunk() {
64105
do {
65-
let _ = try parser.readHttpRequest(TestSocket("GET / HTTP/1.0\n"))
66-
XCTAssert(false, "Parser should throw an error if there is no 'Content-Length' header.")
67-
} catch { }
68-
106+
var request: Request? = nil
107+
let data = [UInt8]("GET / HTTP/1.0\r\nContent-Length: 10\r\n\r\n123".utf8)
108+
try HttpIncomingDataPorcessor(0, { item in
109+
request = item
110+
}).process(data[0..<data.count])
111+
XCTAssertNil(request)
112+
} catch {
113+
XCTAssert(false, "No exception")
114+
}
115+
}
116+
117+
func testContentProcessedInChunks() {
69118
do {
70-
let _ = try parser.readHttpRequest(TestSocket("GET / HTTP/1.0\r\nContent-Length: 0\r\n\r\n"))
119+
var request: Request? = nil
120+
121+
let processor = HttpIncomingDataPorcessor(0, { item in
122+
request = item
123+
})
124+
125+
let chunk1 = [UInt8]("GET /chunk HTTP/1.0\r\nContent-Length: 20\r\n\r\n123".utf8)
126+
try processor.process(chunk1[0..<chunk1.count])
127+
128+
XCTAssertNil(request)
129+
130+
let chunk2 = [UInt8]("1234567890".utf8)
131+
try processor.process(chunk2[0..<chunk2.count])
132+
133+
XCTAssertNil(request)
134+
135+
let chunk3 = [UInt8]("1234567".utf8)
136+
try processor.process(chunk3[0..<chunk3.count])
137+
138+
XCTAssertEqual(request?.path, "/chunk")
139+
XCTAssertEqual(request?.method, "GET")
140+
XCTAssertEqual(request?.body.count, 20)
141+
XCTAssertEqual(request?.httpVersion, .http10)
142+
71143
} catch {
72-
XCTAssert(false, "Parser should not throw any errors if there is a valid 'Content-Length' header.")
144+
XCTAssert(false, "No exception")
73145
}
74-
146+
}
147+
148+
func testHeaders() {
75149
do {
76-
let _ = try parser.readHttpRequest(TestSocket("GET / HTTP/1.0\nContent-Length: 0\r\n\n"))
150+
var request: Request? = nil
151+
let data = [UInt8]("GET / HTTP/1.0\r\na: b\r\nc: d\r\nContent-Length: 0\r\n\r\n".utf8)
152+
try HttpIncomingDataPorcessor(0, { item in
153+
request = item
154+
}).process(data[0..<data.count])
155+
XCTAssertNotNil(request)
156+
XCTAssertEqual(request?.headers.first?.0, "a")
157+
XCTAssertEqual(request?.headers.first?.1, "b")
158+
XCTAssertEqual(request?.headers[1].0, "c")
159+
XCTAssertEqual(request?.headers[1].1, "d")
77160
} catch {
78-
XCTAssert(false, "Parser should not throw any errors if there is a valid 'Content-Length' header.")
161+
XCTAssert(false, "No exception")
79162
}
80-
163+
}
164+
165+
func testPath() {
81166
do {
82-
let _ = try parser.readHttpRequest(TestSocket("GET / HTTP/1.0\nContent-Length: 5\n\n12345"))
167+
var request: Request? = nil
168+
let data = [UInt8]("GET /a/b/c/d?1345678=1231 HTTP/1.0\r\nContent-Length: 0\r\n\r\n".utf8)
169+
try HttpIncomingDataPorcessor(0, { item in
170+
request = item
171+
}).process(data[0..<data.count])
172+
XCTAssertEqual(request?.path, "/a/b/c/d")
173+
XCTAssertEqual(request?.method, "GET")
174+
XCTAssertEqual(request?.body.count, 0)
175+
XCTAssertEqual(request?.httpVersion, .http10)
83176
} catch {
84-
XCTAssert(false, "Parser should not throw any errors if there is a valid 'Content-Length' header.")
177+
XCTAssert(false, "No exception")
85178
}
86-
179+
}
180+
181+
func testPathWithComplexQuery() {
87182
do {
88-
let _ = try parser.readHttpRequest(TestSocket("GET / HTTP/1.0\nContent-Length: 10\r\n\n"))
89-
XCTAssert(false, "Parser should throw an error if request' body is too short.")
90-
} catch { }
91-
92-
var r = try? parser.readHttpRequest(TestSocket("GET / HTTP/1.0\nContent-Length: 10\n\n1234567890"))
93-
XCTAssertEqual(r?.method, "GET", "Parser should extract HTTP method name from the status line.")
94-
XCTAssertEqual(r?.path, "/", "Parser should extract HTTP path value from the status line.")
95-
XCTAssertEqual(r?.headers["content-length"], "10", "Parser should extract Content-Length header value.")
96-
97-
r = try? parser.readHttpRequest(TestSocket("POST / HTTP/1.0\nContent-Length: 10\n\n1234567890"))
98-
XCTAssertEqual(r?.method, "POST", "Parser should extract HTTP method name from the status line.")
99-
100-
r = try? parser.readHttpRequest(TestSocket("GET / HTTP/1.0\nHeader1: 1\nHeader2: 2\nContent-Length: 0\n\n"))
101-
XCTAssertEqual(r?.headers["header1"], "1", "Parser should extract multiple headers from the request.")
102-
XCTAssertEqual(r?.headers["header2"], "2", "Parser should extract multiple headers from the request.")
183+
var request: Request? = nil
184+
let data = [UInt8]("GET /a/b/c/d?key=value1?&key=???s HTTP/1.0\r\nContent-Length: 0\r\n\r\n".utf8)
185+
try HttpIncomingDataPorcessor(0, { item in
186+
request = item
187+
}).process(data[0..<data.count])
188+
XCTAssertEqual(request?.path, "/a/b/c/d")
189+
XCTAssertEqual(request?.method, "GET")
190+
XCTAssertEqual(request?.query[0].0, "key")
191+
XCTAssertEqual(request?.query[0].1, "value1?")
192+
XCTAssertEqual(request?.query[1].0, "key")
193+
XCTAssertEqual(request?.query[1].1, "???s")
194+
XCTAssertEqual(request?.body.count, 0)
195+
XCTAssertEqual(request?.httpVersion, .http10)
196+
} catch {
197+
XCTAssert(false, "No exception")
198+
}
103199
}
104200
}

0 commit comments

Comments
 (0)