12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <string>
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chrome_notification_types.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser.h"
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/ui/login/login_prompt.h"
1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/ui/login/login_prompt_test_utils.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/navigation_controller.h"
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/notification_details.h"
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/notification_registrar.h"
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/notification_source.h"
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/web_contents.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/test/browser_test_utils.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/test_data_directory.h"
23b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/test/spawned_test_server/spawned_test_server.h"
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "url/gurl.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WebSocketBrowserTest : public InProcessBrowserTest {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebSocketBrowserTest()
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : ws_server_(net::SpawnedTestServer::TYPE_WS,
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   net::SpawnedTestServer::kLocalhost,
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   net::GetWebSocketTestDataDirectory()),
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        wss_server_(net::SpawnedTestServer::TYPE_WSS,
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    SSLOptions(SSLOptions::CERT_OK),
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    net::GetWebSocketTestDataDirectory()) {}
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void NavigateToHTTP(const std::string& path) {
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Visit a HTTP page for testing.
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    std::string scheme("http");
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    GURL::Replacements replacements;
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    replacements.SetSchemeStr(scheme);
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ui_test_utils::NavigateToURL(
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        browser(), ws_server_.GetURL(path).ReplaceComponents(replacements));
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void NavigateToHTTPS(const std::string& path) {
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Visit a HTTPS page for testing.
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    std::string scheme("https");
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    GURL::Replacements replacements;
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    replacements.SetSchemeStr(scheme);
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ui_test_utils::NavigateToURL(
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        browser(), wss_server_.GetURL(path).ReplaceComponents(replacements));
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Prepare the title watcher.
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void SetUpOnMainThread() OVERRIDE {
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    watcher_.reset(new content::TitleWatcher(
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        browser()->tab_strip_model()->GetActiveWebContents(),
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::ASCIIToUTF16("PASS")));
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    watcher_->AlsoWaitForTitle(base::ASCIIToUTF16("FAIL"));
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void TearDownOnMainThread() OVERRIDE { watcher_.reset(); }
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string WaitAndGetTitle() {
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return base::UTF16ToUTF8(watcher_->WaitAndGetTitle());
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::SpawnedTestServer ws_server_;
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::SpawnedTestServer wss_server_;
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  typedef net::SpawnedTestServer::SSLOptions SSLOptions;
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<content::TitleWatcher> watcher_;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WebSocketBrowserTest);
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Framework for tests using the connect_to.html page served by a separate HTTP
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// server.
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class WebSocketBrowserConnectToTest : public WebSocketBrowserTest {
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) protected:
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  WebSocketBrowserConnectToTest()
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : http_server_(net::SpawnedTestServer::TYPE_HTTP,
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                     net::SpawnedTestServer::kLocalhost,
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                     net::GetWebSocketTestDataDirectory()) {}
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The title watcher and HTTP server are set up automatically by the test
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // framework. Each test case still needs to configure and start the
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // WebSocket server(s) it needs.
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void SetUpOnMainThread() OVERRIDE {
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    WebSocketBrowserTest::SetUpOnMainThread();
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ASSERT_TRUE(http_server_.StartInBackground());
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Supply a ws: or wss: URL to connect to.
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void ConnectTo(GURL url) {
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ASSERT_TRUE(http_server_.BlockUntilStarted());
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    std::string query("url=" + url.spec());
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    GURL::Replacements replacements;
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    replacements.SetQueryStr(query);
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ui_test_utils::NavigateToURL(browser(),
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 http_server_.GetURL("files/connect_to.html")
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     .ReplaceComponents(replacements));
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private:
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  net::SpawnedTestServer http_server_;
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Automatically fill in any login prompts that appear with the supplied
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// credentials.
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class AutoLogin : public content::NotificationObserver {
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AutoLogin(const std::string& username,
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            const std::string& password,
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            content::NavigationController* navigation_controller)
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : username_(base::UTF8ToUTF16(username)),
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        password_(base::UTF8ToUTF16(password)),
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        logged_in_(false) {
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    registrar_.Add(
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        this,
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        chrome::NOTIFICATION_AUTH_NEEDED,
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        content::Source<content::NavigationController>(navigation_controller));
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // NotificationObserver implementation
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void Observe(int type,
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       const content::NotificationSource& source,
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE {
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    DCHECK_EQ(chrome::NOTIFICATION_AUTH_NEEDED, type);
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_refptr<LoginHandler> login_handler =
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        content::Details<LoginNotificationDetails>(details)->handler();
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    login_handler->SetAuth(username_, password_);
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    logged_in_ = true;
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool logged_in() const { return logged_in_; }
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private:
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const base::string16 username_;
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const base::string16 password_;
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool logged_in_;
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  content::NotificationRegistrar registrar_;
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AutoLogin);
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test that the browser can handle a WebSocket frame split into multiple TCP
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// segments.
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, WebSocketSplitSegments) {
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Launch a WebSocket server.
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(ws_server_.Start());
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  NavigateToHTTP("split_packet_check.html");
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ("PASS", WaitAndGetTitle());
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, SecureWebSocketSplitRecords) {
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Launch a secure WebSocket server.
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(wss_server_.Start());
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  NavigateToHTTPS("split_packet_check.html");
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ("PASS", WaitAndGetTitle());
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, SendCloseFrameWhenTabIsClosed) {
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Launch a WebSocket server.
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(ws_server_.Start());
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  {
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Create a new tab, establish a WebSocket connection and close the tab.
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::WebContents* tab =
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        browser()->tab_strip_model()->GetActiveWebContents();
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::WebContents* new_tab = content::WebContents::Create(
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        content::WebContents::CreateParams(tab->GetBrowserContext()));
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    browser()->tab_strip_model()->AppendWebContents(new_tab, true);
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ASSERT_EQ(new_tab, browser()->tab_strip_model()->GetWebContentsAt(1));
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::TitleWatcher connected_title_watcher(
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        new_tab, base::ASCIIToUTF16("CONNECTED"));
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    connected_title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("CLOSED"));
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    NavigateToHTTP("counted_connection.html");
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const base::string16 result = connected_title_watcher.WaitAndGetTitle();
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_TRUE(EqualsASCII(result, "CONNECTED"));
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::WebContentsDestroyedWatcher destroyed_watcher(new_tab);
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    browser()->tab_strip_model()->CloseWebContentsAt(1, 0);
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    destroyed_watcher.Wait();
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  NavigateToHTTP("count_connection.html");
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ("PASS", WaitAndGetTitle());
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, WebSocketBasicAuthInHTTPURL) {
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Launch a basic-auth-protected WebSocket server.
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ws_server_.set_websocket_basic_auth(true);
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(ws_server_.Start());
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Open connect_check.html via HTTP with credentials in the URL.
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string scheme("http");
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL::Replacements replacements;
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  replacements.SetSchemeStr(scheme);
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_test_utils::NavigateToURL(
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser(),
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ws_server_.GetURLWithUserAndPassword("connect_check.html", "test", "test")
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          .ReplaceComponents(replacements));
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ("PASS", WaitAndGetTitle());
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, WebSocketBasicAuthInHTTPSURL) {
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Launch a basic-auth-protected secure WebSocket server.
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  wss_server_.set_websocket_basic_auth(true);
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(wss_server_.Start());
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Open connect_check.html via HTTPS with credentials in the URL.
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string scheme("https");
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL::Replacements replacements;
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  replacements.SetSchemeStr(scheme);
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_test_utils::NavigateToURL(
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser(),
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      wss_server_.GetURLWithUserAndPassword(
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      "connect_check.html", "test", "test")
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          .ReplaceComponents(replacements));
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ("PASS", WaitAndGetTitle());
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// This test verifies that login details entered by the user into the login
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// prompt to authenticate the main page are re-used for WebSockets from the same
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// origin.
23903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest,
24003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                       ReuseMainPageBasicAuthCredentialsForWebSocket) {
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Launch a basic-auth-protected WebSocket server.
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ws_server_.set_websocket_basic_auth(true);
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(ws_server_.Start());
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  content::NavigationController* navigation_controller =
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AutoLogin auto_login("test", "test", navigation_controller);
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
24903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  WindowedAuthNeededObserver auth_needed_waiter(navigation_controller);
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  NavigateToHTTP("connect_check.html");
25103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  auth_needed_waiter.Wait();
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(auto_login.logged_in());
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ("PASS", WaitAndGetTitle());
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebSocketBrowserConnectToTest,
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       WebSocketBasicAuthInWSURL) {
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Launch a basic-auth-protected WebSocket server.
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ws_server_.set_websocket_basic_auth(true);
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(ws_server_.Start());
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ConnectTo(ws_server_.GetURLWithUserAndPassword(
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "echo-with-no-extension", "test", "test"));
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ("PASS", WaitAndGetTitle());
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebSocketBrowserConnectToTest,
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       WebSocketBasicAuthInWSURLBadCreds) {
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Launch a basic-auth-protected WebSocket server.
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ws_server_.set_websocket_basic_auth(true);
2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(ws_server_.Start());
2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ConnectTo(ws_server_.GetURLWithUserAndPassword(
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "echo-with-no-extension", "wrong-user", "wrong-password"));
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ("FAIL", WaitAndGetTitle());
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebSocketBrowserConnectToTest,
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       WebSocketBasicAuthNoCreds) {
2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Launch a basic-auth-protected WebSocket server.
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ws_server_.set_websocket_basic_auth(true);
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(ws_server_.Start());
2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ConnectTo(ws_server_.GetURL("echo-with-no-extension"));
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ("FAIL", WaitAndGetTitle());
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// HTTPS connection limits should not be applied to wss:. This is only tested
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// for secure connections here because the unencrypted case is tested in the
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Blink layout tests, and browser tests are expensive to run.
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, SSLConnectionLimit) {
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(wss_server_.Start());
2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  NavigateToHTTPS("multiple-connections.html");
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ("PASS", WaitAndGetTitle());
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
304