| 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 11 matching lines...) Expand all Loading... |
| 22 #include "net/base/test_data_directory.h" | 22 #include "net/base/test_data_directory.h" |
| 23 #include "net/http/http_request_headers.h" | 23 #include "net/http/http_request_headers.h" |
| 24 #include "net/http/http_response_headers.h" | 24 #include "net/http/http_response_headers.h" |
| 25 #include "net/proxy/proxy_service.h" | 25 #include "net/proxy/proxy_service.h" |
| 26 #include "net/socket/client_socket_handle.h" | 26 #include "net/socket/client_socket_handle.h" |
| 27 #include "net/socket/socket_test_util.h" | 27 #include "net/socket/socket_test_util.h" |
| 28 #include "net/test/cert_test_util.h" | 28 #include "net/test/cert_test_util.h" |
| 29 #include "net/url_request/url_request_test_util.h" | 29 #include "net/url_request/url_request_test_util.h" |
| 30 #include "net/websockets/websocket_basic_handshake_stream.h" | 30 #include "net/websockets/websocket_basic_handshake_stream.h" |
| 31 #include "net/websockets/websocket_frame.h" | 31 #include "net/websockets/websocket_frame.h" |
| 32 #include "net/websockets/websocket_handshake_request_info.h" | 32 #include "net/websockets/websocket_stream_create_test_base.h" |
| 33 #include "net/websockets/websocket_handshake_response_info.h" | |
| 34 #include "net/websockets/websocket_handshake_stream_create_helper.h" | |
| 35 #include "net/websockets/websocket_test_util.h" | 33 #include "net/websockets/websocket_test_util.h" |
| 36 #include "testing/gtest/include/gtest/gtest.h" | 34 #include "testing/gtest/include/gtest/gtest.h" |
| 37 #include "url/gurl.h" | 35 #include "url/gurl.h" |
| 38 #include "url/origin.h" | 36 #include "url/origin.h" |
| 39 | 37 |
| 40 namespace net { | 38 namespace net { |
| 41 namespace { | 39 namespace { |
| 42 | 40 |
| 43 typedef std::pair<std::string, std::string> HeaderKeyValuePair; | |
| 44 | |
| 45 std::vector<HeaderKeyValuePair> ToVector(const HttpRequestHeaders& headers) { | |
| 46 HttpRequestHeaders::Iterator it(headers); | |
| 47 std::vector<HeaderKeyValuePair> result; | |
| 48 while (it.GetNext()) | |
| 49 result.push_back(HeaderKeyValuePair(it.name(), it.value())); | |
| 50 return result; | |
| 51 } | |
| 52 | |
| 53 std::vector<HeaderKeyValuePair> ToVector(const HttpResponseHeaders& headers) { | |
| 54 void* iter = NULL; | |
| 55 std::string name, value; | |
| 56 std::vector<HeaderKeyValuePair> result; | |
| 57 while (headers.EnumerateHeaderLines(&iter, &name, &value)) | |
| 58 result.push_back(HeaderKeyValuePair(name, value)); | |
| 59 return result; | |
| 60 } | |
| 61 | |
| 62 // Simple builder for a DeterministicSocketData object to save repetitive code. | 41 // Simple builder for a DeterministicSocketData object to save repetitive code. |
| 63 // It always sets the connect data to MockConnect(SYNCHRONOUS, OK), so it cannot | 42 // It always sets the connect data to MockConnect(SYNCHRONOUS, OK), so it cannot |
| 64 // be used in tests where the connect fails. In practice, those tests never have | 43 // be used in tests where the connect fails. In practice, those tests never have |
| 65 // any read/write data and so can't benefit from it anyway. The arrays are not | 44 // any read/write data and so can't benefit from it anyway. The arrays are not |
| 66 // copied. It is up to the caller to ensure they stay in scope until the test | 45 // copied. It is up to the caller to ensure they stay in scope until the test |
| 67 // ends. | 46 // ends. |
| 68 template <size_t reads_count, size_t writes_count> | 47 template <size_t reads_count, size_t writes_count> |
| 69 scoped_ptr<DeterministicSocketData> BuildSocketData( | 48 scoped_ptr<DeterministicSocketData> BuildSocketData( |
| 70 MockRead (&reads)[reads_count], | 49 MockRead (&reads)[reads_count], |
| 71 MockWrite (&writes)[writes_count]) { | 50 MockWrite (&writes)[writes_count]) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 82 return make_scoped_ptr(new DeterministicSocketData(NULL, 0, NULL, 0)); | 61 return make_scoped_ptr(new DeterministicSocketData(NULL, 0, NULL, 0)); |
| 83 } | 62 } |
| 84 | 63 |
| 85 class MockWeakTimer : public base::MockTimer, | 64 class MockWeakTimer : public base::MockTimer, |
| 86 public base::SupportsWeakPtr<MockWeakTimer> { | 65 public base::SupportsWeakPtr<MockWeakTimer> { |
| 87 public: | 66 public: |
| 88 MockWeakTimer(bool retain_user_task, bool is_repeating) | 67 MockWeakTimer(bool retain_user_task, bool is_repeating) |
| 89 : MockTimer(retain_user_task, is_repeating) {} | 68 : MockTimer(retain_user_task, is_repeating) {} |
| 90 }; | 69 }; |
| 91 | 70 |
| 92 // A sub-class of WebSocketHandshakeStreamCreateHelper which always sets a | 71 class WebSocketStreamCreateTest : public ::testing::Test, |
| 93 // deterministic key to use in the WebSocket handshake. | 72 public WebSocketStreamCreateTestBase { |
| 94 class DeterministicKeyWebSocketHandshakeStreamCreateHelper | |
| 95 : public WebSocketHandshakeStreamCreateHelper { | |
| 96 public: | 73 public: |
| 97 DeterministicKeyWebSocketHandshakeStreamCreateHelper( | |
| 98 WebSocketStream::ConnectDelegate* connect_delegate, | |
| 99 const std::vector<std::string>& requested_subprotocols) | |
| 100 : WebSocketHandshakeStreamCreateHelper(connect_delegate, | |
| 101 requested_subprotocols) {} | |
| 102 | |
| 103 void OnStreamCreated(WebSocketBasicHandshakeStream* stream) override { | |
| 104 stream->SetWebSocketKeyForTesting("dGhlIHNhbXBsZSBub25jZQ=="); | |
| 105 } | |
| 106 }; | |
| 107 | |
| 108 class WebSocketStreamCreateTest : public ::testing::Test { | |
| 109 public: | |
| 110 WebSocketStreamCreateTest() : has_failed_(false), ssl_fatal_(false) {} | |
| 111 ~WebSocketStreamCreateTest() override { | 74 ~WebSocketStreamCreateTest() override { |
| 112 // Permit any endpoint locks to be released. | 75 // Permit any endpoint locks to be released. |
| 113 stream_request_.reset(); | 76 stream_request_.reset(); |
| 114 stream_.reset(); | 77 stream_.reset(); |
| 115 RunUntilIdle(); | 78 base::RunLoop().RunUntilIdle(); |
| 116 } | 79 } |
| 117 | 80 |
| 118 void CreateAndConnectCustomResponse( | 81 void CreateAndConnectCustomResponse( |
| 119 const std::string& socket_url, | 82 const std::string& socket_url, |
| 120 const std::string& socket_host, | 83 const std::string& socket_host, |
| 121 const std::string& socket_path, | 84 const std::string& socket_path, |
| 122 const std::vector<std::string>& sub_protocols, | 85 const std::vector<std::string>& sub_protocols, |
| 123 const std::string& origin, | 86 const std::string& origin, |
| 124 const std::string& extra_request_headers, | 87 const std::string& extra_request_headers, |
| 125 const std::string& response_body, | 88 const std::string& response_body, |
| (...skipping 29 matching lines...) Expand all Loading... |
| 155 scoped_ptr<DeterministicSocketData> socket_data, | 118 scoped_ptr<DeterministicSocketData> socket_data, |
| 156 scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) { | 119 scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) { |
| 157 AddRawExpectations(socket_data.Pass()); | 120 AddRawExpectations(socket_data.Pass()); |
| 158 CreateAndConnectStream(socket_url, sub_protocols, origin, timer.Pass()); | 121 CreateAndConnectStream(socket_url, sub_protocols, origin, timer.Pass()); |
| 159 } | 122 } |
| 160 | 123 |
| 161 // Add additional raw expectations for sockets created before the final one. | 124 // Add additional raw expectations for sockets created before the final one. |
| 162 void AddRawExpectations(scoped_ptr<DeterministicSocketData> socket_data) { | 125 void AddRawExpectations(scoped_ptr<DeterministicSocketData> socket_data) { |
| 163 url_request_context_host_.AddRawExpectations(socket_data.Pass()); | 126 url_request_context_host_.AddRawExpectations(socket_data.Pass()); |
| 164 } | 127 } |
| 165 | |
| 166 // A wrapper for CreateAndConnectStreamForTesting that knows about our default | |
| 167 // parameters. | |
| 168 void CreateAndConnectStream(const std::string& socket_url, | |
| 169 const std::vector<std::string>& sub_protocols, | |
| 170 const std::string& origin, | |
| 171 scoped_ptr<base::Timer> timer) { | |
| 172 for (size_t i = 0; i < ssl_data_.size(); ++i) { | |
| 173 scoped_ptr<SSLSocketDataProvider> ssl_data(ssl_data_[i]); | |
| 174 ssl_data_[i] = NULL; | |
| 175 url_request_context_host_.AddSSLSocketDataProvider(ssl_data.Pass()); | |
| 176 } | |
| 177 ssl_data_.clear(); | |
| 178 scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate( | |
| 179 new TestConnectDelegate(this)); | |
| 180 WebSocketStream::ConnectDelegate* delegate = connect_delegate.get(); | |
| 181 scoped_ptr<WebSocketHandshakeStreamCreateHelper> create_helper( | |
| 182 new DeterministicKeyWebSocketHandshakeStreamCreateHelper( | |
| 183 delegate, sub_protocols)); | |
| 184 stream_request_ = ::net::CreateAndConnectStreamForTesting( | |
| 185 GURL(socket_url), | |
| 186 create_helper.Pass(), | |
| 187 url::Origin(origin), | |
| 188 url_request_context_host_.GetURLRequestContext(), | |
| 189 BoundNetLog(), | |
| 190 connect_delegate.Pass(), | |
| 191 timer ? timer.Pass() : scoped_ptr<base::Timer>( | |
| 192 new base::Timer(false, false))); | |
| 193 } | |
| 194 | |
| 195 static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); } | |
| 196 | |
| 197 // A simple function to make the tests more readable. Creates an empty vector. | |
| 198 static std::vector<std::string> NoSubProtocols() { | |
| 199 return std::vector<std::string>(); | |
| 200 } | |
| 201 | |
| 202 const std::string& failure_message() const { return failure_message_; } | |
| 203 bool has_failed() const { return has_failed_; } | |
| 204 | |
| 205 class TestConnectDelegate : public WebSocketStream::ConnectDelegate { | |
| 206 public: | |
| 207 explicit TestConnectDelegate(WebSocketStreamCreateTest* owner) | |
| 208 : owner_(owner) {} | |
| 209 | |
| 210 void OnSuccess(scoped_ptr<WebSocketStream> stream) override { | |
| 211 stream.swap(owner_->stream_); | |
| 212 } | |
| 213 | |
| 214 void OnFailure(const std::string& message) override { | |
| 215 owner_->has_failed_ = true; | |
| 216 owner_->failure_message_ = message; | |
| 217 } | |
| 218 | |
| 219 void OnStartOpeningHandshake( | |
| 220 scoped_ptr<WebSocketHandshakeRequestInfo> request) override { | |
| 221 // Can be called multiple times (in the case of HTTP auth). Last call | |
| 222 // wins. | |
| 223 owner_->request_info_ = request.Pass(); | |
| 224 } | |
| 225 void OnFinishOpeningHandshake( | |
| 226 scoped_ptr<WebSocketHandshakeResponseInfo> response) override { | |
| 227 if (owner_->response_info_) | |
| 228 ADD_FAILURE(); | |
| 229 owner_->response_info_ = response.Pass(); | |
| 230 } | |
| 231 void OnSSLCertificateError( | |
| 232 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks> | |
| 233 ssl_error_callbacks, | |
| 234 const SSLInfo& ssl_info, | |
| 235 bool fatal) override { | |
| 236 owner_->ssl_error_callbacks_ = ssl_error_callbacks.Pass(); | |
| 237 owner_->ssl_info_ = ssl_info; | |
| 238 owner_->ssl_fatal_ = fatal; | |
| 239 } | |
| 240 | |
| 241 private: | |
| 242 WebSocketStreamCreateTest* owner_; | |
| 243 }; | |
| 244 | |
| 245 WebSocketTestURLRequestContextHost url_request_context_host_; | |
| 246 scoped_ptr<WebSocketStreamRequest> stream_request_; | |
| 247 // Only set if the connection succeeded. | |
| 248 scoped_ptr<WebSocketStream> stream_; | |
| 249 // Only set if the connection failed. | |
| 250 std::string failure_message_; | |
| 251 bool has_failed_; | |
| 252 scoped_ptr<WebSocketHandshakeRequestInfo> request_info_; | |
| 253 scoped_ptr<WebSocketHandshakeResponseInfo> response_info_; | |
| 254 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks> ssl_error_callbacks_; | |
| 255 SSLInfo ssl_info_; | |
| 256 bool ssl_fatal_; | |
| 257 ScopedVector<SSLSocketDataProvider> ssl_data_; | |
| 258 ScopedWebSocketEndpointZeroUnlockDelay zero_unlock_delay_; | |
| 259 }; | 128 }; |
| 260 | 129 |
| 261 // There are enough tests of the Sec-WebSocket-Extensions header that they | 130 // There are enough tests of the Sec-WebSocket-Extensions header that they |
| 262 // deserve their own test fixture. | 131 // deserve their own test fixture. |
| 263 class WebSocketStreamCreateExtensionTest : public WebSocketStreamCreateTest { | 132 class WebSocketStreamCreateExtensionTest : public WebSocketStreamCreateTest { |
| 264 public: | 133 public: |
| 265 // Performs a standard connect, with the value of the Sec-WebSocket-Extensions | 134 // Performs a standard connect, with the value of the Sec-WebSocket-Extensions |
| 266 // header in the response set to |extensions_header_value|. Runs the event | 135 // header in the response set to |extensions_header_value|. Runs the event |
| 267 // loop to allow the connect to complete. | 136 // loop to allow the connect to complete. |
| 268 void CreateAndConnectWithExtensions( | 137 void CreateAndConnectWithExtensions( |
| 269 const std::string& extensions_header_value) { | 138 const std::string& extensions_header_value) { |
| 270 CreateAndConnectStandard( | 139 CreateAndConnectStandard( |
| 271 "ws://localhost/testing_path", "localhost", "/testing_path", | 140 "ws://localhost/testing_path", "localhost", "/testing_path", |
| 272 NoSubProtocols(), "http://localhost", "", | 141 NoSubProtocols(), "http://localhost", "", |
| 273 "Sec-WebSocket-Extensions: " + extensions_header_value + "\r\n"); | 142 "Sec-WebSocket-Extensions: " + extensions_header_value + "\r\n"); |
| 274 RunUntilIdle(); | 143 WaitUntilConnectDone(); |
| 275 } | 144 } |
| 276 }; | 145 }; |
| 277 | 146 |
| 278 // Common code to construct expectations for authentication tests that receive | 147 // Common code to construct expectations for authentication tests that receive |
| 279 // the auth challenge on one connection and then create a second connection to | 148 // the auth challenge on one connection and then create a second connection to |
| 280 // send the authenticated request on. | 149 // send the authenticated request on. |
| 281 class CommonAuthTestHelper { | 150 class CommonAuthTestHelper { |
| 282 public: | 151 public: |
| 283 CommonAuthTestHelper() : reads1_(), writes1_(), reads2_(), writes2_() {} | 152 CommonAuthTestHelper() : reads1_(), writes1_(), reads2_(), writes2_() {} |
| 284 | 153 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 : scoped_ptr<base::HistogramSamples>(); | 292 : scoped_ptr<base::HistogramSamples>(); |
| 424 } | 293 } |
| 425 }; | 294 }; |
| 426 | 295 |
| 427 // Confirm that the basic case works as expected. | 296 // Confirm that the basic case works as expected. |
| 428 TEST_F(WebSocketStreamCreateTest, SimpleSuccess) { | 297 TEST_F(WebSocketStreamCreateTest, SimpleSuccess) { |
| 429 CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 298 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 430 NoSubProtocols(), "http://localhost", "", ""); | 299 NoSubProtocols(), "http://localhost", "", ""); |
| 431 EXPECT_FALSE(request_info_); | 300 EXPECT_FALSE(request_info_); |
| 432 EXPECT_FALSE(response_info_); | 301 EXPECT_FALSE(response_info_); |
| 433 RunUntilIdle(); | 302 WaitUntilConnectDone(); |
| 434 EXPECT_FALSE(has_failed()); | 303 EXPECT_FALSE(has_failed()); |
| 435 EXPECT_TRUE(stream_); | 304 EXPECT_TRUE(stream_); |
| 436 EXPECT_TRUE(request_info_); | 305 EXPECT_TRUE(request_info_); |
| 437 EXPECT_TRUE(response_info_); | 306 EXPECT_TRUE(response_info_); |
| 438 } | 307 } |
| 439 | 308 |
| 440 TEST_F(WebSocketStreamCreateTest, HandshakeInfo) { | 309 TEST_F(WebSocketStreamCreateTest, HandshakeInfo) { |
| 441 static const char kResponse[] = | 310 static const char kResponse[] = |
| 442 "HTTP/1.1 101 Switching Protocols\r\n" | 311 "HTTP/1.1 101 Switching Protocols\r\n" |
| 443 "Upgrade: websocket\r\n" | 312 "Upgrade: websocket\r\n" |
| 444 "Connection: Upgrade\r\n" | 313 "Connection: Upgrade\r\n" |
| 445 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 314 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 446 "foo: bar, baz\r\n" | 315 "foo: bar, baz\r\n" |
| 447 "hoge: fuga\r\n" | 316 "hoge: fuga\r\n" |
| 448 "hoge: piyo\r\n" | 317 "hoge: piyo\r\n" |
| 449 "\r\n"; | 318 "\r\n"; |
| 450 | 319 |
| 451 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 320 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 452 NoSubProtocols(), "http://localhost", "", | 321 NoSubProtocols(), "http://localhost", "", |
| 453 kResponse); | 322 kResponse); |
| 454 EXPECT_FALSE(request_info_); | 323 EXPECT_FALSE(request_info_); |
| 455 EXPECT_FALSE(response_info_); | 324 EXPECT_FALSE(response_info_); |
| 456 RunUntilIdle(); | 325 WaitUntilConnectDone(); |
| 457 EXPECT_TRUE(stream_); | 326 EXPECT_TRUE(stream_); |
| 458 ASSERT_TRUE(request_info_); | 327 ASSERT_TRUE(request_info_); |
| 459 ASSERT_TRUE(response_info_); | 328 ASSERT_TRUE(response_info_); |
| 460 std::vector<HeaderKeyValuePair> request_headers = | 329 std::vector<HeaderKeyValuePair> request_headers = |
| 461 ToVector(request_info_->headers); | 330 RequestHeadersToVector(request_info_->headers); |
| 462 // We examine the contents of request_info_ and response_info_ | 331 // We examine the contents of request_info_ and response_info_ |
| 463 // mainly only in this test case. | 332 // mainly only in this test case. |
| 464 EXPECT_EQ(GURL("ws://localhost/"), request_info_->url); | 333 EXPECT_EQ(GURL("ws://localhost/"), request_info_->url); |
| 465 EXPECT_EQ(GURL("ws://localhost/"), response_info_->url); | 334 EXPECT_EQ(GURL("ws://localhost/"), response_info_->url); |
| 466 EXPECT_EQ(101, response_info_->status_code); | 335 EXPECT_EQ(101, response_info_->status_code); |
| 467 EXPECT_EQ("Switching Protocols", response_info_->status_text); | 336 EXPECT_EQ("Switching Protocols", response_info_->status_text); |
| 468 ASSERT_EQ(12u, request_headers.size()); | 337 ASSERT_EQ(12u, request_headers.size()); |
| 469 EXPECT_EQ(HeaderKeyValuePair("Host", "localhost"), request_headers[0]); | 338 EXPECT_EQ(HeaderKeyValuePair("Host", "localhost"), request_headers[0]); |
| 470 EXPECT_EQ(HeaderKeyValuePair("Connection", "Upgrade"), request_headers[1]); | 339 EXPECT_EQ(HeaderKeyValuePair("Connection", "Upgrade"), request_headers[1]); |
| 471 EXPECT_EQ(HeaderKeyValuePair("Pragma", "no-cache"), request_headers[2]); | 340 EXPECT_EQ(HeaderKeyValuePair("Pragma", "no-cache"), request_headers[2]); |
| 472 EXPECT_EQ(HeaderKeyValuePair("Cache-Control", "no-cache"), | 341 EXPECT_EQ(HeaderKeyValuePair("Cache-Control", "no-cache"), |
| 473 request_headers[3]); | 342 request_headers[3]); |
| 474 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), request_headers[4]); | 343 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), request_headers[4]); |
| 475 EXPECT_EQ(HeaderKeyValuePair("Origin", "http://localhost"), | 344 EXPECT_EQ(HeaderKeyValuePair("Origin", "http://localhost"), |
| 476 request_headers[5]); | 345 request_headers[5]); |
| 477 EXPECT_EQ(HeaderKeyValuePair("Sec-WebSocket-Version", "13"), | 346 EXPECT_EQ(HeaderKeyValuePair("Sec-WebSocket-Version", "13"), |
| 478 request_headers[6]); | 347 request_headers[6]); |
| 479 EXPECT_EQ(HeaderKeyValuePair("User-Agent", ""), request_headers[7]); | 348 EXPECT_EQ(HeaderKeyValuePair("User-Agent", ""), request_headers[7]); |
| 480 EXPECT_EQ(HeaderKeyValuePair("Accept-Encoding", "gzip, deflate"), | 349 EXPECT_EQ(HeaderKeyValuePair("Accept-Encoding", "gzip, deflate"), |
| 481 request_headers[8]); | 350 request_headers[8]); |
| 482 EXPECT_EQ(HeaderKeyValuePair("Accept-Language", "en-us,fr"), | 351 EXPECT_EQ(HeaderKeyValuePair("Accept-Language", "en-us,fr"), |
| 483 request_headers[9]); | 352 request_headers[9]); |
| 484 EXPECT_EQ("Sec-WebSocket-Key", request_headers[10].first); | 353 EXPECT_EQ("Sec-WebSocket-Key", request_headers[10].first); |
| 485 EXPECT_EQ(HeaderKeyValuePair("Sec-WebSocket-Extensions", | 354 EXPECT_EQ(HeaderKeyValuePair("Sec-WebSocket-Extensions", |
| 486 "permessage-deflate; client_max_window_bits"), | 355 "permessage-deflate; client_max_window_bits"), |
| 487 request_headers[11]); | 356 request_headers[11]); |
| 488 | 357 |
| 489 std::vector<HeaderKeyValuePair> response_headers = | 358 std::vector<HeaderKeyValuePair> response_headers = |
| 490 ToVector(*response_info_->headers.get()); | 359 ResponseHeadersToVector(*response_info_->headers.get()); |
| 491 ASSERT_EQ(6u, response_headers.size()); | 360 ASSERT_EQ(6u, response_headers.size()); |
| 492 // Sort the headers for ease of verification. | 361 // Sort the headers for ease of verification. |
| 493 std::sort(response_headers.begin(), response_headers.end()); | 362 std::sort(response_headers.begin(), response_headers.end()); |
| 494 | 363 |
| 495 EXPECT_EQ(HeaderKeyValuePair("Connection", "Upgrade"), response_headers[0]); | 364 EXPECT_EQ(HeaderKeyValuePair("Connection", "Upgrade"), response_headers[0]); |
| 496 EXPECT_EQ("Sec-WebSocket-Accept", response_headers[1].first); | 365 EXPECT_EQ("Sec-WebSocket-Accept", response_headers[1].first); |
| 497 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), response_headers[2]); | 366 EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), response_headers[2]); |
| 498 EXPECT_EQ(HeaderKeyValuePair("foo", "bar, baz"), response_headers[3]); | 367 EXPECT_EQ(HeaderKeyValuePair("foo", "bar, baz"), response_headers[3]); |
| 499 EXPECT_EQ(HeaderKeyValuePair("hoge", "fuga"), response_headers[4]); | 368 EXPECT_EQ(HeaderKeyValuePair("hoge", "fuga"), response_headers[4]); |
| 500 EXPECT_EQ(HeaderKeyValuePair("hoge", "piyo"), response_headers[5]); | 369 EXPECT_EQ(HeaderKeyValuePair("hoge", "piyo"), response_headers[5]); |
| 501 } | 370 } |
| 502 | 371 |
| 503 // Confirm that the stream isn't established until the message loop runs. | 372 // Confirm that the stream isn't established until the message loop runs. |
| 504 TEST_F(WebSocketStreamCreateTest, NeedsToRunLoop) { | 373 TEST_F(WebSocketStreamCreateTest, NeedsToRunLoop) { |
| 505 CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 374 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 506 NoSubProtocols(), "http://localhost", "", ""); | 375 NoSubProtocols(), "http://localhost", "", ""); |
| 507 EXPECT_FALSE(has_failed()); | 376 EXPECT_FALSE(has_failed()); |
| 508 EXPECT_FALSE(stream_); | 377 EXPECT_FALSE(stream_); |
| 509 } | 378 } |
| 510 | 379 |
| 511 // Check the path is used. | 380 // Check the path is used. |
| 512 TEST_F(WebSocketStreamCreateTest, PathIsUsed) { | 381 TEST_F(WebSocketStreamCreateTest, PathIsUsed) { |
| 513 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 382 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 514 "/testing_path", NoSubProtocols(), | 383 "/testing_path", NoSubProtocols(), |
| 515 "http://localhost", "", ""); | 384 "http://localhost", "", ""); |
| 516 RunUntilIdle(); | 385 WaitUntilConnectDone(); |
| 517 EXPECT_FALSE(has_failed()); | 386 EXPECT_FALSE(has_failed()); |
| 518 EXPECT_TRUE(stream_); | 387 EXPECT_TRUE(stream_); |
| 519 } | 388 } |
| 520 | 389 |
| 521 // Check that the origin is used. | 390 // Check that the origin is used. |
| 522 TEST_F(WebSocketStreamCreateTest, OriginIsUsed) { | 391 TEST_F(WebSocketStreamCreateTest, OriginIsUsed) { |
| 523 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 392 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 524 "/testing_path", NoSubProtocols(), | 393 "/testing_path", NoSubProtocols(), |
| 525 "http://google.com", "", ""); | 394 "http://google.com", "", ""); |
| 526 RunUntilIdle(); | 395 WaitUntilConnectDone(); |
| 527 EXPECT_FALSE(has_failed()); | 396 EXPECT_FALSE(has_failed()); |
| 528 EXPECT_TRUE(stream_); | 397 EXPECT_TRUE(stream_); |
| 529 } | 398 } |
| 530 | 399 |
| 531 // Check that sub-protocols are sent and parsed. | 400 // Check that sub-protocols are sent and parsed. |
| 532 TEST_F(WebSocketStreamCreateTest, SubProtocolIsUsed) { | 401 TEST_F(WebSocketStreamCreateTest, SubProtocolIsUsed) { |
| 533 std::vector<std::string> sub_protocols; | 402 std::vector<std::string> sub_protocols; |
| 534 sub_protocols.push_back("chatv11.chromium.org"); | 403 sub_protocols.push_back("chatv11.chromium.org"); |
| 535 sub_protocols.push_back("chatv20.chromium.org"); | 404 sub_protocols.push_back("chatv20.chromium.org"); |
| 536 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 405 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 537 "/testing_path", sub_protocols, "http://google.com", | 406 "/testing_path", sub_protocols, "http://google.com", |
| 538 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 407 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
| 539 "chatv20.chromium.org\r\n", | 408 "chatv20.chromium.org\r\n", |
| 540 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); | 409 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); |
| 541 RunUntilIdle(); | 410 WaitUntilConnectDone(); |
| 542 EXPECT_TRUE(stream_); | 411 EXPECT_TRUE(stream_); |
| 543 EXPECT_FALSE(has_failed()); | 412 EXPECT_FALSE(has_failed()); |
| 544 EXPECT_EQ("chatv20.chromium.org", stream_->GetSubProtocol()); | 413 EXPECT_EQ("chatv20.chromium.org", stream_->GetSubProtocol()); |
| 545 } | 414 } |
| 546 | 415 |
| 547 // Unsolicited sub-protocols are rejected. | 416 // Unsolicited sub-protocols are rejected. |
| 548 TEST_F(WebSocketStreamCreateTest, UnsolicitedSubProtocol) { | 417 TEST_F(WebSocketStreamCreateTest, UnsolicitedSubProtocol) { |
| 549 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 418 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 550 "/testing_path", NoSubProtocols(), | 419 "/testing_path", NoSubProtocols(), |
| 551 "http://google.com", "", | 420 "http://google.com", "", |
| 552 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); | 421 "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n"); |
| 553 RunUntilIdle(); | 422 WaitUntilConnectDone(); |
| 554 EXPECT_FALSE(stream_); | 423 EXPECT_FALSE(stream_); |
| 555 EXPECT_TRUE(has_failed()); | 424 EXPECT_TRUE(has_failed()); |
| 556 EXPECT_EQ("Error during WebSocket handshake: " | 425 EXPECT_EQ("Error during WebSocket handshake: " |
| 557 "Response must not include 'Sec-WebSocket-Protocol' header " | 426 "Response must not include 'Sec-WebSocket-Protocol' header " |
| 558 "if not present in request: chatv20.chromium.org", | 427 "if not present in request: chatv20.chromium.org", |
| 559 failure_message()); | 428 failure_message()); |
| 560 } | 429 } |
| 561 | 430 |
| 562 // Missing sub-protocol response is rejected. | 431 // Missing sub-protocol response is rejected. |
| 563 TEST_F(WebSocketStreamCreateTest, UnacceptedSubProtocol) { | 432 TEST_F(WebSocketStreamCreateTest, UnacceptedSubProtocol) { |
| 564 std::vector<std::string> sub_protocols; | 433 std::vector<std::string> sub_protocols; |
| 565 sub_protocols.push_back("chat.example.com"); | 434 sub_protocols.push_back("chat.example.com"); |
| 566 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 435 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 567 "/testing_path", sub_protocols, "http://localhost", | 436 "/testing_path", sub_protocols, "http://localhost", |
| 568 "Sec-WebSocket-Protocol: chat.example.com\r\n", ""); | 437 "Sec-WebSocket-Protocol: chat.example.com\r\n", ""); |
| 569 RunUntilIdle(); | 438 WaitUntilConnectDone(); |
| 570 EXPECT_FALSE(stream_); | 439 EXPECT_FALSE(stream_); |
| 571 EXPECT_TRUE(has_failed()); | 440 EXPECT_TRUE(has_failed()); |
| 572 EXPECT_EQ("Error during WebSocket handshake: " | 441 EXPECT_EQ("Error during WebSocket handshake: " |
| 573 "Sent non-empty 'Sec-WebSocket-Protocol' header " | 442 "Sent non-empty 'Sec-WebSocket-Protocol' header " |
| 574 "but no response was received", | 443 "but no response was received", |
| 575 failure_message()); | 444 failure_message()); |
| 576 } | 445 } |
| 577 | 446 |
| 578 // Only one sub-protocol can be accepted. | 447 // Only one sub-protocol can be accepted. |
| 579 TEST_F(WebSocketStreamCreateTest, MultipleSubProtocolsInResponse) { | 448 TEST_F(WebSocketStreamCreateTest, MultipleSubProtocolsInResponse) { |
| 580 std::vector<std::string> sub_protocols; | 449 std::vector<std::string> sub_protocols; |
| 581 sub_protocols.push_back("chatv11.chromium.org"); | 450 sub_protocols.push_back("chatv11.chromium.org"); |
| 582 sub_protocols.push_back("chatv20.chromium.org"); | 451 sub_protocols.push_back("chatv20.chromium.org"); |
| 583 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 452 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 584 "/testing_path", sub_protocols, "http://google.com", | 453 "/testing_path", sub_protocols, "http://google.com", |
| 585 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 454 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
| 586 "chatv20.chromium.org\r\n", | 455 "chatv20.chromium.org\r\n", |
| 587 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 456 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
| 588 "chatv20.chromium.org\r\n"); | 457 "chatv20.chromium.org\r\n"); |
| 589 RunUntilIdle(); | 458 WaitUntilConnectDone(); |
| 590 EXPECT_FALSE(stream_); | 459 EXPECT_FALSE(stream_); |
| 591 EXPECT_TRUE(has_failed()); | 460 EXPECT_TRUE(has_failed()); |
| 592 EXPECT_EQ("Error during WebSocket handshake: " | 461 EXPECT_EQ("Error during WebSocket handshake: " |
| 593 "'Sec-WebSocket-Protocol' header must not appear " | 462 "'Sec-WebSocket-Protocol' header must not appear " |
| 594 "more than once in a response", | 463 "more than once in a response", |
| 595 failure_message()); | 464 failure_message()); |
| 596 } | 465 } |
| 597 | 466 |
| 598 // Unmatched sub-protocol should be rejected. | 467 // Unmatched sub-protocol should be rejected. |
| 599 TEST_F(WebSocketStreamCreateTest, UnmatchedSubProtocolInResponse) { | 468 TEST_F(WebSocketStreamCreateTest, UnmatchedSubProtocolInResponse) { |
| 600 std::vector<std::string> sub_protocols; | 469 std::vector<std::string> sub_protocols; |
| 601 sub_protocols.push_back("chatv11.chromium.org"); | 470 sub_protocols.push_back("chatv11.chromium.org"); |
| 602 sub_protocols.push_back("chatv20.chromium.org"); | 471 sub_protocols.push_back("chatv20.chromium.org"); |
| 603 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", | 472 CreateAndConnectStandard("ws://localhost/testing_path", "localhost", |
| 604 "/testing_path", sub_protocols, "http://google.com", | 473 "/testing_path", sub_protocols, "http://google.com", |
| 605 "Sec-WebSocket-Protocol: chatv11.chromium.org, " | 474 "Sec-WebSocket-Protocol: chatv11.chromium.org, " |
| 606 "chatv20.chromium.org\r\n", | 475 "chatv20.chromium.org\r\n", |
| 607 "Sec-WebSocket-Protocol: chatv21.chromium.org\r\n"); | 476 "Sec-WebSocket-Protocol: chatv21.chromium.org\r\n"); |
| 608 RunUntilIdle(); | 477 WaitUntilConnectDone(); |
| 609 EXPECT_FALSE(stream_); | 478 EXPECT_FALSE(stream_); |
| 610 EXPECT_TRUE(has_failed()); | 479 EXPECT_TRUE(has_failed()); |
| 611 EXPECT_EQ("Error during WebSocket handshake: " | 480 EXPECT_EQ("Error during WebSocket handshake: " |
| 612 "'Sec-WebSocket-Protocol' header value 'chatv21.chromium.org' " | 481 "'Sec-WebSocket-Protocol' header value 'chatv21.chromium.org' " |
| 613 "in response does not match any of sent values", | 482 "in response does not match any of sent values", |
| 614 failure_message()); | 483 failure_message()); |
| 615 } | 484 } |
| 616 | 485 |
| 617 // permessage-deflate extension basic success case. | 486 // permessage-deflate extension basic success case. |
| 618 TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateSuccess) { | 487 TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateSuccess) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 636 TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateInflates) { | 505 TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateInflates) { |
| 637 CreateAndConnectCustomResponse( | 506 CreateAndConnectCustomResponse( |
| 638 "ws://localhost/testing_path", "localhost", "/testing_path", | 507 "ws://localhost/testing_path", "localhost", "/testing_path", |
| 639 NoSubProtocols(), "http://localhost", "", | 508 NoSubProtocols(), "http://localhost", "", |
| 640 WebSocketStandardResponse( | 509 WebSocketStandardResponse( |
| 641 "Sec-WebSocket-Extensions: permessage-deflate\r\n") + | 510 "Sec-WebSocket-Extensions: permessage-deflate\r\n") + |
| 642 std::string( | 511 std::string( |
| 643 "\xc1\x07" // WebSocket header (FIN + RSV1, Text payload 7 bytes) | 512 "\xc1\x07" // WebSocket header (FIN + RSV1, Text payload 7 bytes) |
| 644 "\xf2\x48\xcd\xc9\xc9\x07\x00", // "Hello" DEFLATE compressed | 513 "\xf2\x48\xcd\xc9\xc9\x07\x00", // "Hello" DEFLATE compressed |
| 645 9)); | 514 9)); |
| 646 RunUntilIdle(); | 515 WaitUntilConnectDone(); |
| 647 | 516 |
| 648 ASSERT_TRUE(stream_); | 517 ASSERT_TRUE(stream_); |
| 649 ScopedVector<WebSocketFrame> frames; | 518 ScopedVector<WebSocketFrame> frames; |
| 650 CompletionCallback callback; | 519 CompletionCallback callback; |
| 651 ASSERT_EQ(OK, stream_->ReadFrames(&frames, callback)); | 520 ASSERT_EQ(OK, stream_->ReadFrames(&frames, callback)); |
| 652 ASSERT_EQ(1U, frames.size()); | 521 ASSERT_EQ(1U, frames.size()); |
| 653 ASSERT_EQ(5U, frames[0]->header.payload_length); | 522 ASSERT_EQ(5U, frames[0]->header.payload_length); |
| 654 EXPECT_EQ("Hello", std::string(frames[0]->data->data(), 5)); | 523 EXPECT_EQ("Hello", std::string(frames[0]->data->data(), 5)); |
| 655 } | 524 } |
| 656 | 525 |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 | 682 |
| 814 // TODO(ricea): Check that WebSocketDeflateStream is initialised with the | 683 // TODO(ricea): Check that WebSocketDeflateStream is initialised with the |
| 815 // arguments from the server. This is difficult because the data written to the | 684 // arguments from the server. This is difficult because the data written to the |
| 816 // socket is randomly masked. | 685 // socket is randomly masked. |
| 817 | 686 |
| 818 // Additional Sec-WebSocket-Accept headers should be rejected. | 687 // Additional Sec-WebSocket-Accept headers should be rejected. |
| 819 TEST_F(WebSocketStreamCreateTest, DoubleAccept) { | 688 TEST_F(WebSocketStreamCreateTest, DoubleAccept) { |
| 820 CreateAndConnectStandard( | 689 CreateAndConnectStandard( |
| 821 "ws://localhost/", "localhost", "/", NoSubProtocols(), "http://localhost", | 690 "ws://localhost/", "localhost", "/", NoSubProtocols(), "http://localhost", |
| 822 "", "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"); | 691 "", "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"); |
| 823 RunUntilIdle(); | 692 WaitUntilConnectDone(); |
| 824 EXPECT_FALSE(stream_); | 693 EXPECT_FALSE(stream_); |
| 825 EXPECT_TRUE(has_failed()); | 694 EXPECT_TRUE(has_failed()); |
| 826 EXPECT_EQ("Error during WebSocket handshake: " | 695 EXPECT_EQ("Error during WebSocket handshake: " |
| 827 "'Sec-WebSocket-Accept' header must not appear " | 696 "'Sec-WebSocket-Accept' header must not appear " |
| 828 "more than once in a response", | 697 "more than once in a response", |
| 829 failure_message()); | 698 failure_message()); |
| 830 } | 699 } |
| 831 | 700 |
| 832 // Response code 200 must be rejected. | 701 // Response code 200 must be rejected. |
| 833 TEST_F(WebSocketStreamCreateTest, InvalidStatusCode) { | 702 TEST_F(WebSocketStreamCreateTest, InvalidStatusCode) { |
| 834 static const char kInvalidStatusCodeResponse[] = | 703 static const char kInvalidStatusCodeResponse[] = |
| 835 "HTTP/1.1 200 OK\r\n" | 704 "HTTP/1.1 200 OK\r\n" |
| 836 "Upgrade: websocket\r\n" | 705 "Upgrade: websocket\r\n" |
| 837 "Connection: Upgrade\r\n" | 706 "Connection: Upgrade\r\n" |
| 838 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 707 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 839 "\r\n"; | 708 "\r\n"; |
| 840 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 709 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 841 NoSubProtocols(), "http://localhost", "", | 710 NoSubProtocols(), "http://localhost", "", |
| 842 kInvalidStatusCodeResponse); | 711 kInvalidStatusCodeResponse); |
| 843 RunUntilIdle(); | 712 WaitUntilConnectDone(); |
| 844 EXPECT_TRUE(has_failed()); | 713 EXPECT_TRUE(has_failed()); |
| 845 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 200", | 714 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 200", |
| 846 failure_message()); | 715 failure_message()); |
| 847 } | 716 } |
| 848 | 717 |
| 849 // Redirects are not followed (according to the WHATWG WebSocket API, which | 718 // Redirects are not followed (according to the WHATWG WebSocket API, which |
| 850 // overrides RFC6455 for browser applications). | 719 // overrides RFC6455 for browser applications). |
| 851 TEST_F(WebSocketStreamCreateTest, RedirectsRejected) { | 720 TEST_F(WebSocketStreamCreateTest, RedirectsRejected) { |
| 852 static const char kRedirectResponse[] = | 721 static const char kRedirectResponse[] = |
| 853 "HTTP/1.1 302 Moved Temporarily\r\n" | 722 "HTTP/1.1 302 Moved Temporarily\r\n" |
| 854 "Content-Type: text/html\r\n" | 723 "Content-Type: text/html\r\n" |
| 855 "Content-Length: 34\r\n" | 724 "Content-Length: 34\r\n" |
| 856 "Connection: keep-alive\r\n" | 725 "Connection: keep-alive\r\n" |
| 857 "Location: ws://localhost/other\r\n" | 726 "Location: ws://localhost/other\r\n" |
| 858 "\r\n" | 727 "\r\n" |
| 859 "<title>Moved</title><h1>Moved</h1>"; | 728 "<title>Moved</title><h1>Moved</h1>"; |
| 860 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 729 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 861 NoSubProtocols(), "http://localhost", "", | 730 NoSubProtocols(), "http://localhost", "", |
| 862 kRedirectResponse); | 731 kRedirectResponse); |
| 863 RunUntilIdle(); | 732 WaitUntilConnectDone(); |
| 864 EXPECT_TRUE(has_failed()); | 733 EXPECT_TRUE(has_failed()); |
| 865 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 302", | 734 EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 302", |
| 866 failure_message()); | 735 failure_message()); |
| 867 } | 736 } |
| 868 | 737 |
| 869 // Malformed responses should be rejected. HttpStreamParser will accept just | 738 // Malformed responses should be rejected. HttpStreamParser will accept just |
| 870 // about any garbage in the middle of the headers. To make it give up, the junk | 739 // about any garbage in the middle of the headers. To make it give up, the junk |
| 871 // has to be at the start of the response. Even then, it just gets treated as an | 740 // has to be at the start of the response. Even then, it just gets treated as an |
| 872 // HTTP/0.9 response. | 741 // HTTP/0.9 response. |
| 873 TEST_F(WebSocketStreamCreateTest, MalformedResponse) { | 742 TEST_F(WebSocketStreamCreateTest, MalformedResponse) { |
| 874 static const char kMalformedResponse[] = | 743 static const char kMalformedResponse[] = |
| 875 "220 mx.google.com ESMTP\r\n" | 744 "220 mx.google.com ESMTP\r\n" |
| 876 "HTTP/1.1 101 OK\r\n" | 745 "HTTP/1.1 101 OK\r\n" |
| 877 "Upgrade: websocket\r\n" | 746 "Upgrade: websocket\r\n" |
| 878 "Connection: Upgrade\r\n" | 747 "Connection: Upgrade\r\n" |
| 879 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 748 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 880 "\r\n"; | 749 "\r\n"; |
| 881 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 750 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 882 NoSubProtocols(), "http://localhost", "", | 751 NoSubProtocols(), "http://localhost", "", |
| 883 kMalformedResponse); | 752 kMalformedResponse); |
| 884 RunUntilIdle(); | 753 WaitUntilConnectDone(); |
| 885 EXPECT_TRUE(has_failed()); | 754 EXPECT_TRUE(has_failed()); |
| 886 EXPECT_EQ("Error during WebSocket handshake: Invalid status line", | 755 EXPECT_EQ("Error during WebSocket handshake: Invalid status line", |
| 887 failure_message()); | 756 failure_message()); |
| 888 } | 757 } |
| 889 | 758 |
| 890 // Upgrade header must be present. | 759 // Upgrade header must be present. |
| 891 TEST_F(WebSocketStreamCreateTest, MissingUpgradeHeader) { | 760 TEST_F(WebSocketStreamCreateTest, MissingUpgradeHeader) { |
| 892 static const char kMissingUpgradeResponse[] = | 761 static const char kMissingUpgradeResponse[] = |
| 893 "HTTP/1.1 101 Switching Protocols\r\n" | 762 "HTTP/1.1 101 Switching Protocols\r\n" |
| 894 "Connection: Upgrade\r\n" | 763 "Connection: Upgrade\r\n" |
| 895 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 764 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 896 "\r\n"; | 765 "\r\n"; |
| 897 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 766 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 898 NoSubProtocols(), "http://localhost", "", | 767 NoSubProtocols(), "http://localhost", "", |
| 899 kMissingUpgradeResponse); | 768 kMissingUpgradeResponse); |
| 900 RunUntilIdle(); | 769 WaitUntilConnectDone(); |
| 901 EXPECT_TRUE(has_failed()); | 770 EXPECT_TRUE(has_failed()); |
| 902 EXPECT_EQ("Error during WebSocket handshake: 'Upgrade' header is missing", | 771 EXPECT_EQ("Error during WebSocket handshake: 'Upgrade' header is missing", |
| 903 failure_message()); | 772 failure_message()); |
| 904 } | 773 } |
| 905 | 774 |
| 906 // There must only be one upgrade header. | 775 // There must only be one upgrade header. |
| 907 TEST_F(WebSocketStreamCreateTest, DoubleUpgradeHeader) { | 776 TEST_F(WebSocketStreamCreateTest, DoubleUpgradeHeader) { |
| 908 CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 777 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 909 NoSubProtocols(), "http://localhost", "", | 778 NoSubProtocols(), "http://localhost", "", |
| 910 "Upgrade: HTTP/2.0\r\n"); | 779 "Upgrade: HTTP/2.0\r\n"); |
| 911 RunUntilIdle(); | 780 WaitUntilConnectDone(); |
| 912 EXPECT_TRUE(has_failed()); | 781 EXPECT_TRUE(has_failed()); |
| 913 EXPECT_EQ("Error during WebSocket handshake: " | 782 EXPECT_EQ("Error during WebSocket handshake: " |
| 914 "'Upgrade' header must not appear more than once in a response", | 783 "'Upgrade' header must not appear more than once in a response", |
| 915 failure_message()); | 784 failure_message()); |
| 916 } | 785 } |
| 917 | 786 |
| 918 // There must only be one correct upgrade header. | 787 // There must only be one correct upgrade header. |
| 919 TEST_F(WebSocketStreamCreateTest, IncorrectUpgradeHeader) { | 788 TEST_F(WebSocketStreamCreateTest, IncorrectUpgradeHeader) { |
| 920 static const char kMissingUpgradeResponse[] = | 789 static const char kMissingUpgradeResponse[] = |
| 921 "HTTP/1.1 101 Switching Protocols\r\n" | 790 "HTTP/1.1 101 Switching Protocols\r\n" |
| 922 "Connection: Upgrade\r\n" | 791 "Connection: Upgrade\r\n" |
| 923 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 792 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 924 "Upgrade: hogefuga\r\n" | 793 "Upgrade: hogefuga\r\n" |
| 925 "\r\n"; | 794 "\r\n"; |
| 926 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 795 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 927 NoSubProtocols(), "http://localhost", "", | 796 NoSubProtocols(), "http://localhost", "", |
| 928 kMissingUpgradeResponse); | 797 kMissingUpgradeResponse); |
| 929 RunUntilIdle(); | 798 WaitUntilConnectDone(); |
| 930 EXPECT_TRUE(has_failed()); | 799 EXPECT_TRUE(has_failed()); |
| 931 EXPECT_EQ("Error during WebSocket handshake: " | 800 EXPECT_EQ("Error during WebSocket handshake: " |
| 932 "'Upgrade' header value is not 'WebSocket': hogefuga", | 801 "'Upgrade' header value is not 'WebSocket': hogefuga", |
| 933 failure_message()); | 802 failure_message()); |
| 934 } | 803 } |
| 935 | 804 |
| 936 // Connection header must be present. | 805 // Connection header must be present. |
| 937 TEST_F(WebSocketStreamCreateTest, MissingConnectionHeader) { | 806 TEST_F(WebSocketStreamCreateTest, MissingConnectionHeader) { |
| 938 static const char kMissingConnectionResponse[] = | 807 static const char kMissingConnectionResponse[] = |
| 939 "HTTP/1.1 101 Switching Protocols\r\n" | 808 "HTTP/1.1 101 Switching Protocols\r\n" |
| 940 "Upgrade: websocket\r\n" | 809 "Upgrade: websocket\r\n" |
| 941 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 810 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 942 "\r\n"; | 811 "\r\n"; |
| 943 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 812 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 944 NoSubProtocols(), "http://localhost", "", | 813 NoSubProtocols(), "http://localhost", "", |
| 945 kMissingConnectionResponse); | 814 kMissingConnectionResponse); |
| 946 RunUntilIdle(); | 815 WaitUntilConnectDone(); |
| 947 EXPECT_TRUE(has_failed()); | 816 EXPECT_TRUE(has_failed()); |
| 948 EXPECT_EQ("Error during WebSocket handshake: " | 817 EXPECT_EQ("Error during WebSocket handshake: " |
| 949 "'Connection' header is missing", | 818 "'Connection' header is missing", |
| 950 failure_message()); | 819 failure_message()); |
| 951 } | 820 } |
| 952 | 821 |
| 953 // Connection header must contain "Upgrade". | 822 // Connection header must contain "Upgrade". |
| 954 TEST_F(WebSocketStreamCreateTest, IncorrectConnectionHeader) { | 823 TEST_F(WebSocketStreamCreateTest, IncorrectConnectionHeader) { |
| 955 static const char kMissingConnectionResponse[] = | 824 static const char kMissingConnectionResponse[] = |
| 956 "HTTP/1.1 101 Switching Protocols\r\n" | 825 "HTTP/1.1 101 Switching Protocols\r\n" |
| 957 "Upgrade: websocket\r\n" | 826 "Upgrade: websocket\r\n" |
| 958 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 827 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 959 "Connection: hogefuga\r\n" | 828 "Connection: hogefuga\r\n" |
| 960 "\r\n"; | 829 "\r\n"; |
| 961 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 830 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 962 NoSubProtocols(), "http://localhost", "", | 831 NoSubProtocols(), "http://localhost", "", |
| 963 kMissingConnectionResponse); | 832 kMissingConnectionResponse); |
| 964 RunUntilIdle(); | 833 WaitUntilConnectDone(); |
| 965 EXPECT_TRUE(has_failed()); | 834 EXPECT_TRUE(has_failed()); |
| 966 EXPECT_EQ("Error during WebSocket handshake: " | 835 EXPECT_EQ("Error during WebSocket handshake: " |
| 967 "'Connection' header value must contain 'Upgrade'", | 836 "'Connection' header value must contain 'Upgrade'", |
| 968 failure_message()); | 837 failure_message()); |
| 969 } | 838 } |
| 970 | 839 |
| 971 // Connection header is permitted to contain other tokens. | 840 // Connection header is permitted to contain other tokens. |
| 972 TEST_F(WebSocketStreamCreateTest, AdditionalTokenInConnectionHeader) { | 841 TEST_F(WebSocketStreamCreateTest, AdditionalTokenInConnectionHeader) { |
| 973 static const char kAdditionalConnectionTokenResponse[] = | 842 static const char kAdditionalConnectionTokenResponse[] = |
| 974 "HTTP/1.1 101 Switching Protocols\r\n" | 843 "HTTP/1.1 101 Switching Protocols\r\n" |
| 975 "Upgrade: websocket\r\n" | 844 "Upgrade: websocket\r\n" |
| 976 "Connection: Upgrade, Keep-Alive\r\n" | 845 "Connection: Upgrade, Keep-Alive\r\n" |
| 977 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 846 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 978 "\r\n"; | 847 "\r\n"; |
| 979 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 848 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 980 NoSubProtocols(), "http://localhost", "", | 849 NoSubProtocols(), "http://localhost", "", |
| 981 kAdditionalConnectionTokenResponse); | 850 kAdditionalConnectionTokenResponse); |
| 982 RunUntilIdle(); | 851 WaitUntilConnectDone(); |
| 983 EXPECT_FALSE(has_failed()); | 852 EXPECT_FALSE(has_failed()); |
| 984 EXPECT_TRUE(stream_); | 853 EXPECT_TRUE(stream_); |
| 985 } | 854 } |
| 986 | 855 |
| 987 // Sec-WebSocket-Accept header must be present. | 856 // Sec-WebSocket-Accept header must be present. |
| 988 TEST_F(WebSocketStreamCreateTest, MissingSecWebSocketAccept) { | 857 TEST_F(WebSocketStreamCreateTest, MissingSecWebSocketAccept) { |
| 989 static const char kMissingAcceptResponse[] = | 858 static const char kMissingAcceptResponse[] = |
| 990 "HTTP/1.1 101 Switching Protocols\r\n" | 859 "HTTP/1.1 101 Switching Protocols\r\n" |
| 991 "Upgrade: websocket\r\n" | 860 "Upgrade: websocket\r\n" |
| 992 "Connection: Upgrade\r\n" | 861 "Connection: Upgrade\r\n" |
| 993 "\r\n"; | 862 "\r\n"; |
| 994 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 863 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 995 NoSubProtocols(), "http://localhost", "", | 864 NoSubProtocols(), "http://localhost", "", |
| 996 kMissingAcceptResponse); | 865 kMissingAcceptResponse); |
| 997 RunUntilIdle(); | 866 WaitUntilConnectDone(); |
| 998 EXPECT_TRUE(has_failed()); | 867 EXPECT_TRUE(has_failed()); |
| 999 EXPECT_EQ("Error during WebSocket handshake: " | 868 EXPECT_EQ("Error during WebSocket handshake: " |
| 1000 "'Sec-WebSocket-Accept' header is missing", | 869 "'Sec-WebSocket-Accept' header is missing", |
| 1001 failure_message()); | 870 failure_message()); |
| 1002 } | 871 } |
| 1003 | 872 |
| 1004 // Sec-WebSocket-Accept header must match the key that was sent. | 873 // Sec-WebSocket-Accept header must match the key that was sent. |
| 1005 TEST_F(WebSocketStreamCreateTest, WrongSecWebSocketAccept) { | 874 TEST_F(WebSocketStreamCreateTest, WrongSecWebSocketAccept) { |
| 1006 static const char kIncorrectAcceptResponse[] = | 875 static const char kIncorrectAcceptResponse[] = |
| 1007 "HTTP/1.1 101 Switching Protocols\r\n" | 876 "HTTP/1.1 101 Switching Protocols\r\n" |
| 1008 "Upgrade: websocket\r\n" | 877 "Upgrade: websocket\r\n" |
| 1009 "Connection: Upgrade\r\n" | 878 "Connection: Upgrade\r\n" |
| 1010 "Sec-WebSocket-Accept: x/byyPZ2tOFvJCGkkugcKvqhhPk=\r\n" | 879 "Sec-WebSocket-Accept: x/byyPZ2tOFvJCGkkugcKvqhhPk=\r\n" |
| 1011 "\r\n"; | 880 "\r\n"; |
| 1012 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 881 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 1013 NoSubProtocols(), "http://localhost", "", | 882 NoSubProtocols(), "http://localhost", "", |
| 1014 kIncorrectAcceptResponse); | 883 kIncorrectAcceptResponse); |
| 1015 RunUntilIdle(); | 884 WaitUntilConnectDone(); |
| 1016 EXPECT_TRUE(has_failed()); | 885 EXPECT_TRUE(has_failed()); |
| 1017 EXPECT_EQ("Error during WebSocket handshake: " | 886 EXPECT_EQ("Error during WebSocket handshake: " |
| 1018 "Incorrect 'Sec-WebSocket-Accept' header value", | 887 "Incorrect 'Sec-WebSocket-Accept' header value", |
| 1019 failure_message()); | 888 failure_message()); |
| 1020 } | 889 } |
| 1021 | 890 |
| 1022 // Cancellation works. | 891 // Cancellation works. |
| 1023 TEST_F(WebSocketStreamCreateTest, Cancellation) { | 892 TEST_F(WebSocketStreamCreateTest, Cancellation) { |
| 1024 CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 893 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 1025 NoSubProtocols(), "http://localhost", "", ""); | 894 NoSubProtocols(), "http://localhost", "", ""); |
| 1026 stream_request_.reset(); | 895 stream_request_.reset(); |
| 1027 RunUntilIdle(); | 896 // WaitUntilConnectDone doesn't work in this case. |
| 897 base::RunLoop().RunUntilIdle(); |
| 1028 EXPECT_FALSE(has_failed()); | 898 EXPECT_FALSE(has_failed()); |
| 1029 EXPECT_FALSE(stream_); | 899 EXPECT_FALSE(stream_); |
| 1030 EXPECT_FALSE(request_info_); | 900 EXPECT_FALSE(request_info_); |
| 1031 EXPECT_FALSE(response_info_); | 901 EXPECT_FALSE(response_info_); |
| 1032 } | 902 } |
| 1033 | 903 |
| 1034 // Connect failure must look just like negotiation failure. | 904 // Connect failure must look just like negotiation failure. |
| 1035 TEST_F(WebSocketStreamCreateTest, ConnectionFailure) { | 905 TEST_F(WebSocketStreamCreateTest, ConnectionFailure) { |
| 1036 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData()); | 906 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData()); |
| 1037 socket_data->set_connect_data( | 907 socket_data->set_connect_data( |
| 1038 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); | 908 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); |
| 1039 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 909 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
| 1040 "http://localhost", socket_data.Pass()); | 910 "http://localhost", socket_data.Pass()); |
| 1041 RunUntilIdle(); | 911 WaitUntilConnectDone(); |
| 1042 EXPECT_TRUE(has_failed()); | 912 EXPECT_TRUE(has_failed()); |
| 1043 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", | 913 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", |
| 1044 failure_message()); | 914 failure_message()); |
| 1045 EXPECT_FALSE(request_info_); | 915 EXPECT_FALSE(request_info_); |
| 1046 EXPECT_FALSE(response_info_); | 916 EXPECT_FALSE(response_info_); |
| 1047 } | 917 } |
| 1048 | 918 |
| 1049 // Connect timeout must look just like any other failure. | 919 // Connect timeout must look just like any other failure. |
| 1050 TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) { | 920 TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) { |
| 1051 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData()); | 921 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData()); |
| 1052 socket_data->set_connect_data( | 922 socket_data->set_connect_data( |
| 1053 MockConnect(ASYNC, ERR_CONNECTION_TIMED_OUT)); | 923 MockConnect(ASYNC, ERR_CONNECTION_TIMED_OUT)); |
| 1054 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 924 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
| 1055 "http://localhost", socket_data.Pass()); | 925 "http://localhost", socket_data.Pass()); |
| 1056 RunUntilIdle(); | 926 WaitUntilConnectDone(); |
| 1057 EXPECT_TRUE(has_failed()); | 927 EXPECT_TRUE(has_failed()); |
| 1058 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT", | 928 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT", |
| 1059 failure_message()); | 929 failure_message()); |
| 1060 } | 930 } |
| 1061 | 931 |
| 1062 // The server doesn't respond to the opening handshake. | 932 // The server doesn't respond to the opening handshake. |
| 1063 TEST_F(WebSocketStreamCreateTest, HandshakeTimeout) { | 933 TEST_F(WebSocketStreamCreateTest, HandshakeTimeout) { |
| 1064 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData()); | 934 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData()); |
| 1065 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); | 935 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); |
| 1066 scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); | 936 scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); |
| 1067 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); | 937 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); |
| 1068 CreateAndConnectRawExpectations("ws://localhost/", | 938 CreateAndConnectRawExpectations("ws://localhost/", |
| 1069 NoSubProtocols(), | 939 NoSubProtocols(), |
| 1070 "http://localhost", | 940 "http://localhost", |
| 1071 socket_data.Pass(), | 941 socket_data.Pass(), |
| 1072 timer.Pass()); | 942 timer.Pass()); |
| 1073 EXPECT_FALSE(has_failed()); | 943 EXPECT_FALSE(has_failed()); |
| 1074 ASSERT_TRUE(weak_timer.get()); | 944 ASSERT_TRUE(weak_timer.get()); |
| 1075 EXPECT_TRUE(weak_timer->IsRunning()); | 945 EXPECT_TRUE(weak_timer->IsRunning()); |
| 1076 | 946 |
| 1077 weak_timer->Fire(); | 947 weak_timer->Fire(); |
| 1078 RunUntilIdle(); | 948 WaitUntilConnectDone(); |
| 1079 | 949 |
| 1080 EXPECT_TRUE(has_failed()); | 950 EXPECT_TRUE(has_failed()); |
| 1081 EXPECT_EQ("WebSocket opening handshake timed out", failure_message()); | 951 EXPECT_EQ("WebSocket opening handshake timed out", failure_message()); |
| 1082 ASSERT_TRUE(weak_timer.get()); | 952 ASSERT_TRUE(weak_timer.get()); |
| 1083 EXPECT_FALSE(weak_timer->IsRunning()); | 953 EXPECT_FALSE(weak_timer->IsRunning()); |
| 1084 } | 954 } |
| 1085 | 955 |
| 1086 // When the connection establishes the timer should be stopped. | 956 // When the connection establishes the timer should be stopped. |
| 1087 TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnSuccess) { | 957 TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnSuccess) { |
| 1088 scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); | 958 scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); |
| 1089 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); | 959 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); |
| 1090 | 960 |
| 1091 CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 961 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 1092 NoSubProtocols(), "http://localhost", "", "", | 962 NoSubProtocols(), "http://localhost", "", "", |
| 1093 timer.Pass()); | 963 timer.Pass()); |
| 1094 ASSERT_TRUE(weak_timer); | 964 ASSERT_TRUE(weak_timer); |
| 1095 EXPECT_TRUE(weak_timer->IsRunning()); | 965 EXPECT_TRUE(weak_timer->IsRunning()); |
| 1096 | 966 |
| 1097 RunUntilIdle(); | 967 WaitUntilConnectDone(); |
| 1098 EXPECT_FALSE(has_failed()); | 968 EXPECT_FALSE(has_failed()); |
| 1099 EXPECT_TRUE(stream_); | 969 EXPECT_TRUE(stream_); |
| 1100 ASSERT_TRUE(weak_timer); | 970 ASSERT_TRUE(weak_timer); |
| 1101 EXPECT_FALSE(weak_timer->IsRunning()); | 971 EXPECT_FALSE(weak_timer->IsRunning()); |
| 1102 } | 972 } |
| 1103 | 973 |
| 1104 // When the connection fails the timer should be stopped. | 974 // When the connection fails the timer should be stopped. |
| 1105 TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnFailure) { | 975 TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnFailure) { |
| 1106 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData()); | 976 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData()); |
| 1107 socket_data->set_connect_data( | 977 socket_data->set_connect_data( |
| 1108 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); | 978 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); |
| 1109 scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); | 979 scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); |
| 1110 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); | 980 base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); |
| 1111 CreateAndConnectRawExpectations("ws://localhost/", | 981 CreateAndConnectRawExpectations("ws://localhost/", |
| 1112 NoSubProtocols(), | 982 NoSubProtocols(), |
| 1113 "http://localhost", | 983 "http://localhost", |
| 1114 socket_data.Pass(), | 984 socket_data.Pass(), |
| 1115 timer.Pass()); | 985 timer.Pass()); |
| 1116 ASSERT_TRUE(weak_timer.get()); | 986 ASSERT_TRUE(weak_timer.get()); |
| 1117 EXPECT_TRUE(weak_timer->IsRunning()); | 987 EXPECT_TRUE(weak_timer->IsRunning()); |
| 1118 | 988 |
| 1119 RunUntilIdle(); | 989 WaitUntilConnectDone(); |
| 1120 EXPECT_TRUE(has_failed()); | 990 EXPECT_TRUE(has_failed()); |
| 1121 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", | 991 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", |
| 1122 failure_message()); | 992 failure_message()); |
| 1123 ASSERT_TRUE(weak_timer.get()); | 993 ASSERT_TRUE(weak_timer.get()); |
| 1124 EXPECT_FALSE(weak_timer->IsRunning()); | 994 EXPECT_FALSE(weak_timer->IsRunning()); |
| 1125 } | 995 } |
| 1126 | 996 |
| 1127 // Cancellation during connect works. | 997 // Cancellation during connect works. |
| 1128 TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) { | 998 TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) { |
| 1129 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData()); | 999 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData()); |
| 1130 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); | 1000 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); |
| 1131 CreateAndConnectRawExpectations("ws://localhost/", | 1001 CreateAndConnectRawExpectations("ws://localhost/", |
| 1132 NoSubProtocols(), | 1002 NoSubProtocols(), |
| 1133 "http://localhost", | 1003 "http://localhost", |
| 1134 socket_data.Pass()); | 1004 socket_data.Pass()); |
| 1135 stream_request_.reset(); | 1005 stream_request_.reset(); |
| 1136 RunUntilIdle(); | 1006 // WaitUntilConnectDone doesn't work in this case. |
| 1007 base::RunLoop().RunUntilIdle(); |
| 1137 EXPECT_FALSE(has_failed()); | 1008 EXPECT_FALSE(has_failed()); |
| 1138 EXPECT_FALSE(stream_); | 1009 EXPECT_FALSE(stream_); |
| 1139 } | 1010 } |
| 1140 | 1011 |
| 1141 // Cancellation during write of the request headers works. | 1012 // Cancellation during write of the request headers works. |
| 1142 TEST_F(WebSocketStreamCreateTest, CancellationDuringWrite) { | 1013 TEST_F(WebSocketStreamCreateTest, CancellationDuringWrite) { |
| 1143 // We seem to need at least two operations in order to use SetStop(). | 1014 // We seem to need at least two operations in order to use SetStop(). |
| 1144 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/"), | 1015 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/"), |
| 1145 MockWrite(ASYNC, 1, "1.1\r\n")}; | 1016 MockWrite(ASYNC, 1, "1.1\r\n")}; |
| 1146 // We keep a copy of the pointer so that we can call RunFor() on it later. | 1017 // We keep a copy of the pointer so that we can call RunFor() on it later. |
| 1147 DeterministicSocketData* socket_data( | 1018 DeterministicSocketData* socket_data( |
| 1148 new DeterministicSocketData(NULL, 0, writes, arraysize(writes))); | 1019 new DeterministicSocketData(NULL, 0, writes, arraysize(writes))); |
| 1149 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | 1020 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
| 1150 socket_data->SetStop(1); | 1021 socket_data->SetStop(1); |
| 1151 CreateAndConnectRawExpectations("ws://localhost/", | 1022 CreateAndConnectRawExpectations("ws://localhost/", |
| 1152 NoSubProtocols(), | 1023 NoSubProtocols(), |
| 1153 "http://localhost", | 1024 "http://localhost", |
| 1154 make_scoped_ptr(socket_data)); | 1025 make_scoped_ptr(socket_data)); |
| 1155 socket_data->Run(); | 1026 socket_data->Run(); |
| 1156 stream_request_.reset(); | 1027 stream_request_.reset(); |
| 1157 RunUntilIdle(); | 1028 // WaitUntilConnectDone doesn't work in this case. |
| 1029 base::RunLoop().RunUntilIdle(); |
| 1158 EXPECT_FALSE(has_failed()); | 1030 EXPECT_FALSE(has_failed()); |
| 1159 EXPECT_FALSE(stream_); | 1031 EXPECT_FALSE(stream_); |
| 1160 EXPECT_TRUE(request_info_); | 1032 EXPECT_TRUE(request_info_); |
| 1161 EXPECT_FALSE(response_info_); | 1033 EXPECT_FALSE(response_info_); |
| 1162 } | 1034 } |
| 1163 | 1035 |
| 1164 // Cancellation during read of the response headers works. | 1036 // Cancellation during read of the response headers works. |
| 1165 TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) { | 1037 TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) { |
| 1166 std::string request = | 1038 std::string request = |
| 1167 WebSocketStandardRequest("/", "localhost", "http://localhost", ""); | 1039 WebSocketStandardRequest("/", "localhost", "http://localhost", ""); |
| 1168 MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())}; | 1040 MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())}; |
| 1169 MockRead reads[] = { | 1041 MockRead reads[] = { |
| 1170 MockRead(ASYNC, 1, "HTTP/1.1 101 Switching Protocols\r\nUpgr"), | 1042 MockRead(ASYNC, 1, "HTTP/1.1 101 Switching Protocols\r\nUpgr"), |
| 1171 }; | 1043 }; |
| 1172 scoped_ptr<DeterministicSocketData> socket_data( | 1044 scoped_ptr<DeterministicSocketData> socket_data( |
| 1173 BuildSocketData(reads, writes)); | 1045 BuildSocketData(reads, writes)); |
| 1174 socket_data->SetStop(1); | 1046 socket_data->SetStop(1); |
| 1175 DeterministicSocketData* socket_data_raw_ptr = socket_data.get(); | 1047 DeterministicSocketData* socket_data_raw_ptr = socket_data.get(); |
| 1176 CreateAndConnectRawExpectations("ws://localhost/", | 1048 CreateAndConnectRawExpectations("ws://localhost/", |
| 1177 NoSubProtocols(), | 1049 NoSubProtocols(), |
| 1178 "http://localhost", | 1050 "http://localhost", |
| 1179 socket_data.Pass()); | 1051 socket_data.Pass()); |
| 1180 socket_data_raw_ptr->Run(); | 1052 socket_data_raw_ptr->Run(); |
| 1181 stream_request_.reset(); | 1053 stream_request_.reset(); |
| 1182 RunUntilIdle(); | 1054 // WaitUntilConnectDone doesn't work in this case. |
| 1055 base::RunLoop().RunUntilIdle(); |
| 1183 EXPECT_FALSE(has_failed()); | 1056 EXPECT_FALSE(has_failed()); |
| 1184 EXPECT_FALSE(stream_); | 1057 EXPECT_FALSE(stream_); |
| 1185 EXPECT_TRUE(request_info_); | 1058 EXPECT_TRUE(request_info_); |
| 1186 EXPECT_FALSE(response_info_); | 1059 EXPECT_FALSE(response_info_); |
| 1187 } | 1060 } |
| 1188 | 1061 |
| 1189 // Over-size response headers (> 256KB) should not cause a crash. This is a | 1062 // Over-size response headers (> 256KB) should not cause a crash. This is a |
| 1190 // regression test for crbug.com/339456. It is based on the layout test | 1063 // regression test for crbug.com/339456. It is based on the layout test |
| 1191 // "cookie-flood.html". | 1064 // "cookie-flood.html". |
| 1192 TEST_F(WebSocketStreamCreateTest, VeryLargeResponseHeaders) { | 1065 TEST_F(WebSocketStreamCreateTest, VeryLargeResponseHeaders) { |
| 1193 std::string set_cookie_headers; | 1066 std::string set_cookie_headers; |
| 1194 set_cookie_headers.reserve(45 * 10000); | 1067 set_cookie_headers.reserve(45 * 10000); |
| 1195 for (int i = 0; i < 10000; ++i) { | 1068 for (int i = 0; i < 10000; ++i) { |
| 1196 set_cookie_headers += | 1069 set_cookie_headers += |
| 1197 base::StringPrintf("Set-Cookie: WK-websocket-test-flood-%d=1\r\n", i); | 1070 base::StringPrintf("Set-Cookie: WK-websocket-test-flood-%d=1\r\n", i); |
| 1198 } | 1071 } |
| 1199 CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 1072 CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 1200 NoSubProtocols(), "http://localhost", "", | 1073 NoSubProtocols(), "http://localhost", "", |
| 1201 set_cookie_headers); | 1074 set_cookie_headers); |
| 1202 RunUntilIdle(); | 1075 WaitUntilConnectDone(); |
| 1203 EXPECT_TRUE(has_failed()); | 1076 EXPECT_TRUE(has_failed()); |
| 1204 EXPECT_FALSE(response_info_); | 1077 EXPECT_FALSE(response_info_); |
| 1205 } | 1078 } |
| 1206 | 1079 |
| 1207 // If the remote host closes the connection without sending headers, we should | 1080 // If the remote host closes the connection without sending headers, we should |
| 1208 // log the console message "Connection closed before receiving a handshake | 1081 // log the console message "Connection closed before receiving a handshake |
| 1209 // response". | 1082 // response". |
| 1210 TEST_F(WebSocketStreamCreateTest, NoResponse) { | 1083 TEST_F(WebSocketStreamCreateTest, NoResponse) { |
| 1211 std::string request = | 1084 std::string request = |
| 1212 WebSocketStandardRequest("/", "localhost", "http://localhost", ""); | 1085 WebSocketStandardRequest("/", "localhost", "http://localhost", ""); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1231 ssl_data_.push_back( | 1104 ssl_data_.push_back( |
| 1232 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)); | 1105 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)); |
| 1233 ssl_data_[0]->cert = | 1106 ssl_data_[0]->cert = |
| 1234 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); | 1107 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); |
| 1235 ASSERT_TRUE(ssl_data_[0]->cert.get()); | 1108 ASSERT_TRUE(ssl_data_[0]->cert.get()); |
| 1236 scoped_ptr<DeterministicSocketData> raw_socket_data(BuildNullSocketData()); | 1109 scoped_ptr<DeterministicSocketData> raw_socket_data(BuildNullSocketData()); |
| 1237 CreateAndConnectRawExpectations("wss://localhost/", | 1110 CreateAndConnectRawExpectations("wss://localhost/", |
| 1238 NoSubProtocols(), | 1111 NoSubProtocols(), |
| 1239 "http://localhost", | 1112 "http://localhost", |
| 1240 raw_socket_data.Pass()); | 1113 raw_socket_data.Pass()); |
| 1241 RunUntilIdle(); | 1114 // WaitUntilConnectDone doesn't work in this case. |
| 1115 base::RunLoop().RunUntilIdle(); |
| 1242 EXPECT_FALSE(has_failed()); | 1116 EXPECT_FALSE(has_failed()); |
| 1243 ASSERT_TRUE(ssl_error_callbacks_); | 1117 ASSERT_TRUE(ssl_error_callbacks_); |
| 1244 ssl_error_callbacks_->CancelSSLRequest(ERR_CERT_AUTHORITY_INVALID, | 1118 ssl_error_callbacks_->CancelSSLRequest(ERR_CERT_AUTHORITY_INVALID, |
| 1245 &ssl_info_); | 1119 &ssl_info_); |
| 1246 RunUntilIdle(); | 1120 WaitUntilConnectDone(); |
| 1247 EXPECT_TRUE(has_failed()); | 1121 EXPECT_TRUE(has_failed()); |
| 1248 } | 1122 } |
| 1249 | 1123 |
| 1250 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) { | 1124 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) { |
| 1251 scoped_ptr<SSLSocketDataProvider> ssl_data( | 1125 scoped_ptr<SSLSocketDataProvider> ssl_data( |
| 1252 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)); | 1126 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)); |
| 1253 ssl_data->cert = | 1127 ssl_data->cert = |
| 1254 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); | 1128 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); |
| 1255 ASSERT_TRUE(ssl_data->cert.get()); | 1129 ASSERT_TRUE(ssl_data->cert.get()); |
| 1256 ssl_data_.push_back(ssl_data.release()); | 1130 ssl_data_.push_back(ssl_data.release()); |
| 1257 ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK)); | 1131 ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK)); |
| 1258 ssl_data_.push_back(ssl_data.release()); | 1132 ssl_data_.push_back(ssl_data.release()); |
| 1259 url_request_context_host_.AddRawExpectations(BuildNullSocketData()); | 1133 url_request_context_host_.AddRawExpectations(BuildNullSocketData()); |
| 1260 CreateAndConnectStandard("wss://localhost/", "localhost", "/", | 1134 CreateAndConnectStandard("wss://localhost/", "localhost", "/", |
| 1261 NoSubProtocols(), "http://localhost", "", ""); | 1135 NoSubProtocols(), "http://localhost", "", ""); |
| 1262 RunUntilIdle(); | 1136 // WaitUntilConnectDone doesn't work in this case. |
| 1137 base::RunLoop().RunUntilIdle(); |
| 1263 ASSERT_TRUE(ssl_error_callbacks_); | 1138 ASSERT_TRUE(ssl_error_callbacks_); |
| 1264 ssl_error_callbacks_->ContinueSSLRequest(); | 1139 ssl_error_callbacks_->ContinueSSLRequest(); |
| 1265 RunUntilIdle(); | 1140 WaitUntilConnectDone(); |
| 1266 EXPECT_FALSE(has_failed()); | 1141 EXPECT_FALSE(has_failed()); |
| 1267 EXPECT_TRUE(stream_); | 1142 EXPECT_TRUE(stream_); |
| 1268 } | 1143 } |
| 1269 | 1144 |
| 1270 // If the server requests authorisation, but we have no credentials, the | 1145 // If the server requests authorisation, but we have no credentials, the |
| 1271 // connection should fail cleanly. | 1146 // connection should fail cleanly. |
| 1272 TEST_F(WebSocketStreamCreateBasicAuthTest, FailureNoCredentials) { | 1147 TEST_F(WebSocketStreamCreateBasicAuthTest, FailureNoCredentials) { |
| 1273 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", | 1148 CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/", |
| 1274 NoSubProtocols(), "http://localhost", "", | 1149 NoSubProtocols(), "http://localhost", "", |
| 1275 kUnauthorizedResponse); | 1150 kUnauthorizedResponse); |
| 1276 RunUntilIdle(); | 1151 WaitUntilConnectDone(); |
| 1277 EXPECT_TRUE(has_failed()); | 1152 EXPECT_TRUE(has_failed()); |
| 1278 EXPECT_EQ("HTTP Authentication failed; no valid credentials available", | 1153 EXPECT_EQ("HTTP Authentication failed; no valid credentials available", |
| 1279 failure_message()); | 1154 failure_message()); |
| 1280 EXPECT_TRUE(response_info_); | 1155 EXPECT_TRUE(response_info_); |
| 1281 } | 1156 } |
| 1282 | 1157 |
| 1283 TEST_F(WebSocketStreamCreateBasicAuthTest, SuccessPasswordInUrl) { | 1158 TEST_F(WebSocketStreamCreateBasicAuthTest, SuccessPasswordInUrl) { |
| 1284 CreateAndConnectAuthHandshake("ws://foo:bar@localhost/", | 1159 CreateAndConnectAuthHandshake("ws://foo:bar@localhost/", |
| 1285 "Zm9vOmJhcg==", | 1160 "Zm9vOmJhcg==", |
| 1286 WebSocketStandardResponse(std::string())); | 1161 WebSocketStandardResponse(std::string())); |
| 1287 RunUntilIdle(); | 1162 WaitUntilConnectDone(); |
| 1288 EXPECT_FALSE(has_failed()); | 1163 EXPECT_FALSE(has_failed()); |
| 1289 EXPECT_TRUE(stream_); | 1164 EXPECT_TRUE(stream_); |
| 1290 ASSERT_TRUE(response_info_); | 1165 ASSERT_TRUE(response_info_); |
| 1291 EXPECT_EQ(101, response_info_->status_code); | 1166 EXPECT_EQ(101, response_info_->status_code); |
| 1292 } | 1167 } |
| 1293 | 1168 |
| 1294 TEST_F(WebSocketStreamCreateBasicAuthTest, FailureIncorrectPasswordInUrl) { | 1169 TEST_F(WebSocketStreamCreateBasicAuthTest, FailureIncorrectPasswordInUrl) { |
| 1295 CreateAndConnectAuthHandshake( | 1170 CreateAndConnectAuthHandshake( |
| 1296 "ws://foo:baz@localhost/", "Zm9vOmJheg==", kUnauthorizedResponse); | 1171 "ws://foo:baz@localhost/", "Zm9vOmJheg==", kUnauthorizedResponse); |
| 1297 RunUntilIdle(); | 1172 WaitUntilConnectDone(); |
| 1298 EXPECT_TRUE(has_failed()); | 1173 EXPECT_TRUE(has_failed()); |
| 1299 EXPECT_TRUE(response_info_); | 1174 EXPECT_TRUE(response_info_); |
| 1300 } | 1175 } |
| 1301 | 1176 |
| 1302 // Digest auth has the same connection semantics as Basic auth, so we can | 1177 // Digest auth has the same connection semantics as Basic auth, so we can |
| 1303 // generally assume that whatever works for Basic auth will also work for | 1178 // generally assume that whatever works for Basic auth will also work for |
| 1304 // Digest. There's just one test here, to confirm that it works at all. | 1179 // Digest. There's just one test here, to confirm that it works at all. |
| 1305 TEST_F(WebSocketStreamCreateDigestAuthTest, DigestPasswordInUrl) { | 1180 TEST_F(WebSocketStreamCreateDigestAuthTest, DigestPasswordInUrl) { |
| 1306 AddRawExpectations(helper_.BuildSocketData1(kUnauthorizedResponse)); | 1181 AddRawExpectations(helper_.BuildSocketData1(kUnauthorizedResponse)); |
| 1307 | 1182 |
| 1308 CreateAndConnectRawExpectations( | 1183 CreateAndConnectRawExpectations( |
| 1309 "ws://FooBar:pass@localhost/", | 1184 "ws://FooBar:pass@localhost/", |
| 1310 NoSubProtocols(), | 1185 NoSubProtocols(), |
| 1311 "http://localhost", | 1186 "http://localhost", |
| 1312 helper_.BuildSocketData2(kAuthorizedRequest, | 1187 helper_.BuildSocketData2(kAuthorizedRequest, |
| 1313 WebSocketStandardResponse(std::string()))); | 1188 WebSocketStandardResponse(std::string()))); |
| 1314 RunUntilIdle(); | 1189 WaitUntilConnectDone(); |
| 1315 EXPECT_FALSE(has_failed()); | 1190 EXPECT_FALSE(has_failed()); |
| 1316 EXPECT_TRUE(stream_); | 1191 EXPECT_TRUE(stream_); |
| 1317 ASSERT_TRUE(response_info_); | 1192 ASSERT_TRUE(response_info_); |
| 1318 EXPECT_EQ(101, response_info_->status_code); | 1193 EXPECT_EQ(101, response_info_->status_code); |
| 1319 } | 1194 } |
| 1320 | 1195 |
| 1321 TEST_F(WebSocketStreamCreateUMATest, Incomplete) { | 1196 TEST_F(WebSocketStreamCreateUMATest, Incomplete) { |
| 1322 const std::string name("Net.WebSocket.HandshakeResult"); | 1197 const std::string name("Net.WebSocket.HandshakeResult"); |
| 1323 scoped_ptr<base::HistogramSamples> original(GetSamples(name)); | 1198 scoped_ptr<base::HistogramSamples> original(GetSamples(name)); |
| 1324 | 1199 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1341 | 1216 |
| 1342 TEST_F(WebSocketStreamCreateUMATest, Connected) { | 1217 TEST_F(WebSocketStreamCreateUMATest, Connected) { |
| 1343 const std::string name("Net.WebSocket.HandshakeResult"); | 1218 const std::string name("Net.WebSocket.HandshakeResult"); |
| 1344 scoped_ptr<base::HistogramSamples> original(GetSamples(name)); | 1219 scoped_ptr<base::HistogramSamples> original(GetSamples(name)); |
| 1345 | 1220 |
| 1346 { | 1221 { |
| 1347 StreamCreation creation; | 1222 StreamCreation creation; |
| 1348 creation.CreateAndConnectStandard("ws://localhost/", "localhost", "/", | 1223 creation.CreateAndConnectStandard("ws://localhost/", "localhost", "/", |
| 1349 creation.NoSubProtocols(), | 1224 creation.NoSubProtocols(), |
| 1350 "http://localhost", "", ""); | 1225 "http://localhost", "", ""); |
| 1351 creation.RunUntilIdle(); | 1226 creation.WaitUntilConnectDone(); |
| 1352 } | 1227 } |
| 1353 | 1228 |
| 1354 scoped_ptr<base::HistogramSamples> samples(GetSamples(name)); | 1229 scoped_ptr<base::HistogramSamples> samples(GetSamples(name)); |
| 1355 ASSERT_TRUE(samples); | 1230 ASSERT_TRUE(samples); |
| 1356 if (original) { | 1231 if (original) { |
| 1357 samples->Subtract(*original); // Cancel the original values. | 1232 samples->Subtract(*original); // Cancel the original values. |
| 1358 } | 1233 } |
| 1359 EXPECT_EQ(0, samples->GetCount(INCOMPLETE)); | 1234 EXPECT_EQ(0, samples->GetCount(INCOMPLETE)); |
| 1360 EXPECT_EQ(1, samples->GetCount(CONNECTED)); | 1235 EXPECT_EQ(1, samples->GetCount(CONNECTED)); |
| 1361 EXPECT_EQ(0, samples->GetCount(FAILED)); | 1236 EXPECT_EQ(0, samples->GetCount(FAILED)); |
| 1362 } | 1237 } |
| 1363 | 1238 |
| 1364 TEST_F(WebSocketStreamCreateUMATest, Failed) { | 1239 TEST_F(WebSocketStreamCreateUMATest, Failed) { |
| 1365 const std::string name("Net.WebSocket.HandshakeResult"); | 1240 const std::string name("Net.WebSocket.HandshakeResult"); |
| 1366 scoped_ptr<base::HistogramSamples> original(GetSamples(name)); | 1241 scoped_ptr<base::HistogramSamples> original(GetSamples(name)); |
| 1367 | 1242 |
| 1368 { | 1243 { |
| 1369 StreamCreation creation; | 1244 StreamCreation creation; |
| 1370 static const char kInvalidStatusCodeResponse[] = | 1245 static const char kInvalidStatusCodeResponse[] = |
| 1371 "HTTP/1.1 200 OK\r\n" | 1246 "HTTP/1.1 200 OK\r\n" |
| 1372 "Upgrade: websocket\r\n" | 1247 "Upgrade: websocket\r\n" |
| 1373 "Connection: Upgrade\r\n" | 1248 "Connection: Upgrade\r\n" |
| 1374 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | 1249 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 1375 "\r\n"; | 1250 "\r\n"; |
| 1376 creation.CreateAndConnectCustomResponse( | 1251 creation.CreateAndConnectCustomResponse( |
| 1377 "ws://localhost/", "localhost", "/", creation.NoSubProtocols(), | 1252 "ws://localhost/", "localhost", "/", creation.NoSubProtocols(), |
| 1378 "http://localhost", "", kInvalidStatusCodeResponse); | 1253 "http://localhost", "", kInvalidStatusCodeResponse); |
| 1379 creation.RunUntilIdle(); | 1254 creation.WaitUntilConnectDone(); |
| 1380 } | 1255 } |
| 1381 | 1256 |
| 1382 scoped_ptr<base::HistogramSamples> samples(GetSamples(name)); | 1257 scoped_ptr<base::HistogramSamples> samples(GetSamples(name)); |
| 1383 ASSERT_TRUE(samples); | 1258 ASSERT_TRUE(samples); |
| 1384 if (original) { | 1259 if (original) { |
| 1385 samples->Subtract(*original); // Cancel the original values. | 1260 samples->Subtract(*original); // Cancel the original values. |
| 1386 } | 1261 } |
| 1387 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); | 1262 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); |
| 1388 EXPECT_EQ(0, samples->GetCount(CONNECTED)); | 1263 EXPECT_EQ(0, samples->GetCount(CONNECTED)); |
| 1389 EXPECT_EQ(0, samples->GetCount(FAILED)); | 1264 EXPECT_EQ(0, samples->GetCount(FAILED)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1402 MockRead reads[] = { | 1277 MockRead reads[] = { |
| 1403 MockRead(SYNCHRONOUS, 1, kTruncatedResponse), | 1278 MockRead(SYNCHRONOUS, 1, kTruncatedResponse), |
| 1404 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 2), | 1279 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 2), |
| 1405 }; | 1280 }; |
| 1406 MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, request.c_str())}; | 1281 MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, request.c_str())}; |
| 1407 scoped_ptr<DeterministicSocketData> socket_data( | 1282 scoped_ptr<DeterministicSocketData> socket_data( |
| 1408 BuildSocketData(reads, writes)); | 1283 BuildSocketData(reads, writes)); |
| 1409 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | 1284 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
| 1410 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 1285 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
| 1411 "http://localhost", socket_data.Pass()); | 1286 "http://localhost", socket_data.Pass()); |
| 1412 RunUntilIdle(); | 1287 WaitUntilConnectDone(); |
| 1413 EXPECT_TRUE(has_failed()); | 1288 EXPECT_TRUE(has_failed()); |
| 1414 } | 1289 } |
| 1415 | 1290 |
| 1416 TEST_F(WebSocketStreamCreateTest, HandleErrTunnelConnectionFailed) { | 1291 TEST_F(WebSocketStreamCreateTest, HandleErrTunnelConnectionFailed) { |
| 1417 static const char kConnectRequest[] = | 1292 static const char kConnectRequest[] = |
| 1418 "CONNECT localhost:80 HTTP/1.1\r\n" | 1293 "CONNECT localhost:80 HTTP/1.1\r\n" |
| 1419 "Host: localhost\r\n" | 1294 "Host: localhost\r\n" |
| 1420 "Proxy-Connection: keep-alive\r\n" | 1295 "Proxy-Connection: keep-alive\r\n" |
| 1421 "\r\n"; | 1296 "\r\n"; |
| 1422 | 1297 |
| 1423 static const char kProxyResponse[] = | 1298 static const char kProxyResponse[] = |
| 1424 "HTTP/1.1 403 Forbidden\r\n" | 1299 "HTTP/1.1 403 Forbidden\r\n" |
| 1425 "Content-Type: text/html\r\n" | 1300 "Content-Type: text/html\r\n" |
| 1426 "Content-Length: 9\r\n" | 1301 "Content-Length: 9\r\n" |
| 1427 "Connection: keep-alive\r\n" | 1302 "Connection: keep-alive\r\n" |
| 1428 "\r\n" | 1303 "\r\n" |
| 1429 "Forbidden"; | 1304 "Forbidden"; |
| 1430 | 1305 |
| 1431 MockRead reads[] = {MockRead(SYNCHRONOUS, 1, kProxyResponse)}; | 1306 MockRead reads[] = {MockRead(SYNCHRONOUS, 1, kProxyResponse)}; |
| 1432 MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, kConnectRequest)}; | 1307 MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, kConnectRequest)}; |
| 1433 scoped_ptr<DeterministicSocketData> socket_data( | 1308 scoped_ptr<DeterministicSocketData> socket_data( |
| 1434 BuildSocketData(reads, writes)); | 1309 BuildSocketData(reads, writes)); |
| 1435 url_request_context_host_.SetProxyConfig("https=proxy:8000"); | 1310 url_request_context_host_.SetProxyConfig("https=proxy:8000"); |
| 1436 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), | 1311 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
| 1437 "http://localhost", socket_data.Pass()); | 1312 "http://localhost", socket_data.Pass()); |
| 1438 RunUntilIdle(); | 1313 WaitUntilConnectDone(); |
| 1439 EXPECT_TRUE(has_failed()); | 1314 EXPECT_TRUE(has_failed()); |
| 1440 EXPECT_EQ("Establishing a tunnel via proxy server failed.", | 1315 EXPECT_EQ("Establishing a tunnel via proxy server failed.", |
| 1441 failure_message()); | 1316 failure_message()); |
| 1442 } | 1317 } |
| 1443 | 1318 |
| 1444 } // namespace | 1319 } // namespace |
| 1445 } // namespace net | 1320 } // namespace net |
| OLD | NEW |