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

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

Issue 11033046: DevTools: [remote debugging] introduce json/new and json/close for creating and closing the tabs. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review comments addressed Created 8 years, 2 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 <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 } else if (EndsWith(filename, ".gif", false)) { 211 } else if (EndsWith(filename, ".gif", false)) {
212 return "image/gif"; 212 return "image/gif";
213 } 213 }
214 NOTREACHED(); 214 NOTREACHED();
215 return "text/plain"; 215 return "text/plain";
216 } 216 }
217 217
218 void DevToolsHttpHandlerImpl::OnHttpRequest( 218 void DevToolsHttpHandlerImpl::OnHttpRequest(
219 int connection_id, 219 int connection_id,
220 const net::HttpServerRequestInfo& info) { 220 const net::HttpServerRequestInfo& info) {
221 if (info.path.find("/json/new") == 0) {
222 // New page request.
223 BrowserThread::PostTask(
224 BrowserThread::UI,
225 FROM_HERE,
226 base::Bind(&DevToolsHttpHandlerImpl::OnNewTargetRequestUI,
227 this,
228 connection_id,
229 info));
230 return;
231 }
232
233 if (info.path.find("/json/close/") == 0) {
234 // Close page request.
235 BrowserThread::PostTask(
236 BrowserThread::UI,
237 FROM_HERE,
238 base::Bind(&DevToolsHttpHandlerImpl::OnCloseTargetRequestUI,
239 this,
240 connection_id,
241 info));
242 return;
243 }
244
221 if (info.path.find("/json") == 0) { 245 if (info.path.find("/json") == 0) {
222 // Pages discovery json request. 246 // Pages discovery json request.
223 BrowserThread::PostTask( 247 BrowserThread::PostTask(
224 BrowserThread::UI, 248 BrowserThread::UI,
225 FROM_HERE, 249 FROM_HERE,
226 base::Bind(&DevToolsHttpHandlerImpl::OnJsonRequestUI, 250 base::Bind(&DevToolsHttpHandlerImpl::OnJsonRequestUI,
227 this, 251 this,
228 connection_id, 252 connection_id,
229 info)); 253 info));
230 return; 254 return;
231 } else if (info.path.find("/thumb/") == 0) { 255 }
256
257 if (info.path.find("/thumb/") == 0) {
232 // Thumbnail request. 258 // Thumbnail request.
233 BrowserThread::PostTask( 259 BrowserThread::PostTask(
234 BrowserThread::UI, 260 BrowserThread::UI,
235 FROM_HERE, 261 FROM_HERE,
236 base::Bind(&DevToolsHttpHandlerImpl::OnThumbnailRequestUI, 262 base::Bind(&DevToolsHttpHandlerImpl::OnThumbnailRequestUI,
237 this, 263 this,
238 connection_id, 264 connection_id,
239 info)); 265 info));
240 return; 266 return;
241 } 267 }
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 RenderProcessHost::RenderWidgetHostsIterator rwit( 371 RenderProcessHost::RenderWidgetHostsIterator rwit(
346 render_process_host->GetRenderWidgetHostsIterator()); 372 render_process_host->GetRenderWidgetHostsIterator());
347 for (; !rwit.IsAtEnd(); rwit.Advance()) { 373 for (; !rwit.IsAtEnd(); rwit.Advance()) {
348 const RenderWidgetHost* widget = rwit.GetCurrentValue(); 374 const RenderWidgetHost* widget = rwit.GetCurrentValue();
349 DCHECK(widget); 375 DCHECK(widget);
350 if (!widget || !widget->IsRenderView()) 376 if (!widget || !widget->IsRenderView())
351 continue; 377 continue;
352 378
353 RenderViewHost* host = 379 RenderViewHost* host =
354 RenderViewHost::From(const_cast<RenderWidgetHost*>(widget)); 380 RenderViewHost::From(const_cast<RenderWidgetHost*>(widget));
355 content::RenderViewHostDelegate* host_delegate = host->GetDelegate(); 381 page_list.push_back(CreatePageInfo(host));
356
357 DevToolsAgentHost* agent =
358 DevToolsAgentHostRegistry::GetDevToolsAgentHost(host);
359 DevToolsClientHost* client_host = DevToolsManager::GetInstance()->
360 GetDevToolsClientHostFor(agent);
361 PageInfo page_info;
362 page_info.id = binding_->GetIdentifier(host);
363 page_info.attached = client_host != NULL;
364 page_info.url = host_delegate->GetURL().spec();
365
366 WebContents* web_contents = host_delegate->GetAsWebContents();
367 if (web_contents) {
368 page_info.title = UTF16ToUTF8(
369 net::EscapeForHTML(web_contents->GetTitle()));
370 page_info.last_selected_time = web_contents->GetLastSelectedTime();
371
372 NavigationController& controller = web_contents->GetController();
373 NavigationEntry* entry = controller.GetActiveEntry();
374 if (entry != NULL && entry->GetURL().is_valid()) {
375 page_info.thumbnail_url = "/thumb/" + entry->GetURL().spec();
376 page_info.favicon_url = entry->GetFavicon().url.spec();
377 }
378 }
379 page_list.push_back(page_info);
380 } 382 }
381 } 383 }
382 std::sort(page_list.begin(), page_list.end(), SortPageListByTime); 384 std::sort(page_list.begin(), page_list.end(), SortPageListByTime);
383 return page_list; 385 return page_list;
384 } 386 }
385 387
386 std::string DevToolsHttpHandlerImpl::GetFrontendURLInternal( 388 std::string DevToolsHttpHandlerImpl::GetFrontendURLInternal(
387 const std::string rvh_id, 389 const std::string rvh_id,
388 const std::string& host) { 390 const std::string& host) {
389 return base::StringPrintf( 391 return base::StringPrintf(
390 "%s%sws=%s/devtools/page/%s", 392 "%s%sws=%s/devtools/page/%s",
391 overridden_frontend_url_.c_str(), 393 overridden_frontend_url_.c_str(),
392 overridden_frontend_url_.find("?") == std::string::npos ? "?" : "&", 394 overridden_frontend_url_.find("?") == std::string::npos ? "?" : "&",
393 host.c_str(), 395 host.c_str(),
394 rvh_id.c_str()); 396 rvh_id.c_str());
395 } 397 }
396 398
397 void DevToolsHttpHandlerImpl::OnJsonRequestUI( 399 void DevToolsHttpHandlerImpl::OnJsonRequestUI(
398 int connection_id, 400 int connection_id,
399 const net::HttpServerRequestInfo& info) { 401 const net::HttpServerRequestInfo& info) {
400 PageList page_list = GeneratePageList(); 402 PageList page_list = GeneratePageList();
401 ListValue json_pages_list; 403 ListValue json_pages_list;
402 std::string host = info.headers["Host"]; 404 std::string host = info.headers["Host"];
403 for (PageList::iterator i = page_list.begin(); 405 for (PageList::iterator i = page_list.begin(); i != page_list.end(); ++i)
404 i != page_list.end(); ++i) { 406 json_pages_list.Append(SerializePageInfo(*i, host));
405 DictionaryValue* page_info = new DictionaryValue; 407 SendJson(connection_id, info, json_pages_list);
406 json_pages_list.Append(page_info); 408 }
407 page_info->SetString("title", i->title); 409
408 page_info->SetString("url", i->url); 410 void DevToolsHttpHandlerImpl::OnNewTargetRequestUI(
409 page_info->SetString("thumbnailUrl", i->thumbnail_url); 411 int connection_id,
410 page_info->SetString("faviconUrl", i->favicon_url); 412 const net::HttpServerRequestInfo& info) {
411 if (!i->attached) { 413 RenderViewHost* rvh = delegate_->CreateNewTarget();
412 page_info->SetString("webSocketDebuggerUrl", 414 if (!rvh) {
413 base::StringPrintf("ws://%s/devtools/page/%s", 415 Send500(connection_id, "Could not create new page");
414 host.c_str(), 416 return;
415 i->id.c_str()));
416 std::string devtools_frontend_url = GetFrontendURLInternal(i->id.c_str(),
417 host);
418 page_info->SetString("devtoolsFrontendUrl", devtools_frontend_url);
419 }
420 } 417 }
418 PageInfo page_info = CreatePageInfo(rvh);
419 std::string host = info.headers["Host"];
420 scoped_ptr<DictionaryValue> dictionary(SerializePageInfo(page_info, host));
421 SendJson(connection_id, info, *dictionary);
422 }
421 423
422 std::string response; 424 void DevToolsHttpHandlerImpl::OnCloseTargetRequestUI(
423 base::JSONWriter::WriteWithOptions(&json_pages_list, 425 int connection_id,
424 base::JSONWriter::OPTIONS_PRETTY_PRINT, 426 const net::HttpServerRequestInfo& info) {
425 &response); 427 std::string prefix = "/json/close/";
426 428 std::string page_id = info.path.substr(prefix.length());
427 size_t jsonp_pos = info.path.find("?jsonp="); 429 RenderViewHost* rvh = binding_->ForIdentifier(page_id);
428 if (jsonp_pos == std::string::npos) { 430 if (!rvh) {
429 Send200(connection_id, response, "application/json; charset=UTF-8"); 431 Send500(connection_id, "No such target id: " + page_id);
430 return; 432 return;
431 } 433 }
432 434
433 std::string jsonp = info.path.substr(jsonp_pos + 7); 435 rvh->ClosePage();
434 response = StringPrintf("%s(%s);", jsonp.c_str(), response.c_str()); 436 Send200(connection_id, "Target is closing");
435 Send200(connection_id, response, "text/javascript; charset=UTF-8");
436 } 437 }
437 438
438 void DevToolsHttpHandlerImpl::OnThumbnailRequestUI( 439 void DevToolsHttpHandlerImpl::OnThumbnailRequestUI(
439 int connection_id, 440 int connection_id,
440 const net::HttpServerRequestInfo& info) { 441 const net::HttpServerRequestInfo& info) {
441 std::string prefix = "/thumb/"; 442 std::string prefix = "/thumb/";
442 size_t pos = info.path.find(prefix); 443 size_t pos = info.path.find(prefix);
443 if (pos != 0) { 444 if (pos != 0) {
444 Send404(connection_id); 445 Send404(connection_id);
445 return; 446 return;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 // Run on the handler thread 541 // Run on the handler thread
541 void DevToolsHttpHandlerImpl::TeardownAndRelease() { 542 void DevToolsHttpHandlerImpl::TeardownAndRelease() {
542 server_ = NULL; 543 server_ = NULL;
543 544
544 BrowserThread::PostTask( 545 BrowserThread::PostTask(
545 BrowserThread::UI, FROM_HERE, 546 BrowserThread::UI, FROM_HERE,
546 base::Bind(&DevToolsHttpHandlerImpl::Release, this)); 547 base::Bind(&DevToolsHttpHandlerImpl::Release, this));
547 } 548 }
548 549
549 void DevToolsHttpHandlerImpl::Send200(int connection_id, 550 void DevToolsHttpHandlerImpl::Send200(int connection_id,
550 const std::string& data, 551 const std::string& data,
551 const std::string& mime_type) { 552 const std::string& mime_type) {
552 thread_->message_loop()->PostTask( 553 thread_->message_loop()->PostTask(
553 FROM_HERE, 554 FROM_HERE,
554 base::Bind(&net::HttpServer::Send200, 555 base::Bind(&net::HttpServer::Send200,
555 server_.get(), 556 server_.get(),
556 connection_id, 557 connection_id,
557 data, 558 data,
558 mime_type)); 559 mime_type));
559 } 560 }
560 561
562 void DevToolsHttpHandlerImpl::SendJson(int connection_id,
563 const net::HttpServerRequestInfo& info,
564 const Value& value) {
565 std::string response;
566 base::JSONWriter::WriteWithOptions(&value,
567 base::JSONWriter::OPTIONS_PRETTY_PRINT,
568 &response);
569
570 size_t jsonp_pos = info.path.find("?jsonp=");
571 if (jsonp_pos == std::string::npos) {
572 Send200(connection_id, response, "application/json; charset=UTF-8");
573 return;
574 }
575
576 std::string jsonp = info.path.substr(jsonp_pos + 7);
577 response = StringPrintf("%s(%s);", jsonp.c_str(), response.c_str());
578 Send200(connection_id, response, "text/javascript; charset=UTF-8");
579 }
580
561 void DevToolsHttpHandlerImpl::Send404(int connection_id) { 581 void DevToolsHttpHandlerImpl::Send404(int connection_id) {
562 thread_->message_loop()->PostTask( 582 thread_->message_loop()->PostTask(
563 FROM_HERE, 583 FROM_HERE,
564 base::Bind(&net::HttpServer::Send404, server_.get(), connection_id)); 584 base::Bind(&net::HttpServer::Send404, server_.get(), connection_id));
565 } 585 }
566 586
567 void DevToolsHttpHandlerImpl::Send500(int connection_id, 587 void DevToolsHttpHandlerImpl::Send500(int connection_id,
568 const std::string& message) { 588 const std::string& message) {
569 thread_->message_loop()->PostTask( 589 thread_->message_loop()->PostTask(
570 FROM_HERE, 590 FROM_HERE,
571 base::Bind(&net::HttpServer::Send500, server_.get(), connection_id, 591 base::Bind(&net::HttpServer::Send500, server_.get(), connection_id,
572 message)); 592 message));
573 } 593 }
574 594
575 void DevToolsHttpHandlerImpl::AcceptWebSocket( 595 void DevToolsHttpHandlerImpl::AcceptWebSocket(
576 int connection_id, 596 int connection_id,
577 const net::HttpServerRequestInfo& request) { 597 const net::HttpServerRequestInfo& request) {
578 thread_->message_loop()->PostTask( 598 thread_->message_loop()->PostTask(
579 FROM_HERE, 599 FROM_HERE,
580 base::Bind(&net::HttpServer::AcceptWebSocket, server_.get(), 600 base::Bind(&net::HttpServer::AcceptWebSocket, server_.get(),
581 connection_id, request)); 601 connection_id, request));
582 } 602 }
583 603
604 DevToolsHttpHandlerImpl::PageInfo
605 DevToolsHttpHandlerImpl::CreatePageInfo(RenderViewHost* rvh)
606 {
607 content::RenderViewHostDelegate* host_delegate = rvh->GetDelegate();
608 DevToolsAgentHost* agent =
609 DevToolsAgentHostRegistry::GetDevToolsAgentHost(rvh);
610 DevToolsClientHost* client_host = DevToolsManager::GetInstance()->
611 GetDevToolsClientHostFor(agent);
612 PageInfo page_info;
613 page_info.id = binding_->GetIdentifier(rvh);
614 page_info.attached = client_host != NULL;
615 page_info.url = host_delegate->GetURL().spec();
616
617 WebContents* web_contents = host_delegate->GetAsWebContents();
618 if (web_contents) {
619 page_info.title = UTF16ToUTF8(
620 net::EscapeForHTML(web_contents->GetTitle()));
621 page_info.last_selected_time = web_contents->GetLastSelectedTime();
622
623 NavigationController& controller = web_contents->GetController();
624 NavigationEntry* entry = controller.GetActiveEntry();
625 if (entry != NULL && entry->GetURL().is_valid()) {
626 page_info.thumbnail_url = "/thumb/" + entry->GetURL().spec();
627 page_info.favicon_url = entry->GetFavicon().url.spec();
628 }
629 }
630 return page_info;
631 }
632
633 DictionaryValue* DevToolsHttpHandlerImpl::SerializePageInfo(
634 const PageInfo& page_info,
635 const std::string& host) {
636 DictionaryValue* dictionary = new DictionaryValue;
637 dictionary->SetString("title", page_info.title);
638 dictionary->SetString("url", page_info.url);
639 dictionary->SetString("thumbnailUrl", page_info.thumbnail_url);
640 dictionary->SetString("faviconUrl", page_info.favicon_url);
641 if (!page_info.attached) {
642 dictionary->SetString("webSocketDebuggerUrl",
643 base::StringPrintf("ws://%s/devtools/page/%s",
644 host.c_str(),
645 page_info.id.c_str()));
646 std::string devtools_frontend_url = GetFrontendURLInternal(
647 page_info.id.c_str(),
648 host);
649 dictionary->SetString("devtoolsFrontendUrl", devtools_frontend_url);
650 }
651 return dictionary;
652 }
653
584 } // namespace content 654 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698