OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/websockets/websocket_stream.h" | 5 #include "net/websockets/websocket_stream.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 stream_.reset(); | 85 stream_.reset(); |
86 base::RunLoop().RunUntilIdle(); | 86 base::RunLoop().RunUntilIdle(); |
87 } | 87 } |
88 | 88 |
89 void CreateAndConnectCustomResponse( | 89 void CreateAndConnectCustomResponse( |
90 const std::string& socket_url, | 90 const std::string& socket_url, |
91 const std::string& socket_host, | 91 const std::string& socket_host, |
92 const std::string& socket_path, | 92 const std::string& socket_path, |
93 const std::vector<std::string>& sub_protocols, | 93 const std::vector<std::string>& sub_protocols, |
94 const url::Origin& origin, | 94 const url::Origin& origin, |
| 95 const std::string& send_additional_request_headers, |
95 const std::string& extra_request_headers, | 96 const std::string& extra_request_headers, |
96 const std::string& response_body, | 97 const std::string& response_body, |
97 std::unique_ptr<base::Timer> timer = std::unique_ptr<base::Timer>()) { | 98 std::unique_ptr<base::Timer> timer = std::unique_ptr<base::Timer>()) { |
98 url_request_context_host_.SetExpectations( | 99 url_request_context_host_.SetExpectations( |
99 WebSocketStandardRequest(socket_path, socket_host, origin, | 100 WebSocketStandardRequest(socket_path, socket_host, origin, |
| 101 send_additional_request_headers, |
100 extra_request_headers), | 102 extra_request_headers), |
101 response_body); | 103 response_body); |
102 CreateAndConnectStream(socket_url, sub_protocols, origin, std::move(timer)); | 104 CreateAndConnectStream(socket_url, sub_protocols, origin, |
| 105 send_additional_request_headers, std::move(timer)); |
103 } | 106 } |
104 | 107 |
105 // |extra_request_headers| and |extra_response_headers| must end in "\r\n" or | 108 // |extra_request_headers| and |extra_response_headers| must end in "\r\n" or |
106 // errors like "Unable to perform synchronous IO while stopped" will occur. | 109 // errors like "Unable to perform synchronous IO while stopped" will occur. |
107 void CreateAndConnectStandard( | 110 void CreateAndConnectStandard( |
108 const std::string& socket_url, | 111 const std::string& socket_url, |
109 const std::string& socket_host, | 112 const std::string& socket_host, |
110 const std::string& socket_path, | 113 const std::string& socket_path, |
111 const std::vector<std::string>& sub_protocols, | 114 const std::vector<std::string>& sub_protocols, |
112 const url::Origin& origin, | 115 const url::Origin& origin, |
| 116 const std::string& send_additional_request_headers, |
113 const std::string& extra_request_headers, | 117 const std::string& extra_request_headers, |
114 const std::string& extra_response_headers, | 118 const std::string& extra_response_headers, |
115 std::unique_ptr<base::Timer> timer = std::unique_ptr<base::Timer>()) { | 119 std::unique_ptr<base::Timer> timer = std::unique_ptr<base::Timer>()) { |
116 CreateAndConnectCustomResponse( | 120 CreateAndConnectCustomResponse( |
117 socket_url, socket_host, socket_path, sub_protocols, origin, | 121 socket_url, socket_host, socket_path, sub_protocols, origin, |
118 extra_request_headers, | 122 send_additional_request_headers, extra_request_headers, |
119 WebSocketStandardResponse(extra_response_headers), std::move(timer)); | 123 WebSocketStandardResponse(extra_response_headers), std::move(timer)); |
120 } | 124 } |
121 | 125 |
122 void CreateAndConnectRawExpectations( | 126 void CreateAndConnectRawExpectations( |
123 const std::string& socket_url, | 127 const std::string& socket_url, |
124 const std::vector<std::string>& sub_protocols, | 128 const std::vector<std::string>& sub_protocols, |
125 const url::Origin& origin, | 129 const url::Origin& origin, |
| 130 const std::string& send_additional_request_headers, |
126 std::unique_ptr<SequencedSocketData> socket_data, | 131 std::unique_ptr<SequencedSocketData> socket_data, |
127 std::unique_ptr<base::Timer> timer = std::unique_ptr<base::Timer>()) { | 132 std::unique_ptr<base::Timer> timer = std::unique_ptr<base::Timer>()) { |
128 AddRawExpectations(std::move(socket_data)); | 133 AddRawExpectations(std::move(socket_data)); |
129 CreateAndConnectStream(socket_url, sub_protocols, origin, std::move(timer)); | 134 CreateAndConnectStream(socket_url, sub_protocols, origin, |
| 135 send_additional_request_headers, std::move(timer)); |
130 } | 136 } |
131 | 137 |
132 // Add additional raw expectations for sockets created before the final one. | 138 // Add additional raw expectations for sockets created before the final one. |
133 void AddRawExpectations(std::unique_ptr<SequencedSocketData> socket_data) { | 139 void AddRawExpectations(std::unique_ptr<SequencedSocketData> socket_data) { |
134 url_request_context_host_.AddRawExpectations(std::move(socket_data)); | 140 url_request_context_host_.AddRawExpectations(std::move(socket_data)); |
135 } | 141 } |
136 }; | 142 }; |
137 | 143 |
138 // There are enough tests of the Sec-WebSocket-Extensions header that they | 144 // There are enough tests of the Sec-WebSocket-Extensions header that they |
139 // deserve their own test fixture. | 145 // deserve their own test fixture. |
140 class WebSocketStreamCreateExtensionTest : public WebSocketStreamCreateTest { | 146 class WebSocketStreamCreateExtensionTest : public WebSocketStreamCreateTest { |
141 public: | 147 public: |
142 // Performs a standard connect, with the value of the Sec-WebSocket-Extensions | 148 // Performs a standard connect, with the value of the Sec-WebSocket-Extensions |
143 // header in the response set to |extensions_header_value|. Runs the event | 149 // header in the response set to |extensions_header_value|. Runs the event |
144 // loop to allow the connect to complete. | 150 // loop to allow the connect to complete. |
145 void CreateAndConnectWithExtensions( | 151 void CreateAndConnectWithExtensions( |
146 const std::string& extensions_header_value) { | 152 const std::string& extensions_header_value) { |
147 CreateAndConnectStandard( | 153 CreateAndConnectStandard( |
148 "ws://localhost/testing_path", "localhost", "/testing_path", | 154 "ws://localhost/testing_path", "localhost", "/testing_path", |
149 NoSubProtocols(), LocalhostOrigin(), "", | 155 NoSubProtocols(), LocalhostOrigin(), "", "", |
150 "Sec-WebSocket-Extensions: " + extensions_header_value + "\r\n"); | 156 "Sec-WebSocket-Extensions: " + extensions_header_value + "\r\n"); |
151 WaitUntilConnectDone(); | 157 WaitUntilConnectDone(); |
152 } | 158 } |
153 }; | 159 }; |
154 | 160 |
155 // Common code to construct expectations for authentication tests that receive | 161 // Common code to construct expectations for authentication tests that receive |
156 // the auth challenge on one connection and then create a second connection to | 162 // the auth challenge on one connection and then create a second connection to |
157 // send the authenticated request on. | 163 // send the authenticated request on. |
158 class CommonAuthTestHelper { | 164 class CommonAuthTestHelper { |
159 public: | 165 public: |
160 CommonAuthTestHelper() : reads1_(), writes1_(), reads2_(), writes2_() {} | 166 CommonAuthTestHelper() : reads1_(), writes1_(), reads2_(), writes2_() {} |
161 | 167 |
162 std::unique_ptr<SequencedSocketData> BuildSocketData1( | 168 std::unique_ptr<SequencedSocketData> BuildSocketData1( |
163 const std::string& response) { | 169 const std::string& response) { |
164 request1_ = | 170 request1_ = |
165 WebSocketStandardRequest("/", "localhost", LocalhostOrigin(), ""); | 171 WebSocketStandardRequest("/", "localhost", LocalhostOrigin(), "", ""); |
166 writes1_[0] = MockWrite(SYNCHRONOUS, 0, request1_.c_str()); | 172 writes1_[0] = MockWrite(SYNCHRONOUS, 0, request1_.c_str()); |
167 response1_ = response; | 173 response1_ = response; |
168 reads1_[0] = MockRead(SYNCHRONOUS, 1, response1_.c_str()); | 174 reads1_[0] = MockRead(SYNCHRONOUS, 1, response1_.c_str()); |
169 reads1_[1] = MockRead(SYNCHRONOUS, OK, 2); // Close connection | 175 reads1_[1] = MockRead(SYNCHRONOUS, OK, 2); // Close connection |
170 | 176 |
171 return BuildSocketData(reads1_, writes1_); | 177 return BuildSocketData(reads1_, writes1_); |
172 } | 178 } |
173 | 179 |
174 std::unique_ptr<SequencedSocketData> BuildSocketData2( | 180 std::unique_ptr<SequencedSocketData> BuildSocketData2( |
175 const std::string& request, | 181 const std::string& request, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 "User-Agent:\r\n" | 223 "User-Agent:\r\n" |
218 "Accept-Encoding: gzip, deflate\r\n" | 224 "Accept-Encoding: gzip, deflate\r\n" |
219 "Accept-Language: en-us,fr\r\n" | 225 "Accept-Language: en-us,fr\r\n" |
220 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | 226 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" |
221 "Sec-WebSocket-Extensions: permessage-deflate; " | 227 "Sec-WebSocket-Extensions: permessage-deflate; " |
222 "client_max_window_bits\r\n" | 228 "client_max_window_bits\r\n" |
223 "\r\n"; | 229 "\r\n"; |
224 const std::string request = | 230 const std::string request = |
225 base::StringPrintf(request2format, base64_user_pass.c_str()); | 231 base::StringPrintf(request2format, base64_user_pass.c_str()); |
226 CreateAndConnectRawExpectations( | 232 CreateAndConnectRawExpectations( |
227 url, NoSubProtocols(), LocalhostOrigin(), | 233 url, NoSubProtocols(), LocalhostOrigin(), "", |
228 helper_.BuildSocketData2(request, response2)); | 234 helper_.BuildSocketData2(request, response2)); |
229 } | 235 } |
230 | 236 |
231 static const char kUnauthorizedResponse[]; | 237 static const char kUnauthorizedResponse[]; |
232 | 238 |
233 CommonAuthTestHelper helper_; | 239 CommonAuthTestHelper helper_; |
234 }; | 240 }; |
235 | 241 |
236 class WebSocketStreamCreateDigestAuthTest : public WebSocketStreamCreateTest { | 242 class WebSocketStreamCreateDigestAuthTest : public WebSocketStreamCreateTest { |
237 protected: | 243 protected: |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 base::HistogramBase* histogram = | 301 base::HistogramBase* histogram = |
296 base::StatisticsRecorder::FindHistogram(name); | 302 base::StatisticsRecorder::FindHistogram(name); |
297 return histogram ? histogram->SnapshotSamples() | 303 return histogram ? histogram->SnapshotSamples() |
298 : std::unique_ptr<base::HistogramSamples>(); | 304 : std::unique_ptr<base::HistogramSamples>(); |
299 } | 305 } |
300 }; | 306 }; |
301 | 307 |
302 // Confirm that the basic case works as expected. | 308 // Confirm that the basic case works as expected. |
303 TEST_F(WebSocketStreamCreateTest, SimpleSuccess) { | 309 TEST_F(WebSocketStreamCreateTest, SimpleSuccess) { |
304 CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 310 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
305 NoSubProtocols(), LocalhostOrigin(), "", ""); | 311 NoSubProtocols(), LocalhostOrigin(), "", "", ""); |
306 EXPECT_FALSE(request_info_); | 312 EXPECT_FALSE(request_info_); |
307 EXPECT_FALSE(response_info_); | 313 EXPECT_FALSE(response_info_); |
308 WaitUntilConnectDone(); | 314 WaitUntilConnectDone(); |
309 EXPECT_FALSE(has_failed()); | 315 EXPECT_FALSE(has_failed()); |
310 EXPECT_TRUE(stream_); | 316 EXPECT_TRUE(stream_); |
311 EXPECT_TRUE(request_info_); | 317 EXPECT_TRUE(request_info_); |
312 EXPECT_TRUE(response_info_); | 318 EXPECT_TRUE(response_info_); |
313 } | 319 } |
314 | 320 |
315 TEST_F(WebSocketStreamCreateTest, HandshakeInfo) { | 321 TEST_F(WebSocketStreamCreateTest, HandshakeInfo) { |
316 static const char kResponse[] = | 322 static const char kResponse[] = |
317 "HTTP/1.1 101 Switching Protocols\r\n" | 323 "HTTP/1.1 101 Switching Protocols\r\n" |
318 "Upgrade: websocket\r\n" | 324 "Upgrade: websocket\r\n" |
319 "Connection: Upgrade\r\n" | 325 "Connection: Upgrade\r\n" |
320 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 326 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
321 "foo: bar, baz\r\n" | 327 "foo: bar, baz\r\n" |
322 "hoge: fuga\r\n" | 328 "hoge: fuga\r\n" |
323 "hoge: piyo\r\n" | 329 "hoge: piyo\r\n" |
324 "\r\n"; | 330 "\r\n"; |
325 | 331 |
326 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 332 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
327 NoSubProtocols(), LocalhostOrigin(), "", | 333 NoSubProtocols(), LocalhostOrigin(), "", "", |
328 kResponse); | 334 kResponse); |
329 EXPECT_FALSE(request_info_); | 335 EXPECT_FALSE(request_info_); |
330 EXPECT_FALSE(response_info_); | 336 EXPECT_FALSE(response_info_); |
331 WaitUntilConnectDone(); | 337 WaitUntilConnectDone(); |
332 EXPECT_TRUE(stream_); | 338 EXPECT_TRUE(stream_); |
333 ASSERT_TRUE(request_info_); | 339 ASSERT_TRUE(request_info_); |
334 ASSERT_TRUE(response_info_); | 340 ASSERT_TRUE(response_info_); |
335 std::vector<HeaderKeyValuePair> request_headers = | 341 std::vector<HeaderKeyValuePair> request_headers = |
336 RequestHeadersToVector(request_info_->headers); | 342 RequestHeadersToVector(request_info_->headers); |
337 // We examine the contents of request_info_ and response_info_ | 343 // We examine the contents of request_info_ and response_info_ |
(...skipping 30 matching lines...) Expand all Loading... |
368 std::sort(response_headers.begin(), response_headers.end()); | 374 std::sort(response_headers.begin(), response_headers.end()); |
369 | 375 |
370 EXPECT_EQ(HeaderKeyValuePair("Connection", "Upgrade"), response_headers[0]); | 376 EXPECT_EQ(HeaderKeyValuePair("Connection", "Upgrade"), response_headers[0]); |
371 EXPECT_EQ("Sec-WebSocket-Accept", response_headers[1].first); | 377 EXPECT_EQ("Sec-WebSocket-Accept", response_headers[1].first); |
372 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), response_headers[2]); | 378 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), response_headers[2]); |
373 EXPECT_EQ(HeaderKeyValuePair("foo", "bar, baz"), response_headers[3]); | 379 EXPECT_EQ(HeaderKeyValuePair("foo", "bar, baz"), response_headers[3]); |
374 EXPECT_EQ(HeaderKeyValuePair("hoge", "fuga"), response_headers[4]); | 380 EXPECT_EQ(HeaderKeyValuePair("hoge", "fuga"), response_headers[4]); |
375 EXPECT_EQ(HeaderKeyValuePair("hoge", "piyo"), response_headers[5]); | 381 EXPECT_EQ(HeaderKeyValuePair("hoge", "piyo"), response_headers[5]); |
376 } | 382 } |
377 | 383 |
| 384 // Confirms that request headers are overriden/added after handshake |
| 385 TEST_F(WebSocketStreamCreateTest, HandshakeOverrideHeaders) { |
| 386 std::string additional_headers( |
| 387 "User-Agent: OveRrIde\r\n" |
| 388 "rAnDomHeader: foobar\r\n"); |
| 389 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 390 NoSubProtocols(), LocalhostOrigin(), |
| 391 additional_headers, additional_headers, ""); |
| 392 EXPECT_FALSE(request_info_); |
| 393 EXPECT_FALSE(response_info_); |
| 394 WaitUntilConnectDone(); |
| 395 EXPECT_FALSE(has_failed()); |
| 396 EXPECT_TRUE(stream_); |
| 397 EXPECT_TRUE(request_info_); |
| 398 EXPECT_TRUE(response_info_); |
| 399 |
| 400 std::vector<HeaderKeyValuePair> request_headers = |
| 401 RequestHeadersToVector(request_info_->headers); |
| 402 EXPECT_EQ(HeaderKeyValuePair("User-Agent", "OveRrIde"), request_headers[7]); |
| 403 EXPECT_EQ(HeaderKeyValuePair("rAnDomHeader", "foobar"), request_headers[8]); |
| 404 } |
| 405 |
378 // Confirm that the stream isn't established until the message loop runs. | 406 // Confirm that the stream isn't established until the message loop runs. |
379 TEST_F(WebSocketStreamCreateTest, NeedsToRunLoop) { | 407 TEST_F(WebSocketStreamCreateTest, NeedsToRunLoop) { |
380 CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 408 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
381 NoSubProtocols(), LocalhostOrigin(), "", ""); | 409 NoSubProtocols(), LocalhostOrigin(), "", "", ""); |
382 EXPECT_FALSE(has_failed()); | 410 EXPECT_FALSE(has_failed()); |
383 EXPECT_FALSE(stream_); | 411 EXPECT_FALSE(stream_); |
384 } | 412 } |
385 | 413 |
386 // Check the path is used. | 414 // Check the path is used. |
387 TEST_F(WebSocketStreamCreateTest, PathIsUsed) { | 415 TEST_F(WebSocketStreamCreateTest, PathIsUsed) { |
388 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 416 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
389 "/testing_path", NoSubProtocols(), LocalhostOrigin(), | 417 "/testing_path", NoSubProtocols(), LocalhostOrigin(), |
390 "", ""); | 418 "", "", ""); |
391 WaitUntilConnectDone(); | 419 WaitUntilConnectDone(); |
392 EXPECT_FALSE(has_failed()); | 420 EXPECT_FALSE(has_failed()); |
393 EXPECT_TRUE(stream_); | 421 EXPECT_TRUE(stream_); |
394 } | 422 } |
395 | 423 |
396 // Check that the origin is used. | 424 // Check that the origin is used. |
397 TEST_F(WebSocketStreamCreateTest, OriginIsUsed) { | 425 TEST_F(WebSocketStreamCreateTest, OriginIsUsed) { |
398 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 426 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
399 "/testing_path", NoSubProtocols(), GoogleOrigin(), | 427 "/testing_path", NoSubProtocols(), GoogleOrigin(), |
400 "", ""); | 428 "", "", ""); |
401 WaitUntilConnectDone(); | 429 WaitUntilConnectDone(); |
402 EXPECT_FALSE(has_failed()); | 430 EXPECT_FALSE(has_failed()); |
403 EXPECT_TRUE(stream_); | 431 EXPECT_TRUE(stream_); |
404 } | 432 } |
405 | 433 |
406 // Check that sub-protocols are sent and parsed. | 434 // Check that sub-protocols are sent and parsed. |
407 TEST_F(WebSocketStreamCreateTest, SubProtocolIsUsed) { | 435 TEST_F(WebSocketStreamCreateTest, SubProtocolIsUsed) { |
408 std::vector<std::string> sub_protocols; | 436 std::vector<std::string> sub_protocols; |
409 sub_protocols.push_back("chatv11.chromium.org"); | 437 sub_protocols.push_back("chatv11.chromium.org"); |
410 sub_protocols.push_back("chatv20.chromium.org"); | 438 sub_protocols.push_back("chatv20.chromium.org"); |
411 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 439 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
412 "/testing_path", sub_protocols, GoogleOrigin(), | 440 "/testing_path", sub_protocols, GoogleOrigin(), "", |
413 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 441 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
414 "chatv20.chromium.org\r\n", | 442 "chatv20.chromium.org\r\n", |
415 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); | 443 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); |
416 WaitUntilConnectDone(); | 444 WaitUntilConnectDone(); |
417 EXPECT_TRUE(stream_); | 445 EXPECT_TRUE(stream_); |
418 EXPECT_FALSE(has_failed()); | 446 EXPECT_FALSE(has_failed()); |
419 EXPECT_EQ("chatv20.chromium.org", stream_->GetSubProtocol()); | 447 EXPECT_EQ("chatv20.chromium.org", stream_->GetSubProtocol()); |
420 } | 448 } |
421 | 449 |
422 // Unsolicited sub-protocols are rejected. | 450 // Unsolicited sub-protocols are rejected. |
423 TEST_F(WebSocketStreamCreateTest, UnsolicitedSubProtocol) { | 451 TEST_F(WebSocketStreamCreateTest, UnsolicitedSubProtocol) { |
424 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 452 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
425 "/testing_path", NoSubProtocols(), GoogleOrigin(), | 453 "/testing_path", NoSubProtocols(), GoogleOrigin(), |
426 "", | 454 "", "", |
427 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); | 455 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); |
428 WaitUntilConnectDone(); | 456 WaitUntilConnectDone(); |
429 EXPECT_FALSE(stream_); | 457 EXPECT_FALSE(stream_); |
430 EXPECT_TRUE(has_failed()); | 458 EXPECT_TRUE(has_failed()); |
431 EXPECT_EQ("Error during WebSocket handshake: " | 459 EXPECT_EQ("Error during WebSocket handshake: " |
432 "Response must not include 'Sec-WebSocket-Protocol' header " | 460 "Response must not include 'Sec-WebSocket-Protocol' header " |
433 "if not present in request: chatv20.chromium.org", | 461 "if not present in request: chatv20.chromium.org", |
434 failure_message()); | 462 failure_message()); |
435 } | 463 } |
436 | 464 |
437 // Missing sub-protocol response is rejected. | 465 // Missing sub-protocol response is rejected. |
438 TEST_F(WebSocketStreamCreateTest, UnacceptedSubProtocol) { | 466 TEST_F(WebSocketStreamCreateTest, UnacceptedSubProtocol) { |
439 std::vector<std::string> sub_protocols; | 467 std::vector<std::string> sub_protocols; |
440 sub_protocols.push_back("chat.example.com"); | 468 sub_protocols.push_back("chat.example.com"); |
441 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 469 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
442 "/testing_path", sub_protocols, LocalhostOrigin(), | 470 "/testing_path", sub_protocols, LocalhostOrigin(), |
443 "Sec-WebSocket-Protocol: chat.example.com\r\n", ""); | 471 "", "Sec-WebSocket-Protocol: chat.example.com\r\n", |
| 472 ""); |
444 WaitUntilConnectDone(); | 473 WaitUntilConnectDone(); |
445 EXPECT_FALSE(stream_); | 474 EXPECT_FALSE(stream_); |
446 EXPECT_TRUE(has_failed()); | 475 EXPECT_TRUE(has_failed()); |
447 EXPECT_EQ("Error during WebSocket handshake: " | 476 EXPECT_EQ("Error during WebSocket handshake: " |
448 "Sent non-empty 'Sec-WebSocket-Protocol' header " | 477 "Sent non-empty 'Sec-WebSocket-Protocol' header " |
449 "but no response was received", | 478 "but no response was received", |
450 failure_message()); | 479 failure_message()); |
451 } | 480 } |
452 | 481 |
453 // Only one sub-protocol can be accepted. | 482 // Only one sub-protocol can be accepted. |
454 TEST_F(WebSocketStreamCreateTest, MultipleSubProtocolsInResponse) { | 483 TEST_F(WebSocketStreamCreateTest, MultipleSubProtocolsInResponse) { |
455 std::vector<std::string> sub_protocols; | 484 std::vector<std::string> sub_protocols; |
456 sub_protocols.push_back("chatv11.chromium.org"); | 485 sub_protocols.push_back("chatv11.chromium.org"); |
457 sub_protocols.push_back("chatv20.chromium.org"); | 486 sub_protocols.push_back("chatv20.chromium.org"); |
458 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 487 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
459 "/testing_path", sub_protocols, GoogleOrigin(), | 488 "/testing_path", sub_protocols, GoogleOrigin(), "", |
460 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 489 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
461 "chatv20.chromium.org\r\n", | 490 "chatv20.chromium.org\r\n", |
462 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 491 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
463 "chatv20.chromium.org\r\n"); | 492 "chatv20.chromium.org\r\n"); |
464 WaitUntilConnectDone(); | 493 WaitUntilConnectDone(); |
465 EXPECT_FALSE(stream_); | 494 EXPECT_FALSE(stream_); |
466 EXPECT_TRUE(has_failed()); | 495 EXPECT_TRUE(has_failed()); |
467 EXPECT_EQ("Error during WebSocket handshake: " | 496 EXPECT_EQ("Error during WebSocket handshake: " |
468 "'Sec-WebSocket-Protocol' header must not appear " | 497 "'Sec-WebSocket-Protocol' header must not appear " |
469 "more than once in a response", | 498 "more than once in a response", |
470 failure_message()); | 499 failure_message()); |
471 } | 500 } |
472 | 501 |
473 // Unmatched sub-protocol should be rejected. | 502 // Unmatched sub-protocol should be rejected. |
474 TEST_F(WebSocketStreamCreateTest, UnmatchedSubProtocolInResponse) { | 503 TEST_F(WebSocketStreamCreateTest, UnmatchedSubProtocolInResponse) { |
475 std::vector<std::string> sub_protocols; | 504 std::vector<std::string> sub_protocols; |
476 sub_protocols.push_back("chatv11.chromium.org"); | 505 sub_protocols.push_back("chatv11.chromium.org"); |
477 sub_protocols.push_back("chatv20.chromium.org"); | 506 sub_protocols.push_back("chatv20.chromium.org"); |
478 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 507 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
479 "/testing_path", sub_protocols, GoogleOrigin(), | 508 "/testing_path", sub_protocols, GoogleOrigin(), "", |
480 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 509 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
481 "chatv20.chromium.org\r\n", | 510 "chatv20.chromium.org\r\n", |
482 "Sec-WebSocket-Protocol: chatv21.chromium.org\r\n"); | 511 "Sec-WebSocket-Protocol: chatv21.chromium.org\r\n"); |
483 WaitUntilConnectDone(); | 512 WaitUntilConnectDone(); |
484 EXPECT_FALSE(stream_); | 513 EXPECT_FALSE(stream_); |
485 EXPECT_TRUE(has_failed()); | 514 EXPECT_TRUE(has_failed()); |
486 EXPECT_EQ("Error during WebSocket handshake: " | 515 EXPECT_EQ("Error during WebSocket handshake: " |
487 "'Sec-WebSocket-Protocol' header value 'chatv21.chromium.org' " | 516 "'Sec-WebSocket-Protocol' header value 'chatv21.chromium.org' " |
488 "in response does not match any of sent values", | 517 "in response does not match any of sent values", |
489 failure_message()); | 518 failure_message()); |
(...skipping 14 matching lines...) Expand all Loading... |
504 "server_no_context_takeover"); | 533 "server_no_context_takeover"); |
505 EXPECT_TRUE(stream_); | 534 EXPECT_TRUE(stream_); |
506 EXPECT_FALSE(has_failed()); | 535 EXPECT_FALSE(has_failed()); |
507 } | 536 } |
508 | 537 |
509 // Verify that incoming messages are actually decompressed with | 538 // Verify that incoming messages are actually decompressed with |
510 // permessage-deflate enabled. | 539 // permessage-deflate enabled. |
511 TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateInflates) { | 540 TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateInflates) { |
512 CreateAndConnectCustomResponse( | 541 CreateAndConnectCustomResponse( |
513 "ws://localhost/testing_path", "localhost", "/testing_path", | 542 "ws://localhost/testing_path", "localhost", "/testing_path", |
514 NoSubProtocols(), LocalhostOrigin(), "", | 543 NoSubProtocols(), LocalhostOrigin(), "", "", |
515 WebSocketStandardResponse( | 544 WebSocketStandardResponse( |
516 "Sec-WebSocket-Extensions: permessage-deflate\r\n") + | 545 "Sec-WebSocket-Extensions: permessage-deflate\r\n") + |
517 std::string( | 546 std::string( |
518 "\xc1\x07" // WebSocket header (FIN + RSV1, Text payload 7 bytes) | 547 "\xc1\x07" // WebSocket header (FIN + RSV1, Text payload 7 bytes) |
519 "\xf2\x48\xcd\xc9\xc9\x07\x00", // "Hello" DEFLATE compressed | 548 "\xf2\x48\xcd\xc9\xc9\x07\x00", // "Hello" DEFLATE compressed |
520 9)); | 549 9)); |
521 WaitUntilConnectDone(); | 550 WaitUntilConnectDone(); |
522 | 551 |
523 ASSERT_TRUE(stream_); | 552 ASSERT_TRUE(stream_); |
524 std::vector<std::unique_ptr<WebSocketFrame>> frames; | 553 std::vector<std::unique_ptr<WebSocketFrame>> frames; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 // websocket_deflate_parameters_test.cc. | 608 // websocket_deflate_parameters_test.cc. |
580 | 609 |
581 // TODO(ricea): Check that WebSocketDeflateStream is initialised with the | 610 // TODO(ricea): Check that WebSocketDeflateStream is initialised with the |
582 // arguments from the server. This is difficult because the data written to the | 611 // arguments from the server. This is difficult because the data written to the |
583 // socket is randomly masked. | 612 // socket is randomly masked. |
584 | 613 |
585 // Additional Sec-WebSocket-Accept headers should be rejected. | 614 // Additional Sec-WebSocket-Accept headers should be rejected. |
586 TEST_F(WebSocketStreamCreateTest, DoubleAccept) { | 615 TEST_F(WebSocketStreamCreateTest, DoubleAccept) { |
587 CreateAndConnectStandard( | 616 CreateAndConnectStandard( |
588 "ws://localhost/", "localhost", "/", NoSubProtocols(), LocalhostOrigin(), | 617 "ws://localhost/", "localhost", "/", NoSubProtocols(), LocalhostOrigin(), |
589 "", "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"); | 618 "", "", "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"); |
590 WaitUntilConnectDone(); | 619 WaitUntilConnectDone(); |
591 EXPECT_FALSE(stream_); | 620 EXPECT_FALSE(stream_); |
592 EXPECT_TRUE(has_failed()); | 621 EXPECT_TRUE(has_failed()); |
593 EXPECT_EQ("Error during WebSocket handshake: " | 622 EXPECT_EQ("Error during WebSocket handshake: " |
594 "'Sec-WebSocket-Accept' header must not appear " | 623 "'Sec-WebSocket-Accept' header must not appear " |
595 "more than once in a response", | 624 "more than once in a response", |
596 failure_message()); | 625 failure_message()); |
597 } | 626 } |
598 | 627 |
599 // Response code 200 must be rejected. | 628 // Response code 200 must be rejected. |
600 TEST_F(WebSocketStreamCreateTest, InvalidStatusCode) { | 629 TEST_F(WebSocketStreamCreateTest, InvalidStatusCode) { |
601 static const char kInvalidStatusCodeResponse[] = | 630 static const char kInvalidStatusCodeResponse[] = |
602 "HTTP/1.1 200 OK\r\n" | 631 "HTTP/1.1 200 OK\r\n" |
603 "Upgrade: websocket\r\n" | 632 "Upgrade: websocket\r\n" |
604 "Connection: Upgrade\r\n" | 633 "Connection: Upgrade\r\n" |
605 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 634 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
606 "\r\n"; | 635 "\r\n"; |
607 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 636 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
608 NoSubProtocols(), LocalhostOrigin(), "", | 637 NoSubProtocols(), LocalhostOrigin(), "", "", |
609 kInvalidStatusCodeResponse); | 638 kInvalidStatusCodeResponse); |
610 WaitUntilConnectDone(); | 639 WaitUntilConnectDone(); |
611 EXPECT_TRUE(has_failed()); | 640 EXPECT_TRUE(has_failed()); |
612 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 200", | 641 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 200", |
613 failure_message()); | 642 failure_message()); |
614 } | 643 } |
615 | 644 |
616 // Redirects are not followed (according to the WHATWG WebSocket API, which | 645 // Redirects are not followed (according to the WHATWG WebSocket API, which |
617 // overrides RFC6455 for browser applications). | 646 // overrides RFC6455 for browser applications). |
618 TEST_F(WebSocketStreamCreateTest, RedirectsRejected) { | 647 TEST_F(WebSocketStreamCreateTest, RedirectsRejected) { |
619 static const char kRedirectResponse[] = | 648 static const char kRedirectResponse[] = |
620 "HTTP/1.1 302 Moved Temporarily\r\n" | 649 "HTTP/1.1 302 Moved Temporarily\r\n" |
621 "Content-Type: text/html\r\n" | 650 "Content-Type: text/html\r\n" |
622 "Content-Length: 34\r\n" | 651 "Content-Length: 34\r\n" |
623 "Connection: keep-alive\r\n" | 652 "Connection: keep-alive\r\n" |
624 "Location: ws://localhost/other\r\n" | 653 "Location: ws://localhost/other\r\n" |
625 "\r\n" | 654 "\r\n" |
626 "<title>Moved</title><h1>Moved</h1>"; | 655 "<title>Moved</title><h1>Moved</h1>"; |
627 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 656 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
628 NoSubProtocols(), LocalhostOrigin(), "", | 657 NoSubProtocols(), LocalhostOrigin(), "", "", |
629 kRedirectResponse); | 658 kRedirectResponse); |
630 WaitUntilConnectDone(); | 659 WaitUntilConnectDone(); |
631 EXPECT_TRUE(has_failed()); | 660 EXPECT_TRUE(has_failed()); |
632 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 302", | 661 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 302", |
633 failure_message()); | 662 failure_message()); |
634 } | 663 } |
635 | 664 |
636 // Malformed responses should be rejected. HttpStreamParser will accept just | 665 // Malformed responses should be rejected. HttpStreamParser will accept just |
637 // about any garbage in the middle of the headers. To make it give up, the junk | 666 // about any garbage in the middle of the headers. To make it give up, the junk |
638 // has to be at the start of the response. Even then, it just gets treated as an | 667 // has to be at the start of the response. Even then, it just gets treated as an |
639 // HTTP/0.9 response. | 668 // HTTP/0.9 response. |
640 TEST_F(WebSocketStreamCreateTest, MalformedResponse) { | 669 TEST_F(WebSocketStreamCreateTest, MalformedResponse) { |
641 static const char kMalformedResponse[] = | 670 static const char kMalformedResponse[] = |
642 "220 mx.google.com ESMTP\r\n" | 671 "220 mx.google.com ESMTP\r\n" |
643 "HTTP/1.1 101 OK\r\n" | 672 "HTTP/1.1 101 OK\r\n" |
644 "Upgrade: websocket\r\n" | 673 "Upgrade: websocket\r\n" |
645 "Connection: Upgrade\r\n" | 674 "Connection: Upgrade\r\n" |
646 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 675 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
647 "\r\n"; | 676 "\r\n"; |
648 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 677 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
649 NoSubProtocols(), LocalhostOrigin(), "", | 678 NoSubProtocols(), LocalhostOrigin(), "", "", |
650 kMalformedResponse); | 679 kMalformedResponse); |
651 WaitUntilConnectDone(); | 680 WaitUntilConnectDone(); |
652 EXPECT_TRUE(has_failed()); | 681 EXPECT_TRUE(has_failed()); |
653 EXPECT_EQ("Error during WebSocket handshake: Invalid status line", | 682 EXPECT_EQ("Error during WebSocket handshake: Invalid status line", |
654 failure_message()); | 683 failure_message()); |
655 } | 684 } |
656 | 685 |
657 // Upgrade header must be present. | 686 // Upgrade header must be present. |
658 TEST_F(WebSocketStreamCreateTest, MissingUpgradeHeader) { | 687 TEST_F(WebSocketStreamCreateTest, MissingUpgradeHeader) { |
659 static const char kMissingUpgradeResponse[] = | 688 static const char kMissingUpgradeResponse[] = |
660 "HTTP/1.1 101 Switching Protocols\r\n" | 689 "HTTP/1.1 101 Switching Protocols\r\n" |
661 "Connection: Upgrade\r\n" | 690 "Connection: Upgrade\r\n" |
662 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 691 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
663 "\r\n"; | 692 "\r\n"; |
664 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 693 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
665 NoSubProtocols(), LocalhostOrigin(), "", | 694 NoSubProtocols(), LocalhostOrigin(), "", "", |
666 kMissingUpgradeResponse); | 695 kMissingUpgradeResponse); |
667 WaitUntilConnectDone(); | 696 WaitUntilConnectDone(); |
668 EXPECT_TRUE(has_failed()); | 697 EXPECT_TRUE(has_failed()); |
669 EXPECT_EQ("Error during WebSocket handshake: 'Upgrade' header is missing", | 698 EXPECT_EQ("Error during WebSocket handshake: 'Upgrade' header is missing", |
670 failure_message()); | 699 failure_message()); |
671 } | 700 } |
672 | 701 |
673 // There must only be one upgrade header. | 702 // There must only be one upgrade header. |
674 TEST_F(WebSocketStreamCreateTest, DoubleUpgradeHeader) { | 703 TEST_F(WebSocketStreamCreateTest, DoubleUpgradeHeader) { |
675 CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 704 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
676 NoSubProtocols(), LocalhostOrigin(), "", | 705 NoSubProtocols(), LocalhostOrigin(), "", "", |
677 "Upgrade: HTTP/2.0\r\n"); | 706 "Upgrade: HTTP/2.0\r\n"); |
678 WaitUntilConnectDone(); | 707 WaitUntilConnectDone(); |
679 EXPECT_TRUE(has_failed()); | 708 EXPECT_TRUE(has_failed()); |
680 EXPECT_EQ("Error during WebSocket handshake: " | 709 EXPECT_EQ("Error during WebSocket handshake: " |
681 "'Upgrade' header must not appear more than once in a response", | 710 "'Upgrade' header must not appear more than once in a response", |
682 failure_message()); | 711 failure_message()); |
683 } | 712 } |
684 | 713 |
685 // There must only be one correct upgrade header. | 714 // There must only be one correct upgrade header. |
686 TEST_F(WebSocketStreamCreateTest, IncorrectUpgradeHeader) { | 715 TEST_F(WebSocketStreamCreateTest, IncorrectUpgradeHeader) { |
687 static const char kMissingUpgradeResponse[] = | 716 static const char kMissingUpgradeResponse[] = |
688 "HTTP/1.1 101 Switching Protocols\r\n" | 717 "HTTP/1.1 101 Switching Protocols\r\n" |
689 "Connection: Upgrade\r\n" | 718 "Connection: Upgrade\r\n" |
690 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 719 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
691 "Upgrade: hogefuga\r\n" | 720 "Upgrade: hogefuga\r\n" |
692 "\r\n"; | 721 "\r\n"; |
693 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 722 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
694 NoSubProtocols(), LocalhostOrigin(), "", | 723 NoSubProtocols(), LocalhostOrigin(), "", "", |
695 kMissingUpgradeResponse); | 724 kMissingUpgradeResponse); |
696 WaitUntilConnectDone(); | 725 WaitUntilConnectDone(); |
697 EXPECT_TRUE(has_failed()); | 726 EXPECT_TRUE(has_failed()); |
698 EXPECT_EQ("Error during WebSocket handshake: " | 727 EXPECT_EQ("Error during WebSocket handshake: " |
699 "'Upgrade' header value is not 'WebSocket': hogefuga", | 728 "'Upgrade' header value is not 'WebSocket': hogefuga", |
700 failure_message()); | 729 failure_message()); |
701 } | 730 } |
702 | 731 |
703 // Connection header must be present. | 732 // Connection header must be present. |
704 TEST_F(WebSocketStreamCreateTest, MissingConnectionHeader) { | 733 TEST_F(WebSocketStreamCreateTest, MissingConnectionHeader) { |
705 static const char kMissingConnectionResponse[] = | 734 static const char kMissingConnectionResponse[] = |
706 "HTTP/1.1 101 Switching Protocols\r\n" | 735 "HTTP/1.1 101 Switching Protocols\r\n" |
707 "Upgrade: websocket\r\n" | 736 "Upgrade: websocket\r\n" |
708 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 737 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
709 "\r\n"; | 738 "\r\n"; |
710 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 739 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
711 NoSubProtocols(), LocalhostOrigin(), "", | 740 NoSubProtocols(), LocalhostOrigin(), "", "", |
712 kMissingConnectionResponse); | 741 kMissingConnectionResponse); |
713 WaitUntilConnectDone(); | 742 WaitUntilConnectDone(); |
714 EXPECT_TRUE(has_failed()); | 743 EXPECT_TRUE(has_failed()); |
715 EXPECT_EQ("Error during WebSocket handshake: " | 744 EXPECT_EQ("Error during WebSocket handshake: " |
716 "'Connection' header is missing", | 745 "'Connection' header is missing", |
717 failure_message()); | 746 failure_message()); |
718 } | 747 } |
719 | 748 |
720 // Connection header must contain "Upgrade". | 749 // Connection header must contain "Upgrade". |
721 TEST_F(WebSocketStreamCreateTest, IncorrectConnectionHeader) { | 750 TEST_F(WebSocketStreamCreateTest, IncorrectConnectionHeader) { |
722 static const char kMissingConnectionResponse[] = | 751 static const char kMissingConnectionResponse[] = |
723 "HTTP/1.1 101 Switching Protocols\r\n" | 752 "HTTP/1.1 101 Switching Protocols\r\n" |
724 "Upgrade: websocket\r\n" | 753 "Upgrade: websocket\r\n" |
725 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 754 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
726 "Connection: hogefuga\r\n" | 755 "Connection: hogefuga\r\n" |
727 "\r\n"; | 756 "\r\n"; |
728 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 757 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
729 NoSubProtocols(), LocalhostOrigin(), "", | 758 NoSubProtocols(), LocalhostOrigin(), "", "", |
730 kMissingConnectionResponse); | 759 kMissingConnectionResponse); |
731 WaitUntilConnectDone(); | 760 WaitUntilConnectDone(); |
732 EXPECT_TRUE(has_failed()); | 761 EXPECT_TRUE(has_failed()); |
733 EXPECT_EQ("Error during WebSocket handshake: " | 762 EXPECT_EQ("Error during WebSocket handshake: " |
734 "'Connection' header value must contain 'Upgrade'", | 763 "'Connection' header value must contain 'Upgrade'", |
735 failure_message()); | 764 failure_message()); |
736 } | 765 } |
737 | 766 |
738 // Connection header is permitted to contain other tokens. | 767 // Connection header is permitted to contain other tokens. |
739 TEST_F(WebSocketStreamCreateTest, AdditionalTokenInConnectionHeader) { | 768 TEST_F(WebSocketStreamCreateTest, AdditionalTokenInConnectionHeader) { |
740 static const char kAdditionalConnectionTokenResponse[] = | 769 static const char kAdditionalConnectionTokenResponse[] = |
741 "HTTP/1.1 101 Switching Protocols\r\n" | 770 "HTTP/1.1 101 Switching Protocols\r\n" |
742 "Upgrade: websocket\r\n" | 771 "Upgrade: websocket\r\n" |
743 "Connection: Upgrade, Keep-Alive\r\n" | 772 "Connection: Upgrade, Keep-Alive\r\n" |
744 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 773 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
745 "\r\n"; | 774 "\r\n"; |
746 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 775 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
747 NoSubProtocols(), LocalhostOrigin(), "", | 776 NoSubProtocols(), LocalhostOrigin(), "", "", |
748 kAdditionalConnectionTokenResponse); | 777 kAdditionalConnectionTokenResponse); |
749 WaitUntilConnectDone(); | 778 WaitUntilConnectDone(); |
750 EXPECT_FALSE(has_failed()); | 779 EXPECT_FALSE(has_failed()); |
751 EXPECT_TRUE(stream_); | 780 EXPECT_TRUE(stream_); |
752 } | 781 } |
753 | 782 |
754 // Sec-WebSocket-Accept header must be present. | 783 // Sec-WebSocket-Accept header must be present. |
755 TEST_F(WebSocketStreamCreateTest, MissingSecWebSocketAccept) { | 784 TEST_F(WebSocketStreamCreateTest, MissingSecWebSocketAccept) { |
756 static const char kMissingAcceptResponse[] = | 785 static const char kMissingAcceptResponse[] = |
757 "HTTP/1.1 101 Switching Protocols\r\n" | 786 "HTTP/1.1 101 Switching Protocols\r\n" |
758 "Upgrade: websocket\r\n" | 787 "Upgrade: websocket\r\n" |
759 "Connection: Upgrade\r\n" | 788 "Connection: Upgrade\r\n" |
760 "\r\n"; | 789 "\r\n"; |
761 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 790 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
762 NoSubProtocols(), LocalhostOrigin(), "", | 791 NoSubProtocols(), LocalhostOrigin(), "", "", |
763 kMissingAcceptResponse); | 792 kMissingAcceptResponse); |
764 WaitUntilConnectDone(); | 793 WaitUntilConnectDone(); |
765 EXPECT_TRUE(has_failed()); | 794 EXPECT_TRUE(has_failed()); |
766 EXPECT_EQ("Error during WebSocket handshake: " | 795 EXPECT_EQ("Error during WebSocket handshake: " |
767 "'Sec-WebSocket-Accept' header is missing", | 796 "'Sec-WebSocket-Accept' header is missing", |
768 failure_message()); | 797 failure_message()); |
769 } | 798 } |
770 | 799 |
771 // Sec-WebSocket-Accept header must match the key that was sent. | 800 // Sec-WebSocket-Accept header must match the key that was sent. |
772 TEST_F(WebSocketStreamCreateTest, WrongSecWebSocketAccept) { | 801 TEST_F(WebSocketStreamCreateTest, WrongSecWebSocketAccept) { |
773 static const char kIncorrectAcceptResponse[] = | 802 static const char kIncorrectAcceptResponse[] = |
774 "HTTP/1.1 101 Switching Protocols\r\n" | 803 "HTTP/1.1 101 Switching Protocols\r\n" |
775 "Upgrade: websocket\r\n" | 804 "Upgrade: websocket\r\n" |
776 "Connection: Upgrade\r\n" | 805 "Connection: Upgrade\r\n" |
777 "Sec-WebSocket-Accept: x/byyPZ2tOFvJCGkkugcKvqhhPk=\r\n" | 806 "Sec-WebSocket-Accept: x/byyPZ2tOFvJCGkkugcKvqhhPk=\r\n" |
778 "\r\n"; | 807 "\r\n"; |
779 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 808 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
780 NoSubProtocols(), LocalhostOrigin(), "", | 809 NoSubProtocols(), LocalhostOrigin(), "", "", |
781 kIncorrectAcceptResponse); | 810 kIncorrectAcceptResponse); |
782 WaitUntilConnectDone(); | 811 WaitUntilConnectDone(); |
783 EXPECT_TRUE(has_failed()); | 812 EXPECT_TRUE(has_failed()); |
784 EXPECT_EQ("Error during WebSocket handshake: " | 813 EXPECT_EQ("Error during WebSocket handshake: " |
785 "Incorrect 'Sec-WebSocket-Accept' header value", | 814 "Incorrect 'Sec-WebSocket-Accept' header value", |
786 failure_message()); | 815 failure_message()); |
787 } | 816 } |
788 | 817 |
789 // Cancellation works. | 818 // Cancellation works. |
790 TEST_F(WebSocketStreamCreateTest, Cancellation) { | 819 TEST_F(WebSocketStreamCreateTest, Cancellation) { |
791 CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 820 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
792 NoSubProtocols(), LocalhostOrigin(), "", ""); | 821 NoSubProtocols(), LocalhostOrigin(), "", "", ""); |
793 stream_request_.reset(); | 822 stream_request_.reset(); |
794 // WaitUntilConnectDone doesn't work in this case. | 823 // WaitUntilConnectDone doesn't work in this case. |
795 base::RunLoop().RunUntilIdle(); | 824 base::RunLoop().RunUntilIdle(); |
796 EXPECT_FALSE(has_failed()); | 825 EXPECT_FALSE(has_failed()); |
797 EXPECT_FALSE(stream_); | 826 EXPECT_FALSE(stream_); |
798 EXPECT_FALSE(request_info_); | 827 EXPECT_FALSE(request_info_); |
799 EXPECT_FALSE(response_info_); | 828 EXPECT_FALSE(response_info_); |
800 } | 829 } |
801 | 830 |
802 // Connect failure must look just like negotiation failure. | 831 // Connect failure must look just like negotiation failure. |
803 TEST_F(WebSocketStreamCreateTest, ConnectionFailure) { | 832 TEST_F(WebSocketStreamCreateTest, ConnectionFailure) { |
804 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); | 833 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); |
805 socket_data->set_connect_data( | 834 socket_data->set_connect_data( |
806 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); | 835 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); |
807 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 836 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
808 LocalhostOrigin(), std::move(socket_data)); | 837 LocalhostOrigin(), "", |
| 838 std::move(socket_data)); |
809 WaitUntilConnectDone(); | 839 WaitUntilConnectDone(); |
810 EXPECT_TRUE(has_failed()); | 840 EXPECT_TRUE(has_failed()); |
811 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", | 841 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", |
812 failure_message()); | 842 failure_message()); |
813 EXPECT_FALSE(request_info_); | 843 EXPECT_FALSE(request_info_); |
814 EXPECT_FALSE(response_info_); | 844 EXPECT_FALSE(response_info_); |
815 } | 845 } |
816 | 846 |
817 // Connect timeout must look just like any other failure. | 847 // Connect timeout must look just like any other failure. |
818 TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) { | 848 TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) { |
819 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); | 849 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); |
820 socket_data->set_connect_data( | 850 socket_data->set_connect_data( |
821 MockConnect(ASYNC, ERR_CONNECTION_TIMED_OUT)); | 851 MockConnect(ASYNC, ERR_CONNECTION_TIMED_OUT)); |
822 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 852 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
823 LocalhostOrigin(), std::move(socket_data)); | 853 LocalhostOrigin(), "", |
| 854 std::move(socket_data)); |
824 WaitUntilConnectDone(); | 855 WaitUntilConnectDone(); |
825 EXPECT_TRUE(has_failed()); | 856 EXPECT_TRUE(has_failed()); |
826 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT", | 857 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT", |
827 failure_message()); | 858 failure_message()); |
828 } | 859 } |
829 | 860 |
830 // The server doesn't respond to the opening handshake. | 861 // The server doesn't respond to the opening handshake. |
831 TEST_F(WebSocketStreamCreateTest, HandshakeTimeout) { | 862 TEST_F(WebSocketStreamCreateTest, HandshakeTimeout) { |
832 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); | 863 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); |
833 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); | 864 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); |
834 std::unique_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); | 865 std::unique_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); |
835 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); | 866 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); |
836 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 867 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
837 LocalhostOrigin(), std::move(socket_data), | 868 LocalhostOrigin(), "", std::move(socket_data), |
838 std::move(timer)); | 869 std::move(timer)); |
839 EXPECT_FALSE(has_failed()); | 870 EXPECT_FALSE(has_failed()); |
840 ASSERT_TRUE(weak_timer.get()); | 871 ASSERT_TRUE(weak_timer.get()); |
841 EXPECT_TRUE(weak_timer->IsRunning()); | 872 EXPECT_TRUE(weak_timer->IsRunning()); |
842 | 873 |
843 weak_timer->Fire(); | 874 weak_timer->Fire(); |
844 WaitUntilConnectDone(); | 875 WaitUntilConnectDone(); |
845 | 876 |
846 EXPECT_TRUE(has_failed()); | 877 EXPECT_TRUE(has_failed()); |
847 EXPECT_EQ("WebSocket opening handshake timed out", failure_message()); | 878 EXPECT_EQ("WebSocket opening handshake timed out", failure_message()); |
848 ASSERT_TRUE(weak_timer.get()); | 879 ASSERT_TRUE(weak_timer.get()); |
849 EXPECT_FALSE(weak_timer->IsRunning()); | 880 EXPECT_FALSE(weak_timer->IsRunning()); |
850 } | 881 } |
851 | 882 |
852 // When the connection establishes the timer should be stopped. | 883 // When the connection establishes the timer should be stopped. |
853 TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnSuccess) { | 884 TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnSuccess) { |
854 std::unique_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); | 885 std::unique_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); |
855 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); | 886 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); |
856 | 887 |
857 CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 888 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
858 NoSubProtocols(), LocalhostOrigin(), "", "", | 889 NoSubProtocols(), LocalhostOrigin(), "", "", "", |
859 std::move(timer)); | 890 std::move(timer)); |
860 ASSERT_TRUE(weak_timer); | 891 ASSERT_TRUE(weak_timer); |
861 EXPECT_TRUE(weak_timer->IsRunning()); | 892 EXPECT_TRUE(weak_timer->IsRunning()); |
862 | 893 |
863 WaitUntilConnectDone(); | 894 WaitUntilConnectDone(); |
864 EXPECT_FALSE(has_failed()); | 895 EXPECT_FALSE(has_failed()); |
865 EXPECT_TRUE(stream_); | 896 EXPECT_TRUE(stream_); |
866 ASSERT_TRUE(weak_timer); | 897 ASSERT_TRUE(weak_timer); |
867 EXPECT_FALSE(weak_timer->IsRunning()); | 898 EXPECT_FALSE(weak_timer->IsRunning()); |
868 } | 899 } |
869 | 900 |
870 // When the connection fails the timer should be stopped. | 901 // When the connection fails the timer should be stopped. |
871 TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnFailure) { | 902 TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnFailure) { |
872 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); | 903 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); |
873 socket_data->set_connect_data( | 904 socket_data->set_connect_data( |
874 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); | 905 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); |
875 std::unique_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); | 906 std::unique_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); |
876 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); | 907 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); |
877 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 908 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
878 LocalhostOrigin(), std::move(socket_data), | 909 LocalhostOrigin(), "", std::move(socket_data), |
879 std::move(timer)); | 910 std::move(timer)); |
880 ASSERT_TRUE(weak_timer.get()); | 911 ASSERT_TRUE(weak_timer.get()); |
881 EXPECT_TRUE(weak_timer->IsRunning()); | 912 EXPECT_TRUE(weak_timer->IsRunning()); |
882 | 913 |
883 WaitUntilConnectDone(); | 914 WaitUntilConnectDone(); |
884 EXPECT_TRUE(has_failed()); | 915 EXPECT_TRUE(has_failed()); |
885 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", | 916 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", |
886 failure_message()); | 917 failure_message()); |
887 ASSERT_TRUE(weak_timer.get()); | 918 ASSERT_TRUE(weak_timer.get()); |
888 EXPECT_FALSE(weak_timer->IsRunning()); | 919 EXPECT_FALSE(weak_timer->IsRunning()); |
889 } | 920 } |
890 | 921 |
891 // Cancellation during connect works. | 922 // Cancellation during connect works. |
892 TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) { | 923 TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) { |
893 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); | 924 std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData()); |
894 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); | 925 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); |
895 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 926 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
896 LocalhostOrigin(), std::move(socket_data)); | 927 LocalhostOrigin(), "", |
| 928 std::move(socket_data)); |
897 stream_request_.reset(); | 929 stream_request_.reset(); |
898 // WaitUntilConnectDone doesn't work in this case. | 930 // WaitUntilConnectDone doesn't work in this case. |
899 base::RunLoop().RunUntilIdle(); | 931 base::RunLoop().RunUntilIdle(); |
900 EXPECT_FALSE(has_failed()); | 932 EXPECT_FALSE(has_failed()); |
901 EXPECT_FALSE(stream_); | 933 EXPECT_FALSE(stream_); |
902 } | 934 } |
903 | 935 |
904 // Cancellation during write of the request headers works. | 936 // Cancellation during write of the request headers works. |
905 TEST_F(WebSocketStreamCreateTest, CancellationDuringWrite) { | 937 TEST_F(WebSocketStreamCreateTest, CancellationDuringWrite) { |
906 // First write never completes. | 938 // First write never completes. |
907 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 0)}; | 939 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 0)}; |
908 SequencedSocketData* socket_data( | 940 SequencedSocketData* socket_data( |
909 new SequencedSocketData(NULL, 0, writes, arraysize(writes))); | 941 new SequencedSocketData(NULL, 0, writes, arraysize(writes))); |
910 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | 942 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
911 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 943 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
912 LocalhostOrigin(), | 944 LocalhostOrigin(), "", |
913 base::WrapUnique(socket_data)); | 945 base::WrapUnique(socket_data)); |
914 base::RunLoop().RunUntilIdle(); | 946 base::RunLoop().RunUntilIdle(); |
915 EXPECT_TRUE(socket_data->AllWriteDataConsumed()); | 947 EXPECT_TRUE(socket_data->AllWriteDataConsumed()); |
916 stream_request_.reset(); | 948 stream_request_.reset(); |
917 // WaitUntilConnectDone doesn't work in this case. | 949 // WaitUntilConnectDone doesn't work in this case. |
918 base::RunLoop().RunUntilIdle(); | 950 base::RunLoop().RunUntilIdle(); |
919 EXPECT_FALSE(has_failed()); | 951 EXPECT_FALSE(has_failed()); |
920 EXPECT_FALSE(stream_); | 952 EXPECT_FALSE(stream_); |
921 EXPECT_TRUE(request_info_); | 953 EXPECT_TRUE(request_info_); |
922 EXPECT_FALSE(response_info_); | 954 EXPECT_FALSE(response_info_); |
923 } | 955 } |
924 | 956 |
925 // Cancellation during read of the response headers works. | 957 // Cancellation during read of the response headers works. |
926 TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) { | 958 TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) { |
927 std::string request = | 959 std::string request = |
928 WebSocketStandardRequest("/", "localhost", LocalhostOrigin(), ""); | 960 WebSocketStandardRequest("/", "localhost", LocalhostOrigin(), "", ""); |
929 MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())}; | 961 MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())}; |
930 MockRead reads[] = { | 962 MockRead reads[] = { |
931 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1), | 963 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1), |
932 }; | 964 }; |
933 std::unique_ptr<SequencedSocketData> socket_data( | 965 std::unique_ptr<SequencedSocketData> socket_data( |
934 BuildSocketData(reads, writes)); | 966 BuildSocketData(reads, writes)); |
935 SequencedSocketData* socket_data_raw_ptr = socket_data.get(); | 967 SequencedSocketData* socket_data_raw_ptr = socket_data.get(); |
936 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 968 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
937 LocalhostOrigin(), std::move(socket_data)); | 969 LocalhostOrigin(), "", |
| 970 std::move(socket_data)); |
938 base::RunLoop().RunUntilIdle(); | 971 base::RunLoop().RunUntilIdle(); |
939 EXPECT_TRUE(socket_data_raw_ptr->AllReadDataConsumed()); | 972 EXPECT_TRUE(socket_data_raw_ptr->AllReadDataConsumed()); |
940 stream_request_.reset(); | 973 stream_request_.reset(); |
941 // WaitUntilConnectDone doesn't work in this case. | 974 // WaitUntilConnectDone doesn't work in this case. |
942 base::RunLoop().RunUntilIdle(); | 975 base::RunLoop().RunUntilIdle(); |
943 EXPECT_FALSE(has_failed()); | 976 EXPECT_FALSE(has_failed()); |
944 EXPECT_FALSE(stream_); | 977 EXPECT_FALSE(stream_); |
945 EXPECT_TRUE(request_info_); | 978 EXPECT_TRUE(request_info_); |
946 EXPECT_FALSE(response_info_); | 979 EXPECT_FALSE(response_info_); |
947 } | 980 } |
948 | 981 |
949 // Over-size response headers (> 256KB) should not cause a crash. This is a | 982 // Over-size response headers (> 256KB) should not cause a crash. This is a |
950 // regression test for crbug.com/339456. It is based on the layout test | 983 // regression test for crbug.com/339456. It is based on the layout test |
951 // "cookie-flood.html". | 984 // "cookie-flood.html". |
952 TEST_F(WebSocketStreamCreateTest, VeryLargeResponseHeaders) { | 985 TEST_F(WebSocketStreamCreateTest, VeryLargeResponseHeaders) { |
953 std::string set_cookie_headers; | 986 std::string set_cookie_headers; |
954 set_cookie_headers.reserve(45 * 10000); | 987 set_cookie_headers.reserve(45 * 10000); |
955 for (int i = 0; i < 10000; ++i) { | 988 for (int i = 0; i < 10000; ++i) { |
956 set_cookie_headers += | 989 set_cookie_headers += |
957 base::StringPrintf("Set-Cookie: WK-websocket-test-flood-%d=1\r\n", i); | 990 base::StringPrintf("Set-Cookie: WK-websocket-test-flood-%d=1\r\n", i); |
958 } | 991 } |
959 CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 992 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
960 NoSubProtocols(), LocalhostOrigin(), "", | 993 NoSubProtocols(), LocalhostOrigin(), "", "", |
961 set_cookie_headers); | 994 set_cookie_headers); |
962 WaitUntilConnectDone(); | 995 WaitUntilConnectDone(); |
963 EXPECT_TRUE(has_failed()); | 996 EXPECT_TRUE(has_failed()); |
964 EXPECT_FALSE(response_info_); | 997 EXPECT_FALSE(response_info_); |
965 } | 998 } |
966 | 999 |
967 // If the remote host closes the connection without sending headers, we should | 1000 // If the remote host closes the connection without sending headers, we should |
968 // log the console message "Connection closed before receiving a handshake | 1001 // log the console message "Connection closed before receiving a handshake |
969 // response". | 1002 // response". |
970 TEST_F(WebSocketStreamCreateTest, NoResponse) { | 1003 TEST_F(WebSocketStreamCreateTest, NoResponse) { |
971 std::string request = | 1004 std::string request = |
972 WebSocketStandardRequest("/", "localhost", LocalhostOrigin(), ""); | 1005 WebSocketStandardRequest("/", "localhost", LocalhostOrigin(), "", ""); |
973 MockWrite writes[] = {MockWrite(ASYNC, request.data(), request.size(), 0)}; | 1006 MockWrite writes[] = {MockWrite(ASYNC, request.data(), request.size(), 0)}; |
974 MockRead reads[] = {MockRead(ASYNC, 0, 1)}; | 1007 MockRead reads[] = {MockRead(ASYNC, 0, 1)}; |
975 std::unique_ptr<SequencedSocketData> socket_data( | 1008 std::unique_ptr<SequencedSocketData> socket_data( |
976 BuildSocketData(reads, writes)); | 1009 BuildSocketData(reads, writes)); |
977 SequencedSocketData* socket_data_raw_ptr = socket_data.get(); | 1010 SequencedSocketData* socket_data_raw_ptr = socket_data.get(); |
978 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 1011 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
979 LocalhostOrigin(), std::move(socket_data)); | 1012 LocalhostOrigin(), "", |
| 1013 std::move(socket_data)); |
980 base::RunLoop().RunUntilIdle(); | 1014 base::RunLoop().RunUntilIdle(); |
981 EXPECT_TRUE(socket_data_raw_ptr->AllReadDataConsumed()); | 1015 EXPECT_TRUE(socket_data_raw_ptr->AllReadDataConsumed()); |
982 EXPECT_TRUE(has_failed()); | 1016 EXPECT_TRUE(has_failed()); |
983 EXPECT_FALSE(stream_); | 1017 EXPECT_FALSE(stream_); |
984 EXPECT_FALSE(response_info_); | 1018 EXPECT_FALSE(response_info_); |
985 EXPECT_EQ("Connection closed before receiving a handshake response", | 1019 EXPECT_EQ("Connection closed before receiving a handshake response", |
986 failure_message()); | 1020 failure_message()); |
987 } | 1021 } |
988 | 1022 |
989 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateFailure) { | 1023 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateFailure) { |
990 ssl_data_.push_back(base::WrapUnique( | 1024 ssl_data_.push_back(base::WrapUnique( |
991 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID))); | 1025 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID))); |
992 ssl_data_[0]->cert = | 1026 ssl_data_[0]->cert = |
993 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); | 1027 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); |
994 ASSERT_TRUE(ssl_data_[0]->cert.get()); | 1028 ASSERT_TRUE(ssl_data_[0]->cert.get()); |
995 std::unique_ptr<SequencedSocketData> raw_socket_data(BuildNullSocketData()); | 1029 std::unique_ptr<SequencedSocketData> raw_socket_data(BuildNullSocketData()); |
996 CreateAndConnectRawExpectations("wss://localhost/", NoSubProtocols(), | 1030 CreateAndConnectRawExpectations("wss://localhost/", NoSubProtocols(), |
997 LocalhostOrigin(), | 1031 LocalhostOrigin(), "", |
998 std::move(raw_socket_data)); | 1032 std::move(raw_socket_data)); |
999 // WaitUntilConnectDone doesn't work in this case. | 1033 // WaitUntilConnectDone doesn't work in this case. |
1000 base::RunLoop().RunUntilIdle(); | 1034 base::RunLoop().RunUntilIdle(); |
1001 EXPECT_FALSE(has_failed()); | 1035 EXPECT_FALSE(has_failed()); |
1002 ASSERT_TRUE(ssl_error_callbacks_); | 1036 ASSERT_TRUE(ssl_error_callbacks_); |
1003 ssl_error_callbacks_->CancelSSLRequest(ERR_CERT_AUTHORITY_INVALID, | 1037 ssl_error_callbacks_->CancelSSLRequest(ERR_CERT_AUTHORITY_INVALID, |
1004 &ssl_info_); | 1038 &ssl_info_); |
1005 WaitUntilConnectDone(); | 1039 WaitUntilConnectDone(); |
1006 EXPECT_TRUE(has_failed()); | 1040 EXPECT_TRUE(has_failed()); |
1007 } | 1041 } |
1008 | 1042 |
1009 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) { | 1043 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) { |
1010 std::unique_ptr<SSLSocketDataProvider> ssl_data( | 1044 std::unique_ptr<SSLSocketDataProvider> ssl_data( |
1011 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)); | 1045 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)); |
1012 ssl_data->cert = | 1046 ssl_data->cert = |
1013 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); | 1047 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); |
1014 ASSERT_TRUE(ssl_data->cert.get()); | 1048 ASSERT_TRUE(ssl_data->cert.get()); |
1015 ssl_data_.push_back(std::move(ssl_data)); | 1049 ssl_data_.push_back(std::move(ssl_data)); |
1016 ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK)); | 1050 ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK)); |
1017 ssl_data_.push_back(std::move(ssl_data)); | 1051 ssl_data_.push_back(std::move(ssl_data)); |
1018 url_request_context_host_.AddRawExpectations(BuildNullSocketData()); | 1052 url_request_context_host_.AddRawExpectations(BuildNullSocketData()); |
1019 CreateAndConnectStandard("wss://localhost/", "localhost", "/", | 1053 CreateAndConnectStandard("wss://localhost/", "localhost", "/", |
1020 NoSubProtocols(), LocalhostOrigin(), "", ""); | 1054 NoSubProtocols(), LocalhostOrigin(), "", "", ""); |
1021 // WaitUntilConnectDone doesn't work in this case. | 1055 // WaitUntilConnectDone doesn't work in this case. |
1022 base::RunLoop().RunUntilIdle(); | 1056 base::RunLoop().RunUntilIdle(); |
1023 ASSERT_TRUE(ssl_error_callbacks_); | 1057 ASSERT_TRUE(ssl_error_callbacks_); |
1024 ssl_error_callbacks_->ContinueSSLRequest(); | 1058 ssl_error_callbacks_->ContinueSSLRequest(); |
1025 WaitUntilConnectDone(); | 1059 WaitUntilConnectDone(); |
1026 EXPECT_FALSE(has_failed()); | 1060 EXPECT_FALSE(has_failed()); |
1027 EXPECT_TRUE(stream_); | 1061 EXPECT_TRUE(stream_); |
1028 } | 1062 } |
1029 | 1063 |
1030 // If the server requests authorisation, but we have no credentials, the | 1064 // If the server requests authorisation, but we have no credentials, the |
1031 // connection should fail cleanly. | 1065 // connection should fail cleanly. |
1032 TEST_F(WebSocketStreamCreateBasicAuthTest, FailureNoCredentials) { | 1066 TEST_F(WebSocketStreamCreateBasicAuthTest, FailureNoCredentials) { |
1033 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 1067 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
1034 NoSubProtocols(), LocalhostOrigin(), "", | 1068 NoSubProtocols(), LocalhostOrigin(), "", "", |
1035 kUnauthorizedResponse); | 1069 kUnauthorizedResponse); |
1036 WaitUntilConnectDone(); | 1070 WaitUntilConnectDone(); |
1037 EXPECT_TRUE(has_failed()); | 1071 EXPECT_TRUE(has_failed()); |
1038 EXPECT_EQ("HTTP Authentication failed; no valid credentials available", | 1072 EXPECT_EQ("HTTP Authentication failed; no valid credentials available", |
1039 failure_message()); | 1073 failure_message()); |
1040 EXPECT_TRUE(response_info_); | 1074 EXPECT_TRUE(response_info_); |
1041 } | 1075 } |
1042 | 1076 |
1043 TEST_F(WebSocketStreamCreateBasicAuthTest, SuccessPasswordInUrl) { | 1077 TEST_F(WebSocketStreamCreateBasicAuthTest, SuccessPasswordInUrl) { |
1044 CreateAndConnectAuthHandshake("ws://foo:bar@localhost/", | 1078 CreateAndConnectAuthHandshake("ws://foo:bar@localhost/", |
(...skipping 14 matching lines...) Expand all Loading... |
1059 EXPECT_TRUE(response_info_); | 1093 EXPECT_TRUE(response_info_); |
1060 } | 1094 } |
1061 | 1095 |
1062 // Digest auth has the same connection semantics as Basic auth, so we can | 1096 // Digest auth has the same connection semantics as Basic auth, so we can |
1063 // generally assume that whatever works for Basic auth will also work for | 1097 // generally assume that whatever works for Basic auth will also work for |
1064 // Digest. There's just one test here, to confirm that it works at all. | 1098 // Digest. There's just one test here, to confirm that it works at all. |
1065 TEST_F(WebSocketStreamCreateDigestAuthTest, DigestPasswordInUrl) { | 1099 TEST_F(WebSocketStreamCreateDigestAuthTest, DigestPasswordInUrl) { |
1066 AddRawExpectations(helper_.BuildSocketData1(kUnauthorizedResponse)); | 1100 AddRawExpectations(helper_.BuildSocketData1(kUnauthorizedResponse)); |
1067 | 1101 |
1068 CreateAndConnectRawExpectations( | 1102 CreateAndConnectRawExpectations( |
1069 "ws://FooBar:pass@localhost/", NoSubProtocols(), LocalhostOrigin(), | 1103 "ws://FooBar:pass@localhost/", NoSubProtocols(), LocalhostOrigin(), "", |
1070 helper_.BuildSocketData2(kAuthorizedRequest, | 1104 helper_.BuildSocketData2(kAuthorizedRequest, |
1071 WebSocketStandardResponse(std::string()))); | 1105 WebSocketStandardResponse(std::string()))); |
1072 WaitUntilConnectDone(); | 1106 WaitUntilConnectDone(); |
1073 EXPECT_FALSE(has_failed()); | 1107 EXPECT_FALSE(has_failed()); |
1074 EXPECT_TRUE(stream_); | 1108 EXPECT_TRUE(stream_); |
1075 ASSERT_TRUE(response_info_); | 1109 ASSERT_TRUE(response_info_); |
1076 EXPECT_EQ(101, response_info_->status_code); | 1110 EXPECT_EQ(101, response_info_->status_code); |
1077 } | 1111 } |
1078 | 1112 |
1079 TEST_F(WebSocketStreamCreateUMATest, Incomplete) { | 1113 TEST_F(WebSocketStreamCreateUMATest, Incomplete) { |
1080 const std::string name("Net.WebSocket.HandshakeResult"); | 1114 const std::string name("Net.WebSocket.HandshakeResult"); |
1081 std::unique_ptr<base::HistogramSamples> original(GetSamples(name)); | 1115 std::unique_ptr<base::HistogramSamples> original(GetSamples(name)); |
1082 | 1116 |
1083 { | 1117 { |
1084 StreamCreation creation; | 1118 StreamCreation creation; |
1085 creation.CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 1119 creation.CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
1086 creation.NoSubProtocols(), | 1120 creation.NoSubProtocols(), |
1087 LocalhostOrigin(), "", ""); | 1121 LocalhostOrigin(), "", "", ""); |
1088 } | 1122 } |
1089 | 1123 |
1090 std::unique_ptr<base::HistogramSamples> samples(GetSamples(name)); | 1124 std::unique_ptr<base::HistogramSamples> samples(GetSamples(name)); |
1091 ASSERT_TRUE(samples); | 1125 ASSERT_TRUE(samples); |
1092 if (original) { | 1126 if (original) { |
1093 samples->Subtract(*original); // Cancel the original values. | 1127 samples->Subtract(*original); // Cancel the original values. |
1094 } | 1128 } |
1095 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); | 1129 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); |
1096 EXPECT_EQ(0, samples->GetCount(CONNECTED)); | 1130 EXPECT_EQ(0, samples->GetCount(CONNECTED)); |
1097 EXPECT_EQ(0, samples->GetCount(FAILED)); | 1131 EXPECT_EQ(0, samples->GetCount(FAILED)); |
1098 } | 1132 } |
1099 | 1133 |
1100 TEST_F(WebSocketStreamCreateUMATest, Connected) { | 1134 TEST_F(WebSocketStreamCreateUMATest, Connected) { |
1101 const std::string name("Net.WebSocket.HandshakeResult"); | 1135 const std::string name("Net.WebSocket.HandshakeResult"); |
1102 std::unique_ptr<base::HistogramSamples> original(GetSamples(name)); | 1136 std::unique_ptr<base::HistogramSamples> original(GetSamples(name)); |
1103 | 1137 |
1104 { | 1138 { |
1105 StreamCreation creation; | 1139 StreamCreation creation; |
1106 creation.CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 1140 creation.CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
1107 creation.NoSubProtocols(), | 1141 creation.NoSubProtocols(), |
1108 LocalhostOrigin(), "", ""); | 1142 LocalhostOrigin(), "", "", ""); |
1109 creation.WaitUntilConnectDone(); | 1143 creation.WaitUntilConnectDone(); |
1110 } | 1144 } |
1111 | 1145 |
1112 std::unique_ptr<base::HistogramSamples> samples(GetSamples(name)); | 1146 std::unique_ptr<base::HistogramSamples> samples(GetSamples(name)); |
1113 ASSERT_TRUE(samples); | 1147 ASSERT_TRUE(samples); |
1114 if (original) { | 1148 if (original) { |
1115 samples->Subtract(*original); // Cancel the original values. | 1149 samples->Subtract(*original); // Cancel the original values. |
1116 } | 1150 } |
1117 EXPECT_EQ(0, samples->GetCount(INCOMPLETE)); | 1151 EXPECT_EQ(0, samples->GetCount(INCOMPLETE)); |
1118 EXPECT_EQ(1, samples->GetCount(CONNECTED)); | 1152 EXPECT_EQ(1, samples->GetCount(CONNECTED)); |
1119 EXPECT_EQ(0, samples->GetCount(FAILED)); | 1153 EXPECT_EQ(0, samples->GetCount(FAILED)); |
1120 } | 1154 } |
1121 | 1155 |
1122 TEST_F(WebSocketStreamCreateUMATest, Failed) { | 1156 TEST_F(WebSocketStreamCreateUMATest, Failed) { |
1123 const std::string name("Net.WebSocket.HandshakeResult"); | 1157 const std::string name("Net.WebSocket.HandshakeResult"); |
1124 std::unique_ptr<base::HistogramSamples> original(GetSamples(name)); | 1158 std::unique_ptr<base::HistogramSamples> original(GetSamples(name)); |
1125 | 1159 |
1126 { | 1160 { |
1127 StreamCreation creation; | 1161 StreamCreation creation; |
1128 static const char kInvalidStatusCodeResponse[] = | 1162 static const char kInvalidStatusCodeResponse[] = |
1129 "HTTP/1.1 200 OK\r\n" | 1163 "HTTP/1.1 200 OK\r\n" |
1130 "Upgrade: websocket\r\n" | 1164 "Upgrade: websocket\r\n" |
1131 "Connection: Upgrade\r\n" | 1165 "Connection: Upgrade\r\n" |
1132 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 1166 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
1133 "\r\n"; | 1167 "\r\n"; |
1134 creation.CreateAndConnectCustomResponse( | 1168 creation.CreateAndConnectCustomResponse( |
1135 "ws://localhost/", "localhost", "/", creation.NoSubProtocols(), | 1169 "ws://localhost/", "localhost", "/", creation.NoSubProtocols(), |
1136 LocalhostOrigin(), "", kInvalidStatusCodeResponse); | 1170 LocalhostOrigin(), "", "", kInvalidStatusCodeResponse); |
1137 creation.WaitUntilConnectDone(); | 1171 creation.WaitUntilConnectDone(); |
1138 } | 1172 } |
1139 | 1173 |
1140 std::unique_ptr<base::HistogramSamples> samples(GetSamples(name)); | 1174 std::unique_ptr<base::HistogramSamples> samples(GetSamples(name)); |
1141 ASSERT_TRUE(samples); | 1175 ASSERT_TRUE(samples); |
1142 if (original) { | 1176 if (original) { |
1143 samples->Subtract(*original); // Cancel the original values. | 1177 samples->Subtract(*original); // Cancel the original values. |
1144 } | 1178 } |
1145 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); | 1179 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); |
1146 EXPECT_EQ(0, samples->GetCount(CONNECTED)); | 1180 EXPECT_EQ(0, samples->GetCount(CONNECTED)); |
1147 EXPECT_EQ(0, samples->GetCount(FAILED)); | 1181 EXPECT_EQ(0, samples->GetCount(FAILED)); |
1148 } | 1182 } |
1149 | 1183 |
1150 TEST_F(WebSocketStreamCreateTest, HandleErrConnectionClosed) { | 1184 TEST_F(WebSocketStreamCreateTest, HandleErrConnectionClosed) { |
1151 static const char kTruncatedResponse[] = | 1185 static const char kTruncatedResponse[] = |
1152 "HTTP/1.1 101 Switching Protocols\r\n" | 1186 "HTTP/1.1 101 Switching Protocols\r\n" |
1153 "Upgrade: websocket\r\n" | 1187 "Upgrade: websocket\r\n" |
1154 "Connection: Upgrade\r\n" | 1188 "Connection: Upgrade\r\n" |
1155 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 1189 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
1156 "Cache-Control: no-sto"; | 1190 "Cache-Control: no-sto"; |
1157 | 1191 |
1158 std::string request = | 1192 std::string request = |
1159 WebSocketStandardRequest("/", "localhost", LocalhostOrigin(), ""); | 1193 WebSocketStandardRequest("/", "localhost", LocalhostOrigin(), "", ""); |
1160 MockRead reads[] = { | 1194 MockRead reads[] = { |
1161 MockRead(SYNCHRONOUS, 1, kTruncatedResponse), | 1195 MockRead(SYNCHRONOUS, 1, kTruncatedResponse), |
1162 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 2), | 1196 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 2), |
1163 }; | 1197 }; |
1164 MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, request.c_str())}; | 1198 MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, request.c_str())}; |
1165 std::unique_ptr<SequencedSocketData> socket_data( | 1199 std::unique_ptr<SequencedSocketData> socket_data( |
1166 BuildSocketData(reads, writes)); | 1200 BuildSocketData(reads, writes)); |
1167 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | 1201 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
1168 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 1202 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
1169 LocalhostOrigin(), std::move(socket_data)); | 1203 LocalhostOrigin(), "", |
| 1204 std::move(socket_data)); |
1170 WaitUntilConnectDone(); | 1205 WaitUntilConnectDone(); |
1171 EXPECT_TRUE(has_failed()); | 1206 EXPECT_TRUE(has_failed()); |
1172 } | 1207 } |
1173 | 1208 |
1174 TEST_F(WebSocketStreamCreateTest, HandleErrTunnelConnectionFailed) { | 1209 TEST_F(WebSocketStreamCreateTest, HandleErrTunnelConnectionFailed) { |
1175 static const char kConnectRequest[] = | 1210 static const char kConnectRequest[] = |
1176 "CONNECT localhost:80 HTTP/1.1\r\n" | 1211 "CONNECT localhost:80 HTTP/1.1\r\n" |
1177 "Host: localhost:80\r\n" | 1212 "Host: localhost:80\r\n" |
1178 "Proxy-Connection: keep-alive\r\n" | 1213 "Proxy-Connection: keep-alive\r\n" |
1179 "\r\n"; | 1214 "\r\n"; |
1180 | 1215 |
1181 static const char kProxyResponse[] = | 1216 static const char kProxyResponse[] = |
1182 "HTTP/1.1 403 Forbidden\r\n" | 1217 "HTTP/1.1 403 Forbidden\r\n" |
1183 "Content-Type: text/html\r\n" | 1218 "Content-Type: text/html\r\n" |
1184 "Content-Length: 9\r\n" | 1219 "Content-Length: 9\r\n" |
1185 "Connection: keep-alive\r\n" | 1220 "Connection: keep-alive\r\n" |
1186 "\r\n" | 1221 "\r\n" |
1187 "Forbidden"; | 1222 "Forbidden"; |
1188 | 1223 |
1189 MockRead reads[] = {MockRead(SYNCHRONOUS, 1, kProxyResponse)}; | 1224 MockRead reads[] = {MockRead(SYNCHRONOUS, 1, kProxyResponse)}; |
1190 MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, kConnectRequest)}; | 1225 MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, kConnectRequest)}; |
1191 std::unique_ptr<SequencedSocketData> socket_data( | 1226 std::unique_ptr<SequencedSocketData> socket_data( |
1192 BuildSocketData(reads, writes)); | 1227 BuildSocketData(reads, writes)); |
1193 url_request_context_host_.SetProxyConfig("https=proxy:8000"); | 1228 url_request_context_host_.SetProxyConfig("https=proxy:8000"); |
1194 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 1229 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
1195 LocalhostOrigin(), std::move(socket_data)); | 1230 LocalhostOrigin(), "", |
| 1231 std::move(socket_data)); |
1196 WaitUntilConnectDone(); | 1232 WaitUntilConnectDone(); |
1197 EXPECT_TRUE(has_failed()); | 1233 EXPECT_TRUE(has_failed()); |
1198 EXPECT_EQ("Establishing a tunnel via proxy server failed.", | 1234 EXPECT_EQ("Establishing a tunnel via proxy server failed.", |
1199 failure_message()); | 1235 failure_message()); |
1200 } | 1236 } |
1201 | 1237 |
1202 } // namespace | 1238 } // namespace |
1203 } // namespace net | 1239 } // namespace net |
OLD | NEW |