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

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

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

Powered by Google App Engine
This is Rietveld 408576698