Home | History | Annotate | Download | only in net
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/command_line.h"
      6 #include "base/path_service.h"
      7 #include "base/strings/string_util.h"
      8 #include "base/strings/stringprintf.h"
      9 #include "base/strings/utf_string_conversions.h"
     10 #include "chrome/browser/chrome_notification_types.h"
     11 #include "chrome/browser/ui/browser.h"
     12 #include "chrome/browser/ui/login/login_prompt.h"
     13 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     14 #include "chrome/common/chrome_paths.h"
     15 #include "chrome/common/chrome_switches.h"
     16 #include "chrome/common/pref_names.h"
     17 #include "chrome/test/base/in_process_browser_test.h"
     18 #include "chrome/test/base/ui_test_utils.h"
     19 #include "content/public/browser/notification_details.h"
     20 #include "content/public/browser/notification_source.h"
     21 #include "content/public/browser/web_contents.h"
     22 #include "content/public/browser/web_contents_observer.h"
     23 #include "content/public/test/browser_test_utils.h"
     24 #include "net/base/test_data_directory.h"
     25 #include "net/test/spawned_test_server/spawned_test_server.h"
     26 
     27 namespace {
     28 
     29 // PAC script that sends all requests to an invalid proxy server.
     30 const base::FilePath::CharType kPACScript[] = FILE_PATH_LITERAL(
     31     "bad_server.pac");
     32 
     33 // Verify kPACScript is installed as the PAC script.
     34 void VerifyProxyScript(Browser* browser) {
     35   ui_test_utils::NavigateToURL(browser, GURL("http://google.com"));
     36 
     37   // Verify we get the ERR_PROXY_CONNECTION_FAILED screen.
     38   bool result = false;
     39   EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
     40       browser->tab_strip_model()->GetActiveWebContents(),
     41       "var textContent = document.body.textContent;"
     42       "var hasError = textContent.indexOf('ERR_PROXY_CONNECTION_FAILED') >= 0;"
     43       "domAutomationController.send(hasError);",
     44       &result));
     45   EXPECT_TRUE(result);
     46 }
     47 
     48 // This class observes chrome::NOTIFICATION_AUTH_NEEDED and supplies
     49 // the credential which is required by the test proxy server.
     50 // "foo:bar" is the required username and password for our test proxy server.
     51 class LoginPromptObserver : public content::NotificationObserver {
     52  public:
     53   LoginPromptObserver() : auth_handled_(false) {}
     54 
     55   virtual void Observe(int type,
     56                        const content::NotificationSource& source,
     57                        const content::NotificationDetails& details) OVERRIDE {
     58     if (type == chrome::NOTIFICATION_AUTH_NEEDED) {
     59       LoginNotificationDetails* login_details =
     60           content::Details<LoginNotificationDetails>(details).ptr();
     61       // |login_details->handler()| is the associated LoginHandler object.
     62       // SetAuth() will close the login dialog.
     63       login_details->handler()->SetAuth(ASCIIToUTF16("foo"),
     64                                         ASCIIToUTF16("bar"));
     65       auth_handled_ = true;
     66     }
     67   }
     68 
     69   bool auth_handled() const { return auth_handled_; }
     70 
     71  private:
     72   bool auth_handled_;
     73 
     74   DISALLOW_COPY_AND_ASSIGN(LoginPromptObserver);
     75 };
     76 
     77 class ProxyBrowserTest : public InProcessBrowserTest {
     78  public:
     79   ProxyBrowserTest()
     80       : proxy_server_(net::SpawnedTestServer::TYPE_BASIC_AUTH_PROXY,
     81                       net::SpawnedTestServer::kLocalhost,
     82                       base::FilePath()) {
     83   }
     84 
     85   virtual void SetUp() OVERRIDE {
     86     ASSERT_TRUE(proxy_server_.Start());
     87     InProcessBrowserTest::SetUp();
     88   }
     89 
     90   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
     91     command_line->AppendSwitchASCII(switches::kProxyServer,
     92                                     proxy_server_.host_port_pair().ToString());
     93   }
     94 
     95  protected:
     96   net::SpawnedTestServer proxy_server_;
     97 
     98  private:
     99 
    100   DISALLOW_COPY_AND_ASSIGN(ProxyBrowserTest);
    101 };
    102 
    103 #if defined(OS_CHROMEOS)
    104 // We bypass manually installed proxy for localhost on chromeos.
    105 #define MAYBE_BasicAuthWSConnect DISABLED_BasicAuthWSConnect
    106 #else
    107 #define MAYBE_BasicAuthWSConnect BasicAuthWSConnect
    108 #endif
    109 // Test that the browser can establish a WebSocket connection via a proxy
    110 // that requires basic authentication.
    111 IN_PROC_BROWSER_TEST_F(ProxyBrowserTest, MAYBE_BasicAuthWSConnect) {
    112   // Launch WebSocket server.
    113   net::SpawnedTestServer ws_server(net::SpawnedTestServer::TYPE_WS,
    114                                    net::SpawnedTestServer::kLocalhost,
    115                                    net::GetWebSocketTestDataDirectory());
    116   ASSERT_TRUE(ws_server.Start());
    117 
    118   content::WebContents* tab =
    119       browser()->tab_strip_model()->GetActiveWebContents();
    120   content::NavigationController* controller = &tab->GetController();
    121   content::NotificationRegistrar registrar;
    122   // The proxy server will request basic authentication.
    123   // |observer| supplies the credential.
    124   LoginPromptObserver observer;
    125   registrar.Add(&observer, chrome::NOTIFICATION_AUTH_NEEDED,
    126                 content::Source<content::NavigationController>(controller));
    127 
    128   content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS"));
    129   watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
    130 
    131   // Visit a page that tries to establish WebSocket connection. The title
    132   // of the page will be 'PASS' on success.
    133   std::string scheme("http");
    134   GURL::Replacements replacements;
    135   replacements.SetSchemeStr(scheme);
    136   ui_test_utils::NavigateToURL(
    137       browser(),
    138       ws_server.GetURL("connect_check.html").ReplaceComponents(replacements));
    139 
    140   const string16 result = watcher.WaitAndGetTitle();
    141   EXPECT_TRUE(EqualsASCII(result, "PASS"));
    142   EXPECT_TRUE(observer.auth_handled());
    143 }
    144 
    145 // Fetch PAC script via an http:// URL.
    146 class HttpProxyScriptBrowserTest : public InProcessBrowserTest {
    147  public:
    148   HttpProxyScriptBrowserTest()
    149       : http_server_(net::SpawnedTestServer::TYPE_HTTP,
    150                      net::SpawnedTestServer::kLocalhost,
    151                      base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))) {
    152   }
    153   virtual ~HttpProxyScriptBrowserTest() {}
    154 
    155   virtual void SetUp() OVERRIDE {
    156     ASSERT_TRUE(http_server_.Start());
    157     InProcessBrowserTest::SetUp();
    158   }
    159 
    160   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    161     base::FilePath pac_script_path(FILE_PATH_LITERAL("files"));
    162     command_line->AppendSwitchASCII(switches::kProxyPacUrl, http_server_.GetURL(
    163         pac_script_path.Append(kPACScript).MaybeAsASCII()).spec());
    164   }
    165 
    166  private:
    167   net::SpawnedTestServer http_server_;
    168 
    169   DISALLOW_COPY_AND_ASSIGN(HttpProxyScriptBrowserTest);
    170 };
    171 
    172 IN_PROC_BROWSER_TEST_F(HttpProxyScriptBrowserTest, Verify) {
    173   VerifyProxyScript(browser());
    174 }
    175 
    176 // Fetch PAC script via a file:// URL.
    177 class FileProxyScriptBrowserTest : public InProcessBrowserTest {
    178  public:
    179   FileProxyScriptBrowserTest() {}
    180   virtual ~FileProxyScriptBrowserTest() {}
    181 
    182   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    183     command_line->AppendSwitchASCII(switches::kProxyPacUrl,
    184         ui_test_utils::GetTestUrl(
    185             base::FilePath(base::FilePath::kCurrentDirectory),
    186             base::FilePath(kPACScript)).spec());
    187   }
    188 
    189  private:
    190   DISALLOW_COPY_AND_ASSIGN(FileProxyScriptBrowserTest);
    191 };
    192 
    193 IN_PROC_BROWSER_TEST_F(FileProxyScriptBrowserTest, Verify) {
    194   VerifyProxyScript(browser());
    195 }
    196 
    197 // Fetch PAC script via an ftp:// URL.
    198 class FtpProxyScriptBrowserTest : public InProcessBrowserTest {
    199  public:
    200   FtpProxyScriptBrowserTest()
    201       : ftp_server_(net::SpawnedTestServer::TYPE_FTP,
    202                     net::SpawnedTestServer::kLocalhost,
    203                     base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))) {
    204   }
    205   virtual ~FtpProxyScriptBrowserTest() {}
    206 
    207   virtual void SetUp() OVERRIDE {
    208     ASSERT_TRUE(ftp_server_.Start());
    209     InProcessBrowserTest::SetUp();
    210   }
    211 
    212   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    213     base::FilePath pac_script_path(kPACScript);
    214     command_line->AppendSwitchASCII(
    215         switches::kProxyPacUrl,
    216         ftp_server_.GetURL(pac_script_path.MaybeAsASCII()).spec());
    217   }
    218 
    219  private:
    220   net::SpawnedTestServer ftp_server_;
    221 
    222   DISALLOW_COPY_AND_ASSIGN(FtpProxyScriptBrowserTest);
    223 };
    224 
    225 IN_PROC_BROWSER_TEST_F(FtpProxyScriptBrowserTest, Verify) {
    226   VerifyProxyScript(browser());
    227 }
    228 
    229 // Fetch PAC script via a data: URL.
    230 class DataProxyScriptBrowserTest : public InProcessBrowserTest {
    231  public:
    232   DataProxyScriptBrowserTest() {}
    233   virtual ~DataProxyScriptBrowserTest() {}
    234 
    235   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    236     std::string contents;
    237     // Read in kPACScript contents.
    238     ASSERT_TRUE(file_util::ReadFileToString(ui_test_utils::GetTestFilePath(
    239         base::FilePath(base::FilePath::kCurrentDirectory),
    240         base::FilePath(kPACScript)),
    241         &contents));
    242     command_line->AppendSwitchASCII(switches::kProxyPacUrl,
    243         std::string("data:,") + contents);
    244   }
    245 
    246  private:
    247   DISALLOW_COPY_AND_ASSIGN(DataProxyScriptBrowserTest);
    248 };
    249 
    250 IN_PROC_BROWSER_TEST_F(DataProxyScriptBrowserTest, Verify) {
    251   VerifyProxyScript(browser());
    252 }
    253 
    254 }  // namespace
    255