Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(416)

Side by Side Diff: chrome/browser/net/websocket_browsertest.cc

Issue 336263005: Map WebSocket URL schemes to HTTP URL schemes for auth purposes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Replace accidentally removed #include <string> Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | net/data/websocket/README » ('j') | net/http/http_network_transaction.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <string> 5 #include <string>
6 6
7 #include "base/strings/string_util.h" 7 #include "base/strings/string_util.h"
8 #include "base/strings/utf_string_conversions.h" 8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/ui/browser.h" 10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/login/login_prompt.h"
10 #include "chrome/browser/ui/tabs/tab_strip_model.h" 12 #include "chrome/browser/ui/tabs/tab_strip_model.h"
11 #include "chrome/test/base/in_process_browser_test.h" 13 #include "chrome/test/base/in_process_browser_test.h"
12 #include "chrome/test/base/ui_test_utils.h" 14 #include "chrome/test/base/ui_test_utils.h"
15 #include "content/public/browser/navigation_controller.h"
16 #include "content/public/browser/notification_details.h"
17 #include "content/public/browser/notification_registrar.h"
18 #include "content/public/browser/notification_source.h"
19 #include "content/public/browser/web_contents.h"
13 #include "content/public/test/browser_test_utils.h" 20 #include "content/public/test/browser_test_utils.h"
14 #include "net/base/test_data_directory.h" 21 #include "net/base/test_data_directory.h"
15 #include "net/test/spawned_test_server/spawned_test_server.h" 22 #include "net/test/spawned_test_server/spawned_test_server.h"
16 #include "url/gurl.h" 23 #include "url/gurl.h"
17 24
18 namespace { 25 namespace {
19 26
20 class WebSocketBrowserTest : public InProcessBrowserTest { 27 class WebSocketBrowserTest : public InProcessBrowserTest {
21 public: 28 public:
22 WebSocketBrowserTest() 29 WebSocketBrowserTest()
(...skipping 16 matching lines...) Expand all
39 46
40 void NavigateToHTTPS(const std::string& path) { 47 void NavigateToHTTPS(const std::string& path) {
41 // Visit a HTTPS page for testing. 48 // Visit a HTTPS page for testing.
42 std::string scheme("https"); 49 std::string scheme("https");
43 GURL::Replacements replacements; 50 GURL::Replacements replacements;
44 replacements.SetSchemeStr(scheme); 51 replacements.SetSchemeStr(scheme);
45 ui_test_utils::NavigateToURL( 52 ui_test_utils::NavigateToURL(
46 browser(), wss_server_.GetURL(path).ReplaceComponents(replacements)); 53 browser(), wss_server_.GetURL(path).ReplaceComponents(replacements));
47 } 54 }
48 55
56 // Prepare the title watcher.
57 virtual void SetUpOnMainThread() OVERRIDE {
58 watcher_.reset(new content::TitleWatcher(
59 browser()->tab_strip_model()->GetActiveWebContents(),
60 base::ASCIIToUTF16("PASS")));
61 watcher_->AlsoWaitForTitle(base::ASCIIToUTF16("FAIL"));
62 }
63
64 virtual void TearDownOnMainThread() OVERRIDE { watcher_.reset(); }
65
66 std::string WaitAndGetTitle() {
67 return base::UTF16ToUTF8(watcher_->WaitAndGetTitle());
68 }
69
49 net::SpawnedTestServer ws_server_; 70 net::SpawnedTestServer ws_server_;
50 net::SpawnedTestServer wss_server_; 71 net::SpawnedTestServer wss_server_;
51 72
52 private: 73 private:
53 typedef net::SpawnedTestServer::SSLOptions SSLOptions; 74 typedef net::SpawnedTestServer::SSLOptions SSLOptions;
75 scoped_ptr<content::TitleWatcher> watcher_;
54 76
55 DISALLOW_COPY_AND_ASSIGN(WebSocketBrowserTest); 77 DISALLOW_COPY_AND_ASSIGN(WebSocketBrowserTest);
56 }; 78 };
57 79
80 // Framework for tests using the connect_to.html page served by a separate HTTP
81 // server.
82 class WebSocketBrowserConnectToTest : public WebSocketBrowserTest {
83 protected:
84 WebSocketBrowserConnectToTest()
85 : http_server_(net::SpawnedTestServer::TYPE_HTTP,
86 net::SpawnedTestServer::kLocalhost,
87 net::GetWebSocketTestDataDirectory()) {}
88
89 // The title watcher and HTTP server are set up automatically by the test
90 // framework. Each test case still needs to configure and start the
91 // WebSocket server(s) it needs.
92 virtual void SetUpOnMainThread() OVERRIDE {
93 WebSocketBrowserTest::SetUpOnMainThread();
94 ASSERT_TRUE(http_server_.StartInBackground());
95 }
96
97 // Supply a ws: or wss: URL to connect to.
98 void ConnectTo(GURL url) {
99 ASSERT_TRUE(http_server_.BlockUntilStarted());
100 std::string query("url=" + url.spec());
101 GURL::Replacements replacements;
102 replacements.SetQueryStr(query);
103 ui_test_utils::NavigateToURL(browser(),
104 http_server_.GetURL("files/connect_to.html")
105 .ReplaceComponents(replacements));
106 }
107
108 private:
109 net::SpawnedTestServer http_server_;
110 };
111
112 // Automatically fill in any login prompts that appear with the supplied
113 // credentials.
114 class AutoLogin : public content::NotificationObserver {
115 public:
116 AutoLogin(const std::string& username,
117 const std::string& password,
118 content::NavigationController* navigation_controller)
119 : username_(base::UTF8ToUTF16(username)),
120 password_(base::UTF8ToUTF16(password)),
121 logged_in_(false) {
122 registrar_.Add(
123 this,
124 chrome::NOTIFICATION_AUTH_NEEDED,
125 content::Source<content::NavigationController>(navigation_controller));
126 }
127
128 // NotificationObserver implementation
129 virtual void Observe(int type,
130 const content::NotificationSource& source,
131 const content::NotificationDetails& details) OVERRIDE {
132 DCHECK_EQ(chrome::NOTIFICATION_AUTH_NEEDED, type);
133 scoped_refptr<LoginHandler> login_handler =
134 content::Details<LoginNotificationDetails>(details)->handler();
135 login_handler->SetAuth(username_, password_);
136 logged_in_ = true;
137 }
138
139 bool logged_in() const { return logged_in_; }
140
141 private:
142 const base::string16 username_;
143 const base::string16 password_;
144 bool logged_in_;
145
146 content::NotificationRegistrar registrar_;
147
148 DISALLOW_COPY_AND_ASSIGN(AutoLogin);
149 };
150
58 // Test that the browser can handle a WebSocket frame split into multiple TCP 151 // Test that the browser can handle a WebSocket frame split into multiple TCP
59 // segments. 152 // segments.
60 IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, WebSocketSplitSegments) { 153 IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, WebSocketSplitSegments) {
61 // Launch a WebSocket server. 154 // Launch a WebSocket server.
62 ASSERT_TRUE(ws_server_.Start()); 155 ASSERT_TRUE(ws_server_.Start());
63 156
64 // Setup page title observer.
65 content::WebContents* tab =
66 browser()->tab_strip_model()->GetActiveWebContents();
67 content::TitleWatcher watcher(tab, base::ASCIIToUTF16("PASS"));
68 watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL"));
69
70 NavigateToHTTP("split_packet_check.html"); 157 NavigateToHTTP("split_packet_check.html");
71 158
72 const base::string16 result = watcher.WaitAndGetTitle(); 159 EXPECT_EQ("PASS", WaitAndGetTitle());
73 EXPECT_EQ(base::ASCIIToUTF16("PASS"), result);
74 } 160 }
75 161
76 IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, SecureWebSocketSplitRecords) { 162 IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, SecureWebSocketSplitRecords) {
77 // Launch a secure WebSocket server. 163 // Launch a secure WebSocket server.
78 ASSERT_TRUE(wss_server_.Start()); 164 ASSERT_TRUE(wss_server_.Start());
79 165
80 // Setup page title observer.
81 content::WebContents* tab =
82 browser()->tab_strip_model()->GetActiveWebContents();
83 content::TitleWatcher watcher(tab, base::ASCIIToUTF16("PASS"));
84 watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL"));
85
86 NavigateToHTTPS("split_packet_check.html"); 166 NavigateToHTTPS("split_packet_check.html");
87 167
88 const base::string16 result = watcher.WaitAndGetTitle(); 168 EXPECT_EQ("PASS", WaitAndGetTitle());
89 EXPECT_EQ(base::ASCIIToUTF16("PASS"), result);
90 } 169 }
91 170
92 IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, SendCloseFrameWhenTabIsClosed) { 171 IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, SendCloseFrameWhenTabIsClosed) {
93 // Launch a WebSocket server. 172 // Launch a WebSocket server.
94 ASSERT_TRUE(ws_server_.Start()); 173 ASSERT_TRUE(ws_server_.Start());
95 174
96 content::WebContents* tab =
97 browser()->tab_strip_model()->GetActiveWebContents();
98 { 175 {
99 // Create a new tab, establish a WebSocket connection and close the tab. 176 // Create a new tab, establish a WebSocket connection and close the tab.
177 content::WebContents* tab =
178 browser()->tab_strip_model()->GetActiveWebContents();
100 content::WebContents* new_tab = content::WebContents::Create( 179 content::WebContents* new_tab = content::WebContents::Create(
101 content::WebContents::CreateParams(tab->GetBrowserContext())); 180 content::WebContents::CreateParams(tab->GetBrowserContext()));
102 browser()->tab_strip_model()->AppendWebContents(new_tab, true); 181 browser()->tab_strip_model()->AppendWebContents(new_tab, true);
103 ASSERT_EQ(new_tab, browser()->tab_strip_model()->GetWebContentsAt(1)); 182 ASSERT_EQ(new_tab, browser()->tab_strip_model()->GetWebContentsAt(1));
104 183
105 content::TitleWatcher connected_title_watcher( 184 content::TitleWatcher connected_title_watcher(
106 new_tab, base::ASCIIToUTF16("CONNECTED")); 185 new_tab, base::ASCIIToUTF16("CONNECTED"));
107 connected_title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("CLOSED")); 186 connected_title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("CLOSED"));
108 NavigateToHTTP("counted_connection.html"); 187 NavigateToHTTP("counted_connection.html");
109 const base::string16 result = connected_title_watcher.WaitAndGetTitle(); 188 const base::string16 result = connected_title_watcher.WaitAndGetTitle();
110 EXPECT_TRUE(EqualsASCII(result, "CONNECTED")); 189 EXPECT_TRUE(EqualsASCII(result, "CONNECTED"));
111 190
112 content::WebContentsDestroyedWatcher destroyed_watcher(new_tab); 191 content::WebContentsDestroyedWatcher destroyed_watcher(new_tab);
113 browser()->tab_strip_model()->CloseWebContentsAt(1, 0); 192 browser()->tab_strip_model()->CloseWebContentsAt(1, 0);
114 destroyed_watcher.Wait(); 193 destroyed_watcher.Wait();
115 } 194 }
116 195
117 content::TitleWatcher title_watcher(tab, base::ASCIIToUTF16("PASS")); 196 NavigateToHTTP("count_connection.html");
118 title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL")); 197 EXPECT_EQ("PASS", WaitAndGetTitle());
198 }
119 199
120 NavigateToHTTP("count_connection.html"); 200 IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, WebSocketBasicAuthInHTTPURL) {
121 const base::string16 result = title_watcher.WaitAndGetTitle(); 201 // Launch a basic-auth-protected WebSocket server.
122 EXPECT_EQ(base::ASCIIToUTF16("PASS"), result); 202 ws_server_.set_websocket_basic_auth(true);
203 ASSERT_TRUE(ws_server_.Start());
204
205 // Open connect_check.html via HTTP with credentials in the URL.
206 std::string scheme("http");
207 GURL::Replacements replacements;
208 replacements.SetSchemeStr(scheme);
209 ui_test_utils::NavigateToURL(
210 browser(),
211 ws_server_.GetURLWithUserAndPassword("connect_check.html", "test", "test")
212 .ReplaceComponents(replacements));
213
214 EXPECT_EQ("PASS", WaitAndGetTitle());
215 }
216
217 IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, WebSocketBasicAuthInHTTPSURL) {
218 // Launch a basic-auth-protected secure WebSocket server.
219 wss_server_.set_websocket_basic_auth(true);
220 ASSERT_TRUE(wss_server_.Start());
221
222 // Open connect_check.html via HTTPS with credentials in the URL.
223 std::string scheme("https");
224 GURL::Replacements replacements;
225 replacements.SetSchemeStr(scheme);
226 ui_test_utils::NavigateToURL(
227 browser(),
228 wss_server_.GetURLWithUserAndPassword(
229 "connect_check.html", "test", "test")
230 .ReplaceComponents(replacements));
231
232 EXPECT_EQ("PASS", WaitAndGetTitle());
233 }
234
235 // This test verifies that login details entered by the user into the login
236 // prompt to authenticate the main page are re-used for WebSockets from the same
237 // origin.
238 IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, WebSocketBasicAuthPrompt) {
239 // Launch a basic-auth-protected WebSocket server.
240 ws_server_.set_websocket_basic_auth(true);
241 ASSERT_TRUE(ws_server_.Start());
242
243 content::NavigationController* navigation_controller =
244 &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
245 AutoLogin auto_login("test", "test", navigation_controller);
246
247 NavigateToHTTP("connect_check.html");
248
249 EXPECT_TRUE(auto_login.logged_in());
250 EXPECT_EQ("PASS", WaitAndGetTitle());
251 }
252
253 IN_PROC_BROWSER_TEST_F(WebSocketBrowserConnectToTest,
254 WebSocketBasicAuthInWSURL) {
255 // Launch a basic-auth-protected WebSocket server.
256 ws_server_.set_websocket_basic_auth(true);
257 ASSERT_TRUE(ws_server_.Start());
258
259 ConnectTo(ws_server_.GetURLWithUserAndPassword(
260 "echo-with-no-extension", "test", "test"));
261
262 EXPECT_EQ("PASS", WaitAndGetTitle());
263 }
264
265 IN_PROC_BROWSER_TEST_F(WebSocketBrowserConnectToTest,
266 WebSocketBasicAuthInWSURLBadCreds) {
267 // Launch a basic-auth-protected WebSocket server.
268 ws_server_.set_websocket_basic_auth(true);
269 ASSERT_TRUE(ws_server_.Start());
270
271 ConnectTo(ws_server_.GetURLWithUserAndPassword(
272 "echo-with-no-extension", "wrong-user", "wrong-password"));
273
274 EXPECT_EQ("FAIL", WaitAndGetTitle());
275 }
276
277 IN_PROC_BROWSER_TEST_F(WebSocketBrowserConnectToTest,
278 WebSocketBasicAuthNoCreds) {
279 // Launch a basic-auth-protected WebSocket server.
280 ws_server_.set_websocket_basic_auth(true);
281 ASSERT_TRUE(ws_server_.Start());
282
283 ConnectTo(ws_server_.GetURL("echo-with-no-extension"));
284
285 EXPECT_EQ("FAIL", WaitAndGetTitle());
123 } 286 }
124 287
125 } // namespace 288 } // namespace
OLDNEW
« no previous file with comments | « no previous file | net/data/websocket/README » ('j') | net/http/http_network_transaction.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698