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

Side by Side Diff: chrome/browser/ui/webui/devtools_ui.cc

Issue 2607833002: DevTools: move front-end URL handling to DevToolsUIBindingds (Closed)
Patch Set: review comments addressed Created 3 years, 11 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 | « chrome/browser/ui/webui/devtools_ui.h ('k') | chrome/browser/ui/webui/devtools_ui_unittest.cc » ('j') | no next file with comments »
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 "chrome/browser/ui/webui/devtools_ui.h" 5 #include "chrome/browser/ui/webui/devtools_ui.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/macros.h" 8 #include "base/macros.h"
9 #include "base/memory/ref_counted_memory.h" 9 #include "base/memory/ref_counted_memory.h"
10 #include "base/strings/string_split.h"
11 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
12 #include "chrome/browser/devtools/url_constants.h"
13 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/common/chrome_switches.h" 14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/url_constants.h" 15 #include "chrome/common/url_constants.h"
16 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/devtools_frontend_host.h" 17 #include "content/public/browser/devtools_frontend_host.h"
18 #include "content/public/browser/site_instance.h" 18 #include "content/public/browser/site_instance.h"
19 #include "content/public/browser/storage_partition.h" 19 #include "content/public/browser/storage_partition.h"
20 #include "content/public/browser/url_data_source.h" 20 #include "content/public/browser/url_data_source.h"
21 #include "content/public/browser/web_contents.h" 21 #include "content/public/browser/web_contents.h"
22 #include "content/public/browser/web_ui.h" 22 #include "content/public/browser/web_ui.h"
23 #include "content/public/common/user_agent.h" 23 #include "content/public/common/user_agent.h"
24 #include "net/base/escape.h"
25 #include "net/base/filename_util.h" 24 #include "net/base/filename_util.h"
26 #include "net/base/load_flags.h" 25 #include "net/base/load_flags.h"
27 #include "net/base/url_util.h"
28 #include "net/url_request/url_fetcher.h" 26 #include "net/url_request/url_fetcher.h"
29 #include "net/url_request/url_fetcher_delegate.h" 27 #include "net/url_request/url_fetcher_delegate.h"
30 #include "net/url_request/url_request_context_getter.h" 28 #include "net/url_request/url_request_context_getter.h"
31 #include "storage/browser/fileapi/file_system_context.h" 29 #include "storage/browser/fileapi/file_system_context.h"
32 #include "third_party/WebKit/public/public_features.h" 30 #include "third_party/WebKit/public/public_features.h"
33 31
34 using content::BrowserThread; 32 using content::BrowserThread;
35 using content::WebContents; 33 using content::WebContents;
36 34
37 namespace { 35 namespace {
38 36
39 std::string PathWithoutParams(const std::string& path) { 37 std::string PathWithoutParams(const std::string& path) {
40 return GURL(std::string("chrome-devtools://devtools/") + path) 38 return GURL(std::string("chrome-devtools://devtools/") + path)
41 .path().substr(1); 39 .path().substr(1);
42 } 40 }
43 41
44 const char kRemoteFrontendDomain[] = "chrome-devtools-frontend.appspot.com";
45 const char kRemoteFrontendBase[] =
46 "https://chrome-devtools-frontend.appspot.com/";
47 const char kRemoteFrontendPath[] = "serve_file";
48 const char kHttpNotFound[] = "HTTP/1.1 404 Not Found\n\n"; 42 const char kHttpNotFound[] = "HTTP/1.1 404 Not Found\n\n";
49 43
50 #if BUILDFLAG(DEBUG_DEVTOOLS) 44 #if BUILDFLAG(DEBUG_DEVTOOLS)
51 // Local frontend url provided by InspectUI. 45 // Local frontend url provided by InspectUI.
52 const char kFallbackFrontendURL[] = 46 const char kFallbackFrontendURL[] =
53 "chrome-devtools://devtools/bundled/inspector.html"; 47 "chrome-devtools://devtools/bundled/inspector.html";
54 #else 48 #else
55 // URL causing the DevTools window to display a plain text warning. 49 // URL causing the DevTools window to display a plain text warning.
56 const char kFallbackFrontendURL[] = 50 const char kFallbackFrontendURL[] =
57 "data:text/plain,Cannot load DevTools frontend from an untrusted origin"; 51 "data:text/plain,Cannot load DevTools frontend from an untrusted origin";
58 #endif // BUILDFLAG(DEBUG_DEVTOOLS) 52 #endif // BUILDFLAG(DEBUG_DEVTOOLS)
59 53
60 GURL SanitizeFrontendURL(
61 const GURL& url,
62 const std::string& scheme,
63 const std::string& host,
64 const std::string& path,
65 bool allow_query);
66
67 std::string SanitizeRevision(const std::string& revision) {
68 for (size_t i = 0; i < revision.length(); i++) {
69 if (!(revision[i] == '@' && i == 0)
70 && !(revision[i] >= '0' && revision[i] <= '9')
71 && !(revision[i] >= 'a' && revision[i] <= 'z')
72 && !(revision[i] >= 'A' && revision[i] <= 'Z')) {
73 return std::string();
74 }
75 }
76 return revision;
77 }
78
79 std::string SanitizeFrontendPath(const std::string& path) {
80 for (size_t i = 0; i < path.length(); i++) {
81 if (path[i] != '/' && path[i] != '-' && path[i] != '_'
82 && path[i] != '.' && path[i] != '@'
83 && !(path[i] >= '0' && path[i] <= '9')
84 && !(path[i] >= 'a' && path[i] <= 'z')
85 && !(path[i] >= 'A' && path[i] <= 'Z')) {
86 return std::string();
87 }
88 }
89 return path;
90 }
91
92 std::string SanitizeEndpoint(const std::string& value) {
93 if (value.find('&') != std::string::npos
94 || value.find('?') != std::string::npos)
95 return std::string();
96 return value;
97 }
98
99 std::string SanitizeRemoteBase(const std::string& value) {
100 GURL url(value);
101 std::string path = url.path();
102 std::vector<std::string> parts = base::SplitString(
103 path, "/", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
104 std::string revision = parts.size() > 2 ? parts[2] : "";
105 revision = SanitizeRevision(revision);
106 path = base::StringPrintf("/%s/%s/", kRemoteFrontendPath, revision.c_str());
107 return SanitizeFrontendURL(url, url::kHttpsScheme,
108 kRemoteFrontendDomain, path, false).spec();
109 }
110
111 std::string SanitizeRemoteFrontendURL(const std::string& value) {
112 GURL url(net::UnescapeURLComponent(value,
113 net::UnescapeRule::SPACES | net::UnescapeRule::PATH_SEPARATORS |
114 net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS |
115 net::UnescapeRule::REPLACE_PLUS_WITH_SPACE));
116 std::string path = url.path();
117 std::vector<std::string> parts = base::SplitString(
118 path, "/", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
119 std::string revision = parts.size() > 2 ? parts[2] : "";
120 revision = SanitizeRevision(revision);
121 std::string filename = parts.size() ? parts[parts.size() - 1] : "";
122 if (filename != "devtools.html")
123 filename = "inspector.html";
124 path = base::StringPrintf("/serve_rev/%s/%s",
125 revision.c_str(), filename.c_str());
126 std::string sanitized = SanitizeFrontendURL(url, url::kHttpsScheme,
127 kRemoteFrontendDomain, path, true).spec();
128 return net::EscapeQueryParamValue(sanitized, false);
129 }
130
131 std::string SanitizeFrontendQueryParam(
132 const std::string& key,
133 const std::string& value) {
134 // Convert boolean flags to true.
135 if (key == "can_dock" || key == "debugFrontend" || key == "experiments" ||
136 key == "isSharedWorker" || key == "v8only" || key == "remoteFrontend")
137 return "true";
138
139 // Pass connection endpoints as is.
140 if (key == "ws" || key == "service-backend")
141 return SanitizeEndpoint(value);
142
143 // Only support undocked for old frontends.
144 if (key == "dockSide" && value == "undocked")
145 return value;
146
147 if (key == "panel" && (value == "elements" || value == "console"))
148 return value;
149
150 if (key == "remoteBase")
151 return SanitizeRemoteBase(value);
152
153 if (key == "remoteFrontendUrl")
154 return SanitizeRemoteFrontendURL(value);
155
156 return std::string();
157 }
158
159 GURL SanitizeFrontendURL(
160 const GURL& url,
161 const std::string& scheme,
162 const std::string& host,
163 const std::string& path,
164 bool allow_query) {
165 std::vector<std::string> query_parts;
166 if (allow_query) {
167 for (net::QueryIterator it(url); !it.IsAtEnd(); it.Advance()) {
168 std::string value = SanitizeFrontendQueryParam(it.GetKey(),
169 it.GetValue());
170 if (!value.empty()) {
171 query_parts.push_back(
172 base::StringPrintf("%s=%s", it.GetKey().c_str(), value.c_str()));
173 }
174 }
175 }
176 std::string query =
177 query_parts.empty() ? "" : "?" + base::JoinString(query_parts, "&");
178 std::string constructed = base::StringPrintf("%s://%s%s%s",
179 scheme.c_str(), host.c_str(), path.c_str(), query.c_str());
180 GURL result = GURL(constructed);
181 if (!result.is_valid())
182 return GURL();
183 return result;
184 }
185 54
186 // DevToolsDataSource --------------------------------------------------------- 55 // DevToolsDataSource ---------------------------------------------------------
187 56
188 std::string GetMimeTypeForPath(const std::string& path) { 57 std::string GetMimeTypeForPath(const std::string& path) {
189 std::string filename = PathWithoutParams(path); 58 std::string filename = PathWithoutParams(path);
190 if (base::EndsWith(filename, ".html", base::CompareCase::INSENSITIVE_ASCII)) { 59 if (base::EndsWith(filename, ".html", base::CompareCase::INSENSITIVE_ASCII)) {
191 return "text/html"; 60 return "text/html";
192 } else if (base::EndsWith(filename, ".css", 61 } else if (base::EndsWith(filename, ".css",
193 base::CompareCase::INSENSITIVE_ASCII)) { 62 base::CompareCase::INSENSITIVE_ASCII)) {
194 return "text/css"; 63 return "text/css";
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 291
423 // static 292 // static
424 GURL DevToolsUI::GetRemoteBaseURL() { 293 GURL DevToolsUI::GetRemoteBaseURL() {
425 return GURL(base::StringPrintf( 294 return GURL(base::StringPrintf(
426 "%s%s/%s/", 295 "%s%s/%s/",
427 kRemoteFrontendBase, 296 kRemoteFrontendBase,
428 kRemoteFrontendPath, 297 kRemoteFrontendPath,
429 content::GetWebKitRevision().c_str())); 298 content::GetWebKitRevision().c_str()));
430 } 299 }
431 300
432 // static
433 GURL DevToolsUI::SanitizeFrontendURL(const GURL& url) {
434 return ::SanitizeFrontendURL(url, content::kChromeDevToolsScheme,
435 chrome::kChromeUIDevToolsHost, SanitizeFrontendPath(url.path()), true);
436 }
437
438 DevToolsUI::DevToolsUI(content::WebUI* web_ui) 301 DevToolsUI::DevToolsUI(content::WebUI* web_ui)
439 : WebUIController(web_ui) { 302 : WebUIController(web_ui), bindings_(web_ui->GetWebContents()) {
440 web_ui->SetBindings(0); 303 web_ui->SetBindings(0);
441 Profile* profile = Profile::FromWebUI(web_ui); 304 Profile* profile = Profile::FromWebUI(web_ui);
442 content::URLDataSource::Add( 305 content::URLDataSource::Add(
443 profile, 306 profile,
444 new DevToolsDataSource(profile->GetRequestContext())); 307 new DevToolsDataSource(profile->GetRequestContext()));
445 308
309 if (!profile->IsOffTheRecord())
310 return;
446 GURL url = web_ui->GetWebContents()->GetVisibleURL(); 311 GURL url = web_ui->GetWebContents()->GetVisibleURL();
447 if (url.spec() != SanitizeFrontendURL(url).spec()) 312 GURL site = content::SiteInstance::GetSiteForURL(profile, url);
448 return; 313 content::BrowserContext::GetStoragePartitionForSite(profile, site)->
449 314 GetFileSystemContext()->EnableTemporaryFileSystemInIncognito();
450 if (profile->IsOffTheRecord()) {
451 GURL site = content::SiteInstance::GetSiteForURL(profile, url);
452 content::BrowserContext::GetStoragePartitionForSite(profile, site)->
453 GetFileSystemContext()->EnableTemporaryFileSystemInIncognito();
454 }
455 bindings_.reset(new DevToolsUIBindings(web_ui->GetWebContents()));
456 } 315 }
457 316
458 DevToolsUI::~DevToolsUI() { 317 DevToolsUI::~DevToolsUI() {
459 } 318 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/webui/devtools_ui.h ('k') | chrome/browser/ui/webui/devtools_ui_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698