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

Side by Side Diff: content/browser/debugger/devtools_http_handler_impl.cc

Issue 10169043: Allow customization of remote debugger URL targets. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 8 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 | Annotate | Revision Log
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 "content/browser/debugger/devtools_http_handler_impl.h" 5 #include "content/browser/debugger/devtools_http_handler_impl.h"
6 6
7 #include <algorithm>
7 #include <utility> 8 #include <utility>
8 9
9 #include "base/bind.h" 10 #include "base/bind.h"
10 #include "base/compiler_specific.h" 11 #include "base/compiler_specific.h"
11 #include "base/json/json_writer.h" 12 #include "base/json/json_writer.h"
12 #include "base/lazy_instance.h" 13 #include "base/lazy_instance.h"
13 #include "base/logging.h" 14 #include "base/logging.h"
14 #include "base/message_loop_proxy.h" 15 #include "base/message_loop_proxy.h"
15 #include "base/string_number_conversions.h" 16 #include "base/string_number_conversions.h"
16 #include "base/stringprintf.h" 17 #include "base/stringprintf.h"
(...skipping 20 matching lines...) Expand all
37 #include "net/server/http_server_request_info.h" 38 #include "net/server/http_server_request_info.h"
38 #include "net/url_request/url_request_context.h" 39 #include "net/url_request/url_request_context.h"
39 #include "net/url_request/url_request_context_getter.h" 40 #include "net/url_request/url_request_context_getter.h"
40 41
41 namespace content { 42 namespace content {
42 43
43 const int kBufferSize = 16 * 1024; 44 const int kBufferSize = 16 * 1024;
44 45
45 namespace { 46 namespace {
46 47
48 class DevToolsDefaultBindingHandler
49 : public DevToolsHttpHandlerDelegate::BindingHandler {
50 public:
51 DevToolsDefaultBindingHandler() {
52 }
53
54 virtual std::string GetRenderViewHostIdentifier(
55 RenderViewHost* rvh) OVERRIDE {
56 Target target = std::make_pair(rvh->GetProcess()->GetID(),
57 rvh->GetRoutingID());
58 targets_.push_back(target);
59 size_t index = targets_.size() - 1;
60 return base::StringPrintf("%lu", index);
pfeldman 2012/04/25 05:45:15 Nit: it might be a good time to migrate to the "<p
Marshall 2012/04/25 15:14:57 Done.
61 }
62
63 virtual RenderViewHost* GetRenderViewHostBinding(
64 const std::string& identifier) OVERRIDE {
65 size_t index;
66 if (!base::StringToSizeT(identifier, &index))
67 return NULL;
68 if (index >= targets_.size())
69 return NULL;
70
71 return RenderViewHost::FromID(targets_[index].first,
72 targets_[index].second);
73 }
74
75 virtual void ResetRenderViewHostBinding() OVERRIDE {
76 targets_.clear();
77 }
78
79 private:
80 typedef std::pair<int, int> Target;
81 std::vector<Target> targets_;
82 };
83
84
47 // An internal implementation of DevToolsClientHost that delegates 85 // An internal implementation of DevToolsClientHost that delegates
48 // messages sent for DevToolsClient to a DebuggerShell instance. 86 // messages sent for DevToolsClient to a DebuggerShell instance.
49 class DevToolsClientHostImpl : public DevToolsClientHost { 87 class DevToolsClientHostImpl : public DevToolsClientHost {
50 public: 88 public:
51 DevToolsClientHostImpl( 89 DevToolsClientHostImpl(
52 net::HttpServer* server, 90 net::HttpServer* server,
53 int connection_id) 91 int connection_id)
54 : server_(server), 92 : server_(server),
55 connection_id_(connection_id) { 93 connection_id_(connection_id) {
56 } 94 }
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 293
256 BrowserThread::PostTask( 294 BrowserThread::PostTask(
257 BrowserThread::UI, 295 BrowserThread::UI,
258 FROM_HERE, 296 FROM_HERE,
259 base::Bind( 297 base::Bind(
260 &DevToolsHttpHandlerImpl::OnCloseUI, 298 &DevToolsHttpHandlerImpl::OnCloseUI,
261 this, 299 this,
262 connection_id)); 300 connection_id));
263 } 301 }
264 302
265 struct DevToolsHttpHandlerImpl::PageInfo 303 struct DevToolsHttpHandlerImpl::PageInfo {
266 {
267 PageInfo() 304 PageInfo()
268 : id(0), 305 : attached(false) {
269 attached(false) {
270 } 306 }
271 307
272 int id; 308 std::string id;
273 std::string url; 309 std::string url;
274 bool attached; 310 bool attached;
275 std::string title; 311 std::string title;
276 std::string thumbnail_url; 312 std::string thumbnail_url;
277 std::string favicon_url; 313 std::string favicon_url;
278 base::TimeTicks last_selected_time; 314 base::TimeTicks last_selected_time;
279 }; 315 };
280 316
281 // static 317 // static
282 bool DevToolsHttpHandlerImpl::SortPageListByTime(const PageInfo& info1, 318 bool DevToolsHttpHandlerImpl::SortPageListByTime(const PageInfo& info1,
283 const PageInfo& info2) { 319 const PageInfo& info2) {
284 return info1.last_selected_time > info2.last_selected_time; 320 return info1.last_selected_time > info2.last_selected_time;
285 } 321 }
286 322
287 DevToolsHttpHandlerImpl::PageList DevToolsHttpHandlerImpl::GeneratePageList() { 323 DevToolsHttpHandlerImpl::PageList DevToolsHttpHandlerImpl::GeneratePageList() {
288 ResetRenderViewHostBinding(); 324 binding_handler_->ResetRenderViewHostBinding();
289 PageList page_list; 325 PageList page_list;
290 for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator()); 326 for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
291 !it.IsAtEnd(); it.Advance()) { 327 !it.IsAtEnd(); it.Advance()) {
292 RenderProcessHost* render_process_host = it.GetCurrentValue(); 328 RenderProcessHost* render_process_host = it.GetCurrentValue();
293 DCHECK(render_process_host); 329 DCHECK(render_process_host);
294 330
295 // Ignore processes that don't have a connection, such as crashed contents. 331 // Ignore processes that don't have a connection, such as crashed contents.
296 if (!render_process_host->HasConnection()) 332 if (!render_process_host->HasConnection())
297 continue; 333 continue;
298 334
299 RenderProcessHost::RenderWidgetHostsIterator rwit( 335 RenderProcessHost::RenderWidgetHostsIterator rwit(
300 render_process_host->GetRenderWidgetHostsIterator()); 336 render_process_host->GetRenderWidgetHostsIterator());
301 for (; !rwit.IsAtEnd(); rwit.Advance()) { 337 for (; !rwit.IsAtEnd(); rwit.Advance()) {
302 const RenderWidgetHost* widget = rwit.GetCurrentValue(); 338 const RenderWidgetHost* widget = rwit.GetCurrentValue();
303 DCHECK(widget); 339 DCHECK(widget);
304 if (!widget || !widget->IsRenderView()) 340 if (!widget || !widget->IsRenderView())
305 continue; 341 continue;
306 342
307 RenderViewHost* host = 343 RenderViewHost* host =
308 RenderViewHost::From(const_cast<RenderWidgetHost*>(widget)); 344 RenderViewHost::From(const_cast<RenderWidgetHost*>(widget));
309 content::RenderViewHostDelegate* host_delegate = host->GetDelegate(); 345 content::RenderViewHostDelegate* host_delegate = host->GetDelegate();
310 346
311 DevToolsAgentHost* agent = 347 DevToolsAgentHost* agent =
312 DevToolsAgentHostRegistry::GetDevToolsAgentHost(host); 348 DevToolsAgentHostRegistry::GetDevToolsAgentHost(host);
313 DevToolsClientHost* client_host = DevToolsManager::GetInstance()-> 349 DevToolsClientHost* client_host = DevToolsManager::GetInstance()->
314 GetDevToolsClientHostFor(agent); 350 GetDevToolsClientHostFor(agent);
315 PageInfo page_info; 351 PageInfo page_info;
316 page_info.id = BindRenderViewHost(host); 352 page_info.id = binding_handler_->GetRenderViewHostIdentifier(host);
317 page_info.attached = client_host != NULL; 353 page_info.attached = client_host != NULL;
318 page_info.url = host_delegate->GetURL().spec(); 354 page_info.url = host_delegate->GetURL().spec();
319 355
320 WebContents* web_contents = host_delegate->GetAsWebContents(); 356 WebContents* web_contents = host_delegate->GetAsWebContents();
321 if (web_contents) { 357 if (web_contents) {
322 page_info.title = UTF16ToUTF8( 358 page_info.title = UTF16ToUTF8(
323 net::EscapeForHTML(web_contents->GetTitle())); 359 net::EscapeForHTML(web_contents->GetTitle()));
324 page_info.last_selected_time = web_contents->GetLastSelectedTime(); 360 page_info.last_selected_time = web_contents->GetLastSelectedTime();
325 361
326 NavigationController& controller = web_contents->GetController(); 362 NavigationController& controller = web_contents->GetController();
(...skipping 11 matching lines...) Expand all
338 } 374 }
339 375
340 void DevToolsHttpHandlerImpl::OnJsonRequestUI( 376 void DevToolsHttpHandlerImpl::OnJsonRequestUI(
341 int connection_id, 377 int connection_id,
342 const net::HttpServerRequestInfo& info) { 378 const net::HttpServerRequestInfo& info) {
343 PageList page_list = GeneratePageList(); 379 PageList page_list = GeneratePageList();
344 ListValue json_pages_list; 380 ListValue json_pages_list;
345 std::string host = info.headers["Host"]; 381 std::string host = info.headers["Host"];
346 for (PageList::iterator i = page_list.begin(); 382 for (PageList::iterator i = page_list.begin();
347 i != page_list.end(); ++i) { 383 i != page_list.end(); ++i) {
348
349 DictionaryValue* page_info = new DictionaryValue; 384 DictionaryValue* page_info = new DictionaryValue;
350 json_pages_list.Append(page_info); 385 json_pages_list.Append(page_info);
351 page_info->SetString("title", i->title); 386 page_info->SetString("title", i->title);
352 page_info->SetString("url", i->url); 387 page_info->SetString("url", i->url);
353 page_info->SetString("thumbnailUrl", i->thumbnail_url); 388 page_info->SetString("thumbnailUrl", i->thumbnail_url);
354 page_info->SetString("faviconUrl", i->favicon_url); 389 page_info->SetString("faviconUrl", i->favicon_url);
355 if (!i->attached) { 390 if (!i->attached) {
356 page_info->SetString("webSocketDebuggerUrl", 391 page_info->SetString("webSocketDebuggerUrl",
357 base::StringPrintf("ws://%s/devtools/page/%d", 392 base::StringPrintf("ws://%s/devtools/page/%s",
358 host.c_str(), 393 host.c_str(),
359 i->id)); 394 i->id.c_str()));
360 std::string devtools_frontend_url = base::StringPrintf( 395 std::string devtools_frontend_url = base::StringPrintf(
361 "%s%sws=%s/devtools/page/%d", 396 "%s%sws=%s/devtools/page/%s",
362 overridden_frontend_url_.c_str(), 397 overridden_frontend_url_.c_str(),
363 overridden_frontend_url_.find("?") == std::string::npos ? "?" : "&", 398 overridden_frontend_url_.find("?") == std::string::npos ? "?" : "&",
364 host.c_str(), 399 host.c_str(),
365 i->id); 400 i->id.c_str());
366 page_info->SetString("devtoolsFrontendUrl", devtools_frontend_url); 401 page_info->SetString("devtoolsFrontendUrl", devtools_frontend_url);
367 } 402 }
368 } 403 }
369 404
370 std::string response; 405 std::string response;
371 base::JSONWriter::WriteWithOptions(&json_pages_list, 406 base::JSONWriter::WriteWithOptions(&json_pages_list,
372 base::JSONWriter::OPTIONS_PRETTY_PRINT, 407 base::JSONWriter::OPTIONS_PRETTY_PRINT,
373 &response); 408 &response);
374 Send200(connection_id, response, "application/json; charset=UTF-8"); 409 Send200(connection_id, response, "application/json; charset=UTF-8");
375 } 410 }
376 411
377 void DevToolsHttpHandlerImpl::OnWebSocketRequestUI( 412 void DevToolsHttpHandlerImpl::OnWebSocketRequestUI(
378 int connection_id, 413 int connection_id,
379 const net::HttpServerRequestInfo& request) { 414 const net::HttpServerRequestInfo& request) {
380 std::string prefix = "/devtools/page/"; 415 std::string prefix = "/devtools/page/";
381 size_t pos = request.path.find(prefix); 416 size_t pos = request.path.find(prefix);
382 if (pos != 0) { 417 if (pos != 0) {
383 Send404(connection_id); 418 Send404(connection_id);
384 return; 419 return;
385 } 420 }
421
386 std::string page_id = request.path.substr(prefix.length()); 422 std::string page_id = request.path.substr(prefix.length());
387 int id = 0; 423 RenderViewHost* rvh = binding_handler_->GetRenderViewHostBinding(page_id);
388 if (!base::StringToInt(page_id, &id)) {
389 Send500(connection_id, "Invalid page id: " + page_id);
390 return;
391 }
392
393 RenderViewHost* rvh = GetBoundRenderViewHost(id);
394 if (!rvh) { 424 if (!rvh) {
395 Send500(connection_id, "No such target id: " + page_id); 425 Send500(connection_id, "No such target id: " + page_id);
396 return; 426 return;
397 } 427 }
398 428
399 DevToolsManager* manager = DevToolsManager::GetInstance(); 429 DevToolsManager* manager = DevToolsManager::GetInstance();
400 DevToolsAgentHost* agent = DevToolsAgentHostRegistry::GetDevToolsAgentHost( 430 DevToolsAgentHost* agent = DevToolsAgentHostRegistry::GetDevToolsAgentHost(
401 rvh); 431 rvh);
402 if (manager->GetDevToolsClientHostFor(agent)) { 432 if (manager->GetDevToolsClientHostFor(agent)) {
403 Send500(connection_id, "Target with given id is being inspected: " + 433 Send500(connection_id, "Target with given id is being inspected: " +
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 net::URLRequestContextGetter* request_context_getter, 533 net::URLRequestContextGetter* request_context_getter,
504 DevToolsHttpHandlerDelegate* delegate) 534 DevToolsHttpHandlerDelegate* delegate)
505 : ip_(ip), 535 : ip_(ip),
506 port_(port), 536 port_(port),
507 overridden_frontend_url_(frontend_url), 537 overridden_frontend_url_(frontend_url),
508 request_context_getter_(request_context_getter), 538 request_context_getter_(request_context_getter),
509 delegate_(delegate) { 539 delegate_(delegate) {
510 if (overridden_frontend_url_.empty()) 540 if (overridden_frontend_url_.empty())
511 overridden_frontend_url_ = "/devtools/devtools.html"; 541 overridden_frontend_url_ = "/devtools/devtools.html";
512 542
543 binding_handler_.reset(delegate_->GetBindingHandler());
544 if (!binding_handler_.get())
545 binding_handler_.reset(new DevToolsDefaultBindingHandler);
546
513 AddRef(); 547 AddRef();
514 } 548 }
515 549
516 void DevToolsHttpHandlerImpl::Init() { 550 void DevToolsHttpHandlerImpl::Init() {
517 server_ = new net::HttpServer(ip_, port_, this); 551 server_ = new net::HttpServer(ip_, port_, this);
518 } 552 }
519 553
520 // Run on I/O thread 554 // Run on I/O thread
521 void DevToolsHttpHandlerImpl::TeardownAndRelease() { 555 void DevToolsHttpHandlerImpl::TeardownAndRelease() {
522 server_ = NULL; 556 server_ = NULL;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 616
583 void DevToolsHttpHandlerImpl::AcceptWebSocket( 617 void DevToolsHttpHandlerImpl::AcceptWebSocket(
584 int connection_id, 618 int connection_id,
585 const net::HttpServerRequestInfo& request) { 619 const net::HttpServerRequestInfo& request) {
586 BrowserThread::PostTask( 620 BrowserThread::PostTask(
587 BrowserThread::IO, FROM_HERE, 621 BrowserThread::IO, FROM_HERE,
588 base::Bind(&net::HttpServer::AcceptWebSocket, server_.get(), 622 base::Bind(&net::HttpServer::AcceptWebSocket, server_.get(),
589 connection_id, request)); 623 connection_id, request));
590 } 624 }
591 625
592 size_t DevToolsHttpHandlerImpl::BindRenderViewHost(RenderViewHost* rvh) {
593 Target target = std::make_pair(rvh->GetProcess()->GetID(),
594 rvh->GetRoutingID());
595 targets_.push_back(target);
596 return targets_.size() - 1;
597 }
598
599 RenderViewHost* DevToolsHttpHandlerImpl::GetBoundRenderViewHost(size_t id) {
600 return RenderViewHost::FromID(targets_[id].first,
601 targets_[id].second);
602 }
603
604 void DevToolsHttpHandlerImpl::ResetRenderViewHostBinding() {
605 targets_.clear();
606 }
607
608 } // namespace content 626 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698