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

Side by Side Diff: content/shell/browser/shell_devtools_frontend.cc

Issue 967513002: DevTools: do not use debug target when loading URLs for the front-end (chrome side). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@t5
Patch Set: same, but uses urlfetchwriter to load incrementally. Created 5 years, 9 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "content/shell/browser/shell_devtools_frontend.h" 5 #include "content/shell/browser/shell_devtools_frontend.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/json/json_reader.h" 8 #include "base/json/json_reader.h"
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "content/public/browser/devtools_http_handler.h" 13 #include "content/public/browser/devtools_http_handler.h"
14 #include "content/public/browser/render_frame_host.h" 14 #include "content/public/browser/render_frame_host.h"
15 #include "content/public/browser/render_view_host.h" 15 #include "content/public/browser/render_view_host.h"
16 #include "content/public/browser/web_contents.h" 16 #include "content/public/browser/web_contents.h"
17 #include "content/public/common/content_client.h" 17 #include "content/public/common/content_client.h"
18 #include "content/shell/browser/shell.h" 18 #include "content/shell/browser/shell.h"
19 #include "content/shell/browser/shell_browser_context.h" 19 #include "content/shell/browser/shell_browser_context.h"
20 #include "content/shell/browser/shell_browser_main_parts.h" 20 #include "content/shell/browser/shell_browser_main_parts.h"
21 #include "content/shell/browser/shell_content_browser_client.h" 21 #include "content/shell/browser/shell_content_browser_client.h"
22 #include "content/shell/browser/shell_devtools_manager_delegate.h" 22 #include "content/shell/browser/shell_devtools_manager_delegate.h"
23 #include "content/shell/browser/webkit_test_controller.h" 23 #include "content/shell/browser/webkit_test_controller.h"
24 #include "content/shell/common/shell_switches.h" 24 #include "content/shell/common/shell_switches.h"
25 #include "net/base/filename_util.h" 25 #include "net/base/io_buffer.h"
26 #include "net/base/net_errors.h"
27 #include "net/http/http_response_headers.h"
28 #include "net/url_request/url_fetcher.h"
29 #include "net/url_request/url_fetcher_response_writer.h"
26 30
27 namespace content { 31 namespace content {
28 32
33 namespace {
34
35
36 // ResponseWriter -------------------------------------------------------------
37
38 class ResponseWriter : public net::URLFetcherResponseWriter {
39 public:
40 ResponseWriter(Shell* shell, int stream_id);
41 ~ResponseWriter() override;
42
43 // URLFetcherResponseWriter overrides:
44 int Initialize(const net::CompletionCallback& callback) override;
45 int Write(net::IOBuffer* buffer,
46 int num_bytes,
47 const net::CompletionCallback& callback) override;
48 int Finish(const net::CompletionCallback& callback) override;
49
50 private:
51 Shell* shell_;
52 int stream_id_;
53
54 DISALLOW_COPY_AND_ASSIGN(ResponseWriter);
55 };
56
57 ResponseWriter::ResponseWriter(Shell* shell,
58 int stream_id)
59 : shell_(shell),
60 stream_id_(stream_id) {
61 }
62
63 ResponseWriter::~ResponseWriter() {
64 }
65
66 int ResponseWriter::Initialize(const net::CompletionCallback& callback) {
67 return net::OK;
68 }
69
70 int ResponseWriter::Write(net::IOBuffer* buffer,
71 int num_bytes,
72 const net::CompletionCallback& callback) {
73 base::StringValue chunk(std::string(buffer->data(), num_bytes));
74 std::string encoded;
75 base::JSONWriter::Write(&chunk, &encoded);
76
77 std::string code = base::StringPrintf(
78 "DevToolsAPI.streamWrite(%d, %s)", stream_id_, encoded.c_str());
79 shell_->web_contents()->GetMainFrame()->ExecuteJavaScript(
80 base::UTF8ToUTF16(code));
81
82 return num_bytes;
83 }
84
85 int ResponseWriter::Finish(const net::CompletionCallback& callback) {
86 std::string code = base::StringPrintf(
87 "DevToolsAPI.streamFinish(%d)", stream_id_);
88 shell_->web_contents()->GetMainFrame()->ExecuteJavaScript(
89 base::UTF8ToUTF16(code));
90 return net::OK;
91 }
92
93 } // namespace
94
29 // This constant should be in sync with 95 // This constant should be in sync with
30 // the constant at devtools_ui_bindings.cc. 96 // the constant at devtools_ui_bindings.cc.
31 const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4; 97 const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4;
32 98
33 // static 99 // static
34 ShellDevToolsFrontend* ShellDevToolsFrontend::Show( 100 ShellDevToolsFrontend* ShellDevToolsFrontend::Show(
35 WebContents* inspected_contents) { 101 WebContents* inspected_contents) {
36 scoped_refptr<DevToolsAgentHost> agent( 102 scoped_refptr<DevToolsAgentHost> agent(
37 DevToolsAgentHost::GetOrCreateFor(inspected_contents)); 103 DevToolsAgentHost::GetOrCreateFor(inspected_contents));
38 Shell* shell = Shell::CreateNewWindow(inspected_contents->GetBrowserContext(), 104 Shell* shell = Shell::CreateNewWindow(inspected_contents->GetBrowserContext(),
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 } 142 }
77 143
78 ShellDevToolsFrontend::ShellDevToolsFrontend(Shell* frontend_shell, 144 ShellDevToolsFrontend::ShellDevToolsFrontend(Shell* frontend_shell,
79 DevToolsAgentHost* agent_host) 145 DevToolsAgentHost* agent_host)
80 : WebContentsObserver(frontend_shell->web_contents()), 146 : WebContentsObserver(frontend_shell->web_contents()),
81 frontend_shell_(frontend_shell), 147 frontend_shell_(frontend_shell),
82 agent_host_(agent_host) { 148 agent_host_(agent_host) {
83 } 149 }
84 150
85 ShellDevToolsFrontend::~ShellDevToolsFrontend() { 151 ShellDevToolsFrontend::~ShellDevToolsFrontend() {
152 for (const auto& pair : pending_requests_)
153 delete pair.first;
86 } 154 }
87 155
88 void ShellDevToolsFrontend::RenderViewCreated( 156 void ShellDevToolsFrontend::RenderViewCreated(
89 RenderViewHost* render_view_host) { 157 RenderViewHost* render_view_host) {
90 if (!frontend_host_) { 158 if (!frontend_host_) {
91 frontend_host_.reset( 159 frontend_host_.reset(
92 DevToolsFrontendHost::Create(web_contents()->GetMainFrame(), this)); 160 DevToolsFrontendHost::Create(web_contents()->GetMainFrame(), this));
93 } 161 }
94 } 162 }
95 163
96 void ShellDevToolsFrontend::DidNavigateMainFrame( 164 void ShellDevToolsFrontend::DidNavigateMainFrame(
97 const LoadCommittedDetails& details, 165 const LoadCommittedDetails& details,
98 const FrameNavigateParams& params) { 166 const FrameNavigateParams& params) {
99 if (agent_host_) 167 if (agent_host_)
100 agent_host_->AttachClient(this); 168 agent_host_->AttachClient(this);
101 } 169 }
102 170
103 void ShellDevToolsFrontend::WebContentsDestroyed() { 171 void ShellDevToolsFrontend::WebContentsDestroyed() {
104 if (agent_host_) 172 if (agent_host_)
105 agent_host_->DetachClient(); 173 agent_host_->DetachClient();
106 delete this; 174 delete this;
107 } 175 }
108 176
109 void ShellDevToolsFrontend::HandleMessageFromDevToolsFrontend( 177 void ShellDevToolsFrontend::HandleMessageFromDevToolsFrontend(
110 const std::string& message) { 178 const std::string& message) {
111 if (!agent_host_) 179 if (!agent_host_)
112 return; 180 return;
113 std::string method; 181 std::string method;
114 int id = 0;
115 base::ListValue* params = NULL; 182 base::ListValue* params = NULL;
116 base::DictionaryValue* dict = NULL; 183 base::DictionaryValue* dict = NULL;
117 scoped_ptr<base::Value> parsed_message(base::JSONReader::Read(message)); 184 scoped_ptr<base::Value> parsed_message(base::JSONReader::Read(message));
118 if (!parsed_message || 185 if (!parsed_message ||
119 !parsed_message->GetAsDictionary(&dict) || 186 !parsed_message->GetAsDictionary(&dict) ||
120 !dict->GetString("method", &method)) { 187 !dict->GetString("method", &method)) {
121 return; 188 return;
122 } 189 }
190 int id = 0;
191 dict->GetInteger("id", &id);
123 dict->GetList("params", &params); 192 dict->GetList("params", &params);
124 193
125 std::string browser_message; 194 std::string browser_message;
126 if (method == "sendMessageToBrowser" && params && 195 if (method == "sendMessageToBrowser" && params &&
127 params->GetSize() == 1 && params->GetString(0, &browser_message)) { 196 params->GetSize() == 1 && params->GetString(0, &browser_message)) {
128 agent_host_->DispatchProtocolMessage(browser_message); 197 agent_host_->DispatchProtocolMessage(browser_message);
129 } else if (method == "loadCompleted") { 198 } else if (method == "loadCompleted") {
130 web_contents()->GetMainFrame()->ExecuteJavaScript( 199 web_contents()->GetMainFrame()->ExecuteJavaScript(
131 base::ASCIIToUTF16("DevToolsAPI.setUseSoftMenu(true);")); 200 base::ASCIIToUTF16("DevToolsAPI.setUseSoftMenu(true);"));
201 } else if (method == "loadNetworkResource" && params->GetSize() == 3) {
202 // TODO(pfeldman): handle some of the embedder messages in content.
203 std::string url;
204 std::string headers;
205 int stream_id;
206 if (!params->GetString(0, &url) ||
207 !params->GetString(1, &headers) ||
208 !params->GetInteger(2, &stream_id)) {
209 return;
210 }
211 GURL gurl(url);
212 if (!gurl.is_valid()) {
213 std::string code = base::StringPrintf(
214 "DevToolsAPI.embedderMessageAck(%d, { statusCode: 404 });", id);
215 web_contents()->GetMainFrame()->ExecuteJavaScript(
dgozman 2015/02/27 20:23:01 Call StreamFinish.
pfeldman 2015/02/27 20:37:42 Lets make client responsible for this.
216 base::UTF8ToUTF16(code));
217 return;
218 }
219
220 net::URLFetcher* fetcher =
221 net::URLFetcher::Create(gurl, net::URLFetcher::GET, this);
222 pending_requests_[fetcher] = id;
223 fetcher->SetRequestContext(web_contents()->GetBrowserContext()->
224 GetRequestContext());
225 fetcher->SetExtraRequestHeaders(headers);
226 fetcher->SaveResponseWithWriter(scoped_ptr<net::URLFetcherResponseWriter>(
227 new ResponseWriter(frontend_shell(), stream_id)));
228 fetcher->Start();
229 return;
132 } else { 230 } else {
133 return; 231 return;
134 } 232 }
135 233
136 dict->GetInteger("id", &id);
137 if (id) { 234 if (id) {
138 std::string code = "DevToolsAPI.embedderMessageAck(" + 235 std::string code = "DevToolsAPI.embedderMessageAck(" +
139 base::IntToString(id) + ",\"\");"; 236 base::IntToString(id) + ",\"\");";
140 base::string16 javascript = base::UTF8ToUTF16(code); 237 base::string16 javascript = base::UTF8ToUTF16(code);
141 web_contents()->GetMainFrame()->ExecuteJavaScript(javascript); 238 web_contents()->GetMainFrame()->ExecuteJavaScript(javascript);
142 } 239 }
143 } 240 }
144 241
145 void ShellDevToolsFrontend::HandleMessageFromDevToolsFrontendToBackend( 242 void ShellDevToolsFrontend::HandleMessageFromDevToolsFrontendToBackend(
146 const std::string& message) { 243 const std::string& message) {
(...skipping 15 matching lines...) Expand all
162 for (size_t pos = 0; pos < message.length(); pos += kMaxMessageChunkSize) { 259 for (size_t pos = 0; pos < message.length(); pos += kMaxMessageChunkSize) {
163 base::StringValue message_value(message.substr(pos, kMaxMessageChunkSize)); 260 base::StringValue message_value(message.substr(pos, kMaxMessageChunkSize));
164 std::string param; 261 std::string param;
165 base::JSONWriter::Write(&message_value, &param); 262 base::JSONWriter::Write(&message_value, &param);
166 std::string code = "DevToolsAPI.dispatchMessageChunk(" + param + ");"; 263 std::string code = "DevToolsAPI.dispatchMessageChunk(" + param + ");";
167 base::string16 javascript = base::UTF8ToUTF16(code); 264 base::string16 javascript = base::UTF8ToUTF16(code);
168 web_contents()->GetMainFrame()->ExecuteJavaScript(javascript); 265 web_contents()->GetMainFrame()->ExecuteJavaScript(javascript);
169 } 266 }
170 } 267 }
171 268
269 void ShellDevToolsFrontend::OnURLFetchComplete(const net::URLFetcher* source) {
270 // TODO(pfeldman): this is a copy of chrome's devtools_ui_bindings.cc.
271 // We should handle some of the commands including this one in content.
272 DCHECK(source);
273 PendingRequestsMap::iterator it = pending_requests_.find(source);
274 DCHECK(it != pending_requests_.end());
275
276 base::DictionaryValue response;
277 base::DictionaryValue* headers = new base::DictionaryValue();
278 net::HttpResponseHeaders* rh = source->GetResponseHeaders();
279 response.SetInteger("statusCode", rh ? rh->response_code() : 200);
280 response.Set("headers", headers);
281
282 void* iterator = NULL;
283 std::string name;
284 std::string value;
285 while (rh && rh->EnumerateHeaderLines(&iterator, &name, &value))
286 headers->SetString(name, value);
287
288 std::string json;
289 base::JSONWriter::Write(&response, &json);
290
291 std::string message = base::StringPrintf(
292 "DevToolsAPI.embedderMessageAck(%d, %s)",
293 it->second,
294 json.c_str());
295 web_contents()->GetMainFrame()->
296 ExecuteJavaScript(base::UTF8ToUTF16(message));
297
298 pending_requests_.erase(it);
299 delete source;
300 }
301
172 void ShellDevToolsFrontend::AttachTo(WebContents* inspected_contents) { 302 void ShellDevToolsFrontend::AttachTo(WebContents* inspected_contents) {
173 DisconnectFromTarget(); 303 DisconnectFromTarget();
174 agent_host_ = DevToolsAgentHost::GetOrCreateFor(inspected_contents); 304 agent_host_ = DevToolsAgentHost::GetOrCreateFor(inspected_contents);
175 } 305 }
176 306
177 void ShellDevToolsFrontend::AgentHostClosed( 307 void ShellDevToolsFrontend::AgentHostClosed(
178 DevToolsAgentHost* agent_host, bool replaced) { 308 DevToolsAgentHost* agent_host, bool replaced) {
179 frontend_shell_->Close(); 309 frontend_shell_->Close();
180 } 310 }
181 311
182 } // namespace content 312 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698