| 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_;
|
| +};
|
| +
|
| // 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
|
|
|