12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/devtools/devtools_http_handler_impl.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <algorithm> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <utility> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/file_util.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_writer.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/lazy_instance.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/stl_util.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/devtools/devtools_browser_target.h" 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/browser/devtools/devtools_protocol.h" 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/browser/devtools/devtools_protocol_constants.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/devtools/devtools_tracing_handler.h" 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/browser/devtools/tethering_handler.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/web_contents/web_contents_impl.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/devtools_messages.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/devtools_agent_host.h" 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/devtools_client_host.h" 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/devtools_http_handler_delegate.h" 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/devtools_manager.h" 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/favicon_status.h" 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/navigation_entry.h" 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_service.h" 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_types.h" 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/render_view_host.h" 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_client.h" 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/url_constants.h" 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "grit/devtools_resources_map.h" 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/escape.h" 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/io_buffer.h" 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/ip_endpoint.h" 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/server/http_server_request_info.h" 46a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "net/server/http_server_response_info.h" 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/layout.h" 487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/user_agent/user_agent.h" 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/user_agent/user_agent_util.h" 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content { 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kBufferSize = 16 * 1024; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic const char* kProtocolVersion = "1.0"; 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char* kDevToolsHandlerThreadName = "Chrome_DevToolsHandlerThread"; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char* kThumbUrlPrefix = "/thumb/"; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char* kPageUrlPrefix = "/devtools/page/"; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char* kTargetIdField = "id"; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char* kTargetTypeField = "type"; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char* kTargetTitleField = "title"; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char* kTargetDescriptionField = "description"; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char* kTargetUrlField = "url"; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char* kTargetThumbnailUrlField = "thumbnailUrl"; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char* kTargetFaviconUrlField = "faviconUrl"; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char* kTargetWebSocketDebuggerUrlField = "webSocketDebuggerUrl"; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char* kTargetDevtoolsFrontendUrlField = "devtoolsFrontendUrl"; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char* kTargetTypePage = "page"; 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char* kTargetTypeOther = "other"; 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DevToolsDefaultBindingHandler 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public DevToolsHttpHandler::DevToolsAgentHostBinding { 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DevToolsDefaultBindingHandler() { 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual std::string GetIdentifier(DevToolsAgentHost* agent_host) OVERRIDE { 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return agent_host->GetId(); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual DevToolsAgentHost* ForIdentifier(const std::string& id) OVERRIDE { 897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return DevToolsAgentHost::GetForId(id).get(); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// An internal implementation of DevToolsClientHost that delegates 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// messages sent for DevToolsClient to a DebuggerShell instance. 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DevToolsClientHostImpl : public DevToolsClientHost { 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DevToolsClientHostImpl(base::MessageLoop* message_loop, 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::HttpServer* server, 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int connection_id) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : message_loop_(message_loop), 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_(server), 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_id_(connection_id), 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_closed_(false), 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) detach_reason_("target_closed") {} 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~DevToolsClientHostImpl() {} 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // DevToolsClientHost interface 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void InspectedContentsClosing() OVERRIDE { 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_closed_) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_closed_ = true; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue notification; 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) notification.SetString( 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) devtools::Inspector::detached::kParamReason, detach_reason_); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string response = DevToolsProtocol::CreateNotification( 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) devtools::Inspector::detached::kName, 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) notification.DeepCopy())->Serialize(); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_->PostTask( 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&net::HttpServer::SendOverWebSocket, 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_, 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_id_, 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) response)); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_->PostTask( 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&net::HttpServer::Close, server_, connection_id_)); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void DispatchOnInspectorFrontend(const std::string& data) OVERRIDE { 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_->PostTask( 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&net::HttpServer::SendOverWebSocket, 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_, 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_id_, 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data)); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void ReplacedWithAnotherClient() OVERRIDE { 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) detach_reason_ = "replaced_with_devtools"; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop* message_loop_; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::HttpServer* server_; 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int connection_id_; 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_closed_; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string detach_reason_; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static base::TimeTicks GetLastSelectedTime(RenderViewHost* rvh) { 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebContents* web_contents = rvh->GetDelegate()->GetAsWebContents(); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!web_contents) 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::TimeTicks(); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return web_contents->GetLastSelectedTime(); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef std::pair<RenderViewHost*, base::TimeTicks> PageInfo; 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static bool TimeComparator(const PageInfo& info1, const PageInfo& info2) { 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return info1.second > info2.second; 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool DevToolsHttpHandler::IsSupportedProtocolVersion( 171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& version) { 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return version == kProtocolVersion; 173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// static 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int DevToolsHttpHandler::GetFrontendResourceId(const std::string& name) { 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < kDevtoolsResourcesSize; ++i) { 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (name == kDevtoolsResources[i].name) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kDevtoolsResources[i].value; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DevToolsHttpHandler* DevToolsHttpHandler::Start( 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const net::StreamListenSocketFactory* socket_factory, 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& frontend_url, 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DevToolsHttpHandlerDelegate* delegate) { 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DevToolsHttpHandlerImpl* http_handler = 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new DevToolsHttpHandlerImpl(socket_factory, 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frontend_url, 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) http_handler->Start(); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return http_handler; 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DevToolsHttpHandlerImpl::~DevToolsHttpHandlerImpl() { 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Stop() must be called prior to destruction. 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(server_.get() == NULL); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(thread_.get() == NULL); 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::Start() { 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (thread_) 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_.reset(new base::Thread(kDevToolsHandlerThreadName)); 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::FILE, FROM_HERE, 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DevToolsHttpHandlerImpl::StartHandlerThread, this)); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Runs on FILE thread. 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::StartHandlerThread() { 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Thread::Options options; 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) options.message_loop_type = base::MessageLoop::TYPE_IO; 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!thread_->StartWithOptions(options)) { 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::UI, FROM_HERE, 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DevToolsHttpHandlerImpl::ResetHandlerThread, this)); 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_->message_loop()->PostTask( 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DevToolsHttpHandlerImpl::Init, this)); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::ResetHandlerThread() { 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_.reset(); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::ResetHandlerThreadAndRelease() { 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResetHandlerThread(); 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Release(); 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::Stop() { 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!thread_) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTaskAndReply( 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::FILE, FROM_HERE, 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DevToolsHttpHandlerImpl::StopHandlerThread, this), 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DevToolsHttpHandlerImpl::ResetHandlerThreadAndRelease, this)); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::SetDevToolsAgentHostBinding( 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DevToolsAgentHostBinding* binding) { 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (binding) 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) binding_ = binding; 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) binding_ = default_binding_.get(); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GURL DevToolsHttpHandlerImpl::GetFrontendURL(DevToolsAgentHost* agent_host) { 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::IPEndPoint ip_address; 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (server_->GetLocalAddress(&ip_address)) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GURL(); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!agent_host) { 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GURL(std::string("http://") + ip_address.ToString() + 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overridden_frontend_url_); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string host = ip_address.ToString(); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string id = binding_->GetIdentifier(agent_host); 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GURL(std::string("http://") + 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ip_address.ToString() + 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetFrontendURLInternal(id, host)); 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static std::string PathWithoutParams(const std::string& path) { 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t query_position = path.find("?"); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (query_position != std::string::npos) 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return path.substr(0, query_position); 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return path; 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static std::string GetMimeType(const std::string& filename) { 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (EndsWith(filename, ".html", false)) { 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "text/html"; 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (EndsWith(filename, ".css", false)) { 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "text/css"; 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (EndsWith(filename, ".js", false)) { 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "application/javascript"; 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (EndsWith(filename, ".png", false)) { 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "image/png"; 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (EndsWith(filename, ".gif", false)) { 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "image/gif"; 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "text/plain"; 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::OnHttpRequest( 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int connection_id, 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const net::HttpServerRequestInfo& info) { 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (info.path.find("/json") == 0) { 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::UI, 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DevToolsHttpHandlerImpl::OnJsonRequestUI, 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_id, 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info)); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (info.path.find(kThumbUrlPrefix) == 0) { 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Thumbnail request. 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string target_id = info.path.substr(strlen(kThumbUrlPrefix)); 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DevToolsAgentHost* agent_host = binding_->ForIdentifier(target_id); 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL page_url; 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (agent_host) { 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderViewHost* rvh = agent_host->GetRenderViewHost(); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rvh) 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) page_url = rvh->GetDelegate()->GetURL(); 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::UI, 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DevToolsHttpHandlerImpl::OnThumbnailRequestUI, 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_id, 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) page_url)); 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (info.path == "" || info.path == "/") { 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Discovery page request. 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::UI, 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DevToolsHttpHandlerImpl::OnDiscoveryPageRequestUI, 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_id)); 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (info.path.find("/devtools/") != 0) { 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_->Send404(connection_id); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string filename = PathWithoutParams(info.path.substr(10)); 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string mime_type = GetMimeType(filename); 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath frontend_dir = delegate_->GetDebugFrontendDir(); 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!frontend_dir.empty()) { 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath path = frontend_dir.AppendASCII(filename); 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string data; 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_util::ReadFileToString(path, &data); 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_->Send200(connection_id, data, mime_type); 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (delegate_->BundlesFrontendResources()) { 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int resource_id = DevToolsHttpHandler::GetFrontendResourceId(filename); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (resource_id != -1) { 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringPiece data = GetContentClient()->GetDataResource( 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_id, ui::SCALE_FACTOR_NONE); 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_->Send200(connection_id, data.as_string(), mime_type); 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_->Send404(connection_id); 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::OnWebSocketRequest( 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int connection_id, 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const net::HttpServerRequestInfo& request) { 3697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string browser_prefix = "/devtools/browser"; 3707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch size_t browser_pos = request.path.find(browser_prefix); 3717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (browser_pos == 0) { 3727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (browser_target_) { 3737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch server_->Send500(connection_id, "Another client already attached"); 3747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 3757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 3767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch browser_target_ = new DevToolsBrowserTarget( 3777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch thread_->message_loop_proxy().get(), server_.get(), connection_id); 3787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch browser_target_->RegisterDomainHandler( 3792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch devtools::Tracing::kName, 3802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch new DevToolsTracingHandler(), 3812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch true /* handle on UI thread */); 3822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch browser_target_->RegisterDomainHandler( 3832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch TetheringHandler::kDomain, 3842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch new TetheringHandler(delegate_.get()), 3852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch false /* handle on this thread */); 3867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch server_->AcceptWebSocket(connection_id, request); 3887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 3897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 3907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::UI, 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind( 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &DevToolsHttpHandlerImpl::OnWebSocketRequestUI, 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_id, 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request)); 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::OnWebSocketMessage( 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int connection_id, 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& data) { 4047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (browser_target_ && connection_id == browser_target_->connection_id()) { 4057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch browser_target_->HandleMessage(data); 4067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 4077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 4087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::UI, 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind( 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &DevToolsHttpHandlerImpl::OnWebSocketMessageUI, 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_id, 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data)); 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::OnClose(int connection_id) { 4207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (browser_target_ && browser_target_->connection_id() == connection_id) { 4217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch browser_target_->Detach(); 4227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch browser_target_ = NULL; 4237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 4247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 4257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::UI, 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind( 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &DevToolsHttpHandlerImpl::OnCloseUI, 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_id)); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string DevToolsHttpHandlerImpl::GetFrontendURLInternal( 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string id, 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& host) { 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf( 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "%s%sws=%s%s%s", 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overridden_frontend_url_.c_str(), 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overridden_frontend_url_.find("?") == std::string::npos ? "?" : "&", 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host.c_str(), 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kPageUrlPrefix, 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) id.c_str()); 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static bool ParseJsonPath( 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& path, 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* command, 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* target_id) { 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Fall back to list in case of empty query. 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (path.empty()) { 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *command = "list"; 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (path.find("/") != 0) { 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Malformed command. 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *command = path.substr(1); 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t separator_pos = command->find("/"); 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (separator_pos != std::string::npos) { 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *target_id = command->substr(separator_pos + 1); 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *command = command->substr(0, separator_pos); 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::OnJsonRequestUI( 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int connection_id, 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const net::HttpServerRequestInfo& info) { 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Trim /json 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string path = info.path.substr(5); 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Trim fragment and query 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t query_pos = path.find("?"); 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (query_pos != std::string::npos) 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path = path.substr(0, query_pos); 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t fragment_pos = path.find("#"); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (fragment_pos != std::string::npos) 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path = path.substr(0, fragment_pos); 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string command; 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string target_id; 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!ParseJsonPath(path, &command, &target_id)) { 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendJson(connection_id, 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::HTTP_NOT_FOUND, 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL, 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Malformed query: " + info.path); 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command == "version") { 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue version; 499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch version.SetString("Protocol-Version", kProtocolVersion); 500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch version.SetString("WebKit-Version", webkit_glue::GetWebKitVersion()); 501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch version.SetString("Browser", content::GetContentClient()->GetProduct()); 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) version.SetString("User-Agent", 50390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) webkit_glue::GetUserAgent(GURL(kAboutBlankURL))); 504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendJson(connection_id, net::HTTP_OK, &version, std::string()); 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command == "list") { 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef std::vector<PageInfo> PageList; 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PageList page_list; 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<RenderViewHost*> rvh_list = 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DevToolsAgentHost::GetValidRenderViewHosts(); 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::vector<RenderViewHost*>::iterator it = rvh_list.begin(); 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != rvh_list.end(); ++it) 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) page_list.push_back(PageInfo(*it, GetLastSelectedTime(*it))); 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::sort(page_list.begin(), page_list.end(), TimeComparator); 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* target_list = new base::ListValue(); 521a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string host = info.headers["host"]; 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (PageList::iterator i = page_list.begin(); i != page_list.end(); ++i) 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_list->Append(SerializePageInfo(i->first, host)); 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddRef(); // Balanced in SendTargetList. 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTaskAndReply( 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::IO, 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DevToolsHttpHandlerImpl::CollectWorkerInfo, 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this), 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_list, 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host), 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DevToolsHttpHandlerImpl::SendTargetList, 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this), 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_id, 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_list)); 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command == "new") { 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderViewHost* rvh = delegate_->CreateNewTarget(); 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!rvh) { 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendJson(connection_id, 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::HTTP_INTERNAL_SERVER_ERROR, 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL, 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Could not create new page"); 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 549a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string host = info.headers["host"]; 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> dictionary(SerializePageInfo(rvh, host)); 551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendJson(connection_id, net::HTTP_OK, dictionary.get(), std::string()); 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command == "activate" || command == "close") { 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DevToolsAgentHost* agent_host = binding_->ForIdentifier(target_id); 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderViewHost* rvh = agent_host ? agent_host->GetRenderViewHost() : NULL; 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!rvh) { 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendJson(connection_id, 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::HTTP_NOT_FOUND, 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL, 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "No such target id: " + target_id); 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command == "activate") { 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rvh->GetDelegate()->Activate(); 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendJson(connection_id, net::HTTP_OK, NULL, "Target activated"); 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command == "close") { 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rvh->ClosePage(); 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendJson(connection_id, net::HTTP_OK, NULL, "Target is closing"); 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendJson(connection_id, 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::HTTP_NOT_FOUND, 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL, 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Unknown command: " + command); 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DevToolsHttpHandlerImpl::CollectWorkerInfo(base::ListValue* target_list, 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string host) { 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<WorkerService::WorkerInfo> worker_info = 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WorkerService::GetInstance()->GetWorkers(); 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < worker_info.size(); ++i) 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_list->Append(SerializeWorkerInfo(worker_info[i], host)); 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::SendTargetList(int connection_id, 5967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::ListValue* target_list) { 597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendJson(connection_id, net::HTTP_OK, target_list, std::string()); 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete target_list; 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Release(); // Balanced OnJsonRequestUI. 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::OnThumbnailRequestUI( 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int connection_id, const GURL& page_url) { 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string data = delegate_->GetPageThumbnailData(page_url); 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!data.empty()) 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Send200(connection_id, data, "image/png"); 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Send404(connection_id); 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::OnDiscoveryPageRequestUI(int connection_id) { 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string response = delegate_->GetDiscoveryPageHTML(); 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Send200(connection_id, response, "text/html; charset=UTF-8"); 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::OnWebSocketRequestUI( 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int connection_id, 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const net::HttpServerRequestInfo& request) { 619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!thread_) 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t pos = request.path.find(kPageUrlPrefix); 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (pos != 0) { 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Send404(connection_id); 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string page_id = request.path.substr(strlen(kPageUrlPrefix)); 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DevToolsAgentHost* agent = binding_->ForIdentifier(page_id); 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!agent) { 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Send500(connection_id, "No such target id: " + page_id); 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (agent->IsAttached()) { 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Send500(connection_id, 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Target with given id is being inspected: " + page_id); 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 641868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DevToolsClientHostImpl* client_host = new DevToolsClientHostImpl( 642868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) thread_->message_loop(), server_.get(), connection_id); 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_to_client_host_ui_[connection_id] = client_host; 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DevToolsManager::GetInstance()-> 646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RegisterDevToolsClientHostFor(agent, client_host); 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AcceptWebSocket(connection_id, request); 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::OnWebSocketMessageUI( 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int connection_id, 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& data) { 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConnectionToClientHostMap::iterator it = 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_to_client_host_ui_.find(connection_id); 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it == connection_to_client_host_ui_.end()) 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DevToolsManager* manager = DevToolsManager::GetInstance(); 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manager->DispatchOnInspectorBackend(it->second, data); 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::OnCloseUI(int connection_id) { 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConnectionToClientHostMap::iterator it = 6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_to_client_host_ui_.find(connection_id); 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it != connection_to_client_host_ui_.end()) { 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DevToolsClientHostImpl* client_host = 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<DevToolsClientHostImpl*>(it->second); 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DevToolsManager::GetInstance()->ClientHostClosing(client_host); 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete client_host; 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_to_client_host_ui_.erase(connection_id); 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl( 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const net::StreamListenSocketFactory* socket_factory, 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& frontend_url, 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DevToolsHttpHandlerDelegate* delegate) 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : overridden_frontend_url_(frontend_url), 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) socket_factory_(socket_factory), 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate_(delegate) { 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (overridden_frontend_url_.empty()) 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overridden_frontend_url_ = "/devtools/devtools.html"; 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default_binding_.reset(new DevToolsDefaultBindingHandler); 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) binding_ = default_binding_.get(); 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Balanced in ResetHandlerThreadAndRelease(). 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddRef(); 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Runs on the handler thread 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::Init() { 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_ = new net::HttpServer(*socket_factory_.get(), this); 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Runs on the handler thread 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::Teardown() { 6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_ = NULL; 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Runs on FILE thread to make sure that it is serialized against 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// {Start|Stop}HandlerThread and to allow calling pthread_join. 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::StopHandlerThread() { 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!thread_->message_loop()) 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_->message_loop()->PostTask( 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DevToolsHttpHandlerImpl::Teardown, this)); 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Thread::Stop joins the thread. 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_->Stop(); 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::SendJson(int connection_id, 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::HttpStatusCode status_code, 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value* value, 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& message) { 718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!thread_) 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Serialize value and message. 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string json_value; 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (value) { 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::JSONWriter::WriteWithOptions(value, 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::JSONWriter::OPTIONS_PRETTY_PRINT, 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &json_value); 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string json_message; 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> message_object(new base::StringValue(message)); 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::JSONWriter::Write(message_object.get(), &json_message); 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 732a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch net::HttpServerResponseInfo response(status_code); 733a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch response.SetBody(json_value + message, "application/json; charset=UTF-8"); 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_->message_loop()->PostTask( 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 737a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch base::Bind(&net::HttpServer::SendResponse, 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_.get(), 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_id, 740a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch response)); 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::Send200(int connection_id, 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& data, 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& mime_type) { 746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!thread_) 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_->message_loop()->PostTask( 7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&net::HttpServer::Send200, 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_.get(), 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_id, 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data, 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mime_type)); 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::Send404(int connection_id) { 758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!thread_) 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_->message_loop()->PostTask( 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&net::HttpServer::Send404, server_.get(), connection_id)); 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::Send500(int connection_id, 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& message) { 767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!thread_) 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_->message_loop()->PostTask( 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&net::HttpServer::Send500, server_.get(), connection_id, 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message)); 7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::AcceptWebSocket( 7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int connection_id, 7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const net::HttpServerRequestInfo& request) { 778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!thread_) 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_->message_loop()->PostTask( 7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&net::HttpServer::AcceptWebSocket, server_.get(), 7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection_id, request)); 7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::DictionaryValue* DevToolsHttpHandlerImpl::SerializePageInfo( 7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderViewHost* rvh, 7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& host) { 7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* dictionary = new base::DictionaryValue; 7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<DevToolsAgentHost> agent( 7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DevToolsAgentHost::GetOrCreateFor(rvh)); 7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 794868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string id = binding_->GetIdentifier(agent.get()); 7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dictionary->SetString(kTargetIdField, id); 7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (delegate_->GetTargetType(rvh)) { 7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case DevToolsHttpHandlerDelegate::kTargetTypeTab: 7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dictionary->SetString(kTargetTypeField, kTargetTypePage); 8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dictionary->SetString(kTargetTypeField, kTargetTypeOther); 8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebContents* web_contents = rvh->GetDelegate()->GetAsWebContents(); 8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (web_contents) { 8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dictionary->SetString(kTargetTitleField, UTF16ToUTF8( 8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::EscapeForHTML(web_contents->GetTitle()))); 8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dictionary->SetString(kTargetUrlField, web_contents->GetURL().spec()); 8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dictionary->SetString(kTargetThumbnailUrlField, 8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string(kThumbUrlPrefix) + id); 8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NavigationController& controller = web_contents->GetController(); 8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NavigationEntry* entry = controller.GetActiveEntry(); 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry != NULL && entry->GetURL().is_valid()) { 8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dictionary->SetString(kTargetFaviconUrlField, 8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->GetFavicon().url.spec()); 8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dictionary->SetString(kTargetDescriptionField, 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate_->GetViewDescription(rvh)); 8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!agent->IsAttached()) 8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SerializeDebuggerURLs(dictionary, id, host); 8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dictionary; 8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::DictionaryValue* DevToolsHttpHandlerImpl::SerializeWorkerInfo( 8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const WorkerService::WorkerInfo& worker, 8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& host) { 8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* dictionary = new base::DictionaryValue; 8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetForWorker( 8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) worker.process_id, worker.route_id)); 8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 836868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string id = binding_->GetIdentifier(agent.get()); 8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dictionary->SetString(kTargetIdField, id); 8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dictionary->SetString(kTargetTypeField, kTargetTypeOther); 8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dictionary->SetString(kTargetTitleField, 8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UTF16ToUTF8(net::EscapeForHTML(worker.name))); 8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dictionary->SetString(kTargetUrlField, worker.url.spec()); 8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dictionary->SetString(kTargetDescriptionField, 8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringPrintf("Worker pid:%d", base::GetProcId(worker.handle))); 8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!agent->IsAttached()) 8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SerializeDebuggerURLs(dictionary, id, host); 8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dictionary; 8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsHttpHandlerImpl::SerializeDebuggerURLs( 8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* dictionary, 8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& id, 8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& host) { 8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dictionary->SetString(kTargetWebSocketDebuggerUrlField, 8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringPrintf("ws://%s%s%s", 8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host.c_str(), 8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kPageUrlPrefix, 8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) id.c_str())); 8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string devtools_frontend_url = GetFrontendURLInternal( 8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) id.c_str(), 8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host); 8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dictionary->SetString(kTargetDevtoolsFrontendUrlField, devtools_frontend_url); 8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace content 867