OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/websockets/websocket_stream.h" | 5 #include "net/websockets/websocket_stream.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 public: | 193 public: |
194 // Performs a standard connect, with the value of the Sec-WebSocket-Extensions | 194 // Performs a standard connect, with the value of the Sec-WebSocket-Extensions |
195 // header in the response set to |extensions_header_value|. Runs the event | 195 // header in the response set to |extensions_header_value|. Runs the event |
196 // loop to allow the connect to complete. | 196 // loop to allow the connect to complete. |
197 void CreateAndConnectWithExtensions( | 197 void CreateAndConnectWithExtensions( |
198 const std::string& extensions_header_value) { | 198 const std::string& extensions_header_value) { |
199 CreateAndConnectStandard( | 199 CreateAndConnectStandard( |
200 "ws://localhost/testing_path", | 200 "ws://localhost/testing_path", |
201 "/testing_path", | 201 "/testing_path", |
202 NoSubProtocols(), | 202 NoSubProtocols(), |
203 "http://localhost/", | 203 "http://localhost", |
204 "", | 204 "", |
205 "Sec-WebSocket-Extensions: " + extensions_header_value + "\r\n"); | 205 "Sec-WebSocket-Extensions: " + extensions_header_value + "\r\n"); |
206 RunUntilIdle(); | 206 RunUntilIdle(); |
207 } | 207 } |
208 }; | 208 }; |
209 | 209 |
210 // Confirm that the basic case works as expected. | 210 // Confirm that the basic case works as expected. |
211 TEST_F(WebSocketStreamCreateTest, SimpleSuccess) { | 211 TEST_F(WebSocketStreamCreateTest, SimpleSuccess) { |
212 CreateAndConnectStandard( | 212 CreateAndConnectStandard( |
213 "ws://localhost/", "/", NoSubProtocols(), "http://localhost/", "", ""); | 213 "ws://localhost/", "/", NoSubProtocols(), "http://localhost", "", ""); |
214 EXPECT_FALSE(request_info_); | 214 EXPECT_FALSE(request_info_); |
215 EXPECT_FALSE(response_info_); | 215 EXPECT_FALSE(response_info_); |
216 RunUntilIdle(); | 216 RunUntilIdle(); |
217 EXPECT_FALSE(has_failed()); | 217 EXPECT_FALSE(has_failed()); |
218 EXPECT_TRUE(stream_); | 218 EXPECT_TRUE(stream_); |
219 EXPECT_TRUE(request_info_); | 219 EXPECT_TRUE(request_info_); |
220 EXPECT_TRUE(response_info_); | 220 EXPECT_TRUE(response_info_); |
221 } | 221 } |
222 | 222 |
223 TEST_F(WebSocketStreamCreateTest, HandshakeInfo) { | 223 TEST_F(WebSocketStreamCreateTest, HandshakeInfo) { |
224 static const char kResponse[] = | 224 static const char kResponse[] = |
225 "HTTP/1.1 101 Switching Protocols\r\n" | 225 "HTTP/1.1 101 Switching Protocols\r\n" |
226 "Upgrade: websocket\r\n" | 226 "Upgrade: websocket\r\n" |
227 "Connection: Upgrade\r\n" | 227 "Connection: Upgrade\r\n" |
228 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 228 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
229 "foo: bar, baz\r\n" | 229 "foo: bar, baz\r\n" |
230 "hoge: fuga\r\n" | 230 "hoge: fuga\r\n" |
231 "hoge: piyo\r\n" | 231 "hoge: piyo\r\n" |
232 "\r\n"; | 232 "\r\n"; |
233 | 233 |
234 CreateAndConnectCustomResponse( | 234 CreateAndConnectCustomResponse( |
235 "ws://localhost/", | 235 "ws://localhost/", |
236 "/", | 236 "/", |
237 NoSubProtocols(), | 237 NoSubProtocols(), |
238 "http://localhost/", | 238 "http://localhost:8080", |
239 "", | 239 "", |
240 kResponse); | 240 kResponse); |
241 EXPECT_FALSE(request_info_); | 241 EXPECT_FALSE(request_info_); |
242 EXPECT_FALSE(response_info_); | 242 EXPECT_FALSE(response_info_); |
243 RunUntilIdle(); | 243 RunUntilIdle(); |
244 EXPECT_TRUE(stream_); | 244 EXPECT_TRUE(stream_); |
245 ASSERT_TRUE(request_info_); | 245 ASSERT_TRUE(request_info_); |
246 ASSERT_TRUE(response_info_); | 246 ASSERT_TRUE(response_info_); |
247 std::vector<HeaderKeyValuePair> request_headers = | 247 std::vector<HeaderKeyValuePair> request_headers = |
248 ToVector(request_info_->headers); | 248 ToVector(request_info_->headers); |
249 // We examine the contents of request_info_ and response_info_ | 249 // We examine the contents of request_info_ and response_info_ |
250 // mainly only in this test case. | 250 // mainly only in this test case. |
251 EXPECT_EQ(GURL("ws://localhost/"), request_info_->url); | 251 EXPECT_EQ(GURL("ws://localhost/"), request_info_->url); |
252 EXPECT_EQ(GURL("ws://localhost/"), response_info_->url); | 252 EXPECT_EQ(GURL("ws://localhost/"), response_info_->url); |
253 EXPECT_EQ(101, response_info_->status_code); | 253 EXPECT_EQ(101, response_info_->status_code); |
254 EXPECT_EQ("Switching Protocols", response_info_->status_text); | 254 EXPECT_EQ("Switching Protocols", response_info_->status_text); |
255 ASSERT_EQ(12u, request_headers.size()); | 255 ASSERT_EQ(12u, request_headers.size()); |
256 EXPECT_EQ(HeaderKeyValuePair("Host", "localhost"), request_headers[0]); | 256 EXPECT_EQ(HeaderKeyValuePair("Host", "localhost"), request_headers[0]); |
257 EXPECT_EQ(HeaderKeyValuePair("Connection", "Upgrade"), request_headers[1]); | 257 EXPECT_EQ(HeaderKeyValuePair("Connection", "Upgrade"), request_headers[1]); |
258 EXPECT_EQ(HeaderKeyValuePair("Pragma", "no-cache"), request_headers[2]); | 258 EXPECT_EQ(HeaderKeyValuePair("Pragma", "no-cache"), request_headers[2]); |
259 EXPECT_EQ(HeaderKeyValuePair("Cache-Control", "no-cache"), | 259 EXPECT_EQ(HeaderKeyValuePair("Cache-Control", "no-cache"), |
260 request_headers[3]); | 260 request_headers[3]); |
261 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), request_headers[4]); | 261 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), request_headers[4]); |
262 EXPECT_EQ(HeaderKeyValuePair("Origin", "http://localhost/"), | 262 EXPECT_EQ(HeaderKeyValuePair("Origin", "http://localhost:8080"), |
263 request_headers[5]); | 263 request_headers[5]); |
264 EXPECT_EQ(HeaderKeyValuePair("Sec-WebSocket-Version", "13"), | 264 EXPECT_EQ(HeaderKeyValuePair("Sec-WebSocket-Version", "13"), |
265 request_headers[6]); | 265 request_headers[6]); |
266 EXPECT_EQ(HeaderKeyValuePair("User-Agent", ""), request_headers[7]); | 266 EXPECT_EQ(HeaderKeyValuePair("User-Agent", ""), request_headers[7]); |
267 EXPECT_EQ(HeaderKeyValuePair("Accept-Encoding", "gzip,deflate"), | 267 EXPECT_EQ(HeaderKeyValuePair("Accept-Encoding", "gzip,deflate"), |
268 request_headers[8]); | 268 request_headers[8]); |
269 EXPECT_EQ(HeaderKeyValuePair("Accept-Language", "en-us,fr"), | 269 EXPECT_EQ(HeaderKeyValuePair("Accept-Language", "en-us,fr"), |
270 request_headers[9]); | 270 request_headers[9]); |
271 EXPECT_EQ("Sec-WebSocket-Key", request_headers[10].first); | 271 EXPECT_EQ("Sec-WebSocket-Key", request_headers[10].first); |
272 EXPECT_EQ(HeaderKeyValuePair("Sec-WebSocket-Extensions", | 272 EXPECT_EQ(HeaderKeyValuePair("Sec-WebSocket-Extensions", |
(...skipping 10 matching lines...) Expand all Loading... |
283 EXPECT_EQ("Sec-WebSocket-Accept", response_headers[1].first); | 283 EXPECT_EQ("Sec-WebSocket-Accept", response_headers[1].first); |
284 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), response_headers[2]); | 284 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), response_headers[2]); |
285 EXPECT_EQ(HeaderKeyValuePair("foo", "bar, baz"), response_headers[3]); | 285 EXPECT_EQ(HeaderKeyValuePair("foo", "bar, baz"), response_headers[3]); |
286 EXPECT_EQ(HeaderKeyValuePair("hoge", "fuga"), response_headers[4]); | 286 EXPECT_EQ(HeaderKeyValuePair("hoge", "fuga"), response_headers[4]); |
287 EXPECT_EQ(HeaderKeyValuePair("hoge", "piyo"), response_headers[5]); | 287 EXPECT_EQ(HeaderKeyValuePair("hoge", "piyo"), response_headers[5]); |
288 } | 288 } |
289 | 289 |
290 // Confirm that the stream isn't established until the message loop runs. | 290 // Confirm that the stream isn't established until the message loop runs. |
291 TEST_F(WebSocketStreamCreateTest, NeedsToRunLoop) { | 291 TEST_F(WebSocketStreamCreateTest, NeedsToRunLoop) { |
292 CreateAndConnectStandard( | 292 CreateAndConnectStandard( |
293 "ws://localhost/", "/", NoSubProtocols(), "http://localhost/", "", ""); | 293 "ws://localhost/", "/", NoSubProtocols(), "http://localhost", "", ""); |
294 EXPECT_FALSE(has_failed()); | 294 EXPECT_FALSE(has_failed()); |
295 EXPECT_FALSE(stream_); | 295 EXPECT_FALSE(stream_); |
296 } | 296 } |
297 | 297 |
298 // Check the path is used. | 298 // Check the path is used. |
299 TEST_F(WebSocketStreamCreateTest, PathIsUsed) { | 299 TEST_F(WebSocketStreamCreateTest, PathIsUsed) { |
300 CreateAndConnectStandard("ws://localhost/testing_path", | 300 CreateAndConnectStandard("ws://localhost/testing_path", |
301 "/testing_path", | 301 "/testing_path", |
302 NoSubProtocols(), | 302 NoSubProtocols(), |
303 "http://localhost/", | 303 "http://localhost", |
304 "", | 304 "", |
305 ""); | 305 ""); |
306 RunUntilIdle(); | 306 RunUntilIdle(); |
307 EXPECT_FALSE(has_failed()); | 307 EXPECT_FALSE(has_failed()); |
308 EXPECT_TRUE(stream_); | 308 EXPECT_TRUE(stream_); |
309 } | 309 } |
310 | 310 |
311 // Check that the origin is used. | 311 // Check that the origin is used. |
312 TEST_F(WebSocketStreamCreateTest, OriginIsUsed) { | 312 TEST_F(WebSocketStreamCreateTest, OriginIsUsed) { |
313 CreateAndConnectStandard("ws://localhost/testing_path", | 313 CreateAndConnectStandard("ws://localhost/testing_path", |
314 "/testing_path", | 314 "/testing_path", |
315 NoSubProtocols(), | 315 NoSubProtocols(), |
316 "http://google.com/", | 316 "http://google.com", |
317 "", | 317 "", |
318 ""); | 318 ""); |
319 RunUntilIdle(); | 319 RunUntilIdle(); |
320 EXPECT_FALSE(has_failed()); | 320 EXPECT_FALSE(has_failed()); |
321 EXPECT_TRUE(stream_); | 321 EXPECT_TRUE(stream_); |
322 } | 322 } |
323 | 323 |
324 // Check that sub-protocols are sent and parsed. | 324 // Check that sub-protocols are sent and parsed. |
325 TEST_F(WebSocketStreamCreateTest, SubProtocolIsUsed) { | 325 TEST_F(WebSocketStreamCreateTest, SubProtocolIsUsed) { |
326 std::vector<std::string> sub_protocols; | 326 std::vector<std::string> sub_protocols; |
327 sub_protocols.push_back("chatv11.chromium.org"); | 327 sub_protocols.push_back("chatv11.chromium.org"); |
328 sub_protocols.push_back("chatv20.chromium.org"); | 328 sub_protocols.push_back("chatv20.chromium.org"); |
329 CreateAndConnectStandard("ws://localhost/testing_path", | 329 CreateAndConnectStandard("ws://localhost/testing_path", |
330 "/testing_path", | 330 "/testing_path", |
331 sub_protocols, | 331 sub_protocols, |
332 "http://google.com/", | 332 "http://google.com", |
333 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 333 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
334 "chatv20.chromium.org\r\n", | 334 "chatv20.chromium.org\r\n", |
335 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); | 335 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); |
336 RunUntilIdle(); | 336 RunUntilIdle(); |
337 EXPECT_TRUE(stream_); | 337 EXPECT_TRUE(stream_); |
338 EXPECT_FALSE(has_failed()); | 338 EXPECT_FALSE(has_failed()); |
339 EXPECT_EQ("chatv20.chromium.org", stream_->GetSubProtocol()); | 339 EXPECT_EQ("chatv20.chromium.org", stream_->GetSubProtocol()); |
340 } | 340 } |
341 | 341 |
342 // Unsolicited sub-protocols are rejected. | 342 // Unsolicited sub-protocols are rejected. |
343 TEST_F(WebSocketStreamCreateTest, UnsolicitedSubProtocol) { | 343 TEST_F(WebSocketStreamCreateTest, UnsolicitedSubProtocol) { |
344 CreateAndConnectStandard("ws://localhost/testing_path", | 344 CreateAndConnectStandard("ws://localhost/testing_path", |
345 "/testing_path", | 345 "/testing_path", |
346 NoSubProtocols(), | 346 NoSubProtocols(), |
347 "http://google.com/", | 347 "http://google.com", |
348 "", | 348 "", |
349 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); | 349 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); |
350 RunUntilIdle(); | 350 RunUntilIdle(); |
351 EXPECT_FALSE(stream_); | 351 EXPECT_FALSE(stream_); |
352 EXPECT_TRUE(has_failed()); | 352 EXPECT_TRUE(has_failed()); |
353 EXPECT_EQ("Error during WebSocket handshake: " | 353 EXPECT_EQ("Error during WebSocket handshake: " |
354 "Response must not include 'Sec-WebSocket-Protocol' header " | 354 "Response must not include 'Sec-WebSocket-Protocol' header " |
355 "if not present in request: chatv20.chromium.org", | 355 "if not present in request: chatv20.chromium.org", |
356 failure_message()); | 356 failure_message()); |
357 } | 357 } |
358 | 358 |
359 // Missing sub-protocol response is rejected. | 359 // Missing sub-protocol response is rejected. |
360 TEST_F(WebSocketStreamCreateTest, UnacceptedSubProtocol) { | 360 TEST_F(WebSocketStreamCreateTest, UnacceptedSubProtocol) { |
361 std::vector<std::string> sub_protocols; | 361 std::vector<std::string> sub_protocols; |
362 sub_protocols.push_back("chat.example.com"); | 362 sub_protocols.push_back("chat.example.com"); |
363 CreateAndConnectStandard("ws://localhost/testing_path", | 363 CreateAndConnectStandard("ws://localhost/testing_path", |
364 "/testing_path", | 364 "/testing_path", |
365 sub_protocols, | 365 sub_protocols, |
366 "http://localhost/", | 366 "http://localhost", |
367 "Sec-WebSocket-Protocol: chat.example.com\r\n", | 367 "Sec-WebSocket-Protocol: chat.example.com\r\n", |
368 ""); | 368 ""); |
369 RunUntilIdle(); | 369 RunUntilIdle(); |
370 EXPECT_FALSE(stream_); | 370 EXPECT_FALSE(stream_); |
371 EXPECT_TRUE(has_failed()); | 371 EXPECT_TRUE(has_failed()); |
372 EXPECT_EQ("Error during WebSocket handshake: " | 372 EXPECT_EQ("Error during WebSocket handshake: " |
373 "Sent non-empty 'Sec-WebSocket-Protocol' header " | 373 "Sent non-empty 'Sec-WebSocket-Protocol' header " |
374 "but no response was received", | 374 "but no response was received", |
375 failure_message()); | 375 failure_message()); |
376 } | 376 } |
377 | 377 |
378 // Only one sub-protocol can be accepted. | 378 // Only one sub-protocol can be accepted. |
379 TEST_F(WebSocketStreamCreateTest, MultipleSubProtocolsInResponse) { | 379 TEST_F(WebSocketStreamCreateTest, MultipleSubProtocolsInResponse) { |
380 std::vector<std::string> sub_protocols; | 380 std::vector<std::string> sub_protocols; |
381 sub_protocols.push_back("chatv11.chromium.org"); | 381 sub_protocols.push_back("chatv11.chromium.org"); |
382 sub_protocols.push_back("chatv20.chromium.org"); | 382 sub_protocols.push_back("chatv20.chromium.org"); |
383 CreateAndConnectStandard("ws://localhost/testing_path", | 383 CreateAndConnectStandard("ws://localhost/testing_path", |
384 "/testing_path", | 384 "/testing_path", |
385 sub_protocols, | 385 sub_protocols, |
386 "http://google.com/", | 386 "http://google.com", |
387 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 387 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
388 "chatv20.chromium.org\r\n", | 388 "chatv20.chromium.org\r\n", |
389 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 389 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
390 "chatv20.chromium.org\r\n"); | 390 "chatv20.chromium.org\r\n"); |
391 RunUntilIdle(); | 391 RunUntilIdle(); |
392 EXPECT_FALSE(stream_); | 392 EXPECT_FALSE(stream_); |
393 EXPECT_TRUE(has_failed()); | 393 EXPECT_TRUE(has_failed()); |
394 EXPECT_EQ("Error during WebSocket handshake: " | 394 EXPECT_EQ("Error during WebSocket handshake: " |
395 "'Sec-WebSocket-Protocol' header must not appear " | 395 "'Sec-WebSocket-Protocol' header must not appear " |
396 "more than once in a response", | 396 "more than once in a response", |
397 failure_message()); | 397 failure_message()); |
398 } | 398 } |
399 | 399 |
400 // Unmatched sub-protocol should be rejected. | 400 // Unmatched sub-protocol should be rejected. |
401 TEST_F(WebSocketStreamCreateTest, UnmatchedSubProtocolInResponse) { | 401 TEST_F(WebSocketStreamCreateTest, UnmatchedSubProtocolInResponse) { |
402 std::vector<std::string> sub_protocols; | 402 std::vector<std::string> sub_protocols; |
403 sub_protocols.push_back("chatv11.chromium.org"); | 403 sub_protocols.push_back("chatv11.chromium.org"); |
404 sub_protocols.push_back("chatv20.chromium.org"); | 404 sub_protocols.push_back("chatv20.chromium.org"); |
405 CreateAndConnectStandard("ws://localhost/testing_path", | 405 CreateAndConnectStandard("ws://localhost/testing_path", |
406 "/testing_path", | 406 "/testing_path", |
407 sub_protocols, | 407 sub_protocols, |
408 "http://google.com/", | 408 "http://google.com", |
409 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 409 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
410 "chatv20.chromium.org\r\n", | 410 "chatv20.chromium.org\r\n", |
411 "Sec-WebSocket-Protocol: chatv21.chromium.org\r\n"); | 411 "Sec-WebSocket-Protocol: chatv21.chromium.org\r\n"); |
412 RunUntilIdle(); | 412 RunUntilIdle(); |
413 EXPECT_FALSE(stream_); | 413 EXPECT_FALSE(stream_); |
414 EXPECT_TRUE(has_failed()); | 414 EXPECT_TRUE(has_failed()); |
415 EXPECT_EQ("Error during WebSocket handshake: " | 415 EXPECT_EQ("Error during WebSocket handshake: " |
416 "'Sec-WebSocket-Protocol' header value 'chatv21.chromium.org' " | 416 "'Sec-WebSocket-Protocol' header value 'chatv21.chromium.org' " |
417 "in response does not match any of sent values", | 417 "in response does not match any of sent values", |
418 failure_message()); | 418 failure_message()); |
(...skipping 16 matching lines...) Expand all Loading... |
435 EXPECT_FALSE(has_failed()); | 435 EXPECT_FALSE(has_failed()); |
436 } | 436 } |
437 | 437 |
438 // Verify that incoming messages are actually decompressed with | 438 // Verify that incoming messages are actually decompressed with |
439 // permessage-deflate enabled. | 439 // permessage-deflate enabled. |
440 TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateInflates) { | 440 TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateInflates) { |
441 CreateAndConnectCustomResponse( | 441 CreateAndConnectCustomResponse( |
442 "ws://localhost/testing_path", | 442 "ws://localhost/testing_path", |
443 "/testing_path", | 443 "/testing_path", |
444 NoSubProtocols(), | 444 NoSubProtocols(), |
445 "http://localhost/", | 445 "http://localhost", |
446 "", | 446 "", |
447 WebSocketStandardResponse( | 447 WebSocketStandardResponse( |
448 "Sec-WebSocket-Extensions: permessage-deflate\r\n") + | 448 "Sec-WebSocket-Extensions: permessage-deflate\r\n") + |
449 std::string( | 449 std::string( |
450 "\xc1\x07" // WebSocket header (FIN + RSV1, Text payload 7 bytes) | 450 "\xc1\x07" // WebSocket header (FIN + RSV1, Text payload 7 bytes) |
451 "\xf2\x48\xcd\xc9\xc9\x07\x00", // "Hello" DEFLATE compressed | 451 "\xf2\x48\xcd\xc9\xc9\x07\x00", // "Hello" DEFLATE compressed |
452 9)); | 452 9)); |
453 RunUntilIdle(); | 453 RunUntilIdle(); |
454 | 454 |
455 ASSERT_TRUE(stream_); | 455 ASSERT_TRUE(stream_); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 // TODO(ricea): Check that WebSocketDeflateStream is initialised with the | 620 // TODO(ricea): Check that WebSocketDeflateStream is initialised with the |
621 // arguments from the server. This is difficult because the data written to the | 621 // arguments from the server. This is difficult because the data written to the |
622 // socket is randomly masked. | 622 // socket is randomly masked. |
623 | 623 |
624 // Additional Sec-WebSocket-Accept headers should be rejected. | 624 // Additional Sec-WebSocket-Accept headers should be rejected. |
625 TEST_F(WebSocketStreamCreateTest, DoubleAccept) { | 625 TEST_F(WebSocketStreamCreateTest, DoubleAccept) { |
626 CreateAndConnectStandard( | 626 CreateAndConnectStandard( |
627 "ws://localhost/", | 627 "ws://localhost/", |
628 "/", | 628 "/", |
629 NoSubProtocols(), | 629 NoSubProtocols(), |
630 "http://localhost/", | 630 "http://localhost", |
631 "", | 631 "", |
632 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"); | 632 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"); |
633 RunUntilIdle(); | 633 RunUntilIdle(); |
634 EXPECT_FALSE(stream_); | 634 EXPECT_FALSE(stream_); |
635 EXPECT_TRUE(has_failed()); | 635 EXPECT_TRUE(has_failed()); |
636 EXPECT_EQ("Error during WebSocket handshake: " | 636 EXPECT_EQ("Error during WebSocket handshake: " |
637 "'Sec-WebSocket-Accept' header must not appear " | 637 "'Sec-WebSocket-Accept' header must not appear " |
638 "more than once in a response", | 638 "more than once in a response", |
639 failure_message()); | 639 failure_message()); |
640 } | 640 } |
641 | 641 |
642 // Response code 200 must be rejected. | 642 // Response code 200 must be rejected. |
643 TEST_F(WebSocketStreamCreateTest, InvalidStatusCode) { | 643 TEST_F(WebSocketStreamCreateTest, InvalidStatusCode) { |
644 static const char kInvalidStatusCodeResponse[] = | 644 static const char kInvalidStatusCodeResponse[] = |
645 "HTTP/1.1 200 OK\r\n" | 645 "HTTP/1.1 200 OK\r\n" |
646 "Upgrade: websocket\r\n" | 646 "Upgrade: websocket\r\n" |
647 "Connection: Upgrade\r\n" | 647 "Connection: Upgrade\r\n" |
648 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 648 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
649 "\r\n"; | 649 "\r\n"; |
650 CreateAndConnectCustomResponse("ws://localhost/", | 650 CreateAndConnectCustomResponse("ws://localhost/", |
651 "/", | 651 "/", |
652 NoSubProtocols(), | 652 NoSubProtocols(), |
653 "http://localhost/", | 653 "http://localhost", |
654 "", | 654 "", |
655 kInvalidStatusCodeResponse); | 655 kInvalidStatusCodeResponse); |
656 RunUntilIdle(); | 656 RunUntilIdle(); |
657 EXPECT_TRUE(has_failed()); | 657 EXPECT_TRUE(has_failed()); |
658 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 200", | 658 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 200", |
659 failure_message()); | 659 failure_message()); |
660 } | 660 } |
661 | 661 |
662 // Redirects are not followed (according to the WHATWG WebSocket API, which | 662 // Redirects are not followed (according to the WHATWG WebSocket API, which |
663 // overrides RFC6455 for browser applications). | 663 // overrides RFC6455 for browser applications). |
664 TEST_F(WebSocketStreamCreateTest, RedirectsRejected) { | 664 TEST_F(WebSocketStreamCreateTest, RedirectsRejected) { |
665 static const char kRedirectResponse[] = | 665 static const char kRedirectResponse[] = |
666 "HTTP/1.1 302 Moved Temporarily\r\n" | 666 "HTTP/1.1 302 Moved Temporarily\r\n" |
667 "Content-Type: text/html\r\n" | 667 "Content-Type: text/html\r\n" |
668 "Content-Length: 34\r\n" | 668 "Content-Length: 34\r\n" |
669 "Connection: keep-alive\r\n" | 669 "Connection: keep-alive\r\n" |
670 "Location: ws://localhost/other\r\n" | 670 "Location: ws://localhost/other\r\n" |
671 "\r\n" | 671 "\r\n" |
672 "<title>Moved</title><h1>Moved</h1>"; | 672 "<title>Moved</title><h1>Moved</h1>"; |
673 CreateAndConnectCustomResponse("ws://localhost/", | 673 CreateAndConnectCustomResponse("ws://localhost/", |
674 "/", | 674 "/", |
675 NoSubProtocols(), | 675 NoSubProtocols(), |
676 "http://localhost/", | 676 "http://localhost", |
677 "", | 677 "", |
678 kRedirectResponse); | 678 kRedirectResponse); |
679 RunUntilIdle(); | 679 RunUntilIdle(); |
680 EXPECT_TRUE(has_failed()); | 680 EXPECT_TRUE(has_failed()); |
681 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 302", | 681 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 302", |
682 failure_message()); | 682 failure_message()); |
683 } | 683 } |
684 | 684 |
685 // Malformed responses should be rejected. HttpStreamParser will accept just | 685 // Malformed responses should be rejected. HttpStreamParser will accept just |
686 // about any garbage in the middle of the headers. To make it give up, the junk | 686 // about any garbage in the middle of the headers. To make it give up, the junk |
687 // has to be at the start of the response. Even then, it just gets treated as an | 687 // has to be at the start of the response. Even then, it just gets treated as an |
688 // HTTP/0.9 response. | 688 // HTTP/0.9 response. |
689 TEST_F(WebSocketStreamCreateTest, MalformedResponse) { | 689 TEST_F(WebSocketStreamCreateTest, MalformedResponse) { |
690 static const char kMalformedResponse[] = | 690 static const char kMalformedResponse[] = |
691 "220 mx.google.com ESMTP\r\n" | 691 "220 mx.google.com ESMTP\r\n" |
692 "HTTP/1.1 101 OK\r\n" | 692 "HTTP/1.1 101 OK\r\n" |
693 "Upgrade: websocket\r\n" | 693 "Upgrade: websocket\r\n" |
694 "Connection: Upgrade\r\n" | 694 "Connection: Upgrade\r\n" |
695 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 695 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
696 "\r\n"; | 696 "\r\n"; |
697 CreateAndConnectCustomResponse("ws://localhost/", | 697 CreateAndConnectCustomResponse("ws://localhost/", |
698 "/", | 698 "/", |
699 NoSubProtocols(), | 699 NoSubProtocols(), |
700 "http://localhost/", | 700 "http://localhost", |
701 "", | 701 "", |
702 kMalformedResponse); | 702 kMalformedResponse); |
703 RunUntilIdle(); | 703 RunUntilIdle(); |
704 EXPECT_TRUE(has_failed()); | 704 EXPECT_TRUE(has_failed()); |
705 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 200", | 705 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 200", |
706 failure_message()); | 706 failure_message()); |
707 } | 707 } |
708 | 708 |
709 // Upgrade header must be present. | 709 // Upgrade header must be present. |
710 TEST_F(WebSocketStreamCreateTest, MissingUpgradeHeader) { | 710 TEST_F(WebSocketStreamCreateTest, MissingUpgradeHeader) { |
711 static const char kMissingUpgradeResponse[] = | 711 static const char kMissingUpgradeResponse[] = |
712 "HTTP/1.1 101 Switching Protocols\r\n" | 712 "HTTP/1.1 101 Switching Protocols\r\n" |
713 "Connection: Upgrade\r\n" | 713 "Connection: Upgrade\r\n" |
714 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 714 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
715 "\r\n"; | 715 "\r\n"; |
716 CreateAndConnectCustomResponse("ws://localhost/", | 716 CreateAndConnectCustomResponse("ws://localhost/", |
717 "/", | 717 "/", |
718 NoSubProtocols(), | 718 NoSubProtocols(), |
719 "http://localhost/", | 719 "http://localhost", |
720 "", | 720 "", |
721 kMissingUpgradeResponse); | 721 kMissingUpgradeResponse); |
722 RunUntilIdle(); | 722 RunUntilIdle(); |
723 EXPECT_TRUE(has_failed()); | 723 EXPECT_TRUE(has_failed()); |
724 EXPECT_EQ("Error during WebSocket handshake: 'Upgrade' header is missing", | 724 EXPECT_EQ("Error during WebSocket handshake: 'Upgrade' header is missing", |
725 failure_message()); | 725 failure_message()); |
726 } | 726 } |
727 | 727 |
728 // There must only be one upgrade header. | 728 // There must only be one upgrade header. |
729 TEST_F(WebSocketStreamCreateTest, DoubleUpgradeHeader) { | 729 TEST_F(WebSocketStreamCreateTest, DoubleUpgradeHeader) { |
730 CreateAndConnectStandard( | 730 CreateAndConnectStandard( |
731 "ws://localhost/", | 731 "ws://localhost/", |
732 "/", | 732 "/", |
733 NoSubProtocols(), | 733 NoSubProtocols(), |
734 "http://localhost/", | 734 "http://localhost", |
735 "", "Upgrade: HTTP/2.0\r\n"); | 735 "", "Upgrade: HTTP/2.0\r\n"); |
736 RunUntilIdle(); | 736 RunUntilIdle(); |
737 EXPECT_TRUE(has_failed()); | 737 EXPECT_TRUE(has_failed()); |
738 EXPECT_EQ("Error during WebSocket handshake: " | 738 EXPECT_EQ("Error during WebSocket handshake: " |
739 "'Upgrade' header must not appear more than once in a response", | 739 "'Upgrade' header must not appear more than once in a response", |
740 failure_message()); | 740 failure_message()); |
741 } | 741 } |
742 | 742 |
743 // There must only be one correct upgrade header. | 743 // There must only be one correct upgrade header. |
744 TEST_F(WebSocketStreamCreateTest, IncorrectUpgradeHeader) { | 744 TEST_F(WebSocketStreamCreateTest, IncorrectUpgradeHeader) { |
745 static const char kMissingUpgradeResponse[] = | 745 static const char kMissingUpgradeResponse[] = |
746 "HTTP/1.1 101 Switching Protocols\r\n" | 746 "HTTP/1.1 101 Switching Protocols\r\n" |
747 "Connection: Upgrade\r\n" | 747 "Connection: Upgrade\r\n" |
748 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 748 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
749 "Upgrade: hogefuga\r\n" | 749 "Upgrade: hogefuga\r\n" |
750 "\r\n"; | 750 "\r\n"; |
751 CreateAndConnectCustomResponse("ws://localhost/", | 751 CreateAndConnectCustomResponse("ws://localhost/", |
752 "/", | 752 "/", |
753 NoSubProtocols(), | 753 NoSubProtocols(), |
754 "http://localhost/", | 754 "http://localhost", |
755 "", | 755 "", |
756 kMissingUpgradeResponse); | 756 kMissingUpgradeResponse); |
757 RunUntilIdle(); | 757 RunUntilIdle(); |
758 EXPECT_TRUE(has_failed()); | 758 EXPECT_TRUE(has_failed()); |
759 EXPECT_EQ("Error during WebSocket handshake: " | 759 EXPECT_EQ("Error during WebSocket handshake: " |
760 "'Upgrade' header value is not 'WebSocket': hogefuga", | 760 "'Upgrade' header value is not 'WebSocket': hogefuga", |
761 failure_message()); | 761 failure_message()); |
762 } | 762 } |
763 | 763 |
764 // Connection header must be present. | 764 // Connection header must be present. |
765 TEST_F(WebSocketStreamCreateTest, MissingConnectionHeader) { | 765 TEST_F(WebSocketStreamCreateTest, MissingConnectionHeader) { |
766 static const char kMissingConnectionResponse[] = | 766 static const char kMissingConnectionResponse[] = |
767 "HTTP/1.1 101 Switching Protocols\r\n" | 767 "HTTP/1.1 101 Switching Protocols\r\n" |
768 "Upgrade: websocket\r\n" | 768 "Upgrade: websocket\r\n" |
769 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 769 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
770 "\r\n"; | 770 "\r\n"; |
771 CreateAndConnectCustomResponse("ws://localhost/", | 771 CreateAndConnectCustomResponse("ws://localhost/", |
772 "/", | 772 "/", |
773 NoSubProtocols(), | 773 NoSubProtocols(), |
774 "http://localhost/", | 774 "http://localhost", |
775 "", | 775 "", |
776 kMissingConnectionResponse); | 776 kMissingConnectionResponse); |
777 RunUntilIdle(); | 777 RunUntilIdle(); |
778 EXPECT_TRUE(has_failed()); | 778 EXPECT_TRUE(has_failed()); |
779 EXPECT_EQ("Error during WebSocket handshake: " | 779 EXPECT_EQ("Error during WebSocket handshake: " |
780 "'Connection' header is missing", | 780 "'Connection' header is missing", |
781 failure_message()); | 781 failure_message()); |
782 } | 782 } |
783 | 783 |
784 // Connection header must contain "Upgrade". | 784 // Connection header must contain "Upgrade". |
785 TEST_F(WebSocketStreamCreateTest, IncorrectConnectionHeader) { | 785 TEST_F(WebSocketStreamCreateTest, IncorrectConnectionHeader) { |
786 static const char kMissingConnectionResponse[] = | 786 static const char kMissingConnectionResponse[] = |
787 "HTTP/1.1 101 Switching Protocols\r\n" | 787 "HTTP/1.1 101 Switching Protocols\r\n" |
788 "Upgrade: websocket\r\n" | 788 "Upgrade: websocket\r\n" |
789 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 789 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
790 "Connection: hogefuga\r\n" | 790 "Connection: hogefuga\r\n" |
791 "\r\n"; | 791 "\r\n"; |
792 CreateAndConnectCustomResponse("ws://localhost/", | 792 CreateAndConnectCustomResponse("ws://localhost/", |
793 "/", | 793 "/", |
794 NoSubProtocols(), | 794 NoSubProtocols(), |
795 "http://localhost/", | 795 "http://localhost", |
796 "", | 796 "", |
797 kMissingConnectionResponse); | 797 kMissingConnectionResponse); |
798 RunUntilIdle(); | 798 RunUntilIdle(); |
799 EXPECT_TRUE(has_failed()); | 799 EXPECT_TRUE(has_failed()); |
800 EXPECT_EQ("Error during WebSocket handshake: " | 800 EXPECT_EQ("Error during WebSocket handshake: " |
801 "'Connection' header value must contain 'Upgrade'", | 801 "'Connection' header value must contain 'Upgrade'", |
802 failure_message()); | 802 failure_message()); |
803 } | 803 } |
804 | 804 |
805 // Connection header is permitted to contain other tokens. | 805 // Connection header is permitted to contain other tokens. |
806 TEST_F(WebSocketStreamCreateTest, AdditionalTokenInConnectionHeader) { | 806 TEST_F(WebSocketStreamCreateTest, AdditionalTokenInConnectionHeader) { |
807 static const char kAdditionalConnectionTokenResponse[] = | 807 static const char kAdditionalConnectionTokenResponse[] = |
808 "HTTP/1.1 101 Switching Protocols\r\n" | 808 "HTTP/1.1 101 Switching Protocols\r\n" |
809 "Upgrade: websocket\r\n" | 809 "Upgrade: websocket\r\n" |
810 "Connection: Upgrade, Keep-Alive\r\n" | 810 "Connection: Upgrade, Keep-Alive\r\n" |
811 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 811 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
812 "\r\n"; | 812 "\r\n"; |
813 CreateAndConnectCustomResponse("ws://localhost/", | 813 CreateAndConnectCustomResponse("ws://localhost/", |
814 "/", | 814 "/", |
815 NoSubProtocols(), | 815 NoSubProtocols(), |
816 "http://localhost/", | 816 "http://localhost", |
817 "", | 817 "", |
818 kAdditionalConnectionTokenResponse); | 818 kAdditionalConnectionTokenResponse); |
819 RunUntilIdle(); | 819 RunUntilIdle(); |
820 EXPECT_FALSE(has_failed()); | 820 EXPECT_FALSE(has_failed()); |
821 EXPECT_TRUE(stream_); | 821 EXPECT_TRUE(stream_); |
822 } | 822 } |
823 | 823 |
824 // Sec-WebSocket-Accept header must be present. | 824 // Sec-WebSocket-Accept header must be present. |
825 TEST_F(WebSocketStreamCreateTest, MissingSecWebSocketAccept) { | 825 TEST_F(WebSocketStreamCreateTest, MissingSecWebSocketAccept) { |
826 static const char kMissingAcceptResponse[] = | 826 static const char kMissingAcceptResponse[] = |
827 "HTTP/1.1 101 Switching Protocols\r\n" | 827 "HTTP/1.1 101 Switching Protocols\r\n" |
828 "Upgrade: websocket\r\n" | 828 "Upgrade: websocket\r\n" |
829 "Connection: Upgrade\r\n" | 829 "Connection: Upgrade\r\n" |
830 "\r\n"; | 830 "\r\n"; |
831 CreateAndConnectCustomResponse("ws://localhost/", | 831 CreateAndConnectCustomResponse("ws://localhost/", |
832 "/", | 832 "/", |
833 NoSubProtocols(), | 833 NoSubProtocols(), |
834 "http://localhost/", | 834 "http://localhost", |
835 "", | 835 "", |
836 kMissingAcceptResponse); | 836 kMissingAcceptResponse); |
837 RunUntilIdle(); | 837 RunUntilIdle(); |
838 EXPECT_TRUE(has_failed()); | 838 EXPECT_TRUE(has_failed()); |
839 EXPECT_EQ("Error during WebSocket handshake: " | 839 EXPECT_EQ("Error during WebSocket handshake: " |
840 "'Sec-WebSocket-Accept' header is missing", | 840 "'Sec-WebSocket-Accept' header is missing", |
841 failure_message()); | 841 failure_message()); |
842 } | 842 } |
843 | 843 |
844 // Sec-WebSocket-Accept header must match the key that was sent. | 844 // Sec-WebSocket-Accept header must match the key that was sent. |
845 TEST_F(WebSocketStreamCreateTest, WrongSecWebSocketAccept) { | 845 TEST_F(WebSocketStreamCreateTest, WrongSecWebSocketAccept) { |
846 static const char kIncorrectAcceptResponse[] = | 846 static const char kIncorrectAcceptResponse[] = |
847 "HTTP/1.1 101 Switching Protocols\r\n" | 847 "HTTP/1.1 101 Switching Protocols\r\n" |
848 "Upgrade: websocket\r\n" | 848 "Upgrade: websocket\r\n" |
849 "Connection: Upgrade\r\n" | 849 "Connection: Upgrade\r\n" |
850 "Sec-WebSocket-Accept: x/byyPZ2tOFvJCGkkugcKvqhhPk=\r\n" | 850 "Sec-WebSocket-Accept: x/byyPZ2tOFvJCGkkugcKvqhhPk=\r\n" |
851 "\r\n"; | 851 "\r\n"; |
852 CreateAndConnectCustomResponse("ws://localhost/", | 852 CreateAndConnectCustomResponse("ws://localhost/", |
853 "/", | 853 "/", |
854 NoSubProtocols(), | 854 NoSubProtocols(), |
855 "http://localhost/", | 855 "http://localhost", |
856 "", | 856 "", |
857 kIncorrectAcceptResponse); | 857 kIncorrectAcceptResponse); |
858 RunUntilIdle(); | 858 RunUntilIdle(); |
859 EXPECT_TRUE(has_failed()); | 859 EXPECT_TRUE(has_failed()); |
860 EXPECT_EQ("Error during WebSocket handshake: " | 860 EXPECT_EQ("Error during WebSocket handshake: " |
861 "Incorrect 'Sec-WebSocket-Accept' header value", | 861 "Incorrect 'Sec-WebSocket-Accept' header value", |
862 failure_message()); | 862 failure_message()); |
863 } | 863 } |
864 | 864 |
865 // Cancellation works. | 865 // Cancellation works. |
866 TEST_F(WebSocketStreamCreateTest, Cancellation) { | 866 TEST_F(WebSocketStreamCreateTest, Cancellation) { |
867 CreateAndConnectStandard( | 867 CreateAndConnectStandard( |
868 "ws://localhost/", "/", NoSubProtocols(), "http://localhost/", "", ""); | 868 "ws://localhost/", "/", NoSubProtocols(), "http://localhost", "", ""); |
869 stream_request_.reset(); | 869 stream_request_.reset(); |
870 RunUntilIdle(); | 870 RunUntilIdle(); |
871 EXPECT_FALSE(has_failed()); | 871 EXPECT_FALSE(has_failed()); |
872 EXPECT_FALSE(stream_); | 872 EXPECT_FALSE(stream_); |
873 EXPECT_FALSE(request_info_); | 873 EXPECT_FALSE(request_info_); |
874 EXPECT_FALSE(response_info_); | 874 EXPECT_FALSE(response_info_); |
875 } | 875 } |
876 | 876 |
877 // Connect failure must look just like negotiation failure. | 877 // Connect failure must look just like negotiation failure. |
878 TEST_F(WebSocketStreamCreateTest, ConnectionFailure) { | 878 TEST_F(WebSocketStreamCreateTest, ConnectionFailure) { |
879 scoped_ptr<DeterministicSocketData> socket_data( | 879 scoped_ptr<DeterministicSocketData> socket_data( |
880 new DeterministicSocketData(NULL, 0, NULL, 0)); | 880 new DeterministicSocketData(NULL, 0, NULL, 0)); |
881 socket_data->set_connect_data( | 881 socket_data->set_connect_data( |
882 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); | 882 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); |
883 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 883 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
884 "http://localhost/", socket_data.Pass()); | 884 "http://localhost", socket_data.Pass()); |
885 RunUntilIdle(); | 885 RunUntilIdle(); |
886 EXPECT_TRUE(has_failed()); | 886 EXPECT_TRUE(has_failed()); |
887 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", | 887 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", |
888 failure_message()); | 888 failure_message()); |
889 EXPECT_FALSE(request_info_); | 889 EXPECT_FALSE(request_info_); |
890 EXPECT_FALSE(response_info_); | 890 EXPECT_FALSE(response_info_); |
891 } | 891 } |
892 | 892 |
893 // Connect timeout must look just like any other failure. | 893 // Connect timeout must look just like any other failure. |
894 TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) { | 894 TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) { |
895 scoped_ptr<DeterministicSocketData> socket_data( | 895 scoped_ptr<DeterministicSocketData> socket_data( |
896 new DeterministicSocketData(NULL, 0, NULL, 0)); | 896 new DeterministicSocketData(NULL, 0, NULL, 0)); |
897 socket_data->set_connect_data( | 897 socket_data->set_connect_data( |
898 MockConnect(ASYNC, ERR_CONNECTION_TIMED_OUT)); | 898 MockConnect(ASYNC, ERR_CONNECTION_TIMED_OUT)); |
899 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 899 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
900 "http://localhost/", socket_data.Pass()); | 900 "http://localhost/", socket_data.Pass()); |
901 RunUntilIdle(); | 901 RunUntilIdle(); |
902 EXPECT_TRUE(has_failed()); | 902 EXPECT_TRUE(has_failed()); |
903 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT", | 903 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT", |
904 failure_message()); | 904 failure_message()); |
905 } | 905 } |
906 | 906 |
907 // Cancellation during connect works. | 907 // Cancellation during connect works. |
908 TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) { | 908 TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) { |
909 scoped_ptr<DeterministicSocketData> socket_data( | 909 scoped_ptr<DeterministicSocketData> socket_data( |
910 new DeterministicSocketData(NULL, 0, NULL, 0)); | 910 new DeterministicSocketData(NULL, 0, NULL, 0)); |
911 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); | 911 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); |
912 CreateAndConnectRawExpectations("ws://localhost/", | 912 CreateAndConnectRawExpectations("ws://localhost/", |
913 NoSubProtocols(), | 913 NoSubProtocols(), |
914 "http://localhost/", | 914 "http://localhost", |
915 socket_data.Pass()); | 915 socket_data.Pass()); |
916 stream_request_.reset(); | 916 stream_request_.reset(); |
917 RunUntilIdle(); | 917 RunUntilIdle(); |
918 EXPECT_FALSE(has_failed()); | 918 EXPECT_FALSE(has_failed()); |
919 EXPECT_FALSE(stream_); | 919 EXPECT_FALSE(stream_); |
920 } | 920 } |
921 | 921 |
922 // Cancellation during write of the request headers works. | 922 // Cancellation during write of the request headers works. |
923 TEST_F(WebSocketStreamCreateTest, CancellationDuringWrite) { | 923 TEST_F(WebSocketStreamCreateTest, CancellationDuringWrite) { |
924 // We seem to need at least two operations in order to use SetStop(). | 924 // We seem to need at least two operations in order to use SetStop(). |
925 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/"), | 925 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/"), |
926 MockWrite(ASYNC, 1, "1.1\r\n")}; | 926 MockWrite(ASYNC, 1, "1.1\r\n")}; |
927 // We keep a copy of the pointer so that we can call RunFor() on it later. | 927 // We keep a copy of the pointer so that we can call RunFor() on it later. |
928 DeterministicSocketData* socket_data( | 928 DeterministicSocketData* socket_data( |
929 new DeterministicSocketData(NULL, 0, writes, arraysize(writes))); | 929 new DeterministicSocketData(NULL, 0, writes, arraysize(writes))); |
930 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | 930 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
931 socket_data->SetStop(1); | 931 socket_data->SetStop(1); |
932 CreateAndConnectRawExpectations("ws://localhost/", | 932 CreateAndConnectRawExpectations("ws://localhost/", |
933 NoSubProtocols(), | 933 NoSubProtocols(), |
934 "http://localhost/", | 934 "http://localhost", |
935 make_scoped_ptr(socket_data)); | 935 make_scoped_ptr(socket_data)); |
936 socket_data->Run(); | 936 socket_data->Run(); |
937 stream_request_.reset(); | 937 stream_request_.reset(); |
938 RunUntilIdle(); | 938 RunUntilIdle(); |
939 EXPECT_FALSE(has_failed()); | 939 EXPECT_FALSE(has_failed()); |
940 EXPECT_FALSE(stream_); | 940 EXPECT_FALSE(stream_); |
941 EXPECT_TRUE(request_info_); | 941 EXPECT_TRUE(request_info_); |
942 EXPECT_FALSE(response_info_); | 942 EXPECT_FALSE(response_info_); |
943 } | 943 } |
944 | 944 |
945 // Cancellation during read of the response headers works. | 945 // Cancellation during read of the response headers works. |
946 TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) { | 946 TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) { |
947 std::string request = WebSocketStandardRequest("/", "http://localhost/", ""); | 947 std::string request = WebSocketStandardRequest("/", "http://localhost", ""); |
948 MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())}; | 948 MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())}; |
949 MockRead reads[] = { | 949 MockRead reads[] = { |
950 MockRead(ASYNC, 1, "HTTP/1.1 101 Switching Protocols\r\nUpgr"), | 950 MockRead(ASYNC, 1, "HTTP/1.1 101 Switching Protocols\r\nUpgr"), |
951 }; | 951 }; |
952 DeterministicSocketData* socket_data(new DeterministicSocketData( | 952 DeterministicSocketData* socket_data(new DeterministicSocketData( |
953 reads, arraysize(reads), writes, arraysize(writes))); | 953 reads, arraysize(reads), writes, arraysize(writes))); |
954 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | 954 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
955 socket_data->SetStop(1); | 955 socket_data->SetStop(1); |
956 CreateAndConnectRawExpectations("ws://localhost/", | 956 CreateAndConnectRawExpectations("ws://localhost/", |
957 NoSubProtocols(), | 957 NoSubProtocols(), |
958 "http://localhost/", | 958 "http://localhost", |
959 make_scoped_ptr(socket_data)); | 959 make_scoped_ptr(socket_data)); |
960 socket_data->Run(); | 960 socket_data->Run(); |
961 stream_request_.reset(); | 961 stream_request_.reset(); |
962 RunUntilIdle(); | 962 RunUntilIdle(); |
963 EXPECT_FALSE(has_failed()); | 963 EXPECT_FALSE(has_failed()); |
964 EXPECT_FALSE(stream_); | 964 EXPECT_FALSE(stream_); |
965 EXPECT_TRUE(request_info_); | 965 EXPECT_TRUE(request_info_); |
966 EXPECT_FALSE(response_info_); | 966 EXPECT_FALSE(response_info_); |
967 } | 967 } |
968 | 968 |
969 // Over-size response headers (> 256KB) should not cause a crash. This is a | 969 // Over-size response headers (> 256KB) should not cause a crash. This is a |
970 // regression test for crbug.com/339456. It is based on the layout test | 970 // regression test for crbug.com/339456. It is based on the layout test |
971 // "cookie-flood.html". | 971 // "cookie-flood.html". |
972 TEST_F(WebSocketStreamCreateTest, VeryLargeResponseHeaders) { | 972 TEST_F(WebSocketStreamCreateTest, VeryLargeResponseHeaders) { |
973 std::string set_cookie_headers; | 973 std::string set_cookie_headers; |
974 set_cookie_headers.reserve(45 * 10000); | 974 set_cookie_headers.reserve(45 * 10000); |
975 for (int i = 0; i < 10000; ++i) { | 975 for (int i = 0; i < 10000; ++i) { |
976 set_cookie_headers += | 976 set_cookie_headers += |
977 base::StringPrintf("Set-Cookie: WK-websocket-test-flood-%d=1\r\n", i); | 977 base::StringPrintf("Set-Cookie: WK-websocket-test-flood-%d=1\r\n", i); |
978 } | 978 } |
979 CreateAndConnectStandard("ws://localhost/", "/", NoSubProtocols(), | 979 CreateAndConnectStandard("ws://localhost/", "/", NoSubProtocols(), |
980 "http://localhost/", "", set_cookie_headers); | 980 "http://localhost", "", set_cookie_headers); |
981 RunUntilIdle(); | 981 RunUntilIdle(); |
982 EXPECT_TRUE(has_failed()); | 982 EXPECT_TRUE(has_failed()); |
983 EXPECT_FALSE(response_info_); | 983 EXPECT_FALSE(response_info_); |
984 } | 984 } |
985 | 985 |
986 // If the remote host closes the connection without sending headers, we should | 986 // If the remote host closes the connection without sending headers, we should |
987 // log the console message "Connection closed before receiving a handshake | 987 // log the console message "Connection closed before receiving a handshake |
988 // response". | 988 // response". |
989 TEST_F(WebSocketStreamCreateTest, NoResponse) { | 989 TEST_F(WebSocketStreamCreateTest, NoResponse) { |
990 std::string request = WebSocketStandardRequest("/", "http://localhost/", ""); | 990 std::string request = WebSocketStandardRequest("/", "http://localhost", ""); |
991 MockWrite writes[] = {MockWrite(ASYNC, request.data(), request.size(), 0)}; | 991 MockWrite writes[] = {MockWrite(ASYNC, request.data(), request.size(), 0)}; |
992 MockRead reads[] = {MockRead(ASYNC, 0, 1)}; | 992 MockRead reads[] = {MockRead(ASYNC, 0, 1)}; |
993 DeterministicSocketData* socket_data(new DeterministicSocketData( | 993 DeterministicSocketData* socket_data(new DeterministicSocketData( |
994 reads, arraysize(reads), writes, arraysize(writes))); | 994 reads, arraysize(reads), writes, arraysize(writes))); |
995 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | 995 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
996 CreateAndConnectRawExpectations("ws://localhost/", | 996 CreateAndConnectRawExpectations("ws://localhost/", |
997 NoSubProtocols(), | 997 NoSubProtocols(), |
998 "http://localhost/", | 998 "http://localhost", |
999 make_scoped_ptr(socket_data)); | 999 make_scoped_ptr(socket_data)); |
1000 socket_data->RunFor(2); | 1000 socket_data->RunFor(2); |
1001 EXPECT_TRUE(has_failed()); | 1001 EXPECT_TRUE(has_failed()); |
1002 EXPECT_FALSE(stream_); | 1002 EXPECT_FALSE(stream_); |
1003 EXPECT_FALSE(response_info_); | 1003 EXPECT_FALSE(response_info_); |
1004 EXPECT_EQ("Connection closed before receiving a handshake response", | 1004 EXPECT_EQ("Connection closed before receiving a handshake response", |
1005 failure_message()); | 1005 failure_message()); |
1006 } | 1006 } |
1007 | 1007 |
1008 } // namespace | 1008 } // namespace |
1009 } // namespace net | 1009 } // namespace net |
OLD | NEW |