• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
VerifyProxyScript(Browser * browser)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:
LoginPromptObserver()53   LoginPromptObserver() : auth_handled_(false) {}
54 
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)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 
auth_handled() const69   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:
ProxyBrowserTest()79   ProxyBrowserTest()
80       : proxy_server_(net::SpawnedTestServer::TYPE_BASIC_AUTH_PROXY,
81                       net::SpawnedTestServer::kLocalhost,
82                       base::FilePath()) {
83   }
84 
SetUp()85   virtual void SetUp() OVERRIDE {
86     ASSERT_TRUE(proxy_server_.Start());
87     InProcessBrowserTest::SetUp();
88   }
89 
SetUpCommandLine(CommandLine * command_line)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.
IN_PROC_BROWSER_TEST_F(ProxyBrowserTest,MAYBE_BasicAuthWSConnect)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 base::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:
HttpProxyScriptBrowserTest()148   HttpProxyScriptBrowserTest()
149       : http_server_(net::SpawnedTestServer::TYPE_HTTP,
150                      net::SpawnedTestServer::kLocalhost,
151                      base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))) {
152   }
~HttpProxyScriptBrowserTest()153   virtual ~HttpProxyScriptBrowserTest() {}
154 
SetUp()155   virtual void SetUp() OVERRIDE {
156     ASSERT_TRUE(http_server_.Start());
157     InProcessBrowserTest::SetUp();
158   }
159 
SetUpCommandLine(CommandLine * command_line)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 
IN_PROC_BROWSER_TEST_F(HttpProxyScriptBrowserTest,Verify)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:
FileProxyScriptBrowserTest()179   FileProxyScriptBrowserTest() {}
~FileProxyScriptBrowserTest()180   virtual ~FileProxyScriptBrowserTest() {}
181 
SetUpCommandLine(CommandLine * command_line)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 
IN_PROC_BROWSER_TEST_F(FileProxyScriptBrowserTest,Verify)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:
FtpProxyScriptBrowserTest()200   FtpProxyScriptBrowserTest()
201       : ftp_server_(net::SpawnedTestServer::TYPE_FTP,
202                     net::SpawnedTestServer::kLocalhost,
203                     base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))) {
204   }
~FtpProxyScriptBrowserTest()205   virtual ~FtpProxyScriptBrowserTest() {}
206 
SetUp()207   virtual void SetUp() OVERRIDE {
208     ASSERT_TRUE(ftp_server_.Start());
209     InProcessBrowserTest::SetUp();
210   }
211 
SetUpCommandLine(CommandLine * command_line)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 
IN_PROC_BROWSER_TEST_F(FtpProxyScriptBrowserTest,Verify)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:
DataProxyScriptBrowserTest()232   DataProxyScriptBrowserTest() {}
~DataProxyScriptBrowserTest()233   virtual ~DataProxyScriptBrowserTest() {}
234 
SetUpCommandLine(CommandLine * command_line)235   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
236     std::string contents;
237     // Read in kPACScript contents.
238     ASSERT_TRUE(base::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 
IN_PROC_BROWSER_TEST_F(DataProxyScriptBrowserTest,Verify)250 IN_PROC_BROWSER_TEST_F(DataProxyScriptBrowserTest, Verify) {
251   VerifyProxyScript(browser());
252 }
253 
254 }  // namespace
255