Chromium Code Reviews| 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 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 117 const std::string& extra_request_headers, | 117 const std::string& extra_request_headers, |
| 118 const std::string& response_body, | 118 const std::string& response_body, |
| 119 scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) { | 119 scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) { |
| 120 url_request_context_host_.SetExpectations( | 120 url_request_context_host_.SetExpectations( |
| 121 WebSocketStandardRequest(socket_path, socket_host, origin, | 121 WebSocketStandardRequest(socket_path, socket_host, origin, |
| 122 extra_request_headers), | 122 extra_request_headers), |
| 123 response_body); | 123 response_body); |
| 124 CreateAndConnectStream(socket_url, sub_protocols, origin, timer.Pass()); | 124 CreateAndConnectStream(socket_url, sub_protocols, origin, timer.Pass()); |
| 125 } | 125 } |
| 126 | 126 |
| 127 void CreateAndConnectCustomResponseWithCookies( | |
| 128 const std::string& socket_url, | |
| 129 const std::string& socket_host, | |
| 130 const std::string& socket_path, | |
| 131 const std::vector<std::string>& sub_protocols, | |
| 132 const std::string& origin, | |
| 133 const std::string& cookies, | |
| 134 const std::string& extra_request_headers, | |
| 135 const std::string& response_body, | |
| 136 scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) { | |
| 137 url_request_context_host_.SetExpectations( | |
| 138 WebSocketStandardRequestWithCookies(socket_path, socket_host, origin, | |
| 139 cookies, extra_request_headers), | |
| 140 response_body); | |
| 141 CreateAndConnectStream(socket_url, sub_protocols, origin, timer.Pass()); | |
| 142 } | |
| 143 | |
| 127 // |extra_request_headers| and |extra_response_headers| must end in "\r\n" or | 144 // |extra_request_headers| and |extra_response_headers| must end in "\r\n" or |
| 128 // errors like "Unable to perform synchronous IO while stopped" will occur. | 145 // errors like "Unable to perform synchronous IO while stopped" will occur. |
| 129 void CreateAndConnectStandard( | 146 void CreateAndConnectStandard( |
| 130 const std::string& socket_url, | 147 const std::string& socket_url, |
| 131 const std::string& socket_host, | 148 const std::string& socket_host, |
| 132 const std::string& socket_path, | 149 const std::string& socket_path, |
| 133 const std::vector<std::string>& sub_protocols, | 150 const std::vector<std::string>& sub_protocols, |
| 134 const std::string& origin, | 151 const std::string& origin, |
| 135 const std::string& extra_request_headers, | 152 const std::string& extra_request_headers, |
| 136 const std::string& extra_response_headers, | 153 const std::string& extra_response_headers, |
| 137 scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) { | 154 scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) { |
| 138 CreateAndConnectCustomResponse( | 155 CreateAndConnectCustomResponse( |
| 139 socket_url, socket_host, socket_path, sub_protocols, origin, | 156 socket_url, socket_host, socket_path, sub_protocols, origin, |
| 140 extra_request_headers, | 157 extra_request_headers, |
| 141 WebSocketStandardResponse(extra_response_headers), timer.Pass()); | 158 WebSocketStandardResponse(extra_response_headers), timer.Pass()); |
| 142 } | 159 } |
| 143 | 160 |
| 161 // |cookies| must be empty or end with "\r\n". | |
| 162 // |extra_request_headers| and |extra_response_headers| must end in "\r\n" or | |
| 163 // errors like "Unable to perform synchronous IO while stopped" will occur. | |
| 164 void CreateAndConnectStandardWithCookies( | |
| 165 const std::string& socket_url, | |
| 166 const std::string& socket_host, | |
| 167 const std::string& socket_path, | |
| 168 const std::vector<std::string>& sub_protocols, | |
| 169 const std::string& origin, | |
| 170 const std::string& cookies, | |
| 171 const std::string& extra_request_headers, | |
| 172 const std::string& extra_response_headers, | |
| 173 scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) { | |
| 174 CreateAndConnectCustomResponseWithCookies( | |
| 175 socket_url, socket_host, socket_path, sub_protocols, origin, cookies, | |
| 176 extra_request_headers, | |
| 177 WebSocketStandardResponse(extra_response_headers), timer.Pass()); | |
| 178 } | |
| 179 | |
| 144 void CreateAndConnectRawExpectations( | 180 void CreateAndConnectRawExpectations( |
| 145 const std::string& socket_url, | 181 const std::string& socket_url, |
| 146 const std::vector<std::string>& sub_protocols, | 182 const std::vector<std::string>& sub_protocols, |
| 147 const std::string& origin, | 183 const std::string& origin, |
| 148 scoped_ptr<DeterministicSocketData> socket_data, | 184 scoped_ptr<DeterministicSocketData> socket_data, |
| 149 scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) { | 185 scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) { |
| 150 AddRawExpectations(socket_data.Pass()); | 186 AddRawExpectations(socket_data.Pass()); |
| 151 CreateAndConnectStream(socket_url, sub_protocols, origin, timer.Pass()); | 187 CreateAndConnectStream(socket_url, sub_protocols, origin, timer.Pass()); |
| 152 } | 188 } |
| 153 | 189 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 185 new base::Timer(false, false))); | 221 new base::Timer(false, false))); |
| 186 } | 222 } |
| 187 | 223 |
| 188 static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); } | 224 static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); } |
| 189 | 225 |
| 190 // A simple function to make the tests more readable. Creates an empty vector. | 226 // A simple function to make the tests more readable. Creates an empty vector. |
| 191 static std::vector<std::string> NoSubProtocols() { | 227 static std::vector<std::string> NoSubProtocols() { |
| 192 return std::vector<std::string>(); | 228 return std::vector<std::string>(); |
| 193 } | 229 } |
| 194 | 230 |
| 231 struct WaitTask { | |
|
Adam Rice
2015/01/23 07:31:27
You don't need this class. You can do the same thi
yhirano
2015/01/23 10:16:32
Done.
| |
| 232 WaitTask() : done_(false) {} | |
| 233 void Run() const { | |
| 234 if (!done_) { | |
| 235 base::MessageLoop::current()->PostTask( | |
| 236 FROM_HERE, base::Bind(&WaitTask::Run, base::Unretained(this))); | |
| 237 } | |
| 238 } | |
| 239 | |
| 240 // Accept any arguments and ignore them. | |
| 241 template <typename... T> | |
| 242 void Stop(T... args) { | |
| 243 done_ = true; | |
| 244 } | |
| 245 | |
| 246 private: | |
| 247 bool done_; | |
| 248 }; | |
| 249 | |
| 250 void SetCookie(CookieStore* store, | |
| 251 const GURL& url, | |
| 252 const std::string& cookie_line) { | |
| 253 WaitTask task; | |
| 254 | |
| 255 task.Run(); | |
| 256 store->SetCookieWithOptionsAsync( | |
| 257 url, cookie_line, CookieOptions(), | |
| 258 base::Bind(&WaitTask::Stop<bool>, base::Unretained(&task))); | |
| 259 WebSocketStreamCreateTest::RunUntilIdle(); | |
| 260 } | |
| 261 | |
| 262 std::string GetCookies(CookieStore* store, const GURL& url) { | |
| 263 struct GetCookies { | |
| 264 void RunTask() { task_.Run(); } | |
| 265 void Run(const std::string& cookies) { | |
| 266 cookies_ = cookies; | |
| 267 task_.Stop(); | |
| 268 } | |
| 269 | |
| 270 const std::string& cookies() const { return cookies_; } | |
| 271 | |
| 272 private: | |
| 273 WaitTask task_; | |
| 274 std::string cookies_; | |
| 275 }; | |
| 276 GetCookies callback; | |
| 277 callback.RunTask(); | |
| 278 | |
| 279 store->GetCookiesWithOptionsAsync( | |
| 280 url, CookieOptions(), | |
| 281 base::Bind(&GetCookies::Run, base::Unretained(&callback))); | |
| 282 WebSocketStreamCreateTest::RunUntilIdle(); | |
| 283 return callback.cookies(); | |
| 284 } | |
| 285 | |
| 195 const std::string& failure_message() const { return failure_message_; } | 286 const std::string& failure_message() const { return failure_message_; } |
| 196 bool has_failed() const { return has_failed_; } | 287 bool has_failed() const { return has_failed_; } |
| 197 | 288 |
| 198 class TestConnectDelegate : public WebSocketStream::ConnectDelegate { | 289 class TestConnectDelegate : public WebSocketStream::ConnectDelegate { |
| 199 public: | 290 public: |
| 200 explicit TestConnectDelegate(WebSocketStreamCreateTest* owner) | 291 explicit TestConnectDelegate(WebSocketStreamCreateTest* owner) |
| 201 : owner_(owner) {} | 292 : owner_(owner) {} |
| 202 | 293 |
| 203 void OnSuccess(scoped_ptr<WebSocketStream> stream) override { | 294 void OnSuccess(scoped_ptr<WebSocketStream> stream) override { |
| 204 stream.swap(owner_->stream_); | 295 stream.swap(owner_->stream_); |
| (...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1232 raw_socket_data.Pass()); | 1323 raw_socket_data.Pass()); |
| 1233 RunUntilIdle(); | 1324 RunUntilIdle(); |
| 1234 EXPECT_FALSE(has_failed()); | 1325 EXPECT_FALSE(has_failed()); |
| 1235 ASSERT_TRUE(ssl_error_callbacks_); | 1326 ASSERT_TRUE(ssl_error_callbacks_); |
| 1236 ssl_error_callbacks_->CancelSSLRequest(ERR_CERT_AUTHORITY_INVALID, | 1327 ssl_error_callbacks_->CancelSSLRequest(ERR_CERT_AUTHORITY_INVALID, |
| 1237 &ssl_info_); | 1328 &ssl_info_); |
| 1238 RunUntilIdle(); | 1329 RunUntilIdle(); |
| 1239 EXPECT_TRUE(has_failed()); | 1330 EXPECT_TRUE(has_failed()); |
| 1240 } | 1331 } |
| 1241 | 1332 |
| 1333 TEST_F(WebSocketStreamCreateTest, UseCookie) { | |
|
Adam Rice
2015/01/23 07:31:27
You should try to only test one thing per test cas
yhirano
2015/01/23 10:16:32
Done.
| |
| 1334 CookieStore* store = | |
| 1335 url_request_context_host_.GetURLRequestContext()->cookie_store(); | |
| 1336 | |
| 1337 SetCookie(store, GURL("http://www.example.com/"), "test-http-cookie=1"); | |
| 1338 SetCookie(store, GURL("https://www.example.com/"), "test-https-cookie=1"); | |
| 1339 SetCookie(store, GURL("https://www.example.com/"), | |
| 1340 "test-https-secure-cookie=1; secure"); | |
| 1341 SetCookie(store, GURL("ws://www.example.com/"), "test-ws-cookie=1"); | |
| 1342 SetCookie(store, GURL("wss://www.example.com/"), "test-wss-cookie=1"); | |
| 1343 SetCookie(store, GURL("wss://www.example.com/"), | |
| 1344 "test-wss-secure-cookie=1; secure"); | |
| 1345 | |
| 1346 // We use "www.example.com" to verify if the cookie domain is correctly | |
| 1347 // handled. | |
| 1348 std::string cookies = | |
| 1349 "Cookie: test-http-cookie=1; test-https-cookie=1; test-ws-cookie=1; " | |
| 1350 "test-wss-cookie=1\r\n"; | |
| 1351 CreateAndConnectStandardWithCookies( | |
| 1352 "ws://www.example.com/testing_path", "www.example.com", "/testing_path", | |
| 1353 NoSubProtocols(), "http://www.example.com", cookies, "", ""); | |
| 1354 | |
| 1355 RunUntilIdle(); | |
| 1356 EXPECT_FALSE(has_failed()); | |
| 1357 } | |
| 1358 | |
| 1359 TEST_F(WebSocketStreamCreateTest, UseCookieSecure) { | |
| 1360 ssl_data_.push_back(new SSLSocketDataProvider(ASYNC, OK)); | |
| 1361 | |
| 1362 CookieStore* store = | |
| 1363 url_request_context_host_.GetURLRequestContext()->cookie_store(); | |
| 1364 | |
| 1365 SetCookie(store, GURL("http://www.example.com/"), "test-http-cookie=1"); | |
| 1366 SetCookie(store, GURL("https://www.example.com/"), "test-https-cookie=1"); | |
| 1367 SetCookie(store, GURL("https://www.example.com/"), | |
| 1368 "test-https-secure-cookie=1; secure"); | |
| 1369 SetCookie(store, GURL("ws://www.example.com/"), "test-ws-cookie=1"); | |
| 1370 SetCookie(store, GURL("wss://www.example.com/"), "test-wss-cookie=1"); | |
| 1371 SetCookie(store, GURL("wss://www.example.com/"), | |
| 1372 "test-wss-secure-cookie=1; secure"); | |
| 1373 | |
| 1374 // We use "www.example.com" to verify if the cookie domain is correctly | |
| 1375 // handled. | |
| 1376 std::string cookies = | |
| 1377 "Cookie: test-http-cookie=1; test-https-cookie=1; " | |
| 1378 "test-https-secure-cookie=1; test-ws-cookie=1; test-wss-cookie=1; " | |
| 1379 "test-wss-secure-cookie=1\r\n"; | |
| 1380 CreateAndConnectStandardWithCookies( | |
| 1381 "wss://www.example.com/testing_path", "www.example.com", "/testing_path", | |
| 1382 NoSubProtocols(), "http://www.example.com", cookies, "", ""); | |
| 1383 | |
| 1384 RunUntilIdle(); | |
| 1385 EXPECT_FALSE(has_failed()); | |
| 1386 } | |
| 1387 | |
| 1388 TEST_F(WebSocketStreamCreateTest, SetCookie) { | |
| 1389 static const char kResponse[] = | |
| 1390 "HTTP/1.1 101 Switching Protocols\r\n" | |
| 1391 "Upgrade: websocket\r\n" | |
| 1392 "Connection: Upgrade\r\n" | |
| 1393 "Set-Cookie: test-ws-cookie=1\r\n" | |
| 1394 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | |
| 1395 "\r\n"; | |
| 1396 | |
| 1397 CookieStore* store = | |
| 1398 url_request_context_host_.GetURLRequestContext()->cookie_store(); | |
| 1399 | |
| 1400 // We use "www.example.com" to verify if the cookie domain is correctly | |
| 1401 // handled. | |
| 1402 CreateAndConnectCustomResponse( | |
| 1403 "ws://www.example.com/testing_path", "www.example.com", "/testing_path", | |
| 1404 NoSubProtocols(), "http://www.example.com", "", kResponse); | |
| 1405 | |
| 1406 RunUntilIdle(); | |
| 1407 EXPECT_FALSE(has_failed()); | |
| 1408 | |
| 1409 EXPECT_EQ("test-ws-cookie=1", | |
| 1410 GetCookies(store, GURL("http://www.example.com/"))); | |
| 1411 EXPECT_EQ("test-ws-cookie=1", | |
| 1412 GetCookies(store, GURL("https://www.example.com/"))); | |
| 1413 EXPECT_EQ("test-ws-cookie=1", | |
| 1414 GetCookies(store, GURL("ws://www.example.com/"))); | |
| 1415 EXPECT_EQ("test-ws-cookie=1", | |
| 1416 GetCookies(store, GURL("wss://www.example.com/"))); | |
| 1417 } | |
| 1418 | |
| 1419 TEST_F(WebSocketStreamCreateTest, SetCookieSecure) { | |
| 1420 static const char kResponse[] = | |
| 1421 "HTTP/1.1 101 Switching Protocols\r\n" | |
| 1422 "Upgrade: websocket\r\n" | |
| 1423 "Connection: Upgrade\r\n" | |
| 1424 "Set-Cookie: test-wss-cookie=1\r\n" | |
| 1425 "Set-Cookie: test-wss-secure-cookie=1; secure\r\n" | |
| 1426 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" | |
| 1427 "\r\n"; | |
| 1428 | |
| 1429 ssl_data_.push_back(new SSLSocketDataProvider(ASYNC, OK)); | |
| 1430 CookieStore* store = | |
| 1431 url_request_context_host_.GetURLRequestContext()->cookie_store(); | |
| 1432 | |
| 1433 // We use "www.example.com" to verify if the cookie domain is correctly | |
| 1434 // handled. | |
| 1435 CreateAndConnectCustomResponse( | |
| 1436 "wss://www.example.com/testing_path", "www.example.com", "/testing_path", | |
| 1437 NoSubProtocols(), "http://www.example.com", "", kResponse); | |
| 1438 | |
| 1439 RunUntilIdle(); | |
| 1440 EXPECT_FALSE(has_failed()); | |
| 1441 | |
| 1442 EXPECT_EQ("test-wss-cookie=1", | |
| 1443 GetCookies(store, GURL("http://www.example.com/"))); | |
| 1444 EXPECT_EQ("test-wss-cookie=1; test-wss-secure-cookie=1", | |
| 1445 GetCookies(store, GURL("https://www.example.com/"))); | |
| 1446 EXPECT_EQ("test-wss-cookie=1", | |
| 1447 GetCookies(store, GURL("ws://www.example.com/"))); | |
| 1448 EXPECT_EQ("test-wss-cookie=1; test-wss-secure-cookie=1", | |
| 1449 GetCookies(store, GURL("wss://www.example.com/"))); | |
| 1450 } | |
| 1451 | |
| 1242 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) { | 1452 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) { |
| 1243 scoped_ptr<SSLSocketDataProvider> ssl_data( | 1453 scoped_ptr<SSLSocketDataProvider> ssl_data( |
| 1244 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)); | 1454 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)); |
| 1245 ssl_data->cert = | 1455 ssl_data->cert = |
| 1246 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); | 1456 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); |
| 1247 ASSERT_TRUE(ssl_data->cert.get()); | 1457 ASSERT_TRUE(ssl_data->cert.get()); |
| 1248 ssl_data_.push_back(ssl_data.release()); | 1458 ssl_data_.push_back(ssl_data.release()); |
| 1249 ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK)); | 1459 ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK)); |
| 1250 ssl_data_.push_back(ssl_data.release()); | 1460 ssl_data_.push_back(ssl_data.release()); |
| 1251 url_request_context_host_.AddRawExpectations(BuildNullSocketData()); | 1461 url_request_context_host_.AddRawExpectations(BuildNullSocketData()); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1376 if (original) { | 1586 if (original) { |
| 1377 samples->Subtract(*original); // Cancel the original values. | 1587 samples->Subtract(*original); // Cancel the original values. |
| 1378 } | 1588 } |
| 1379 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); | 1589 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); |
| 1380 EXPECT_EQ(0, samples->GetCount(CONNECTED)); | 1590 EXPECT_EQ(0, samples->GetCount(CONNECTED)); |
| 1381 EXPECT_EQ(0, samples->GetCount(FAILED)); | 1591 EXPECT_EQ(0, samples->GetCount(FAILED)); |
| 1382 } | 1592 } |
| 1383 | 1593 |
| 1384 } // namespace | 1594 } // namespace |
| 1385 } // namespace net | 1595 } // namespace net |
| OLD | NEW |