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

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

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