OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |