Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Side by Side Diff: net/websockets/websocket_stream_test.cc

Issue 158453004: [ABANDONED] [WebSocket] Remove the trailing slash from the origin header. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/websockets/websocket_stream.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/websockets/websocket_stream.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698