| 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/devtools/devtools_http_handler_impl.h" | 5 #include "content/browser/devtools/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" |
| 11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
| 12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
| 13 #include "base/json/json_writer.h" | 13 #include "base/json/json_writer.h" |
| 14 #include "base/lazy_instance.h" | |
| 15 #include "base/logging.h" | 14 #include "base/logging.h" |
| 16 #include "base/message_loop/message_loop_proxy.h" | 15 #include "base/message_loop/message_loop_proxy.h" |
| 17 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
| 18 #include "base/strings/string_number_conversions.h" | |
| 19 #include "base/strings/utf_string_conversions.h" | |
| 20 #include "base/threading/thread.h" | 17 #include "base/threading/thread.h" |
| 21 #include "base/values.h" | 18 #include "base/values.h" |
| 22 #include "content/browser/devtools/devtools_browser_target.h" | 19 #include "content/browser/devtools/devtools_browser_target.h" |
| 23 #include "content/browser/devtools/devtools_protocol.h" | 20 #include "content/browser/devtools/devtools_protocol.h" |
| 24 #include "content/browser/devtools/devtools_protocol_constants.h" | 21 #include "content/browser/devtools/devtools_protocol_constants.h" |
| 25 #include "content/browser/devtools/devtools_system_info_handler.h" | 22 #include "content/browser/devtools/devtools_system_info_handler.h" |
| 26 #include "content/browser/devtools/devtools_tracing_handler.h" | 23 #include "content/browser/devtools/devtools_tracing_handler.h" |
| 27 #include "content/browser/devtools/tethering_handler.h" | 24 #include "content/browser/devtools/tethering_handler.h" |
| 28 #include "content/browser/web_contents/web_contents_impl.h" | |
| 29 #include "content/common/devtools_messages.h" | 25 #include "content/common/devtools_messages.h" |
| 30 #include "content/public/browser/browser_thread.h" | 26 #include "content/public/browser/browser_thread.h" |
| 31 #include "content/public/browser/devtools_agent_host.h" | 27 #include "content/public/browser/devtools_agent_host.h" |
| 32 #include "content/public/browser/devtools_client_host.h" | 28 #include "content/public/browser/devtools_client_host.h" |
| 33 #include "content/public/browser/devtools_http_handler_delegate.h" | 29 #include "content/public/browser/devtools_http_handler_delegate.h" |
| 34 #include "content/public/browser/devtools_manager.h" | 30 #include "content/public/browser/devtools_manager.h" |
| 35 #include "content/public/browser/favicon_status.h" | |
| 36 #include "content/public/browser/navigation_entry.h" | |
| 37 #include "content/public/browser/notification_service.h" | |
| 38 #include "content/public/browser/notification_types.h" | |
| 39 #include "content/public/browser/render_view_host.h" | |
| 40 #include "content/public/common/content_client.h" | 31 #include "content/public/common/content_client.h" |
| 41 #include "content/public/common/url_constants.h" | 32 #include "content/public/common/url_constants.h" |
| 42 #include "grit/devtools_resources_map.h" | 33 #include "grit/devtools_resources_map.h" |
| 43 #include "net/base/escape.h" | |
| 44 #include "net/base/io_buffer.h" | 34 #include "net/base/io_buffer.h" |
| 45 #include "net/base/ip_endpoint.h" | 35 #include "net/base/ip_endpoint.h" |
| 46 #include "net/server/http_server_request_info.h" | 36 #include "net/server/http_server_request_info.h" |
| 47 #include "net/server/http_server_response_info.h" | 37 #include "net/server/http_server_response_info.h" |
| 48 #include "ui/base/layout.h" | |
| 49 #include "url/gurl.h" | |
| 50 #include "webkit/common/user_agent/user_agent.h" | 38 #include "webkit/common/user_agent/user_agent.h" |
| 51 #include "webkit/common/user_agent/user_agent_util.h" | 39 #include "webkit/common/user_agent/user_agent_util.h" |
| 52 | 40 |
| 53 namespace content { | 41 namespace content { |
| 54 | 42 |
| 55 namespace { | 43 namespace { |
| 56 | 44 |
| 57 const char kProtocolVersion[] = "1.0"; | 45 const char kProtocolVersion[] = "1.0"; |
| 58 | 46 |
| 59 const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread"; | 47 const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread"; |
| 60 | 48 |
| 61 const char kThumbUrlPrefix[] = "/thumb/"; | 49 const char kThumbUrlPrefix[] = "/thumb/"; |
| 62 const char kPageUrlPrefix[] = "/devtools/page/"; | 50 const char kPageUrlPrefix[] = "/devtools/page/"; |
| 63 | 51 |
| 64 const char kTargetIdField[] = "id"; | 52 const char kTargetIdField[] = "id"; |
| 65 const char kTargetTypeField[] = "type"; | 53 const char kTargetTypeField[] = "type"; |
| 66 const char kTargetTitleField[] = "title"; | 54 const char kTargetTitleField[] = "title"; |
| 67 const char kTargetDescriptionField[] = "description"; | 55 const char kTargetDescriptionField[] = "description"; |
| 68 const char kTargetUrlField[] = "url"; | 56 const char kTargetUrlField[] = "url"; |
| 69 const char kTargetThumbnailUrlField[] = "thumbnailUrl"; | 57 const char kTargetThumbnailUrlField[] = "thumbnailUrl"; |
| 70 const char kTargetFaviconUrlField[] = "faviconUrl"; | 58 const char kTargetFaviconUrlField[] = "faviconUrl"; |
| 71 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl"; | 59 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl"; |
| 72 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl"; | 60 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl"; |
| 73 | 61 |
| 74 const char kTargetTypePage[] = "page"; | |
| 75 const char kTargetTypeOther[] = "other"; | |
| 76 | |
| 77 class DevToolsDefaultBindingHandler | |
| 78 : public DevToolsHttpHandler::DevToolsAgentHostBinding { | |
| 79 public: | |
| 80 DevToolsDefaultBindingHandler() { | |
| 81 } | |
| 82 | |
| 83 virtual std::string GetIdentifier(DevToolsAgentHost* agent_host) OVERRIDE { | |
| 84 return agent_host->GetId(); | |
| 85 } | |
| 86 | |
| 87 virtual DevToolsAgentHost* ForIdentifier(const std::string& id) OVERRIDE { | |
| 88 return DevToolsAgentHost::GetForId(id).get(); | |
| 89 } | |
| 90 }; | |
| 91 | |
| 92 // An internal implementation of DevToolsClientHost that delegates | 62 // An internal implementation of DevToolsClientHost that delegates |
| 93 // messages sent for DevToolsClient to a DebuggerShell instance. | 63 // messages sent for DevToolsClient to a DebuggerShell instance. |
| 94 class DevToolsClientHostImpl : public DevToolsClientHost { | 64 class DevToolsClientHostImpl : public DevToolsClientHost { |
| 95 public: | 65 public: |
| 96 DevToolsClientHostImpl(base::MessageLoop* message_loop, | 66 DevToolsClientHostImpl(base::MessageLoop* message_loop, |
| 97 net::HttpServer* server, | 67 net::HttpServer* server, |
| 98 int connection_id) | 68 int connection_id) |
| 99 : message_loop_(message_loop), | 69 : message_loop_(message_loop), |
| 100 server_(server), | 70 server_(server), |
| 101 connection_id_(connection_id), | 71 connection_id_(connection_id), |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 } | 112 } |
| 143 | 113 |
| 144 private: | 114 private: |
| 145 base::MessageLoop* message_loop_; | 115 base::MessageLoop* message_loop_; |
| 146 net::HttpServer* server_; | 116 net::HttpServer* server_; |
| 147 int connection_id_; | 117 int connection_id_; |
| 148 bool is_closed_; | 118 bool is_closed_; |
| 149 std::string detach_reason_; | 119 std::string detach_reason_; |
| 150 }; | 120 }; |
| 151 | 121 |
| 152 static base::TimeTicks GetLastSelectedTime(RenderViewHost* rvh) { | 122 static bool TimeComparator(scoped_refptr<DevToolsTarget> target1, |
| 153 WebContents* web_contents = rvh->GetDelegate()->GetAsWebContents(); | 123 scoped_refptr<DevToolsTarget> target2) { |
| 154 if (!web_contents) | 124 return target1->GetLastActivityTime() > target2->GetLastActivityTime(); |
| 155 return base::TimeTicks(); | |
| 156 | |
| 157 return web_contents->GetLastSelectedTime(); | |
| 158 } | |
| 159 | |
| 160 typedef std::pair<RenderViewHost*, base::TimeTicks> PageInfo; | |
| 161 | |
| 162 static bool TimeComparator(const PageInfo& info1, const PageInfo& info2) { | |
| 163 return info1.second > info2.second; | |
| 164 } | 125 } |
| 165 | 126 |
| 166 } // namespace | 127 } // namespace |
| 167 | 128 |
| 168 // static | 129 // static |
| 169 bool DevToolsHttpHandler::IsSupportedProtocolVersion( | 130 bool DevToolsHttpHandler::IsSupportedProtocolVersion( |
| 170 const std::string& version) { | 131 const std::string& version) { |
| 171 return version == kProtocolVersion; | 132 return version == kProtocolVersion; |
| 172 } | 133 } |
| 173 | 134 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 | 197 |
| 237 void DevToolsHttpHandlerImpl::Stop() { | 198 void DevToolsHttpHandlerImpl::Stop() { |
| 238 if (!thread_) | 199 if (!thread_) |
| 239 return; | 200 return; |
| 240 BrowserThread::PostTaskAndReply( | 201 BrowserThread::PostTaskAndReply( |
| 241 BrowserThread::FILE, FROM_HERE, | 202 BrowserThread::FILE, FROM_HERE, |
| 242 base::Bind(&DevToolsHttpHandlerImpl::StopHandlerThread, this), | 203 base::Bind(&DevToolsHttpHandlerImpl::StopHandlerThread, this), |
| 243 base::Bind(&DevToolsHttpHandlerImpl::ResetHandlerThreadAndRelease, this)); | 204 base::Bind(&DevToolsHttpHandlerImpl::ResetHandlerThreadAndRelease, this)); |
| 244 } | 205 } |
| 245 | 206 |
| 246 void DevToolsHttpHandlerImpl::SetDevToolsAgentHostBinding( | 207 GURL DevToolsHttpHandlerImpl::GetFrontendURL() { |
| 247 DevToolsAgentHostBinding* binding) { | |
| 248 if (binding) | |
| 249 binding_ = binding; | |
| 250 else | |
| 251 binding_ = default_binding_.get(); | |
| 252 } | |
| 253 | |
| 254 GURL DevToolsHttpHandlerImpl::GetFrontendURL(DevToolsAgentHost* agent_host) { | |
| 255 net::IPEndPoint ip_address; | 208 net::IPEndPoint ip_address; |
| 256 if (server_->GetLocalAddress(&ip_address)) | 209 if (server_->GetLocalAddress(&ip_address)) |
| 257 return GURL(); | 210 return GURL(); |
| 258 if (!agent_host) { | 211 return GURL(std::string("http://") + ip_address.ToString() + |
| 259 return GURL(std::string("http://") + ip_address.ToString() + | 212 overridden_frontend_url_); |
| 260 overridden_frontend_url_); | |
| 261 } | |
| 262 std::string host = ip_address.ToString(); | |
| 263 std::string id = binding_->GetIdentifier(agent_host); | |
| 264 return GURL(std::string("http://") + | |
| 265 ip_address.ToString() + | |
| 266 GetFrontendURLInternal(id, host)); | |
| 267 } | 213 } |
| 268 | 214 |
| 269 static std::string PathWithoutParams(const std::string& path) { | 215 static std::string PathWithoutParams(const std::string& path) { |
| 270 size_t query_position = path.find("?"); | 216 size_t query_position = path.find("?"); |
| 271 if (query_position != std::string::npos) | 217 if (query_position != std::string::npos) |
| 272 return path.substr(0, query_position); | 218 return path.substr(0, query_position); |
| 273 return path; | 219 return path; |
| 274 } | 220 } |
| 275 | 221 |
| 276 static std::string GetMimeType(const std::string& filename) { | 222 static std::string GetMimeType(const std::string& filename) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 299 base::Bind(&DevToolsHttpHandlerImpl::OnJsonRequestUI, | 245 base::Bind(&DevToolsHttpHandlerImpl::OnJsonRequestUI, |
| 300 this, | 246 this, |
| 301 connection_id, | 247 connection_id, |
| 302 info)); | 248 info)); |
| 303 return; | 249 return; |
| 304 } | 250 } |
| 305 | 251 |
| 306 if (info.path.find(kThumbUrlPrefix) == 0) { | 252 if (info.path.find(kThumbUrlPrefix) == 0) { |
| 307 // Thumbnail request. | 253 // Thumbnail request. |
| 308 const std::string target_id = info.path.substr(strlen(kThumbUrlPrefix)); | 254 const std::string target_id = info.path.substr(strlen(kThumbUrlPrefix)); |
| 309 DevToolsAgentHost* agent_host = binding_->ForIdentifier(target_id); | 255 scoped_refptr<DevToolsTarget> target = GetTarget(target_id); |
| 310 GURL page_url; | 256 GURL page_url; |
| 311 if (agent_host) { | 257 if (target) |
| 312 RenderViewHost* rvh = agent_host->GetRenderViewHost(); | 258 page_url = target->GetUrl(); |
| 313 if (rvh) | |
| 314 page_url = rvh->GetDelegate()->GetURL(); | |
| 315 } | |
| 316 BrowserThread::PostTask( | 259 BrowserThread::PostTask( |
| 317 BrowserThread::UI, | 260 BrowserThread::UI, |
| 318 FROM_HERE, | 261 FROM_HERE, |
| 319 base::Bind(&DevToolsHttpHandlerImpl::OnThumbnailRequestUI, | 262 base::Bind(&DevToolsHttpHandlerImpl::OnThumbnailRequestUI, |
| 320 this, | 263 this, |
| 321 connection_id, | 264 connection_id, |
| 322 page_url)); | 265 page_url)); |
| 323 return; | 266 return; |
| 324 } | 267 } |
| 325 | 268 |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 version.SetString("Protocol-Version", kProtocolVersion); | 445 version.SetString("Protocol-Version", kProtocolVersion); |
| 503 version.SetString("WebKit-Version", webkit_glue::GetWebKitVersion()); | 446 version.SetString("WebKit-Version", webkit_glue::GetWebKitVersion()); |
| 504 version.SetString("Browser", content::GetContentClient()->GetProduct()); | 447 version.SetString("Browser", content::GetContentClient()->GetProduct()); |
| 505 version.SetString("User-Agent", | 448 version.SetString("User-Agent", |
| 506 webkit_glue::GetUserAgent(GURL(kAboutBlankURL))); | 449 webkit_glue::GetUserAgent(GURL(kAboutBlankURL))); |
| 507 SendJson(connection_id, net::HTTP_OK, &version, std::string()); | 450 SendJson(connection_id, net::HTTP_OK, &version, std::string()); |
| 508 return; | 451 return; |
| 509 } | 452 } |
| 510 | 453 |
| 511 if (command == "list") { | 454 if (command == "list") { |
| 512 typedef std::vector<PageInfo> PageList; | |
| 513 PageList page_list; | |
| 514 | |
| 515 std::vector<RenderViewHost*> rvh_list = | |
| 516 DevToolsAgentHost::GetValidRenderViewHosts(); | |
| 517 for (std::vector<RenderViewHost*>::iterator it = rvh_list.begin(); | |
| 518 it != rvh_list.end(); ++it) | |
| 519 page_list.push_back(PageInfo(*it, GetLastSelectedTime(*it))); | |
| 520 | |
| 521 std::sort(page_list.begin(), page_list.end(), TimeComparator); | |
| 522 | |
| 523 base::ListValue* target_list = new base::ListValue(); | |
| 524 std::string host = info.headers["host"]; | 455 std::string host = info.headers["host"]; |
| 525 for (PageList::iterator i = page_list.begin(); i != page_list.end(); ++i) | 456 AddRef(); // Balanced in OnTargetListReceived. |
| 526 target_list->Append(SerializePageInfo(i->first, host)); | 457 delegate_->EnumerateTargets( |
| 527 | 458 base::Bind(&DevToolsHttpHandlerImpl::OnTargetListReceived, |
| 528 AddRef(); // Balanced in SendTargetList. | 459 this, connection_id, host)); |
| 529 BrowserThread::PostTaskAndReply( | |
| 530 BrowserThread::IO, | |
| 531 FROM_HERE, | |
| 532 base::Bind(&DevToolsHttpHandlerImpl::CollectWorkerInfo, | |
| 533 base::Unretained(this), | |
| 534 target_list, | |
| 535 host), | |
| 536 base::Bind(&DevToolsHttpHandlerImpl::SendTargetList, | |
| 537 base::Unretained(this), | |
| 538 connection_id, | |
| 539 target_list)); | |
| 540 return; | 460 return; |
| 541 } | 461 } |
| 542 | 462 |
| 543 if (command == "new") { | 463 if (command == "new") { |
| 544 RenderViewHost* rvh = delegate_->CreateNewTarget(); | 464 scoped_refptr<DevToolsTarget> target = delegate_->CreateNewTarget(); |
| 545 if (!rvh) { | 465 if (!target) { |
| 546 SendJson(connection_id, | 466 SendJson(connection_id, |
| 547 net::HTTP_INTERNAL_SERVER_ERROR, | 467 net::HTTP_INTERNAL_SERVER_ERROR, |
| 548 NULL, | 468 NULL, |
| 549 "Could not create new page"); | 469 "Could not create new page"); |
| 550 return; | 470 return; |
| 551 } | 471 } |
| 472 target_map_[target->GetId()] = target; |
| 552 std::string host = info.headers["host"]; | 473 std::string host = info.headers["host"]; |
| 553 scoped_ptr<base::DictionaryValue> dictionary(SerializePageInfo(rvh, host)); | 474 scoped_ptr<base::DictionaryValue> dictionary( |
| 475 SerializeTarget(*target.get(), host)); |
| 554 SendJson(connection_id, net::HTTP_OK, dictionary.get(), std::string()); | 476 SendJson(connection_id, net::HTTP_OK, dictionary.get(), std::string()); |
| 555 return; | 477 return; |
| 556 } | 478 } |
| 557 | 479 |
| 558 if (command == "activate" || command == "close") { | 480 if (command == "activate" || command == "close") { |
| 559 DevToolsAgentHost* agent_host = binding_->ForIdentifier(target_id); | 481 DevToolsTarget* target = GetTarget(target_id); |
| 560 RenderViewHost* rvh = agent_host ? agent_host->GetRenderViewHost() : NULL; | 482 if (!target) { |
| 561 if (!rvh) { | |
| 562 SendJson(connection_id, | 483 SendJson(connection_id, |
| 563 net::HTTP_NOT_FOUND, | 484 net::HTTP_NOT_FOUND, |
| 564 NULL, | 485 NULL, |
| 565 "No such target id: " + target_id); | 486 "No such target id: " + target_id); |
| 566 return; | 487 return; |
| 567 } | 488 } |
| 568 | 489 |
| 569 if (command == "activate") { | 490 if (command == "activate") { |
| 570 rvh->GetDelegate()->Activate(); | 491 if (target->Activate()) { |
| 571 SendJson(connection_id, net::HTTP_OK, NULL, "Target activated"); | 492 SendJson(connection_id, net::HTTP_OK, NULL, "Target activated"); |
| 493 } else { |
| 494 SendJson(connection_id, |
| 495 net::HTTP_INTERNAL_SERVER_ERROR, |
| 496 NULL, |
| 497 "Could not activate target id: " + target_id); |
| 498 } |
| 572 return; | 499 return; |
| 573 } | 500 } |
| 574 | 501 |
| 575 if (command == "close") { | 502 if (command == "close") { |
| 576 rvh->ClosePage(); | 503 if (target->Close()) { |
| 577 SendJson(connection_id, net::HTTP_OK, NULL, "Target is closing"); | 504 SendJson(connection_id, net::HTTP_OK, NULL, "Target is closing"); |
| 505 } else { |
| 506 SendJson(connection_id, |
| 507 net::HTTP_INTERNAL_SERVER_ERROR, |
| 508 NULL, |
| 509 "Could not close target id: " + target_id); |
| 510 } |
| 578 return; | 511 return; |
| 579 } | 512 } |
| 580 } | 513 } |
| 581 SendJson(connection_id, | 514 SendJson(connection_id, |
| 582 net::HTTP_NOT_FOUND, | 515 net::HTTP_NOT_FOUND, |
| 583 NULL, | 516 NULL, |
| 584 "Unknown command: " + command); | 517 "Unknown command: " + command); |
| 585 return; | 518 return; |
| 586 } | 519 } |
| 587 | 520 |
| 588 void DevToolsHttpHandlerImpl::CollectWorkerInfo(base::ListValue* target_list, | 521 void DevToolsHttpHandlerImpl::OnTargetListReceived( |
| 589 std::string host) { | 522 int connection_id, |
| 523 const std::string& host, |
| 524 const DevToolsHttpHandlerDelegate::TargetList& targets) { |
| 525 DevToolsHttpHandlerDelegate::TargetList sorted_targets = targets; |
| 526 std::sort(sorted_targets.begin(), sorted_targets.end(), TimeComparator); |
| 590 | 527 |
| 591 std::vector<WorkerService::WorkerInfo> worker_info = | 528 target_map_.clear(); |
| 592 WorkerService::GetInstance()->GetWorkers(); | 529 base::ListValue list_value; |
| 593 | 530 for (DevToolsHttpHandlerDelegate::TargetList::const_iterator it = |
| 594 for (size_t i = 0; i < worker_info.size(); ++i) | 531 sorted_targets.begin(); it != sorted_targets.end(); ++it) { |
| 595 target_list->Append(SerializeWorkerInfo(worker_info[i], host)); | 532 scoped_refptr<DevToolsTarget> target = *it; |
| 533 target_map_[target->GetId()] = target; |
| 534 list_value.Append(SerializeTarget(*(target.get()), host)); |
| 535 } |
| 536 SendJson(connection_id, net::HTTP_OK, &list_value, std::string()); |
| 537 Release(); // Balanced in OnJsonRequestUI. |
| 596 } | 538 } |
| 597 | 539 |
| 598 void DevToolsHttpHandlerImpl::SendTargetList(int connection_id, | 540 DevToolsTarget* DevToolsHttpHandlerImpl::GetTarget(const std::string& id) { |
| 599 base::ListValue* target_list) { | 541 TargetMap::iterator it = target_map_.find(id); |
| 600 SendJson(connection_id, net::HTTP_OK, target_list, std::string()); | 542 if (it == target_map_.end()) |
| 601 delete target_list; | 543 return NULL; |
| 602 Release(); // Balanced OnJsonRequestUI. | 544 return it->second.get(); |
| 603 } | 545 } |
| 604 | 546 |
| 605 void DevToolsHttpHandlerImpl::OnThumbnailRequestUI( | 547 void DevToolsHttpHandlerImpl::OnThumbnailRequestUI( |
| 606 int connection_id, const GURL& page_url) { | 548 int connection_id, const GURL& page_url) { |
| 607 std::string data = delegate_->GetPageThumbnailData(page_url); | 549 std::string data = delegate_->GetPageThumbnailData(page_url); |
| 608 if (!data.empty()) | 550 if (!data.empty()) |
| 609 Send200(connection_id, data, "image/png"); | 551 Send200(connection_id, data, "image/png"); |
| 610 else | 552 else |
| 611 Send404(connection_id); | 553 Send404(connection_id); |
| 612 } | 554 } |
| 613 | 555 |
| 614 void DevToolsHttpHandlerImpl::OnDiscoveryPageRequestUI(int connection_id) { | 556 void DevToolsHttpHandlerImpl::OnDiscoveryPageRequestUI(int connection_id) { |
| 615 std::string response = delegate_->GetDiscoveryPageHTML(); | 557 std::string response = delegate_->GetDiscoveryPageHTML(); |
| 616 Send200(connection_id, response, "text/html; charset=UTF-8"); | 558 Send200(connection_id, response, "text/html; charset=UTF-8"); |
| 617 } | 559 } |
| 618 | 560 |
| 619 void DevToolsHttpHandlerImpl::OnWebSocketRequestUI( | 561 void DevToolsHttpHandlerImpl::OnWebSocketRequestUI( |
| 620 int connection_id, | 562 int connection_id, |
| 621 const net::HttpServerRequestInfo& request) { | 563 const net::HttpServerRequestInfo& request) { |
| 622 if (!thread_) | 564 if (!thread_) |
| 623 return; | 565 return; |
| 624 | 566 |
| 625 size_t pos = request.path.find(kPageUrlPrefix); | 567 size_t pos = request.path.find(kPageUrlPrefix); |
| 626 if (pos != 0) { | 568 if (pos != 0) { |
| 627 Send404(connection_id); | 569 Send404(connection_id); |
| 628 return; | 570 return; |
| 629 } | 571 } |
| 630 | 572 |
| 631 std::string page_id = request.path.substr(strlen(kPageUrlPrefix)); | 573 std::string page_id = request.path.substr(strlen(kPageUrlPrefix)); |
| 632 DevToolsAgentHost* agent = binding_->ForIdentifier(page_id); | 574 DevToolsTarget* target = GetTarget(page_id); |
| 575 scoped_refptr<DevToolsAgentHost> agent = |
| 576 target ? target->GetAgentHost() : NULL; |
| 633 if (!agent) { | 577 if (!agent) { |
| 634 Send500(connection_id, "No such target id: " + page_id); | 578 Send500(connection_id, "No such target id: " + page_id); |
| 635 return; | 579 return; |
| 636 } | 580 } |
| 637 | 581 |
| 638 if (agent->IsAttached()) { | 582 if (agent->IsAttached()) { |
| 639 Send500(connection_id, | 583 Send500(connection_id, |
| 640 "Target with given id is being inspected: " + page_id); | 584 "Target with given id is being inspected: " + page_id); |
| 641 return; | 585 return; |
| 642 } | 586 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 678 DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl( | 622 DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl( |
| 679 const net::StreamListenSocketFactory* socket_factory, | 623 const net::StreamListenSocketFactory* socket_factory, |
| 680 const std::string& frontend_url, | 624 const std::string& frontend_url, |
| 681 DevToolsHttpHandlerDelegate* delegate) | 625 DevToolsHttpHandlerDelegate* delegate) |
| 682 : overridden_frontend_url_(frontend_url), | 626 : overridden_frontend_url_(frontend_url), |
| 683 socket_factory_(socket_factory), | 627 socket_factory_(socket_factory), |
| 684 delegate_(delegate) { | 628 delegate_(delegate) { |
| 685 if (overridden_frontend_url_.empty()) | 629 if (overridden_frontend_url_.empty()) |
| 686 overridden_frontend_url_ = "/devtools/devtools.html"; | 630 overridden_frontend_url_ = "/devtools/devtools.html"; |
| 687 | 631 |
| 688 default_binding_.reset(new DevToolsDefaultBindingHandler); | |
| 689 binding_ = default_binding_.get(); | |
| 690 | |
| 691 // Balanced in ResetHandlerThreadAndRelease(). | 632 // Balanced in ResetHandlerThreadAndRelease(). |
| 692 AddRef(); | 633 AddRef(); |
| 693 } | 634 } |
| 694 | 635 |
| 695 // Runs on the handler thread | 636 // Runs on the handler thread |
| 696 void DevToolsHttpHandlerImpl::Init() { | 637 void DevToolsHttpHandlerImpl::Init() { |
| 697 server_ = new net::HttpServer(*socket_factory_.get(), this); | 638 server_ = new net::HttpServer(*socket_factory_.get(), this); |
| 698 } | 639 } |
| 699 | 640 |
| 700 // Runs on the handler thread | 641 // Runs on the handler thread |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 int connection_id, | 720 int connection_id, |
| 780 const net::HttpServerRequestInfo& request) { | 721 const net::HttpServerRequestInfo& request) { |
| 781 if (!thread_) | 722 if (!thread_) |
| 782 return; | 723 return; |
| 783 thread_->message_loop()->PostTask( | 724 thread_->message_loop()->PostTask( |
| 784 FROM_HERE, | 725 FROM_HERE, |
| 785 base::Bind(&net::HttpServer::AcceptWebSocket, server_.get(), | 726 base::Bind(&net::HttpServer::AcceptWebSocket, server_.get(), |
| 786 connection_id, request)); | 727 connection_id, request)); |
| 787 } | 728 } |
| 788 | 729 |
| 789 base::DictionaryValue* DevToolsHttpHandlerImpl::SerializePageInfo( | 730 base::DictionaryValue* DevToolsHttpHandlerImpl::SerializeTarget( |
| 790 RenderViewHost* rvh, | 731 const DevToolsTarget& target, |
| 791 const std::string& host) { | 732 const std::string& host) { |
| 792 base::DictionaryValue* dictionary = new base::DictionaryValue; | 733 base::DictionaryValue* dictionary = new base::DictionaryValue; |
| 793 | 734 |
| 794 scoped_refptr<DevToolsAgentHost> agent( | 735 std::string id = target.GetId(); |
| 795 DevToolsAgentHost::GetOrCreateFor(rvh)); | 736 dictionary->SetString(kTargetIdField, id); |
| 737 dictionary->SetString(kTargetTypeField, target.GetType()); |
| 738 dictionary->SetString(kTargetTitleField, target.GetTitle()); |
| 739 dictionary->SetString(kTargetDescriptionField, target.GetDescription()); |
| 796 | 740 |
| 797 std::string id = binding_->GetIdentifier(agent.get()); | 741 GURL url = target.GetUrl(); |
| 798 dictionary->SetString(kTargetIdField, id); | 742 dictionary->SetString(kTargetUrlField, url.spec()); |
| 799 | 743 |
| 800 switch (delegate_->GetTargetType(rvh)) { | 744 GURL favicon_url = target.GetFaviconUrl(); |
| 801 case DevToolsHttpHandlerDelegate::kTargetTypeTab: | 745 if (favicon_url.is_valid()) |
| 802 dictionary->SetString(kTargetTypeField, kTargetTypePage); | 746 dictionary->SetString(kTargetFaviconUrlField, favicon_url.spec()); |
| 803 break; | 747 |
| 804 default: | 748 if (!delegate_->GetPageThumbnailData(url).empty()) { |
| 805 dictionary->SetString(kTargetTypeField, kTargetTypeOther); | 749 dictionary->SetString(kTargetThumbnailUrlField, |
| 750 std::string(kThumbUrlPrefix) + id); |
| 806 } | 751 } |
| 807 | 752 |
| 808 WebContents* web_contents = rvh->GetDelegate()->GetAsWebContents(); | 753 if (!target.IsAttached()) { |
| 809 if (web_contents) { | 754 dictionary->SetString(kTargetWebSocketDebuggerUrlField, |
| 810 dictionary->SetString(kTargetTitleField, UTF16ToUTF8( | 755 base::StringPrintf("ws://%s%s%s", |
| 811 net::EscapeForHTML(web_contents->GetTitle()))); | 756 host.c_str(), |
| 812 dictionary->SetString(kTargetUrlField, web_contents->GetURL().spec()); | 757 kPageUrlPrefix, |
| 813 dictionary->SetString(kTargetThumbnailUrlField, | 758 id.c_str())); |
| 814 std::string(kThumbUrlPrefix) + id); | 759 std::string devtools_frontend_url = GetFrontendURLInternal( |
| 760 id.c_str(), |
| 761 host); |
| 762 dictionary->SetString( |
| 763 kTargetDevtoolsFrontendUrlField, devtools_frontend_url); |
| 764 } |
| 815 | 765 |
| 816 NavigationController& controller = web_contents->GetController(); | |
| 817 NavigationEntry* entry = controller.GetActiveEntry(); | |
| 818 if (entry != NULL && entry->GetURL().is_valid()) { | |
| 819 dictionary->SetString(kTargetFaviconUrlField, | |
| 820 entry->GetFavicon().url.spec()); | |
| 821 } | |
| 822 } | |
| 823 dictionary->SetString(kTargetDescriptionField, | |
| 824 delegate_->GetViewDescription(rvh)); | |
| 825 | |
| 826 if (!agent->IsAttached()) | |
| 827 SerializeDebuggerURLs(dictionary, id, host); | |
| 828 return dictionary; | 766 return dictionary; |
| 829 } | 767 } |
| 830 | 768 |
| 831 base::DictionaryValue* DevToolsHttpHandlerImpl::SerializeWorkerInfo( | |
| 832 const WorkerService::WorkerInfo& worker, | |
| 833 const std::string& host) { | |
| 834 base::DictionaryValue* dictionary = new base::DictionaryValue; | |
| 835 | |
| 836 scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetForWorker( | |
| 837 worker.process_id, worker.route_id)); | |
| 838 | |
| 839 std::string id = binding_->GetIdentifier(agent.get()); | |
| 840 | |
| 841 dictionary->SetString(kTargetIdField, id); | |
| 842 dictionary->SetString(kTargetTypeField, kTargetTypeOther); | |
| 843 dictionary->SetString(kTargetTitleField, | |
| 844 UTF16ToUTF8(net::EscapeForHTML(worker.name))); | |
| 845 dictionary->SetString(kTargetUrlField, worker.url.spec()); | |
| 846 dictionary->SetString(kTargetDescriptionField, | |
| 847 base::StringPrintf("Worker pid:%d", base::GetProcId(worker.handle))); | |
| 848 | |
| 849 if (!agent->IsAttached()) | |
| 850 SerializeDebuggerURLs(dictionary, id, host); | |
| 851 return dictionary; | |
| 852 } | |
| 853 | |
| 854 void DevToolsHttpHandlerImpl::SerializeDebuggerURLs( | |
| 855 base::DictionaryValue* dictionary, | |
| 856 const std::string& id, | |
| 857 const std::string& host) { | |
| 858 dictionary->SetString(kTargetWebSocketDebuggerUrlField, | |
| 859 base::StringPrintf("ws://%s%s%s", | |
| 860 host.c_str(), | |
| 861 kPageUrlPrefix, | |
| 862 id.c_str())); | |
| 863 std::string devtools_frontend_url = GetFrontendURLInternal( | |
| 864 id.c_str(), | |
| 865 host); | |
| 866 dictionary->SetString(kTargetDevtoolsFrontendUrlField, devtools_frontend_url); | |
| 867 } | |
| 868 | |
| 869 } // namespace content | 769 } // namespace content |
| OLD | NEW |