OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/websockets/websocket_handshake_handler.h" | |
6 | |
7 #include <string> | |
8 #include <vector> | |
9 | |
10 #include "base/basictypes.h" | |
11 #include "base/strings/string_util.h" | |
12 #include "base/strings/stringprintf.h" | |
13 #include "net/http/http_response_headers.h" | |
14 #include "net/http/http_util.h" | |
15 #include "url/gurl.h" | |
16 | |
17 #include "testing/gtest/include/gtest/gtest.h" | |
18 | |
19 namespace { | |
20 | |
21 const char* const kCookieHeaders[] = { | |
22 "cookie", "cookie2" | |
23 }; | |
24 | |
25 const char* const kSetCookieHeaders[] = { | |
26 "set-cookie", "set-cookie2" | |
27 }; | |
28 | |
29 // A test fixture to simplify tests for GetKeyNumber(). | |
30 class WebSocketHandshakeGetKeyNumberTest : public ::testing::Test { | |
31 protected: | |
32 static const char kExampleFromDraftKey1[]; | |
33 | |
34 // The object is default-initialised with an empty challenge and the example | |
35 // key from draft-ietf-hybi-thewebsocketprotocol-00. These can be changed | |
36 // using set_challenge() and set_key(). | |
37 WebSocketHandshakeGetKeyNumberTest() | |
38 : challenge_(), key_(kExampleFromDraftKey1) {} | |
39 | |
40 // A convenience wrapper for the function under test which automatically | |
41 // passes in the arguments stored in the object. | |
42 void GetKeyNumber() { ::net::internal::GetKeyNumber(key_, &challenge_); } | |
43 | |
44 // Read current challenge. | |
45 const std::string& challenge() const { return challenge_; } | |
46 | |
47 // Overwrite challenge. | |
48 void set_challenge(const std::string& challenge) { challenge_ = challenge; } | |
49 | |
50 // Reset the challenge to be empty. | |
51 void reset_challenge() { challenge_.clear(); } | |
52 | |
53 // Change key. | |
54 void set_key(const std::string& key) { key_ = key; } | |
55 | |
56 private: | |
57 std::string challenge_; | |
58 std::string key_; | |
59 }; | |
60 | |
61 const char WebSocketHandshakeGetKeyNumberTest::kExampleFromDraftKey1[] = | |
62 "3e6b263 4 17 80"; | |
63 | |
64 // A version of the above fixture for death tests. | |
65 class WebSocketHandshakeGetKeyNumberDeathTest | |
66 : public WebSocketHandshakeGetKeyNumberTest { | |
67 }; | |
68 | |
69 } // namespace | |
70 | |
71 namespace net { | |
72 | |
73 TEST(WebSocketHandshakeRequestHandlerTest, SimpleRequest) { | |
74 WebSocketHandshakeRequestHandler handler; | |
75 | |
76 static const char kHandshakeRequestMessage[] = | |
77 "GET /demo HTTP/1.1\r\n" | |
78 "Host: example.com\r\n" | |
79 "Connection: Upgrade\r\n" | |
80 "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" | |
81 "Sec-WebSocket-Protocol: sample\r\n" | |
82 "Upgrade: WebSocket\r\n" | |
83 "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" | |
84 "Origin: http://example.com\r\n" | |
85 "\r\n" | |
86 "^n:ds[4U"; | |
87 | |
88 EXPECT_TRUE(handler.ParseRequest(kHandshakeRequestMessage, | |
89 strlen(kHandshakeRequestMessage))); | |
90 EXPECT_EQ(0, handler.protocol_version()); | |
91 | |
92 handler.RemoveHeaders(kCookieHeaders, arraysize(kCookieHeaders)); | |
93 | |
94 EXPECT_EQ(kHandshakeRequestMessage, handler.GetRawRequest()); | |
95 } | |
96 | |
97 TEST(WebSocketHandshakeRequestHandlerTest, SimpleRequestHybi06Handshake) { | |
98 WebSocketHandshakeRequestHandler handler; | |
99 | |
100 static const char kHandshakeRequestMessage[] = | |
101 "GET /demo HTTP/1.1\r\n" | |
102 "Host: example.com\r\n" | |
103 "Upgrade: websocket\r\n" | |
104 "Connection: Upgrade\r\n" | |
105 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
106 "Sec-WebSocket-Origin: http://example.com\r\n" | |
107 "Sec-WebSocket-Protocol: sample\r\n" | |
108 "Sec-WebSocket-Version: 6\r\n" | |
109 "\r\n"; | |
110 | |
111 EXPECT_TRUE(handler.ParseRequest(kHandshakeRequestMessage, | |
112 strlen(kHandshakeRequestMessage))); | |
113 EXPECT_EQ(6, handler.protocol_version()); | |
114 | |
115 handler.RemoveHeaders(kCookieHeaders, arraysize(kCookieHeaders)); | |
116 | |
117 EXPECT_EQ(kHandshakeRequestMessage, handler.GetRawRequest()); | |
118 } | |
119 | |
120 TEST(WebSocketHandshakeRequestHandlerTest, ReplaceRequestCookies) { | |
121 WebSocketHandshakeRequestHandler handler; | |
122 | |
123 static const char kHandshakeRequestMessage[] = | |
124 "GET /demo HTTP/1.1\r\n" | |
125 "Host: example.com\r\n" | |
126 "Connection: Upgrade\r\n" | |
127 "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" | |
128 "Sec-WebSocket-Protocol: sample\r\n" | |
129 "Upgrade: WebSocket\r\n" | |
130 "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" | |
131 "Origin: http://example.com\r\n" | |
132 "Cookie: WK-websocket-test=1\r\n" | |
133 "\r\n" | |
134 "^n:ds[4U"; | |
135 | |
136 EXPECT_TRUE(handler.ParseRequest(kHandshakeRequestMessage, | |
137 strlen(kHandshakeRequestMessage))); | |
138 EXPECT_EQ(0, handler.protocol_version()); | |
139 | |
140 handler.RemoveHeaders(kCookieHeaders, arraysize(kCookieHeaders)); | |
141 | |
142 handler.AppendHeaderIfMissing("Cookie", | |
143 "WK-websocket-test=1; " | |
144 "WK-websocket-test-httponly=1"); | |
145 | |
146 static const char kHandshakeRequestExpectedMessage[] = | |
147 "GET /demo HTTP/1.1\r\n" | |
148 "Host: example.com\r\n" | |
149 "Connection: Upgrade\r\n" | |
150 "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" | |
151 "Sec-WebSocket-Protocol: sample\r\n" | |
152 "Upgrade: WebSocket\r\n" | |
153 "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" | |
154 "Origin: http://example.com\r\n" | |
155 "Cookie: WK-websocket-test=1; WK-websocket-test-httponly=1\r\n" | |
156 "\r\n" | |
157 "^n:ds[4U"; | |
158 | |
159 EXPECT_EQ(kHandshakeRequestExpectedMessage, handler.GetRawRequest()); | |
160 } | |
161 | |
162 TEST(WebSocketHandshakeRequestHandlerTest, | |
163 ReplaceRequestCookiesHybi06Handshake) { | |
164 WebSocketHandshakeRequestHandler handler; | |
165 | |
166 static const char kHandshakeRequestMessage[] = | |
167 "GET /demo HTTP/1.1\r\n" | |
168 "Host: example.com\r\n" | |
169 "Upgrade: websocket\r\n" | |
170 "Connection: Upgrade\r\n" | |
171 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
172 "Sec-WebSocket-Origin: http://example.com\r\n" | |
173 "Sec-WebSocket-Protocol: sample\r\n" | |
174 "Sec-WebSocket-Version: 6\r\n" | |
175 "Cookie: WK-websocket-test=1\r\n" | |
176 "\r\n"; | |
177 | |
178 EXPECT_TRUE(handler.ParseRequest(kHandshakeRequestMessage, | |
179 strlen(kHandshakeRequestMessage))); | |
180 EXPECT_EQ(6, handler.protocol_version()); | |
181 | |
182 handler.RemoveHeaders(kCookieHeaders, arraysize(kCookieHeaders)); | |
183 | |
184 handler.AppendHeaderIfMissing("Cookie", | |
185 "WK-websocket-test=1; " | |
186 "WK-websocket-test-httponly=1"); | |
187 | |
188 static const char kHandshakeRequestExpectedMessage[] = | |
189 "GET /demo HTTP/1.1\r\n" | |
190 "Host: example.com\r\n" | |
191 "Upgrade: websocket\r\n" | |
192 "Connection: Upgrade\r\n" | |
193 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
194 "Sec-WebSocket-Origin: http://example.com\r\n" | |
195 "Sec-WebSocket-Protocol: sample\r\n" | |
196 "Sec-WebSocket-Version: 6\r\n" | |
197 "Cookie: WK-websocket-test=1; WK-websocket-test-httponly=1\r\n" | |
198 "\r\n"; | |
199 | |
200 EXPECT_EQ(kHandshakeRequestExpectedMessage, handler.GetRawRequest()); | |
201 } | |
202 | |
203 TEST(WebSocketHandshakeResponseHandlerTest, SimpleResponse) { | |
204 WebSocketHandshakeResponseHandler handler; | |
205 EXPECT_EQ(0, handler.protocol_version()); | |
206 | |
207 static const char kHandshakeResponseMessage[] = | |
208 "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" | |
209 "Upgrade: WebSocket\r\n" | |
210 "Connection: Upgrade\r\n" | |
211 "Sec-WebSocket-Origin: http://example.com\r\n" | |
212 "Sec-WebSocket-Location: ws://example.com/demo\r\n" | |
213 "Sec-WebSocket-Protocol: sample\r\n" | |
214 "\r\n" | |
215 "8jKS'y:G*Co,Wxa-"; | |
216 | |
217 EXPECT_EQ(strlen(kHandshakeResponseMessage), | |
218 handler.ParseRawResponse(kHandshakeResponseMessage, | |
219 strlen(kHandshakeResponseMessage))); | |
220 EXPECT_TRUE(handler.HasResponse()); | |
221 | |
222 handler.RemoveHeaders(kCookieHeaders, arraysize(kCookieHeaders)); | |
223 | |
224 EXPECT_EQ(kHandshakeResponseMessage, handler.GetResponse()); | |
225 } | |
226 | |
227 TEST(WebSocketHandshakeResponseHandlerTest, SimpleResponseHybi06Handshake) { | |
228 WebSocketHandshakeResponseHandler handler; | |
229 handler.set_protocol_version(6); | |
230 EXPECT_EQ(6, handler.protocol_version()); | |
231 | |
232 static const char kHandshakeResponseMessage[] = | |
233 "HTTP/1.1 101 Switching Protocols\r\n" | |
234 "Upgrade: websocket\r\n" | |
235 "Connection: Upgrade\r\n" | |
236 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | |
237 "Sec-WebSocket-Protocol: sample\r\n" | |
238 "\r\n"; | |
239 | |
240 EXPECT_EQ(strlen(kHandshakeResponseMessage), | |
241 handler.ParseRawResponse(kHandshakeResponseMessage, | |
242 strlen(kHandshakeResponseMessage))); | |
243 EXPECT_TRUE(handler.HasResponse()); | |
244 | |
245 handler.RemoveHeaders(kCookieHeaders, arraysize(kCookieHeaders)); | |
246 | |
247 EXPECT_EQ(kHandshakeResponseMessage, handler.GetResponse()); | |
248 } | |
249 | |
250 TEST(WebSocketHandshakeResponseHandlerTest, ReplaceResponseCookies) { | |
251 WebSocketHandshakeResponseHandler handler; | |
252 EXPECT_EQ(0, handler.protocol_version()); | |
253 | |
254 static const char kHandshakeResponseMessage[] = | |
255 "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" | |
256 "Upgrade: WebSocket\r\n" | |
257 "Connection: Upgrade\r\n" | |
258 "Sec-WebSocket-Origin: http://example.com\r\n" | |
259 "Sec-WebSocket-Location: ws://example.com/demo\r\n" | |
260 "Sec-WebSocket-Protocol: sample\r\n" | |
261 "Set-Cookie: WK-websocket-test-1\r\n" | |
262 "Set-Cookie: WK-websocket-test-httponly=1; HttpOnly\r\n" | |
263 "\r\n" | |
264 "8jKS'y:G*Co,Wxa-"; | |
265 | |
266 EXPECT_EQ(strlen(kHandshakeResponseMessage), | |
267 handler.ParseRawResponse(kHandshakeResponseMessage, | |
268 strlen(kHandshakeResponseMessage))); | |
269 EXPECT_TRUE(handler.HasResponse()); | |
270 std::vector<std::string> cookies; | |
271 handler.GetHeaders(kSetCookieHeaders, arraysize(kSetCookieHeaders), &cookies); | |
272 ASSERT_EQ(2U, cookies.size()); | |
273 EXPECT_EQ("WK-websocket-test-1", cookies[0]); | |
274 EXPECT_EQ("WK-websocket-test-httponly=1; HttpOnly", cookies[1]); | |
275 handler.RemoveHeaders(kSetCookieHeaders, arraysize(kSetCookieHeaders)); | |
276 | |
277 static const char kHandshakeResponseExpectedMessage[] = | |
278 "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" | |
279 "Upgrade: WebSocket\r\n" | |
280 "Connection: Upgrade\r\n" | |
281 "Sec-WebSocket-Origin: http://example.com\r\n" | |
282 "Sec-WebSocket-Location: ws://example.com/demo\r\n" | |
283 "Sec-WebSocket-Protocol: sample\r\n" | |
284 "\r\n" | |
285 "8jKS'y:G*Co,Wxa-"; | |
286 | |
287 EXPECT_EQ(kHandshakeResponseExpectedMessage, handler.GetResponse()); | |
288 } | |
289 | |
290 TEST(WebSocketHandshakeResponseHandlerTest, | |
291 ReplaceResponseCookiesHybi06Handshake) { | |
292 WebSocketHandshakeResponseHandler handler; | |
293 handler.set_protocol_version(6); | |
294 EXPECT_EQ(6, handler.protocol_version()); | |
295 | |
296 static const char kHandshakeResponseMessage[] = | |
297 "HTTP/1.1 101 Switching Protocols\r\n" | |
298 "Upgrade: websocket\r\n" | |
299 "Connection: Upgrade\r\n" | |
300 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | |
301 "Sec-WebSocket-Protocol: sample\r\n" | |
302 "Set-Cookie: WK-websocket-test-1\r\n" | |
303 "Set-Cookie: WK-websocket-test-httponly=1; HttpOnly\r\n" | |
304 "\r\n"; | |
305 | |
306 EXPECT_EQ(strlen(kHandshakeResponseMessage), | |
307 handler.ParseRawResponse(kHandshakeResponseMessage, | |
308 strlen(kHandshakeResponseMessage))); | |
309 EXPECT_TRUE(handler.HasResponse()); | |
310 std::vector<std::string> cookies; | |
311 handler.GetHeaders(kSetCookieHeaders, arraysize(kSetCookieHeaders), &cookies); | |
312 ASSERT_EQ(2U, cookies.size()); | |
313 EXPECT_EQ("WK-websocket-test-1", cookies[0]); | |
314 EXPECT_EQ("WK-websocket-test-httponly=1; HttpOnly", cookies[1]); | |
315 handler.RemoveHeaders(kSetCookieHeaders, arraysize(kSetCookieHeaders)); | |
316 | |
317 static const char kHandshakeResponseExpectedMessage[] = | |
318 "HTTP/1.1 101 Switching Protocols\r\n" | |
319 "Upgrade: websocket\r\n" | |
320 "Connection: Upgrade\r\n" | |
321 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | |
322 "Sec-WebSocket-Protocol: sample\r\n" | |
323 "\r\n"; | |
324 | |
325 EXPECT_EQ(kHandshakeResponseExpectedMessage, handler.GetResponse()); | |
326 } | |
327 | |
328 TEST(WebSocketHandshakeResponseHandlerTest, BadResponse) { | |
329 WebSocketHandshakeResponseHandler handler; | |
330 | |
331 static const char kBadMessage[] = "\n\n\r\net-Location: w"; | |
332 EXPECT_EQ(strlen(kBadMessage), | |
333 handler.ParseRawResponse(kBadMessage, strlen(kBadMessage))); | |
334 EXPECT_TRUE(handler.HasResponse()); | |
335 EXPECT_EQ(kBadMessage, handler.GetResponse()); | |
336 } | |
337 | |
338 TEST(WebSocketHandshakeResponseHandlerTest, BadResponse2) { | |
339 WebSocketHandshakeResponseHandler handler; | |
340 | |
341 static const char kBadMessage[] = "\n\r\n\r\net-Location: w"; | |
342 EXPECT_EQ(strlen(kBadMessage), | |
343 handler.ParseRawResponse(kBadMessage, strlen(kBadMessage))); | |
344 EXPECT_TRUE(handler.HasResponse()); | |
345 EXPECT_EQ(kBadMessage, handler.GetResponse()); | |
346 } | |
347 | |
348 TEST(WebSocketHandshakeHandlerTest, HttpRequestResponse) { | |
349 WebSocketHandshakeRequestHandler request_handler; | |
350 | |
351 static const char kHandshakeRequestMessage[] = | |
352 "GET /demo HTTP/1.1\r\n" | |
353 "Host: example.com\r\n" | |
354 "Connection: Upgrade\r\n" | |
355 "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" | |
356 "Sec-WebSocket-Protocol: sample\r\n" | |
357 "Upgrade: WebSocket\r\n" | |
358 "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" | |
359 "Origin: http://example.com\r\n" | |
360 "\r\n" | |
361 "^n:ds[4U"; | |
362 | |
363 EXPECT_TRUE(request_handler.ParseRequest(kHandshakeRequestMessage, | |
364 strlen(kHandshakeRequestMessage))); | |
365 EXPECT_EQ(0, request_handler.protocol_version()); | |
366 | |
367 GURL url("ws://example.com/demo"); | |
368 std::string challenge; | |
369 const HttpRequestInfo& request_info = | |
370 request_handler.GetRequestInfo(url, &challenge); | |
371 | |
372 EXPECT_EQ(url, request_info.url); | |
373 EXPECT_EQ("GET", request_info.method); | |
374 EXPECT_FALSE(request_info.extra_headers.HasHeader("Upgrade")); | |
375 EXPECT_FALSE(request_info.extra_headers.HasHeader("Connection")); | |
376 EXPECT_FALSE(request_info.extra_headers.HasHeader("Sec-WebSocket-Key1")); | |
377 EXPECT_FALSE(request_info.extra_headers.HasHeader("Sec-WebSocket-Key2")); | |
378 std::string value; | |
379 EXPECT_TRUE(request_info.extra_headers.GetHeader("Host", &value)); | |
380 EXPECT_EQ("example.com", value); | |
381 EXPECT_TRUE(request_info.extra_headers.GetHeader("Origin", &value)); | |
382 EXPECT_EQ("http://example.com", value); | |
383 EXPECT_TRUE(request_info.extra_headers.GetHeader("Sec-WebSocket-Protocol", | |
384 &value)); | |
385 EXPECT_EQ("sample", value); | |
386 | |
387 const char expected_challenge[] = "\x31\x6e\x41\x13\x0f\x7e\xd6\x3c^n:ds[4U"; | |
388 | |
389 EXPECT_EQ(expected_challenge, challenge); | |
390 | |
391 static const char kHandshakeResponseHeader[] = | |
392 "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" | |
393 "Sec-WebSocket-Origin: http://example.com\r\n" | |
394 "Sec-WebSocket-Location: ws://example.com/demo\r\n" | |
395 "Sec-WebSocket-Protocol: sample\r\n"; | |
396 | |
397 std::string raw_headers = | |
398 HttpUtil::AssembleRawHeaders(kHandshakeResponseHeader, | |
399 strlen(kHandshakeResponseHeader)); | |
400 HttpResponseInfo response_info; | |
401 response_info.headers = new HttpResponseHeaders(raw_headers); | |
402 | |
403 EXPECT_TRUE(StartsWithASCII(response_info.headers->GetStatusLine(), | |
404 "HTTP/1.1 101 ", false)); | |
405 EXPECT_FALSE(response_info.headers->HasHeader("Upgrade")); | |
406 EXPECT_FALSE(response_info.headers->HasHeader("Connection")); | |
407 EXPECT_TRUE(response_info.headers->HasHeaderValue("Sec-WebSocket-Origin", | |
408 "http://example.com")); | |
409 EXPECT_TRUE(response_info.headers->HasHeaderValue("Sec-WebSocket-Location", | |
410 "ws://example.com/demo")); | |
411 EXPECT_TRUE(response_info.headers->HasHeaderValue("Sec-WebSocket-Protocol", | |
412 "sample")); | |
413 | |
414 WebSocketHandshakeResponseHandler response_handler; | |
415 EXPECT_EQ(0, response_handler.protocol_version()); | |
416 EXPECT_TRUE(response_handler.ParseResponseInfo(response_info, challenge)); | |
417 EXPECT_TRUE(response_handler.HasResponse()); | |
418 | |
419 static const char kHandshakeResponseExpectedMessage[] = | |
420 "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" | |
421 "Upgrade: WebSocket\r\n" | |
422 "Connection: Upgrade\r\n" | |
423 "Sec-WebSocket-Origin: http://example.com\r\n" | |
424 "Sec-WebSocket-Location: ws://example.com/demo\r\n" | |
425 "Sec-WebSocket-Protocol: sample\r\n" | |
426 "\r\n" | |
427 "8jKS'y:G*Co,Wxa-"; | |
428 | |
429 EXPECT_EQ(kHandshakeResponseExpectedMessage, response_handler.GetResponse()); | |
430 } | |
431 | |
432 TEST(WebSocketHandshakeHandlerTest, HttpRequestResponseHybi06Handshake) { | |
433 WebSocketHandshakeRequestHandler request_handler; | |
434 | |
435 static const char kHandshakeRequestMessage[] = | |
436 "GET /demo HTTP/1.1\r\n" | |
437 "Host: example.com\r\n" | |
438 "Upgrade: websocket\r\n" | |
439 "Connection: Upgrade\r\n" | |
440 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
441 "Sec-WebSocket-Origin: http://example.com\r\n" | |
442 "Sec-WebSocket-Protocol: sample\r\n" | |
443 "Sec-WebSocket-Version: 6\r\n" | |
444 "\r\n"; | |
445 | |
446 EXPECT_TRUE(request_handler.ParseRequest(kHandshakeRequestMessage, | |
447 strlen(kHandshakeRequestMessage))); | |
448 EXPECT_EQ(6, request_handler.protocol_version()); | |
449 | |
450 GURL url("ws://example.com/demo"); | |
451 std::string challenge; | |
452 const HttpRequestInfo& request_info = | |
453 request_handler.GetRequestInfo(url, &challenge); | |
454 | |
455 EXPECT_EQ(url, request_info.url); | |
456 EXPECT_EQ("GET", request_info.method); | |
457 EXPECT_FALSE(request_info.extra_headers.HasHeader("Upgrade")); | |
458 EXPECT_FALSE(request_info.extra_headers.HasHeader("Connection")); | |
459 EXPECT_FALSE(request_info.extra_headers.HasHeader("Sec-WebSocket-Key")); | |
460 std::string value; | |
461 EXPECT_TRUE(request_info.extra_headers.GetHeader("Host", &value)); | |
462 EXPECT_EQ("example.com", value); | |
463 EXPECT_TRUE(request_info.extra_headers.GetHeader("Sec-WebSocket-Origin", | |
464 &value)); | |
465 EXPECT_EQ("http://example.com", value); | |
466 EXPECT_TRUE(request_info.extra_headers.GetHeader("Sec-WebSocket-Protocol", | |
467 &value)); | |
468 EXPECT_EQ("sample", value); | |
469 | |
470 EXPECT_EQ("dGhlIHNhbXBsZSBub25jZQ==", challenge); | |
471 | |
472 static const char kHandshakeResponseHeader[] = | |
473 "HTTP/1.1 101 Switching Protocols\r\n" | |
474 "Sec-WebSocket-Protocol: sample\r\n"; | |
475 | |
476 std::string raw_headers = | |
477 HttpUtil::AssembleRawHeaders(kHandshakeResponseHeader, | |
478 strlen(kHandshakeResponseHeader)); | |
479 HttpResponseInfo response_info; | |
480 response_info.headers = new HttpResponseHeaders(raw_headers); | |
481 | |
482 EXPECT_TRUE(StartsWithASCII(response_info.headers->GetStatusLine(), | |
483 "HTTP/1.1 101 ", false)); | |
484 EXPECT_FALSE(response_info.headers->HasHeader("Upgrade")); | |
485 EXPECT_FALSE(response_info.headers->HasHeader("Connection")); | |
486 EXPECT_FALSE(response_info.headers->HasHeader("Sec-WebSocket-Accept")); | |
487 EXPECT_TRUE(response_info.headers->HasHeaderValue("Sec-WebSocket-Protocol", | |
488 "sample")); | |
489 | |
490 WebSocketHandshakeResponseHandler response_handler; | |
491 response_handler.set_protocol_version(request_handler.protocol_version()); | |
492 EXPECT_EQ(6, response_handler.protocol_version()); | |
493 | |
494 EXPECT_TRUE(response_handler.ParseResponseInfo(response_info, challenge)); | |
495 EXPECT_TRUE(response_handler.HasResponse()); | |
496 | |
497 static const char kHandshakeResponseExpectedMessage[] = | |
498 "HTTP/1.1 101 Switching Protocols\r\n" | |
499 "Upgrade: websocket\r\n" | |
500 "Connection: Upgrade\r\n" | |
501 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | |
502 "Sec-WebSocket-Protocol: sample\r\n" | |
503 "\r\n"; | |
504 | |
505 EXPECT_EQ(kHandshakeResponseExpectedMessage, response_handler.GetResponse()); | |
506 } | |
507 | |
508 TEST_F(WebSocketHandshakeGetKeyNumberTest, AppendsToString) { | |
509 set_challenge("hello"); | |
510 GetKeyNumber(); | |
511 EXPECT_EQ("hello", challenge().substr(0, 5)); | |
512 } | |
513 | |
514 TEST_F(WebSocketHandshakeGetKeyNumberTest, AppendsFourBytes) { | |
515 set_challenge("hello"); | |
516 set_key("1 1"); | |
517 GetKeyNumber(); | |
518 EXPECT_EQ(9u, challenge().length()); | |
519 } | |
520 | |
521 TEST_F(WebSocketHandshakeGetKeyNumberTest, IsBigEndian) { | |
522 set_key(base::StringPrintf("%u ", 0x61626364)); | |
523 GetKeyNumber(); | |
524 EXPECT_EQ("abcd", challenge()); | |
525 } | |
526 | |
527 TEST_F(WebSocketHandshakeGetKeyNumberTest, IgnoresLetters) { | |
528 set_key("1b 1"); | |
529 GetKeyNumber(); | |
530 char expected_response[] = { 0, 0, 0, 11 }; | |
531 EXPECT_EQ(std::string(expected_response, 4), challenge()); | |
532 } | |
533 | |
534 TEST_F(WebSocketHandshakeGetKeyNumberTest, DividesBySpaces) { | |
535 set_key("1 2"); | |
536 GetKeyNumber(); | |
537 EXPECT_EQ(12, challenge()[3]); | |
538 reset_challenge(); | |
539 set_key("1 2"); | |
540 GetKeyNumber(); | |
541 EXPECT_EQ(6, challenge()[3]); | |
542 reset_challenge(); | |
543 set_key(" 1 2"); | |
544 GetKeyNumber(); | |
545 EXPECT_EQ(4, challenge()[3]); | |
546 reset_challenge(); | |
547 set_key(" 1 2 "); | |
548 GetKeyNumber(); | |
549 EXPECT_EQ(3, challenge()[3]); | |
550 } | |
551 | |
552 TEST_F(WebSocketHandshakeGetKeyNumberTest, MatchesExampleFromDraft) { | |
553 set_key("3e6b263 4 17 80"); | |
554 GetKeyNumber(); | |
555 char expected_response[] = { 0x36, 0x09, 0x65, 0x65 }; | |
556 EXPECT_EQ(std::string(expected_response, 4), challenge()); | |
557 } | |
558 | |
559 TEST_F(WebSocketHandshakeGetKeyNumberTest, Maximum32bitInteger) { | |
560 set_key("4294967295 "); | |
561 GetKeyNumber(); | |
562 char expected_response[] = { '\xFF', '\xFF', '\xFF', '\xFF' }; | |
563 EXPECT_EQ(std::string(expected_response, 4), challenge()); | |
564 } | |
565 | |
566 #if GTEST_HAS_DEATH_TEST && !defined(NDEBUG) | |
567 TEST_F(WebSocketHandshakeGetKeyNumberDeathTest, ThirtyThreeBitIntegerNoGood) { | |
568 set_key(" 4294967296"); | |
569 EXPECT_DEBUG_DEATH(GetKeyNumber(), "overflow"); | |
570 } | |
571 | |
572 TEST_F(WebSocketHandshakeGetKeyNumberDeathTest, NoSpacesNoGood) { | |
573 set_key("11"); | |
574 EXPECT_DEBUG_DEATH(GetKeyNumber(), "space"); | |
575 } | |
576 | |
577 TEST_F(WebSocketHandshakeGetKeyNumberDeathTest, MustBeIntegralMultiple) { | |
578 set_key("1 1"); | |
579 EXPECT_DEBUG_DEATH(GetKeyNumber(), "spaces"); | |
580 } | |
581 #endif // GTEST_HAS_DEATH_TEST && !defined(NDEBUG) | |
582 | |
583 } // namespace net | |
OLD | NEW |