| 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" | 25 #include "content/browser/web_contents/web_contents_impl.h" |
| 29 #include "content/common/devtools_messages.h" | 26 #include "content/common/devtools_messages.h" |
| 30 #include "content/public/browser/browser_thread.h" | 27 #include "content/public/browser/browser_thread.h" |
| 31 #include "content/public/browser/devtools_agent_host.h" | 28 #include "content/public/browser/devtools_agent_host.h" |
| 32 #include "content/public/browser/devtools_client_host.h" | 29 #include "content/public/browser/devtools_client_host.h" |
| 33 #include "content/public/browser/devtools_http_handler_delegate.h" | 30 #include "content/public/browser/devtools_http_handler_delegate.h" |
| 34 #include "content/public/browser/devtools_manager.h" | 31 #include "content/public/browser/devtools_manager.h" |
| 35 #include "content/public/browser/favicon_status.h" | 32 #include "content/public/browser/devtools_target_descriptor.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" | 33 #include "content/public/common/content_client.h" |
| 41 #include "content/public/common/url_constants.h" | 34 #include "content/public/common/url_constants.h" |
| 42 #include "grit/devtools_resources_map.h" | 35 #include "grit/devtools_resources_map.h" |
| 43 #include "net/base/escape.h" | |
| 44 #include "net/base/io_buffer.h" | 36 #include "net/base/io_buffer.h" |
| 45 #include "net/base/ip_endpoint.h" | 37 #include "net/base/ip_endpoint.h" |
| 46 #include "net/server/http_server_request_info.h" | 38 #include "net/server/http_server_request_info.h" |
| 47 #include "net/server/http_server_response_info.h" | 39 #include "net/server/http_server_response_info.h" |
| 48 #include "ui/base/layout.h" | |
| 49 #include "url/gurl.h" | 40 #include "url/gurl.h" |
| 50 #include "webkit/common/user_agent/user_agent.h" | 41 #include "webkit/common/user_agent/user_agent.h" |
| 51 #include "webkit/common/user_agent/user_agent_util.h" | 42 #include "webkit/common/user_agent/user_agent_util.h" |
| 52 | 43 |
| 53 namespace content { | 44 namespace content { |
| 54 | 45 |
| 55 namespace { | 46 namespace { |
| 56 | 47 |
| 57 const char kProtocolVersion[] = "1.0"; | 48 const char kProtocolVersion[] = "1.0"; |
| 58 | 49 |
| 59 const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread"; | 50 const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread"; |
| 60 | 51 |
| 61 const char kThumbUrlPrefix[] = "/thumb/"; | 52 const char kThumbUrlPrefix[] = "/thumb/"; |
| 62 const char kPageUrlPrefix[] = "/devtools/page/"; | 53 const char kPageUrlPrefix[] = "/devtools/page/"; |
| 63 | 54 |
| 64 const char kTargetIdField[] = "id"; | 55 const char kTargetIdField[] = "id"; |
| 65 const char kTargetTypeField[] = "type"; | 56 const char kTargetTypeField[] = "type"; |
| 66 const char kTargetTitleField[] = "title"; | 57 const char kTargetTitleField[] = "title"; |
| 67 const char kTargetDescriptionField[] = "description"; | 58 const char kTargetDescriptionField[] = "description"; |
| 68 const char kTargetUrlField[] = "url"; | 59 const char kTargetUrlField[] = "url"; |
| 69 const char kTargetThumbnailUrlField[] = "thumbnailUrl"; | 60 const char kTargetThumbnailUrlField[] = "thumbnailUrl"; |
| 70 const char kTargetFaviconUrlField[] = "faviconUrl"; | 61 const char kTargetFaviconUrlField[] = "faviconUrl"; |
| 71 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl"; | 62 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl"; |
| 72 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl"; | 63 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl"; |
| 73 | 64 |
| 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 | 65 // An internal implementation of DevToolsClientHost that delegates |
| 93 // messages sent for DevToolsClient to a DebuggerShell instance. | 66 // messages sent for DevToolsClient to a DebuggerShell instance. |
| 94 class DevToolsClientHostImpl : public DevToolsClientHost { | 67 class DevToolsClientHostImpl : public DevToolsClientHost { |
| 95 public: | 68 public: |
| 96 DevToolsClientHostImpl(base::MessageLoop* message_loop, | 69 DevToolsClientHostImpl(base::MessageLoop* message_loop, |
| 97 net::HttpServer* server, | 70 net::HttpServer* server, |
| 98 int connection_id) | 71 int connection_id) |
| 99 : message_loop_(message_loop), | 72 : message_loop_(message_loop), |
| 100 server_(server), | 73 server_(server), |
| 101 connection_id_(connection_id), | 74 connection_id_(connection_id), |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 } | 115 } |
| 143 | 116 |
| 144 private: | 117 private: |
| 145 base::MessageLoop* message_loop_; | 118 base::MessageLoop* message_loop_; |
| 146 net::HttpServer* server_; | 119 net::HttpServer* server_; |
| 147 int connection_id_; | 120 int connection_id_; |
| 148 bool is_closed_; | 121 bool is_closed_; |
| 149 std::string detach_reason_; | 122 std::string detach_reason_; |
| 150 }; | 123 }; |
| 151 | 124 |
| 152 static base::TimeTicks GetLastSelectedTime(RenderViewHost* rvh) { | |
| 153 WebContents* web_contents = rvh->GetDelegate()->GetAsWebContents(); | |
| 154 if (!web_contents) | |
| 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 } | |
| 165 | |
| 166 } // namespace | 125 } // namespace |
| 167 | 126 |
| 168 // static | 127 // static |
| 169 bool DevToolsHttpHandler::IsSupportedProtocolVersion( | 128 bool DevToolsHttpHandler::IsSupportedProtocolVersion( |
| 170 const std::string& version) { | 129 const std::string& version) { |
| 171 return version == kProtocolVersion; | 130 return version == kProtocolVersion; |
| 172 } | 131 } |
| 173 | 132 |
| 174 // static | 133 // static |
| 175 int DevToolsHttpHandler::GetFrontendResourceId(const std::string& name) { | 134 int DevToolsHttpHandler::GetFrontendResourceId(const std::string& name) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 | 195 |
| 237 void DevToolsHttpHandlerImpl::Stop() { | 196 void DevToolsHttpHandlerImpl::Stop() { |
| 238 if (!thread_) | 197 if (!thread_) |
| 239 return; | 198 return; |
| 240 BrowserThread::PostTaskAndReply( | 199 BrowserThread::PostTaskAndReply( |
| 241 BrowserThread::FILE, FROM_HERE, | 200 BrowserThread::FILE, FROM_HERE, |
| 242 base::Bind(&DevToolsHttpHandlerImpl::StopHandlerThread, this), | 201 base::Bind(&DevToolsHttpHandlerImpl::StopHandlerThread, this), |
| 243 base::Bind(&DevToolsHttpHandlerImpl::ResetHandlerThreadAndRelease, this)); | 202 base::Bind(&DevToolsHttpHandlerImpl::ResetHandlerThreadAndRelease, this)); |
| 244 } | 203 } |
| 245 | 204 |
| 246 void DevToolsHttpHandlerImpl::SetDevToolsAgentHostBinding( | |
| 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) { | 205 GURL DevToolsHttpHandlerImpl::GetFrontendURL(DevToolsAgentHost* agent_host) { |
| 255 net::IPEndPoint ip_address; | 206 net::IPEndPoint ip_address; |
| 256 if (server_->GetLocalAddress(&ip_address)) | 207 if (server_->GetLocalAddress(&ip_address)) |
| 257 return GURL(); | 208 return GURL(); |
| 258 if (!agent_host) { | 209 if (!agent_host) { |
| 259 return GURL(std::string("http://") + ip_address.ToString() + | 210 return GURL(std::string("http://") + ip_address.ToString() + |
| 260 overridden_frontend_url_); | 211 overridden_frontend_url_); |
| 261 } | 212 } |
| 262 std::string host = ip_address.ToString(); | 213 std::string host = ip_address.ToString(); |
| 263 std::string id = binding_->GetIdentifier(agent_host); | 214 std::string id = agent_host->GetId(); |
| 264 return GURL(std::string("http://") + | 215 return GURL(std::string("http://") + |
| 265 ip_address.ToString() + | 216 ip_address.ToString() + |
| 266 GetFrontendURLInternal(id, host)); | 217 GetFrontendURLInternal(id, host)); |
| 267 } | 218 } |
| 268 | 219 |
| 269 static std::string PathWithoutParams(const std::string& path) { | 220 static std::string PathWithoutParams(const std::string& path) { |
| 270 size_t query_position = path.find("?"); | 221 size_t query_position = path.find("?"); |
| 271 if (query_position != std::string::npos) | 222 if (query_position != std::string::npos) |
| 272 return path.substr(0, query_position); | 223 return path.substr(0, query_position); |
| 273 return path; | 224 return path; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 299 base::Bind(&DevToolsHttpHandlerImpl::OnJsonRequestUI, | 250 base::Bind(&DevToolsHttpHandlerImpl::OnJsonRequestUI, |
| 300 this, | 251 this, |
| 301 connection_id, | 252 connection_id, |
| 302 info)); | 253 info)); |
| 303 return; | 254 return; |
| 304 } | 255 } |
| 305 | 256 |
| 306 if (info.path.find(kThumbUrlPrefix) == 0) { | 257 if (info.path.find(kThumbUrlPrefix) == 0) { |
| 307 // Thumbnail request. | 258 // Thumbnail request. |
| 308 const std::string target_id = info.path.substr(strlen(kThumbUrlPrefix)); | 259 const std::string target_id = info.path.substr(strlen(kThumbUrlPrefix)); |
| 309 DevToolsAgentHost* agent_host = binding_->ForIdentifier(target_id); | |
| 310 GURL page_url; | |
| 311 if (agent_host) { | |
| 312 RenderViewHost* rvh = agent_host->GetRenderViewHost(); | |
| 313 if (rvh) | |
| 314 page_url = rvh->GetDelegate()->GetURL(); | |
| 315 } | |
| 316 BrowserThread::PostTask( | 260 BrowserThread::PostTask( |
| 317 BrowserThread::UI, | 261 BrowserThread::UI, |
| 318 FROM_HERE, | 262 FROM_HERE, |
| 319 base::Bind(&DevToolsHttpHandlerImpl::OnThumbnailRequestUI, | 263 base::Bind(&DevToolsHttpHandlerImpl::OnThumbnailRequestUI, |
| 320 this, | 264 this, |
| 321 connection_id, | 265 connection_id, |
| 322 page_url)); | 266 target_id)); |
| 323 return; | 267 return; |
| 324 } | 268 } |
| 325 | 269 |
| 326 if (info.path == "" || info.path == "/") { | 270 if (info.path == "" || info.path == "/") { |
| 327 // Discovery page request. | 271 // Discovery page request. |
| 328 BrowserThread::PostTask( | 272 BrowserThread::PostTask( |
| 329 BrowserThread::UI, | 273 BrowserThread::UI, |
| 330 FROM_HERE, | 274 FROM_HERE, |
| 331 base::Bind(&DevToolsHttpHandlerImpl::OnDiscoveryPageRequestUI, | 275 base::Bind(&DevToolsHttpHandlerImpl::OnDiscoveryPageRequestUI, |
| 332 this, | 276 this, |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 version.SetString("Protocol-Version", kProtocolVersion); | 446 version.SetString("Protocol-Version", kProtocolVersion); |
| 503 version.SetString("WebKit-Version", webkit_glue::GetWebKitVersion()); | 447 version.SetString("WebKit-Version", webkit_glue::GetWebKitVersion()); |
| 504 version.SetString("Browser", content::GetContentClient()->GetProduct()); | 448 version.SetString("Browser", content::GetContentClient()->GetProduct()); |
| 505 version.SetString("User-Agent", | 449 version.SetString("User-Agent", |
| 506 webkit_glue::GetUserAgent(GURL(kAboutBlankURL))); | 450 webkit_glue::GetUserAgent(GURL(kAboutBlankURL))); |
| 507 SendJson(connection_id, net::HTTP_OK, &version, std::string()); | 451 SendJson(connection_id, net::HTTP_OK, &version, std::string()); |
| 508 return; | 452 return; |
| 509 } | 453 } |
| 510 | 454 |
| 511 if (command == "list") { | 455 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"]; | 456 std::string host = info.headers["host"]; |
| 525 for (PageList::iterator i = page_list.begin(); i != page_list.end(); ++i) | 457 delegate_->RequestTargets( |
| 526 target_list->Append(SerializePageInfo(i->first, host)); | |
| 527 | |
| 528 AddRef(); // Balanced in SendTargetList. | |
| 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, | 458 base::Bind(&DevToolsHttpHandlerImpl::SendTargetList, |
| 537 base::Unretained(this), | 459 this, connection_id, host)); |
| 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 Target* 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 } |
| 552 std::string host = info.headers["host"]; | 472 std::string host = info.headers["host"]; |
| 553 scoped_ptr<base::DictionaryValue> dictionary(SerializePageInfo(rvh, host)); | 473 scoped_ptr<base::DictionaryValue> dictionary(Serialize(*target, host)); |
| 554 SendJson(connection_id, net::HTTP_OK, dictionary.get(), std::string()); | 474 SendJson(connection_id, net::HTTP_OK, dictionary.get(), std::string()); |
| 555 return; | 475 return; |
| 556 } | 476 } |
| 557 | 477 |
| 558 if (command == "activate" || command == "close") { | 478 if (command == "activate") { |
| 559 DevToolsAgentHost* agent_host = binding_->ForIdentifier(target_id); | 479 if (delegate_->ActivateTarget(target_id)) |
| 560 RenderViewHost* rvh = agent_host ? agent_host->GetRenderViewHost() : NULL; | 480 SendJson(connection_id, net::HTTP_OK, NULL, "Target activated"); |
| 561 if (!rvh) { | 481 else |
| 562 SendJson(connection_id, | 482 SendJson(connection_id, |
| 563 net::HTTP_NOT_FOUND, | 483 net::HTTP_NOT_FOUND, |
| 564 NULL, | 484 NULL, |
| 565 "No such target id: " + target_id); | 485 "No such target id: " + target_id); |
| 566 return; | 486 return; |
| 567 } | 487 } |
| 568 | 488 |
| 569 if (command == "activate") { | 489 if (command == "close") { |
| 570 rvh->GetDelegate()->Activate(); | 490 if (delegate_->CloseTarget(target_id)) |
| 571 SendJson(connection_id, net::HTTP_OK, NULL, "Target activated"); | 491 SendJson(connection_id, net::HTTP_OK, NULL, "Target is closing"); |
| 572 return; | 492 else |
| 573 } | 493 SendJson(connection_id, |
| 494 net::HTTP_NOT_FOUND, |
| 495 NULL, |
| 496 "No such target id: " + target_id); |
| 497 return; |
| 498 } |
| 574 | 499 |
| 575 if (command == "close") { | |
| 576 rvh->ClosePage(); | |
| 577 SendJson(connection_id, net::HTTP_OK, NULL, "Target is closing"); | |
| 578 return; | |
| 579 } | |
| 580 } | |
| 581 SendJson(connection_id, | 500 SendJson(connection_id, |
| 582 net::HTTP_NOT_FOUND, | 501 net::HTTP_NOT_FOUND, |
| 583 NULL, | 502 NULL, |
| 584 "Unknown command: " + command); | 503 "Unknown command: " + command); |
| 585 return; | 504 return; |
| 586 } | 505 } |
| 587 | 506 |
| 588 void DevToolsHttpHandlerImpl::CollectWorkerInfo(base::ListValue* target_list, | |
| 589 std::string host) { | |
| 590 | |
| 591 std::vector<WorkerService::WorkerInfo> worker_info = | |
| 592 WorkerService::GetInstance()->GetWorkers(); | |
| 593 | |
| 594 for (size_t i = 0; i < worker_info.size(); ++i) | |
| 595 target_list->Append(SerializeWorkerInfo(worker_info[i], host)); | |
| 596 } | |
| 597 | |
| 598 void DevToolsHttpHandlerImpl::SendTargetList(int connection_id, | 507 void DevToolsHttpHandlerImpl::SendTargetList(int connection_id, |
| 599 base::ListValue* target_list) { | 508 const std::string& host, |
| 600 SendJson(connection_id, net::HTTP_OK, target_list, std::string()); | 509 const TargetList& targets) { |
| 601 delete target_list; | 510 base::ListValue list_value; |
| 602 Release(); // Balanced OnJsonRequestUI. | 511 for (TargetList::const_iterator it = targets.begin(); |
| 512 it != targets.end(); ++it) |
| 513 list_value.Append(Serialize(*(*it), host)); |
| 514 STLDeleteContainerPointers(targets.begin(), targets.end()); |
| 515 SendJson(connection_id, net::HTTP_OK, &list_value, std::string()); |
| 603 } | 516 } |
| 604 | 517 |
| 605 void DevToolsHttpHandlerImpl::OnThumbnailRequestUI( | 518 void DevToolsHttpHandlerImpl::OnThumbnailRequestUI( |
| 606 int connection_id, const GURL& page_url) { | 519 int connection_id, const std::string& target_id) { |
| 607 std::string data = delegate_->GetPageThumbnailData(page_url); | 520 std::string data = delegate_->GetPageThumbnailData(target_id); |
| 608 if (!data.empty()) | 521 if (!data.empty()) |
| 609 Send200(connection_id, data, "image/png"); | 522 Send200(connection_id, data, "image/png"); |
| 610 else | 523 else |
| 611 Send404(connection_id); | 524 Send404(connection_id); |
| 612 } | 525 } |
| 613 | 526 |
| 614 void DevToolsHttpHandlerImpl::OnDiscoveryPageRequestUI(int connection_id) { | 527 void DevToolsHttpHandlerImpl::OnDiscoveryPageRequestUI(int connection_id) { |
| 615 std::string response = delegate_->GetDiscoveryPageHTML(); | 528 std::string response = delegate_->GetDiscoveryPageHTML(); |
| 616 Send200(connection_id, response, "text/html; charset=UTF-8"); | 529 Send200(connection_id, response, "text/html; charset=UTF-8"); |
| 617 } | 530 } |
| 618 | 531 |
| 619 void DevToolsHttpHandlerImpl::OnWebSocketRequestUI( | 532 void DevToolsHttpHandlerImpl::OnWebSocketRequestUI( |
| 620 int connection_id, | 533 int connection_id, |
| 621 const net::HttpServerRequestInfo& request) { | 534 const net::HttpServerRequestInfo& request) { |
| 622 if (!thread_) | 535 if (!thread_) |
| 623 return; | 536 return; |
| 624 | 537 |
| 625 size_t pos = request.path.find(kPageUrlPrefix); | 538 size_t pos = request.path.find(kPageUrlPrefix); |
| 626 if (pos != 0) { | 539 if (pos != 0) { |
| 627 Send404(connection_id); | 540 Send404(connection_id); |
| 628 return; | 541 return; |
| 629 } | 542 } |
| 630 | 543 |
| 631 std::string page_id = request.path.substr(strlen(kPageUrlPrefix)); | 544 std::string page_id = request.path.substr(strlen(kPageUrlPrefix)); |
| 632 DevToolsAgentHost* agent = binding_->ForIdentifier(page_id); | 545 scoped_refptr<DevToolsAgentHost> agent = delegate_->GetAgentHost(page_id); |
| 633 if (!agent) { | 546 if (!agent) { |
| 634 Send500(connection_id, "No such target id: " + page_id); | 547 Send500(connection_id, "No such target id: " + page_id); |
| 635 return; | 548 return; |
| 636 } | 549 } |
| 637 | 550 |
| 638 if (agent->IsAttached()) { | 551 if (agent->IsAttached()) { |
| 639 Send500(connection_id, | 552 Send500(connection_id, |
| 640 "Target with given id is being inspected: " + page_id); | 553 "Target with given id is being inspected: " + page_id); |
| 641 return; | 554 return; |
| 642 } | 555 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 678 DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl( | 591 DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl( |
| 679 const net::StreamListenSocketFactory* socket_factory, | 592 const net::StreamListenSocketFactory* socket_factory, |
| 680 const std::string& frontend_url, | 593 const std::string& frontend_url, |
| 681 DevToolsHttpHandlerDelegate* delegate) | 594 DevToolsHttpHandlerDelegate* delegate) |
| 682 : overridden_frontend_url_(frontend_url), | 595 : overridden_frontend_url_(frontend_url), |
| 683 socket_factory_(socket_factory), | 596 socket_factory_(socket_factory), |
| 684 delegate_(delegate) { | 597 delegate_(delegate) { |
| 685 if (overridden_frontend_url_.empty()) | 598 if (overridden_frontend_url_.empty()) |
| 686 overridden_frontend_url_ = "/devtools/devtools.html"; | 599 overridden_frontend_url_ = "/devtools/devtools.html"; |
| 687 | 600 |
| 688 default_binding_.reset(new DevToolsDefaultBindingHandler); | |
| 689 binding_ = default_binding_.get(); | |
| 690 | |
| 691 // Balanced in ResetHandlerThreadAndRelease(). | 601 // Balanced in ResetHandlerThreadAndRelease(). |
| 692 AddRef(); | 602 AddRef(); |
| 693 } | 603 } |
| 694 | 604 |
| 695 // Runs on the handler thread | 605 // Runs on the handler thread |
| 696 void DevToolsHttpHandlerImpl::Init() { | 606 void DevToolsHttpHandlerImpl::Init() { |
| 697 server_ = new net::HttpServer(*socket_factory_.get(), this); | 607 server_ = new net::HttpServer(*socket_factory_.get(), this); |
| 698 } | 608 } |
| 699 | 609 |
| 700 // Runs on the handler thread | 610 // Runs on the handler thread |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 int connection_id, | 689 int connection_id, |
| 780 const net::HttpServerRequestInfo& request) { | 690 const net::HttpServerRequestInfo& request) { |
| 781 if (!thread_) | 691 if (!thread_) |
| 782 return; | 692 return; |
| 783 thread_->message_loop()->PostTask( | 693 thread_->message_loop()->PostTask( |
| 784 FROM_HERE, | 694 FROM_HERE, |
| 785 base::Bind(&net::HttpServer::AcceptWebSocket, server_.get(), | 695 base::Bind(&net::HttpServer::AcceptWebSocket, server_.get(), |
| 786 connection_id, request)); | 696 connection_id, request)); |
| 787 } | 697 } |
| 788 | 698 |
| 789 base::DictionaryValue* DevToolsHttpHandlerImpl::SerializePageInfo( | 699 base::DictionaryValue* DevToolsHttpHandlerImpl::Serialize( |
| 790 RenderViewHost* rvh, | 700 const DevToolsHttpHandlerDelegate::Target& target, |
| 791 const std::string& host) { | 701 const std::string& host) { |
| 792 base::DictionaryValue* dictionary = new base::DictionaryValue; | 702 base::DictionaryValue* dict = target.Serialize(); |
| 793 | 703 |
| 794 scoped_refptr<DevToolsAgentHost> agent( | 704 const std::string id = target.GetId(); |
| 795 DevToolsAgentHost::GetOrCreateFor(rvh)); | 705 if (delegate_->SupportsPageThumbnails()) { |
| 796 | 706 dict->SetString(kTargetThumbnailUrlField, |
| 797 std::string id = binding_->GetIdentifier(agent.get()); | 707 std::string(kThumbUrlPrefix) + id); |
| 798 dictionary->SetString(kTargetIdField, id); | |
| 799 | |
| 800 switch (delegate_->GetTargetType(rvh)) { | |
| 801 case DevToolsHttpHandlerDelegate::kTargetTypeTab: | |
| 802 dictionary->SetString(kTargetTypeField, kTargetTypePage); | |
| 803 break; | |
| 804 default: | |
| 805 dictionary->SetString(kTargetTypeField, kTargetTypeOther); | |
| 806 } | 708 } |
| 807 | 709 |
| 808 WebContents* web_contents = rvh->GetDelegate()->GetAsWebContents(); | 710 scoped_refptr<DevToolsAgentHost> agent = delegate_->GetAgentHost(id); |
| 809 if (web_contents) { | 711 if (!agent || !agent->IsAttached()) { |
| 810 dictionary->SetString(kTargetTitleField, UTF16ToUTF8( | 712 dict->SetString(kTargetWebSocketDebuggerUrlField, |
| 811 net::EscapeForHTML(web_contents->GetTitle()))); | 713 base::StringPrintf("ws://%s%s%s", |
| 812 dictionary->SetString(kTargetUrlField, web_contents->GetURL().spec()); | 714 host.c_str(), |
| 813 dictionary->SetString(kTargetThumbnailUrlField, | 715 kPageUrlPrefix, |
| 814 std::string(kThumbUrlPrefix) + id); | 716 id.c_str())); |
| 717 std::string devtools_frontend_url = GetFrontendURLInternal( |
| 718 id.c_str(), |
| 719 host); |
| 720 dict->SetString(kTargetDevtoolsFrontendUrlField, devtools_frontend_url); |
| 721 } |
| 815 | 722 |
| 816 NavigationController& controller = web_contents->GetController(); | 723 return dict; |
| 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; | |
| 829 } | |
| 830 | |
| 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 } | 724 } |
| 868 | 725 |
| 869 } // namespace content | 726 } // namespace content |
| OLD | NEW |