Index: content/browser/debugger/devtools_http_handler_impl.cc |
diff --git a/content/browser/debugger/devtools_http_handler_impl.cc b/content/browser/debugger/devtools_http_handler_impl.cc |
deleted file mode 100644 |
index a62d4bd3516e5d6c349c6e3ed9a173cc54347e5f..0000000000000000000000000000000000000000 |
--- a/content/browser/debugger/devtools_http_handler_impl.cc |
+++ /dev/null |
@@ -1,873 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "content/browser/debugger/devtools_http_handler_impl.h" |
- |
-#include <algorithm> |
-#include <utility> |
- |
-#include "base/bind.h" |
-#include "base/compiler_specific.h" |
-#include "base/file_util.h" |
-#include "base/json/json_writer.h" |
-#include "base/lazy_instance.h" |
-#include "base/logging.h" |
-#include "base/message_loop_proxy.h" |
-#include "base/string_number_conversions.h" |
-#include "base/stringprintf.h" |
-#include "base/threading/thread.h" |
-#include "base/utf_string_conversions.h" |
-#include "base/values.h" |
-#include "content/browser/debugger/devtools_browser_target.h" |
-#include "content/browser/debugger/devtools_tracing_handler.h" |
-#include "content/browser/web_contents/web_contents_impl.h" |
-#include "content/common/devtools_messages.h" |
-#include "content/public/browser/browser_thread.h" |
-#include "content/public/browser/devtools_agent_host_registry.h" |
-#include "content/public/browser/devtools_client_host.h" |
-#include "content/public/browser/devtools_http_handler_delegate.h" |
-#include "content/public/browser/devtools_manager.h" |
-#include "content/public/browser/favicon_status.h" |
-#include "content/public/browser/navigation_entry.h" |
-#include "content/public/browser/notification_service.h" |
-#include "content/public/browser/notification_types.h" |
-#include "content/public/browser/render_process_host.h" |
-#include "content/public/browser/render_view_host.h" |
-#include "content/public/browser/render_widget_host.h" |
-#include "content/public/common/content_client.h" |
-#include "content/public/common/url_constants.h" |
-#include "googleurl/src/gurl.h" |
-#include "grit/devtools_resources_map.h" |
-#include "net/base/escape.h" |
-#include "net/base/io_buffer.h" |
-#include "net/base/ip_endpoint.h" |
-#include "net/server/http_server_request_info.h" |
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebDevToolsAgent.h" |
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" |
-#include "ui/base/layout.h" |
-#include "webkit/user_agent/user_agent.h" |
-#include "webkit/user_agent/user_agent_util.h" |
- |
-namespace content { |
- |
-const int kBufferSize = 16 * 1024; |
- |
-namespace { |
- |
-static const char* kDevToolsHandlerThreadName = "Chrome_DevToolsHandlerThread"; |
- |
-class DevToolsDefaultBindingHandler |
- : public DevToolsHttpHandler::RenderViewHostBinding { |
- public: |
- DevToolsDefaultBindingHandler() { |
- } |
- |
- virtual std::string GetIdentifier(RenderViewHost* rvh) OVERRIDE { |
- int process_id = rvh->GetProcess()->GetID(); |
- int routing_id = rvh->GetRoutingID(); |
- return base::StringPrintf("%d_%d", process_id, routing_id); |
- } |
- |
- virtual RenderViewHost* ForIdentifier( |
- const std::string& identifier) OVERRIDE { |
- size_t pos = identifier.find("_"); |
- if (pos == std::string::npos) |
- return NULL; |
- |
- int process_id; |
- if (!base::StringToInt(identifier.substr(0, pos), &process_id)) |
- return NULL; |
- |
- int routing_id; |
- if (!base::StringToInt(identifier.substr(pos+1), &routing_id)) |
- return NULL; |
- |
- return RenderViewHost::FromID(process_id, routing_id); |
- } |
-}; |
- |
- |
-// An internal implementation of DevToolsClientHost that delegates |
-// messages sent for DevToolsClient to a DebuggerShell instance. |
-class DevToolsClientHostImpl : public DevToolsClientHost { |
- public: |
- DevToolsClientHostImpl( |
- MessageLoop* message_loop, |
- net::HttpServer* server, |
- int connection_id) |
- : message_loop_(message_loop), |
- server_(server), |
- connection_id_(connection_id), |
- is_closed_(false), |
- detach_reason_("target_closed") { |
- } |
- |
- ~DevToolsClientHostImpl() {} |
- |
- // DevToolsClientHost interface |
- virtual void InspectedContentsClosing() { |
- if (is_closed_) |
- return; |
- is_closed_ = true; |
- |
- std::string response = |
- WebKit::WebDevToolsAgent::inspectorDetachedEvent( |
- WebKit::WebString::fromUTF8(detach_reason_)).utf8(); |
- message_loop_->PostTask( |
- FROM_HERE, |
- base::Bind(&net::HttpServer::SendOverWebSocket, |
- server_, |
- connection_id_, |
- response)); |
- |
- message_loop_->PostTask( |
- FROM_HERE, |
- base::Bind(&net::HttpServer::Close, server_, connection_id_)); |
- } |
- |
- virtual void DispatchOnInspectorFrontend(const std::string& data) { |
- message_loop_->PostTask( |
- FROM_HERE, |
- base::Bind(&net::HttpServer::SendOverWebSocket, |
- server_, |
- connection_id_, |
- data)); |
- } |
- |
- virtual void ContentsReplaced(WebContents* new_contents) { |
- } |
- |
- virtual void ReplacedWithAnotherClient() { |
- detach_reason_ = "replaced_with_devtools"; |
- } |
- |
- private: |
- virtual void FrameNavigating(const std::string& url) {} |
- MessageLoop* message_loop_; |
- net::HttpServer* server_; |
- int connection_id_; |
- bool is_closed_; |
- std::string detach_reason_; |
-}; |
- |
-} // namespace |
- |
-// static |
-int DevToolsHttpHandler::GetFrontendResourceId(const std::string& name) { |
- for (size_t i = 0; i < kDevtoolsResourcesSize; ++i) { |
- if (name == kDevtoolsResources[i].name) |
- return kDevtoolsResources[i].value; |
- } |
- return -1; |
-} |
- |
-// static |
-DevToolsHttpHandler* DevToolsHttpHandler::Start( |
- const net::StreamListenSocketFactory* socket_factory, |
- const std::string& frontend_url, |
- DevToolsHttpHandlerDelegate* delegate) { |
- DevToolsHttpHandlerImpl* http_handler = |
- new DevToolsHttpHandlerImpl(socket_factory, |
- frontend_url, |
- delegate); |
- http_handler->Start(); |
- return http_handler; |
-} |
- |
-DevToolsHttpHandlerImpl::~DevToolsHttpHandlerImpl() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- // Stop() must be called prior to destruction. |
- DCHECK(server_.get() == NULL); |
- DCHECK(thread_.get() == NULL); |
-} |
- |
-void DevToolsHttpHandlerImpl::Start() { |
- if (thread_.get()) |
- return; |
- thread_.reset(new base::Thread(kDevToolsHandlerThreadName)); |
- BrowserThread::PostTask( |
- BrowserThread::FILE, FROM_HERE, |
- base::Bind(&DevToolsHttpHandlerImpl::StartHandlerThread, this)); |
-} |
- |
-// Runs on FILE thread. |
-void DevToolsHttpHandlerImpl::StartHandlerThread() { |
- base::Thread::Options options; |
- options.message_loop_type = MessageLoop::TYPE_IO; |
- if (!thread_->StartWithOptions(options)) { |
- BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
- base::Bind(&DevToolsHttpHandlerImpl::ResetHandlerThread, this)); |
- return; |
- } |
- |
- thread_->message_loop()->PostTask( |
- FROM_HERE, |
- base::Bind(&DevToolsHttpHandlerImpl::Init, this)); |
-} |
- |
-void DevToolsHttpHandlerImpl::ResetHandlerThread() { |
- thread_.reset(); |
-} |
- |
-void DevToolsHttpHandlerImpl::ResetHandlerThreadAndRelease() { |
- ResetHandlerThread(); |
- Release(); |
-} |
- |
-void DevToolsHttpHandlerImpl::Stop() { |
- if (!thread_.get()) |
- return; |
- BrowserThread::PostTaskAndReply( |
- BrowserThread::FILE, FROM_HERE, |
- base::Bind(&DevToolsHttpHandlerImpl::StopHandlerThread, this), |
- base::Bind(&DevToolsHttpHandlerImpl::ResetHandlerThreadAndRelease, this)); |
-} |
- |
-void DevToolsHttpHandlerImpl::SetRenderViewHostBinding( |
- RenderViewHostBinding* binding) { |
- if (binding) |
- binding_ = binding; |
- else |
- binding_ = default_binding_.get(); |
-} |
- |
-GURL DevToolsHttpHandlerImpl::GetFrontendURL(RenderViewHost* render_view_host) { |
- net::IPEndPoint ip_address; |
- if (server_->GetLocalAddress(&ip_address)) |
- return GURL(); |
- std::string host = ip_address.ToString(); |
- std::string id = binding_->GetIdentifier(render_view_host); |
- return GURL(std::string("http://") + |
- ip_address.ToString() + |
- GetFrontendURLInternal(id, host)); |
-} |
- |
-static std::string PathWithoutParams(const std::string& path) { |
- size_t query_position = path.find("?"); |
- if (query_position != std::string::npos) |
- return path.substr(0, query_position); |
- return path; |
-} |
- |
-static std::string GetMimeType(const std::string& filename) { |
- if (EndsWith(filename, ".html", false)) { |
- return "text/html"; |
- } else if (EndsWith(filename, ".css", false)) { |
- return "text/css"; |
- } else if (EndsWith(filename, ".js", false)) { |
- return "application/javascript"; |
- } else if (EndsWith(filename, ".png", false)) { |
- return "image/png"; |
- } else if (EndsWith(filename, ".gif", false)) { |
- return "image/gif"; |
- } |
- NOTREACHED(); |
- return "text/plain"; |
-} |
- |
-void DevToolsHttpHandlerImpl::Observe(int type, |
- const NotificationSource& source, |
- const NotificationDetails& details) { |
- RenderProcessHost* process = Source<RenderProcessHost>(source).ptr(); |
- DevToolsManager* manager = DevToolsManager::GetInstance(); |
- for (ConnectionToClientHostMap::iterator it = |
- connection_to_client_host_ui_.begin(); |
- it != connection_to_client_host_ui_.end(); ++it) { |
- DevToolsAgentHost* agent = manager->GetDevToolsAgentHostFor(it->second); |
- if (!agent) |
- continue; |
- RenderViewHost* rvh = DevToolsAgentHostRegistry::GetRenderViewHost(agent); |
- if (rvh && rvh->GetProcess() == process) |
- it->second->InspectedContentsClosing(); |
- } |
-} |
- |
-void DevToolsHttpHandlerImpl::OnHttpRequest( |
- int connection_id, |
- const net::HttpServerRequestInfo& info) { |
- if (info.path.find("/json") == 0) { |
- BrowserThread::PostTask( |
- BrowserThread::UI, |
- FROM_HERE, |
- base::Bind(&DevToolsHttpHandlerImpl::OnJsonRequestUI, |
- this, |
- connection_id, |
- info)); |
- return; |
- } |
- |
- if (info.path.find("/thumb/") == 0) { |
- // Thumbnail request. |
- BrowserThread::PostTask( |
- BrowserThread::UI, |
- FROM_HERE, |
- base::Bind(&DevToolsHttpHandlerImpl::OnThumbnailRequestUI, |
- this, |
- connection_id, |
- info)); |
- return; |
- } |
- |
- if (info.path == "" || info.path == "/") { |
- // Discovery page request. |
- BrowserThread::PostTask( |
- BrowserThread::UI, |
- FROM_HERE, |
- base::Bind(&DevToolsHttpHandlerImpl::OnDiscoveryPageRequestUI, |
- this, |
- connection_id)); |
- return; |
- } |
- |
- if (info.path.find("/devtools/") != 0) { |
- server_->Send404(connection_id); |
- return; |
- } |
- |
- std::string filename = PathWithoutParams(info.path.substr(10)); |
- std::string mime_type = GetMimeType(filename); |
- |
- FilePath frontend_dir = delegate_->GetDebugFrontendDir(); |
- if (!frontend_dir.empty()) { |
- FilePath path = frontend_dir.AppendASCII(filename); |
- std::string data; |
- file_util::ReadFileToString(path, &data); |
- server_->Send200(connection_id, data, mime_type); |
- return; |
- } |
- if (delegate_->BundlesFrontendResources()) { |
- int resource_id = DevToolsHttpHandler::GetFrontendResourceId(filename); |
- if (resource_id != -1) { |
- base::StringPiece data = GetContentClient()->GetDataResource( |
- resource_id, ui::SCALE_FACTOR_NONE); |
- server_->Send200(connection_id, data.as_string(), mime_type); |
- return; |
- } |
- } |
- server_->Send404(connection_id); |
-} |
- |
-void DevToolsHttpHandlerImpl::OnWebSocketRequest( |
- int connection_id, |
- const net::HttpServerRequestInfo& request) { |
- BrowserThread::PostTask( |
- BrowserThread::UI, |
- FROM_HERE, |
- base::Bind( |
- &DevToolsHttpHandlerImpl::OnWebSocketRequestUI, |
- this, |
- connection_id, |
- request)); |
-} |
- |
-void DevToolsHttpHandlerImpl::OnWebSocketMessage( |
- int connection_id, |
- const std::string& data) { |
- BrowserThread::PostTask( |
- BrowserThread::UI, |
- FROM_HERE, |
- base::Bind( |
- &DevToolsHttpHandlerImpl::OnWebSocketMessageUI, |
- this, |
- connection_id, |
- data)); |
-} |
- |
-void DevToolsHttpHandlerImpl::OnClose(int connection_id) { |
- BrowserThread::PostTask( |
- BrowserThread::UI, |
- FROM_HERE, |
- base::Bind( |
- &DevToolsHttpHandlerImpl::OnCloseUI, |
- this, |
- connection_id)); |
-} |
- |
-struct DevToolsHttpHandlerImpl::PageInfo { |
- PageInfo() |
- : attached(false) { |
- } |
- |
- std::string id; |
- std::string url; |
- bool attached; |
- std::string title; |
- std::string thumbnail_url; |
- std::string favicon_url; |
- base::TimeTicks last_selected_time; |
-}; |
- |
-// static |
-bool DevToolsHttpHandlerImpl::SortPageListByTime(const PageInfo& info1, |
- const PageInfo& info2) { |
- return info1.last_selected_time > info2.last_selected_time; |
-} |
- |
-DevToolsHttpHandlerImpl::PageList DevToolsHttpHandlerImpl::GeneratePageList() { |
- PageList page_list; |
- for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator()); |
- !it.IsAtEnd(); it.Advance()) { |
- RenderProcessHost* render_process_host = it.GetCurrentValue(); |
- DCHECK(render_process_host); |
- |
- // Ignore processes that don't have a connection, such as crashed contents. |
- if (!render_process_host->HasConnection()) |
- continue; |
- |
- RenderProcessHost::RenderWidgetHostsIterator rwit( |
- render_process_host->GetRenderWidgetHostsIterator()); |
- for (; !rwit.IsAtEnd(); rwit.Advance()) { |
- const RenderWidgetHost* widget = rwit.GetCurrentValue(); |
- DCHECK(widget); |
- if (!widget || !widget->IsRenderView()) |
- continue; |
- |
- RenderViewHost* host = |
- RenderViewHost::From(const_cast<RenderWidgetHost*>(widget)); |
- page_list.push_back(CreatePageInfo(host)); |
- } |
- } |
- std::sort(page_list.begin(), page_list.end(), SortPageListByTime); |
- return page_list; |
-} |
- |
-std::string DevToolsHttpHandlerImpl::GetFrontendURLInternal( |
- const std::string rvh_id, |
- const std::string& host) { |
- return base::StringPrintf( |
- "%s%sws=%s/devtools/page/%s", |
- overridden_frontend_url_.c_str(), |
- overridden_frontend_url_.find("?") == std::string::npos ? "?" : "&", |
- host.c_str(), |
- rvh_id.c_str()); |
-} |
- |
-static bool ParseJsonPath( |
- const std::string& path, |
- std::string* command, |
- std::string* target_id) { |
- |
- // Fall back to list in case of empty query. |
- if (path.empty()) { |
- *command = "list"; |
- return true; |
- } |
- |
- if (path.find("/") != 0) { |
- // Malformed command. |
- return false; |
- } |
- *command = path.substr(1); |
- |
- size_t separator_pos = command->find("/"); |
- if (separator_pos != std::string::npos) { |
- *target_id = command->substr(separator_pos + 1); |
- *command = command->substr(0, separator_pos); |
- } |
- return true; |
-} |
- |
-void DevToolsHttpHandlerImpl::OnJsonRequestUI( |
- int connection_id, |
- const net::HttpServerRequestInfo& info) { |
- // Trim /json and ?jsonp=... |
- std::string path = info.path.substr(5); |
- std::string jsonp; |
- size_t jsonp_pos = path.find("?jsonp="); |
- if (jsonp_pos != std::string::npos) { |
- jsonp = path.substr(jsonp_pos + 7); |
- path = path.substr(0, jsonp_pos); |
- } |
- |
- // Trim fragment and query |
- size_t query_pos = path.find("?"); |
- if (query_pos != std::string::npos) |
- path = path.substr(0, query_pos); |
- |
- size_t fragment_pos = path.find("#"); |
- if (fragment_pos != std::string::npos) |
- path = path.substr(0, fragment_pos); |
- |
- std::string command; |
- std::string target_id; |
- if (!ParseJsonPath(path, &command, &target_id)) { |
- SendJson(connection_id, |
- net::HTTP_NOT_FOUND, |
- NULL, |
- "Malformed query: " + info.path, |
- jsonp); |
- return; |
- } |
- |
- if (command == "version") { |
- DictionaryValue version; |
- version.SetString("Protocol-Version", |
- WebKit::WebDevToolsAgent::inspectorProtocolVersion()); |
- version.SetString("WebKit-Version", |
- webkit_glue::GetWebKitVersion()); |
- version.SetString("User-Agent", |
- webkit_glue::GetUserAgent(GURL(chrome::kAboutBlankURL))); |
- SendJson(connection_id, net::HTTP_OK, &version, "", jsonp); |
- return; |
- } |
- |
- if (command == "list") { |
- PageList page_list = GeneratePageList(); |
- ListValue json_pages_list; |
- std::string host = info.headers["Host"]; |
- for (PageList::iterator i = page_list.begin(); i != page_list.end(); ++i) |
- json_pages_list.Append(SerializePageInfo(*i, host)); |
- SendJson(connection_id, net::HTTP_OK, &json_pages_list, "", jsonp); |
- return; |
- } |
- |
- if (command == "new") { |
- RenderViewHost* rvh = delegate_->CreateNewTarget(); |
- if (!rvh) { |
- SendJson(connection_id, |
- net::HTTP_INTERNAL_SERVER_ERROR, |
- NULL, |
- "Could not create new page", |
- jsonp); |
- return; |
- } |
- PageInfo page_info = CreatePageInfo(rvh); |
- std::string host = info.headers["Host"]; |
- scoped_ptr<DictionaryValue> dictionary(SerializePageInfo(page_info, host)); |
- SendJson(connection_id, net::HTTP_OK, dictionary.get(), "", jsonp); |
- return; |
- } |
- |
- if (command == "activate" || command == "close") { |
- RenderViewHost* rvh = binding_->ForIdentifier(target_id); |
- if (!rvh) { |
- SendJson(connection_id, |
- net::HTTP_NOT_FOUND, |
- NULL, |
- "No such target id: " + target_id, |
- jsonp); |
- return; |
- } |
- |
- if (command == "activate") { |
- rvh->GetDelegate()->Activate(); |
- SendJson(connection_id, net::HTTP_OK, NULL, "Target activated", jsonp); |
- return; |
- } |
- |
- if (command == "close") { |
- rvh->ClosePage(); |
- SendJson(connection_id, net::HTTP_OK, NULL, "Target is closing", jsonp); |
- return; |
- } |
- } |
- SendJson(connection_id, |
- net::HTTP_NOT_FOUND, |
- NULL, |
- "Unknown command: " + command, |
- jsonp); |
- return; |
-} |
- |
-void DevToolsHttpHandlerImpl::OnThumbnailRequestUI( |
- int connection_id, |
- const net::HttpServerRequestInfo& info) { |
- std::string prefix = "/thumb/"; |
- size_t pos = info.path.find(prefix); |
- if (pos != 0) { |
- Send404(connection_id); |
- return; |
- } |
- |
- std::string page_url = info.path.substr(prefix.length()); |
- std::string data = delegate_->GetPageThumbnailData(GURL(page_url)); |
- if (!data.empty()) |
- Send200(connection_id, data, "image/png"); |
- else |
- Send404(connection_id); |
-} |
- |
-void DevToolsHttpHandlerImpl::OnDiscoveryPageRequestUI(int connection_id) { |
- std::string response = delegate_->GetDiscoveryPageHTML(); |
- Send200(connection_id, response, "text/html; charset=UTF-8"); |
-} |
- |
-void DevToolsHttpHandlerImpl::OnWebSocketRequestUI( |
- int connection_id, |
- const net::HttpServerRequestInfo& request) { |
- if (!thread_.get()) |
- return; |
- std::string browser_prefix = "/devtools/browser"; |
- size_t browser_pos = request.path.find(browser_prefix); |
- if (browser_pos == 0) { |
- if (browser_target_) { |
- Send500(connection_id, "Another client already attached"); |
- return; |
- } |
- browser_target_.reset(new DevToolsBrowserTarget(connection_id)); |
- browser_target_->RegisterHandler(new DevToolsTracingHandler()); |
- AcceptWebSocket(connection_id, request); |
- return; |
- } |
- |
- std::string page_prefix = "/devtools/page/"; |
- size_t pos = request.path.find(page_prefix); |
- if (pos != 0) { |
- Send404(connection_id); |
- return; |
- } |
- |
- std::string page_id = request.path.substr(page_prefix.length()); |
- RenderViewHost* rvh = binding_->ForIdentifier(page_id); |
- if (!rvh) { |
- Send500(connection_id, "No such target id: " + page_id); |
- return; |
- } |
- |
- DevToolsManager* manager = DevToolsManager::GetInstance(); |
- DevToolsAgentHost* agent = DevToolsAgentHostRegistry::GetDevToolsAgentHost( |
- rvh); |
- if (manager->GetDevToolsClientHostFor(agent)) { |
- Send500(connection_id, |
- "Target with given id is being inspected: " + page_id); |
- return; |
- } |
- |
- DevToolsClientHostImpl* client_host = |
- new DevToolsClientHostImpl(thread_->message_loop(), |
- server_, |
- connection_id); |
- connection_to_client_host_ui_[connection_id] = client_host; |
- |
- manager->RegisterDevToolsClientHostFor(agent, client_host); |
- |
- AcceptWebSocket(connection_id, request); |
-} |
- |
-void DevToolsHttpHandlerImpl::OnWebSocketMessageUI( |
- int connection_id, |
- const std::string& data) { |
- if (browser_target_ && connection_id == browser_target_->connection_id()) { |
- std::string json_response = browser_target_->HandleMessage(data); |
- |
- thread_->message_loop()->PostTask( |
- FROM_HERE, |
- base::Bind(&net::HttpServer::SendOverWebSocket, |
- server_.get(), |
- connection_id, |
- json_response)); |
- return; |
- } |
- |
- ConnectionToClientHostMap::iterator it = |
- connection_to_client_host_ui_.find(connection_id); |
- if (it == connection_to_client_host_ui_.end()) |
- return; |
- |
- DevToolsManager* manager = DevToolsManager::GetInstance(); |
- manager->DispatchOnInspectorBackend(it->second, data); |
-} |
- |
-void DevToolsHttpHandlerImpl::OnCloseUI(int connection_id) { |
- ConnectionToClientHostMap::iterator it = |
- connection_to_client_host_ui_.find(connection_id); |
- if (it != connection_to_client_host_ui_.end()) { |
- DevToolsClientHostImpl* client_host = |
- static_cast<DevToolsClientHostImpl*>(it->second); |
- DevToolsManager::GetInstance()->ClientHostClosing(client_host); |
- delete client_host; |
- connection_to_client_host_ui_.erase(connection_id); |
- } |
- if (browser_target_ && browser_target_->connection_id() == connection_id) { |
- browser_target_.reset(); |
- return; |
- } |
-} |
- |
-DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl( |
- const net::StreamListenSocketFactory* socket_factory, |
- const std::string& frontend_url, |
- DevToolsHttpHandlerDelegate* delegate) |
- : overridden_frontend_url_(frontend_url), |
- socket_factory_(socket_factory), |
- delegate_(delegate) { |
- if (overridden_frontend_url_.empty()) |
- overridden_frontend_url_ = "/devtools/devtools.html"; |
- |
- default_binding_.reset(new DevToolsDefaultBindingHandler); |
- binding_ = default_binding_.get(); |
- |
- registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
- NotificationService::AllBrowserContextsAndSources()); |
- registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CLOSED, |
- NotificationService::AllBrowserContextsAndSources()); |
- |
- // Balanced in ResetHandlerThreadAndRelease(). |
- AddRef(); |
-} |
- |
-// Runs on the handler thread |
-void DevToolsHttpHandlerImpl::Init() { |
- server_ = new net::HttpServer(*socket_factory_.get(), this); |
-} |
- |
-// Runs on the handler thread |
-void DevToolsHttpHandlerImpl::Teardown() { |
- server_ = NULL; |
-} |
- |
-// Runs on FILE thread to make sure that it is serialized against |
-// {Start|Stop}HandlerThread and to allow calling pthread_join. |
-void DevToolsHttpHandlerImpl::StopHandlerThread() { |
- if (!thread_->message_loop()) |
- return; |
- thread_->message_loop()->PostTask( |
- FROM_HERE, |
- base::Bind(&DevToolsHttpHandlerImpl::Teardown, this)); |
- // Thread::Stop joins the thread. |
- thread_->Stop(); |
-} |
- |
-void DevToolsHttpHandlerImpl::SendJson(int connection_id, |
- net::HttpStatusCode status_code, |
- Value* value, |
- const std::string& message, |
- const std::string& jsonp) { |
- if (!thread_.get()) |
- return; |
- |
- // Serialize value and message. |
- std::string json_value; |
- if (value) { |
- base::JSONWriter::WriteWithOptions(value, |
- base::JSONWriter::OPTIONS_PRETTY_PRINT, |
- &json_value); |
- } |
- std::string json_message; |
- scoped_ptr<Value> message_object(Value::CreateStringValue(message)); |
- base::JSONWriter::Write(message_object.get(), &json_message); |
- |
- std::string response; |
- std::string mime_type = "application/json; charset=UTF-8"; |
- |
- // Wrap jsonp if necessary. |
- if (!jsonp.empty()) { |
- mime_type = "text/javascript; charset=UTF-8"; |
- response = StringPrintf("%s(%s, %d, %s);", |
- jsonp.c_str(), |
- json_value.empty() ? "undefined" |
- : json_value.c_str(), |
- status_code, |
- json_message.c_str()); |
- // JSONP always returns 200. |
- status_code = net::HTTP_OK; |
- } else { |
- response = StringPrintf("%s%s", json_value.c_str(), message.c_str()); |
- } |
- |
- thread_->message_loop()->PostTask( |
- FROM_HERE, |
- base::Bind(&net::HttpServer::Send, |
- server_.get(), |
- connection_id, |
- status_code, |
- response, |
- mime_type)); |
-} |
- |
-void DevToolsHttpHandlerImpl::Send200(int connection_id, |
- const std::string& data, |
- const std::string& mime_type) { |
- if (!thread_.get()) |
- return; |
- thread_->message_loop()->PostTask( |
- FROM_HERE, |
- base::Bind(&net::HttpServer::Send200, |
- server_.get(), |
- connection_id, |
- data, |
- mime_type)); |
-} |
- |
-void DevToolsHttpHandlerImpl::Send404(int connection_id) { |
- if (!thread_.get()) |
- return; |
- thread_->message_loop()->PostTask( |
- FROM_HERE, |
- base::Bind(&net::HttpServer::Send404, server_.get(), connection_id)); |
-} |
- |
-void DevToolsHttpHandlerImpl::Send500(int connection_id, |
- const std::string& message) { |
- if (!thread_.get()) |
- return; |
- thread_->message_loop()->PostTask( |
- FROM_HERE, |
- base::Bind(&net::HttpServer::Send500, server_.get(), connection_id, |
- message)); |
-} |
- |
-void DevToolsHttpHandlerImpl::AcceptWebSocket( |
- int connection_id, |
- const net::HttpServerRequestInfo& request) { |
- if (!thread_.get()) |
- return; |
- thread_->message_loop()->PostTask( |
- FROM_HERE, |
- base::Bind(&net::HttpServer::AcceptWebSocket, server_.get(), |
- connection_id, request)); |
-} |
- |
-DevToolsHttpHandlerImpl::PageInfo |
-DevToolsHttpHandlerImpl::CreatePageInfo(RenderViewHost* rvh) |
-{ |
- RenderViewHostDelegate* host_delegate = rvh->GetDelegate(); |
- DevToolsAgentHost* agent = |
- DevToolsAgentHostRegistry::GetDevToolsAgentHost(rvh); |
- DevToolsClientHost* client_host = DevToolsManager::GetInstance()-> |
- GetDevToolsClientHostFor(agent); |
- PageInfo page_info; |
- page_info.id = binding_->GetIdentifier(rvh); |
- page_info.attached = client_host != NULL; |
- page_info.url = host_delegate->GetURL().spec(); |
- |
- WebContents* web_contents = host_delegate->GetAsWebContents(); |
- if (web_contents) { |
- page_info.title = UTF16ToUTF8( |
- net::EscapeForHTML(web_contents->GetTitle())); |
- page_info.last_selected_time = web_contents->GetLastSelectedTime(); |
- |
- NavigationController& controller = web_contents->GetController(); |
- NavigationEntry* entry = controller.GetActiveEntry(); |
- if (entry != NULL && entry->GetURL().is_valid()) { |
- page_info.thumbnail_url = "/thumb/" + entry->GetURL().spec(); |
- page_info.favicon_url = entry->GetFavicon().url.spec(); |
- } |
- } |
- return page_info; |
-} |
- |
-DictionaryValue* DevToolsHttpHandlerImpl::SerializePageInfo( |
- const PageInfo& page_info, |
- const std::string& host) { |
- DictionaryValue* dictionary = new DictionaryValue; |
- dictionary->SetString("title", page_info.title); |
- dictionary->SetString("url", page_info.url); |
- dictionary->SetString("thumbnailUrl", page_info.thumbnail_url); |
- dictionary->SetString("faviconUrl", page_info.favicon_url); |
- if (!page_info.attached) { |
- dictionary->SetString("webSocketDebuggerUrl", |
- base::StringPrintf("ws://%s/devtools/page/%s", |
- host.c_str(), |
- page_info.id.c_str())); |
- std::string devtools_frontend_url = GetFrontendURLInternal( |
- page_info.id.c_str(), |
- host); |
- dictionary->SetString("devtoolsFrontendUrl", devtools_frontend_url); |
- } |
- return dictionary; |
-} |
- |
-} // namespace content |