Chromium Code Reviews| Index: chrome/browser/net/websocket_browsertest.cc |
| diff --git a/chrome/browser/net/websocket_browsertest.cc b/chrome/browser/net/websocket_browsertest.cc |
| index 58605de17472bd041be93ceaeb05db77567c0670..75ba26ea45293e703b707444fea32770122d7e8d 100644 |
| --- a/chrome/browser/net/websocket_browsertest.cc |
| +++ b/chrome/browser/net/websocket_browsertest.cc |
| @@ -2,51 +2,139 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| +#include "base/compiler_specific.h" |
| +#include "base/memory/ref_counted.h" |
| +#include "base/memory/scoped_ptr.h" |
| #include "base/strings/string_util.h" |
| #include "base/strings/utf_string_conversions.h" |
| +#include "chrome/browser/chrome_notification_types.h" |
| #include "chrome/browser/ui/browser.h" |
| +#include "chrome/browser/ui/login/login_prompt.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "chrome/test/base/in_process_browser_test.h" |
| #include "chrome/test/base/ui_test_utils.h" |
| +#include "content/public/browser/navigation_controller.h" |
| +#include "content/public/browser/notification_details.h" |
| +#include "content/public/browser/notification_registrar.h" |
| +#include "content/public/browser/notification_source.h" |
| +#include "content/public/browser/web_contents.h" |
| #include "content/public/test/browser_test_utils.h" |
| #include "net/base/test_data_directory.h" |
| #include "net/test/spawned_test_server/spawned_test_server.h" |
| +#include "url/gurl.h" |
| namespace { |
| class WebSocketBrowserTest : public InProcessBrowserTest { |
| public: |
| WebSocketBrowserTest() |
| - : ws_server_(net::SpawnedTestServer::TYPE_WS, |
| - net::SpawnedTestServer::kLocalhost, |
| - net::GetWebSocketTestDataDirectory()), |
| - wss_server_(net::SpawnedTestServer::TYPE_WSS, |
| - SSLOptions(SSLOptions::CERT_OK), |
| - net::GetWebSocketTestDataDirectory()) { |
| - } |
| + : ws_server_(net::SpawnedTestServer::TYPE_WS, |
| + net::SpawnedTestServer::kLocalhost, |
| + net::GetWebSocketTestDataDirectory()), |
| + wss_server_(net::SpawnedTestServer::TYPE_WSS, |
| + SSLOptions(SSLOptions::CERT_OK), |
| + net::GetWebSocketTestDataDirectory()) {} |
| protected: |
| + // Prepare the title watcher. |
| + virtual void SetUpOnMainThread() OVERRIDE { |
| + watcher_.reset(new content::TitleWatcher( |
| + browser()->tab_strip_model()->GetActiveWebContents(), |
| + base::ASCIIToUTF16("PASS"))); |
| + watcher_->AlsoWaitForTitle(base::ASCIIToUTF16("FAIL")); |
| + } |
| + |
| + virtual void CleanUpOnMainThread() OVERRIDE { watcher_.reset(); } |
| + |
| + std::string WaitAndGetTitle() { |
| + return base::UTF16ToUTF8(watcher_->WaitAndGetTitle()); |
| + } |
| + |
| net::SpawnedTestServer ws_server_; |
| net::SpawnedTestServer wss_server_; |
| private: |
| typedef net::SpawnedTestServer::SSLOptions SSLOptions; |
| + scoped_ptr<content::TitleWatcher> watcher_; |
| DISALLOW_COPY_AND_ASSIGN(WebSocketBrowserTest); |
| }; |
| +// Framework for tests using the connect_to.html page served by a separate HTTP |
| +// server. |
| +class WebSocketBrowserConnectToTest : public WebSocketBrowserTest { |
| + protected: |
| + WebSocketBrowserConnectToTest() |
| + : http_server_(net::SpawnedTestServer::TYPE_HTTP, |
| + net::SpawnedTestServer::kLocalhost, |
| + net::GetWebSocketTestDataDirectory()) {} |
| + |
| + // The title watcher and HTTP server are set up automatically by the test |
| + // framework. Each test case still needs to configure and start the |
| + // WebSocket server(s) it needs. |
| + virtual void SetUpOnMainThread() OVERRIDE { |
| + WebSocketBrowserTest::SetUpOnMainThread(); |
| + ASSERT_TRUE(http_server_.StartInBackground()); |
| + } |
| + |
| + // Supply a ws: or wss: URL to connect to. |
| + void ConnectTo(GURL url) { |
| + ASSERT_TRUE(http_server_.BlockUntilStarted()); |
| + std::string query("url=" + url.spec()); |
| + GURL::Replacements replacements; |
| + replacements.SetQueryStr(query); |
| + ui_test_utils::NavigateToURL(browser(), |
| + http_server_.GetURL("files/connect_to.html") |
| + .ReplaceComponents(replacements)); |
| + } |
| + |
| + private: |
| + net::SpawnedTestServer http_server_; |
| +}; |
| + |
| +// Automatically fill in any login prompts that appear with the supplied |
| +// credentials. |
| +class AutoLogin : public content::NotificationObserver { |
| + public: |
| + AutoLogin(const std::string& username, |
| + const std::string& password, |
| + content::NavigationController* navigation_controller) |
| + : username_(base::UTF8ToUTF16(username)), |
| + password_(base::UTF8ToUTF16(password)), |
| + logged_in_(false) { |
| + registrar_.Add( |
| + this, |
| + chrome::NOTIFICATION_AUTH_NEEDED, |
| + content::Source<content::NavigationController>(navigation_controller)); |
| + } |
| + |
| + // NotificationObserver implementation |
| + virtual void Observe(int type, |
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details) OVERRIDE { |
| + DCHECK_EQ(chrome::NOTIFICATION_AUTH_NEEDED, type); |
| + scoped_refptr<LoginHandler> login_handler = |
| + content::Details<LoginNotificationDetails>(details)->handler(); |
| + login_handler->SetAuth(username_, password_); |
| + logged_in_ = true; |
| + } |
| + |
| + bool logged_in() const { return logged_in_; } |
| + |
| + private: |
| + const base::string16 username_; |
| + const base::string16 password_; |
| + bool logged_in_; |
| + |
| + content::NotificationRegistrar registrar_; |
|
mmenke
2014/07/09 14:19:00
nit: DISALLOW_COPY_AND_ASSIGN.
Adam Rice
2014/07/10 05:30:28
Done.
|
| +}; |
| + |
| // Test that the browser can handle a WebSocket frame split into multiple TCP |
| // segments. |
| IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, WebSocketSplitSegments) { |
| // Launch a WebSocket server. |
| ASSERT_TRUE(ws_server_.Start()); |
| - // Setup page title observer. |
| - content::WebContents* tab = |
| - browser()->tab_strip_model()->GetActiveWebContents(); |
| - content::TitleWatcher watcher(tab, base::ASCIIToUTF16("PASS")); |
| - watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL")); |
| - |
| // Visit a HTTP page for testing. |
| std::string scheme("http"); |
| GURL::Replacements replacements; |
| @@ -56,20 +144,13 @@ IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, WebSocketSplitSegments) { |
| ws_server_.GetURL( |
| "split_packet_check.html").ReplaceComponents(replacements)); |
| - const base::string16 result = watcher.WaitAndGetTitle(); |
| - EXPECT_TRUE(EqualsASCII(result, "PASS")); |
| + EXPECT_EQ("PASS", WaitAndGetTitle()); |
| } |
| IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, SecureWebSocketSplitRecords) { |
| // Launch a secure WebSocket server. |
| ASSERT_TRUE(wss_server_.Start()); |
| - // Setup page title observer. |
| - content::WebContents* tab = |
| - browser()->tab_strip_model()->GetActiveWebContents(); |
| - content::TitleWatcher watcher(tab, base::ASCIIToUTF16("PASS")); |
| - watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL")); |
| - |
| // Visit a HTTPS page for testing. |
| std::string scheme("https"); |
| GURL::Replacements replacements; |
| @@ -79,8 +160,101 @@ IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, SecureWebSocketSplitRecords) { |
| wss_server_.GetURL( |
| "split_packet_check.html").ReplaceComponents(replacements)); |
| - const base::string16 result = watcher.WaitAndGetTitle(); |
| - EXPECT_TRUE(EqualsASCII(result, "PASS")); |
| + EXPECT_EQ("PASS", WaitAndGetTitle()); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, WebSocketBasicAuthInHTTPURL) { |
| + // Launch a basic-auth-protected WebSocket server. |
| + ws_server_.set_websocket_basic_auth(true); |
| + ASSERT_TRUE(ws_server_.Start()); |
| + |
| + // Visit a HTTP page for testing. |
| + std::string scheme("http"); |
| + GURL::Replacements replacements; |
| + replacements.SetSchemeStr(scheme); |
| + ui_test_utils::NavigateToURL( |
| + browser(), |
| + ws_server_.GetURLWithUserAndPassword("connect_check.html", "test", "test") |
| + .ReplaceComponents(replacements)); |
| + |
| + EXPECT_EQ("PASS", WaitAndGetTitle()); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, WebSocketBasicAuthInHTTPSURL) { |
| + // Launch a basic-auth-protected secure WebSocket server. |
| + wss_server_.set_websocket_basic_auth(true); |
| + ASSERT_TRUE(wss_server_.Start()); |
| + |
| + // Visit a HTTPS page for testing. |
| + std::string scheme("https"); |
| + GURL::Replacements replacements; |
| + replacements.SetSchemeStr(scheme); |
| + ui_test_utils::NavigateToURL( |
| + browser(), |
| + wss_server_.GetURLWithUserAndPassword( |
| + "connect_check.html", "test", "test") |
| + .ReplaceComponents(replacements)); |
| + |
| + EXPECT_EQ("PASS", WaitAndGetTitle()); |
| +} |
| + |
| +// This test verifies that login details entered by the user into the login |
| +// prompt to authenticate the main page are re-used for WebSockets from the same |
| +// origin. |
| +IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, WebSocketBasicAuthPrompt) { |
| + // Launch a basic-auth-protected WebSocket server. |
| + ws_server_.set_websocket_basic_auth(true); |
| + ASSERT_TRUE(ws_server_.Start()); |
| + |
| + content::NavigationController* navigation_controller = |
| + &browser()->tab_strip_model()->GetActiveWebContents()->GetController(); |
| + AutoLogin auto_login("test", "test", navigation_controller); |
| + |
| + // Visit a HTTP page for testing. |
| + std::string scheme("http"); |
| + GURL::Replacements replacements; |
| + replacements.SetSchemeStr(scheme); |
| + ui_test_utils::NavigateToURL( |
| + browser(), |
| + ws_server_.GetURL("connect_check.html").ReplaceComponents(replacements)); |
| + |
| + EXPECT_TRUE(auto_login.logged_in()); |
| + EXPECT_EQ("PASS", WaitAndGetTitle()); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(WebSocketBrowserConnectToTest, |
| + WebSocketBasicAuthInWSURL) { |
| + // Launch a basic-auth-protected WebSocket server. |
| + ws_server_.set_websocket_basic_auth(true); |
| + ASSERT_TRUE(ws_server_.Start()); |
| + |
| + ConnectTo(ws_server_.GetURLWithUserAndPassword( |
| + "echo-with-no-extension", "test", "test")); |
| + |
| + EXPECT_EQ("PASS", WaitAndGetTitle()); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(WebSocketBrowserConnectToTest, |
| + WebSocketBasicAuthInWSURLBadCreds) { |
| + // Launch a basic-auth-protected WebSocket server. |
| + ws_server_.set_websocket_basic_auth(true); |
| + ASSERT_TRUE(ws_server_.Start()); |
| + |
| + ConnectTo(ws_server_.GetURLWithUserAndPassword( |
| + "echo-with-no-extension", "wrong-user", "wrong-password")); |
| + |
| + EXPECT_EQ("FAIL", WaitAndGetTitle()); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(WebSocketBrowserConnectToTest, |
| + WebSocketBasicAuthNoCreds) { |
| + // Launch a basic-auth-protected WebSocket server. |
| + ws_server_.set_websocket_basic_auth(true); |
| + ASSERT_TRUE(ws_server_.Start()); |
| + |
| + ConnectTo(ws_server_.GetURL("echo-with-no-extension")); |
| + |
| + EXPECT_EQ("FAIL", WaitAndGetTitle()); |
| } |
| } // namespace |