Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(123)

Unified Diff: components/devtools_http_handler/devtools_http_handler.cc

Issue 2300703005: DevTools: merge devtools_http_handler into content - it is used in all the embedders anyways. (Closed)
Patch Set: for_landing! Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/devtools_http_handler/devtools_http_handler.cc
diff --git a/components/devtools_http_handler/devtools_http_handler.cc b/components/devtools_http_handler/devtools_http_handler.cc
deleted file mode 100644
index 0a623b41fe817fc9bdd5d0723fe3493b4be44a6e..0000000000000000000000000000000000000000
--- a/components/devtools_http_handler/devtools_http_handler.cc
+++ /dev/null
@@ -1,868 +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 <stddef.h>
-#include <stdint.h>
-
-#include <algorithm>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/compiler_specific.h"
-#include "base/files/file_util.h"
-#include "base/json/json_writer.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/threading/thread.h"
-#include "base/values.h"
-#include "build/build_config.h"
-#include "components/devtools_http_handler/devtools_http_handler.h"
-#include "components/devtools_http_handler/devtools_http_handler_delegate.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/devtools_external_agent_proxy_delegate.h"
-#include "content/public/browser/devtools_manager_delegate.h"
-#include "content/public/browser/devtools_socket_factory.h"
-#include "content/public/common/url_constants.h"
-#include "content/public/common/user_agent.h"
-#include "net/base/escape.h"
-#include "net/base/io_buffer.h"
-#include "net/base/ip_endpoint.h"
-#include "net/base/net_errors.h"
-#include "net/server/http_server.h"
-#include "net/server/http_server_request_info.h"
-#include "net/server/http_server_response_info.h"
-#include "net/socket/server_socket.h"
-
-#if defined(OS_ANDROID)
-#include "base/android/build_info.h"
-#endif
-
-using content::BrowserThread;
-using content::DevToolsAgentHost;
-using content::DevToolsAgentHostClient;
-
-namespace devtools_http_handler {
-
-namespace {
-
-const base::FilePath::CharType kDevToolsActivePortFileName[] =
- FILE_PATH_LITERAL("DevToolsActivePort");
-
-const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread";
-
-const char kPageUrlPrefix[] = "/devtools/page/";
-
-const char kTargetIdField[] = "id";
-const char kTargetParentIdField[] = "parentId";
-const char kTargetTypeField[] = "type";
-const char kTargetTitleField[] = "title";
-const char kTargetDescriptionField[] = "description";
-const char kTargetUrlField[] = "url";
-const char kTargetFaviconUrlField[] = "faviconUrl";
-const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl";
-const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl";
-
-// Maximum write buffer size of devtools http/websocket connections.
-// TODO(rmcilroy/pfieldman): Reduce this back to 100Mb when we have
-// added back pressure on the TraceComplete message protocol - crbug.com/456845.
-const int32_t kSendBufferSizeForDevTools = 256 * 1024 * 1024; // 256Mb
-
-} // namespace
-
-// ServerWrapper -------------------------------------------------------------
-// All methods in this class are only called on handler thread.
-class ServerWrapper : net::HttpServer::Delegate {
- public:
- ServerWrapper(base::WeakPtr<DevToolsHttpHandler> handler,
- std::unique_ptr<net::ServerSocket> socket,
- const base::FilePath& frontend_dir,
- bool bundles_resources);
-
- int GetLocalAddress(net::IPEndPoint* address);
-
- void AcceptWebSocket(int connection_id,
- const net::HttpServerRequestInfo& request);
- void SendOverWebSocket(int connection_id, const std::string& message);
- void SendResponse(int connection_id,
- const net::HttpServerResponseInfo& response);
- void Send200(int connection_id,
- const std::string& data,
- const std::string& mime_type);
- void Send404(int connection_id);
- void Send500(int connection_id, const std::string& message);
- void Close(int connection_id);
-
- void WriteActivePortToUserProfile(const base::FilePath& output_directory);
-
- ~ServerWrapper() override {}
-
- private:
- // net::HttpServer::Delegate implementation.
- void OnConnect(int connection_id) override {}
- void OnHttpRequest(int connection_id,
- const net::HttpServerRequestInfo& info) override;
- void OnWebSocketRequest(int connection_id,
- const net::HttpServerRequestInfo& info) override;
- void OnWebSocketMessage(int connection_id,
- const std::string& data) override;
- void OnClose(int connection_id) override;
-
- base::WeakPtr<DevToolsHttpHandler> handler_;
- std::unique_ptr<net::HttpServer> server_;
- base::FilePath frontend_dir_;
- bool bundles_resources_;
-};
-
-ServerWrapper::ServerWrapper(base::WeakPtr<DevToolsHttpHandler> handler,
- std::unique_ptr<net::ServerSocket> socket,
- const base::FilePath& frontend_dir,
- bool bundles_resources)
- : handler_(handler),
- server_(new net::HttpServer(std::move(socket), this)),
- frontend_dir_(frontend_dir),
- bundles_resources_(bundles_resources) {}
-
-int ServerWrapper::GetLocalAddress(net::IPEndPoint* address) {
- return server_->GetLocalAddress(address);
-}
-
-void ServerWrapper::AcceptWebSocket(int connection_id,
- const net::HttpServerRequestInfo& request) {
- server_->SetSendBufferSize(connection_id, kSendBufferSizeForDevTools);
- server_->AcceptWebSocket(connection_id, request);
-}
-
-void ServerWrapper::SendOverWebSocket(int connection_id,
- const std::string& message) {
- server_->SendOverWebSocket(connection_id, message);
-}
-
-void ServerWrapper::SendResponse(int connection_id,
- const net::HttpServerResponseInfo& response) {
- server_->SendResponse(connection_id, response);
-}
-
-void ServerWrapper::Send200(int connection_id,
- const std::string& data,
- const std::string& mime_type) {
- server_->Send200(connection_id, data, mime_type);
-}
-
-void ServerWrapper::Send404(int connection_id) {
- server_->Send404(connection_id);
-}
-
-void ServerWrapper::Send500(int connection_id,
- const std::string& message) {
- server_->Send500(connection_id, message);
-}
-
-void ServerWrapper::Close(int connection_id) {
- server_->Close(connection_id);
-}
-
-// Thread and ServerWrapper lifetime management ------------------------------
-
-void TerminateOnUI(base::Thread* thread,
- ServerWrapper* server_wrapper,
- content::DevToolsSocketFactory* socket_factory) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (server_wrapper) {
- DCHECK(thread);
- thread->task_runner()->DeleteSoon(FROM_HERE, server_wrapper);
- }
- if (socket_factory) {
- DCHECK(thread);
- thread->task_runner()->DeleteSoon(FROM_HERE, socket_factory);
- }
- if (thread) {
- BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, thread);
- }
-}
-
-void ServerStartedOnUI(base::WeakPtr<DevToolsHttpHandler> handler,
- base::Thread* thread,
- ServerWrapper* server_wrapper,
- content::DevToolsSocketFactory* socket_factory,
- std::unique_ptr<net::IPEndPoint> ip_address) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (handler && thread && server_wrapper) {
- handler->ServerStarted(thread, server_wrapper, socket_factory,
- std::move(ip_address));
- } else {
- TerminateOnUI(thread, server_wrapper, socket_factory);
- }
-}
-
-void StartServerOnHandlerThread(
- base::WeakPtr<DevToolsHttpHandler> handler,
- base::Thread* thread,
- content::DevToolsSocketFactory* socket_factory,
- const base::FilePath& output_directory,
- const base::FilePath& frontend_dir,
- bool bundles_resources) {
- DCHECK(thread->task_runner()->BelongsToCurrentThread());
- ServerWrapper* server_wrapper = nullptr;
- std::unique_ptr<net::ServerSocket> server_socket =
- socket_factory->CreateForHttpServer();
- std::unique_ptr<net::IPEndPoint> ip_address(new net::IPEndPoint);
- if (server_socket) {
- server_wrapper = new ServerWrapper(handler, std::move(server_socket),
- frontend_dir, bundles_resources);
- if (!output_directory.empty())
- server_wrapper->WriteActivePortToUserProfile(output_directory);
-
- if (server_wrapper->GetLocalAddress(ip_address.get()) != net::OK)
- ip_address.reset();
- } else {
- ip_address.reset();
- LOG(ERROR) << "Cannot start http server for devtools. Stop devtools.";
- }
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&ServerStartedOnUI,
- handler,
- thread,
- server_wrapper,
- socket_factory,
- base::Passed(&ip_address)));
-}
-
-void StartServerOnFile(
- base::WeakPtr<DevToolsHttpHandler> handler,
- content::DevToolsSocketFactory* socket_factory,
- const base::FilePath& output_directory,
- const base::FilePath& frontend_dir,
- bool bundles_resources) {
- DCHECK_CURRENTLY_ON(BrowserThread::FILE);
- std::unique_ptr<base::Thread> thread(
- new base::Thread(kDevToolsHandlerThreadName));
- base::Thread::Options options;
- options.message_loop_type = base::MessageLoop::TYPE_IO;
- if (thread->StartWithOptions(options)) {
- base::MessageLoop* message_loop = thread->message_loop();
- message_loop->task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&StartServerOnHandlerThread, handler,
- base::Unretained(thread.release()), socket_factory,
- output_directory, frontend_dir, bundles_resources));
- }
-}
-
-// DevToolsAgentHostClientImpl -----------------------------------------------
-// An internal implementation of DevToolsAgentHostClient that delegates
-// messages sent to a DebuggerShell instance.
-class DevToolsAgentHostClientImpl : public DevToolsAgentHostClient {
- public:
- DevToolsAgentHostClientImpl(base::MessageLoop* message_loop,
- ServerWrapper* server_wrapper,
- int connection_id,
- scoped_refptr<DevToolsAgentHost> agent_host)
- : message_loop_(message_loop),
- server_wrapper_(server_wrapper),
- connection_id_(connection_id),
- agent_host_(agent_host) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- agent_host_->AttachClient(this);
- }
-
- ~DevToolsAgentHostClientImpl() override {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (agent_host_.get())
- agent_host_->DetachClient(this);
- }
-
- void AgentHostClosed(DevToolsAgentHost* agent_host,
- bool replaced_with_another_client) override {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(agent_host == agent_host_.get());
-
- std::string message = base::StringPrintf(
- "{ \"method\": \"Inspector.detached\", "
- "\"params\": { \"reason\": \"%s\"} }",
- replaced_with_another_client ?
- "replaced_with_devtools" : "target_closed");
- DispatchProtocolMessage(agent_host, message);
-
- agent_host_ = nullptr;
- message_loop_->task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&ServerWrapper::Close, base::Unretained(server_wrapper_),
- connection_id_));
- }
-
- void DispatchProtocolMessage(DevToolsAgentHost* agent_host,
- const std::string& message) override {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(agent_host == agent_host_.get());
- message_loop_->task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&ServerWrapper::SendOverWebSocket,
- base::Unretained(server_wrapper_), connection_id_, message));
- }
-
- void OnMessage(const std::string& message) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (agent_host_.get())
- agent_host_->DispatchProtocolMessage(this, message);
- }
-
- private:
- base::MessageLoop* const message_loop_;
- ServerWrapper* const server_wrapper_;
- const int connection_id_;
- scoped_refptr<DevToolsAgentHost> agent_host_;
-};
-
-static bool TimeComparator(scoped_refptr<DevToolsAgentHost> host1,
- scoped_refptr<DevToolsAgentHost> host2) {
- return host1->GetLastActivityTime() > host2->GetLastActivityTime();
-}
-
-// DevToolsHttpHandler -------------------------------------------------------
-
-DevToolsHttpHandler::~DevToolsHttpHandler() {
- TerminateOnUI(thread_, server_wrapper_, socket_factory_);
-}
-
-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 (base::EndsWith(filename, ".html", base::CompareCase::INSENSITIVE_ASCII)) {
- return "text/html";
- } else if (base::EndsWith(filename, ".css",
- base::CompareCase::INSENSITIVE_ASCII)) {
- return "text/css";
- } else if (base::EndsWith(filename, ".js",
- base::CompareCase::INSENSITIVE_ASCII)) {
- return "application/javascript";
- } else if (base::EndsWith(filename, ".png",
- base::CompareCase::INSENSITIVE_ASCII)) {
- return "image/png";
- } else if (base::EndsWith(filename, ".gif",
- base::CompareCase::INSENSITIVE_ASCII)) {
- return "image/gif";
- } else if (base::EndsWith(filename, ".json",
- base::CompareCase::INSENSITIVE_ASCII)) {
- return "application/json";
- } else if (base::EndsWith(filename, ".svg",
- base::CompareCase::INSENSITIVE_ASCII)) {
- return "image/svg+xml";
- }
- LOG(ERROR) << "GetMimeType doesn't know mime type for: "
- << filename
- << " text/plain will be returned";
- NOTREACHED();
- return "text/plain";
-}
-
-void ServerWrapper::OnHttpRequest(int connection_id,
- const net::HttpServerRequestInfo& info) {
- server_->SetSendBufferSize(connection_id, kSendBufferSizeForDevTools);
-
- if (base::StartsWith(info.path, "/json", base::CompareCase::SENSITIVE)) {
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(&DevToolsHttpHandler::OnJsonRequest,
- handler_,
- connection_id,
- info));
- return;
- }
-
- if (info.path.empty() || info.path == "/") {
- // Discovery page request.
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(&DevToolsHttpHandler::OnDiscoveryPageRequest,
- handler_,
- connection_id));
- return;
- }
-
- if (!base::StartsWith(info.path, "/devtools/",
- base::CompareCase::SENSITIVE)) {
- server_->Send404(connection_id);
- return;
- }
-
- std::string filename = PathWithoutParams(info.path.substr(10));
- std::string mime_type = GetMimeType(filename);
-
- if (!frontend_dir_.empty()) {
- base::FilePath path = frontend_dir_.AppendASCII(filename);
- std::string data;
- base::ReadFileToString(path, &data);
- server_->Send200(connection_id, data, mime_type);
- return;
- }
-
- if (bundles_resources_) {
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(&DevToolsHttpHandler::OnFrontendResourceRequest,
- handler_,
- connection_id,
- filename));
- return;
- }
- server_->Send404(connection_id);
-}
-
-void ServerWrapper::OnWebSocketRequest(
- int connection_id,
- const net::HttpServerRequestInfo& request) {
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(
- &DevToolsHttpHandler::OnWebSocketRequest,
- handler_,
- connection_id,
- request));
-}
-
-void ServerWrapper::OnWebSocketMessage(int connection_id,
- const std::string& data) {
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(
- &DevToolsHttpHandler::OnWebSocketMessage,
- handler_,
- connection_id,
- data));
-}
-
-void ServerWrapper::OnClose(int connection_id) {
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(
- &DevToolsHttpHandler::OnClose,
- handler_,
- connection_id));
-}
-
-std::string DevToolsHttpHandler::GetFrontendURLInternal(
- const std::string& id,
- const std::string& host) {
- return base::StringPrintf(
- "%s%sws=%s%s%s",
- frontend_url_.c_str(),
- frontend_url_.find("?") == std::string::npos ? "?" : "&",
- host.c_str(),
- kPageUrlPrefix,
- 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 (!base::StartsWith(path, "/", base::CompareCase::SENSITIVE)) {
- // 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 DevToolsHttpHandler::OnJsonRequest(
- int connection_id,
- const net::HttpServerRequestInfo& info) {
- // Trim /json
- std::string path = info.path.substr(5);
-
- // Trim fragment and query
- std::string query;
- size_t query_pos = path.find("?");
- if (query_pos != std::string::npos) {
- query = path.substr(query_pos + 1);
- 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);
- return;
- }
-
- if (command == "version") {
- base::DictionaryValue version;
- version.SetString("Protocol-Version",
- DevToolsAgentHost::GetProtocolVersion().c_str());
- version.SetString("WebKit-Version", content::GetWebKitVersion());
- version.SetString("Browser", product_name_);
- version.SetString("User-Agent", user_agent_);
-#if defined(OS_ANDROID)
- version.SetString("Android-Package",
- base::android::BuildInfo::GetInstance()->package_name());
-#endif
- SendJson(connection_id, net::HTTP_OK, &version, std::string());
- return;
- }
-
- if (command == "list") {
- std::string host = info.headers["host"];
- DevToolsAgentHost::List agent_hosts =
- content::DevToolsAgentHost::DiscoverAllHosts();
- std::sort(agent_hosts.begin(), agent_hosts.end(), TimeComparator);
- agent_host_map_.clear();
- base::ListValue list_value;
- for (auto& agent_host : agent_hosts) {
- agent_host_map_[agent_host->GetId()] = agent_host;
- list_value.Append(SerializeDescriptor(agent_host, host));
- }
- SendJson(connection_id, net::HTTP_OK, &list_value, std::string());
- return;
- }
-
- if (command == "new") {
- GURL url(net::UnescapeURLComponent(
- query, net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS |
- net::UnescapeRule::PATH_SEPARATORS));
- if (!url.is_valid())
- url = GURL(url::kAboutBlankURL);
- scoped_refptr<DevToolsAgentHost> agent_host = nullptr;
- content::DevToolsManagerDelegate* delegate =
- DevToolsAgentHost::GetDevToolsManagerDelegate();
- if (delegate)
- agent_host = delegate->CreateNewTarget(url);
- if (!agent_host) {
- SendJson(connection_id,
- net::HTTP_INTERNAL_SERVER_ERROR,
- NULL,
- "Could not create new page");
- return;
- }
- std::string host = info.headers["host"];
- std::unique_ptr<base::DictionaryValue> dictionary(
- SerializeDescriptor(agent_host, host));
- SendJson(connection_id, net::HTTP_OK, dictionary.get(), std::string());
- const std::string target_id = agent_host->GetId();
- agent_host_map_[target_id] = agent_host;
- return;
- }
-
- if (command == "activate" || command == "close") {
- scoped_refptr<DevToolsAgentHost> agent_host = GetAgentHost(target_id);
- if (!agent_host) {
- SendJson(connection_id,
- net::HTTP_NOT_FOUND,
- NULL,
- "No such target id: " + target_id);
- return;
- }
-
- if (command == "activate") {
- if (agent_host->Activate()) {
- SendJson(connection_id, net::HTTP_OK, NULL, "Target activated");
- } else {
- SendJson(connection_id,
- net::HTTP_INTERNAL_SERVER_ERROR,
- NULL,
- "Could not activate target id: " + target_id);
- }
- return;
- }
-
- if (command == "close") {
- if (agent_host->Close()) {
- SendJson(connection_id, net::HTTP_OK, NULL, "Target is closing");
- } else {
- SendJson(connection_id,
- net::HTTP_INTERNAL_SERVER_ERROR,
- NULL,
- "Could not close target id: " + target_id);
- }
- return;
- }
- }
- SendJson(connection_id,
- net::HTTP_NOT_FOUND,
- NULL,
- "Unknown command: " + command);
- return;
-}
-
-scoped_refptr<DevToolsAgentHost> DevToolsHttpHandler::GetAgentHost(
- const std::string& target_id) {
- DescriptorMap::const_iterator it = agent_host_map_.find(target_id);
- return it != agent_host_map_.end() ? it->second : nullptr;
-}
-
-void DevToolsHttpHandler::OnDiscoveryPageRequest(int connection_id) {
- std::string response = delegate_->GetDiscoveryPageHTML();
- Send200(connection_id, response, "text/html; charset=UTF-8");
-}
-
-void DevToolsHttpHandler::OnFrontendResourceRequest(
- int connection_id, const std::string& path) {
- Send200(connection_id,
- delegate_->GetFrontendResource(path),
- GetMimeType(path));
-}
-
-void DevToolsHttpHandler::OnWebSocketRequest(
- int connection_id,
- const net::HttpServerRequestInfo& request) {
- if (!thread_)
- return;
-
- std::string browser_prefix = "/devtools/browser";
- if (base::StartsWith(request.path, browser_prefix,
- base::CompareCase::SENSITIVE)) {
- scoped_refptr<DevToolsAgentHost> browser_agent =
- DevToolsAgentHost::CreateForBrowser(
- thread_->task_runner(),
- base::Bind(&content::DevToolsSocketFactory::CreateForTethering,
- base::Unretained(socket_factory_)));
- connection_to_client_[connection_id] = new DevToolsAgentHostClientImpl(
- thread_->message_loop(), server_wrapper_, connection_id, browser_agent);
- AcceptWebSocket(connection_id, request);
- return;
- }
-
- if (!base::StartsWith(request.path, kPageUrlPrefix,
- base::CompareCase::SENSITIVE)) {
- Send404(connection_id);
- return;
- }
-
- std::string target_id = request.path.substr(strlen(kPageUrlPrefix));
- scoped_refptr<DevToolsAgentHost> agent = GetAgentHost(target_id);
- if (!agent) {
- Send500(connection_id, "No such target id: " + target_id);
- return;
- }
-
- if (agent->IsAttached()) {
- Send500(connection_id,
- "Target with given id is being inspected: " + target_id);
- return;
- }
-
- DevToolsAgentHostClientImpl* client_host = new DevToolsAgentHostClientImpl(
- thread_->message_loop(), server_wrapper_, connection_id, agent);
- connection_to_client_[connection_id] = client_host;
-
- AcceptWebSocket(connection_id, request);
-}
-
-void DevToolsHttpHandler::OnWebSocketMessage(
- int connection_id,
- const std::string& data) {
- ConnectionToClientMap::iterator it =
- connection_to_client_.find(connection_id);
- if (it != connection_to_client_.end())
- it->second->OnMessage(data);
-}
-
-void DevToolsHttpHandler::OnClose(int connection_id) {
- ConnectionToClientMap::iterator it =
- connection_to_client_.find(connection_id);
- if (it != connection_to_client_.end()) {
- delete it->second;
- connection_to_client_.erase(connection_id);
- }
-}
-
-DevToolsHttpHandler::DevToolsHttpHandler(
- std::unique_ptr<content::DevToolsSocketFactory> socket_factory,
- const std::string& frontend_url,
- DevToolsHttpHandlerDelegate* delegate,
- const base::FilePath& output_directory,
- const base::FilePath& debug_frontend_dir,
- const std::string& product_name,
- const std::string& user_agent)
- : thread_(nullptr),
- frontend_url_(frontend_url),
- product_name_(product_name),
- user_agent_(user_agent),
- server_wrapper_(nullptr),
- delegate_(delegate),
- socket_factory_(nullptr),
- weak_factory_(this) {
- bool bundles_resources = frontend_url_.empty();
- if (frontend_url_.empty())
- frontend_url_ = "/devtools/inspector.html";
-
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- base::Bind(&StartServerOnFile,
- weak_factory_.GetWeakPtr(),
- socket_factory.release(),
- output_directory,
- debug_frontend_dir,
- bundles_resources));
-}
-
-void DevToolsHttpHandler::ServerStarted(
- base::Thread* thread,
- ServerWrapper* server_wrapper,
- content::DevToolsSocketFactory* socket_factory,
- std::unique_ptr<net::IPEndPoint> ip_address) {
- thread_ = thread;
- server_wrapper_ = server_wrapper;
- socket_factory_ = socket_factory;
- server_ip_address_.swap(ip_address);
-}
-
-void ServerWrapper::WriteActivePortToUserProfile(
- const base::FilePath& output_directory) {
- DCHECK(!output_directory.empty());
- net::IPEndPoint endpoint;
- int err;
- if ((err = server_->GetLocalAddress(&endpoint)) != net::OK) {
- LOG(ERROR) << "Error " << err << " getting local address";
- return;
- }
-
- // Write this port to a well-known file in the profile directory
- // so Telemetry can pick it up.
- base::FilePath path = output_directory.Append(kDevToolsActivePortFileName);
- std::string port_string = base::UintToString(endpoint.port());
- if (base::WriteFile(path, port_string.c_str(),
- static_cast<int>(port_string.length())) < 0) {
- LOG(ERROR) << "Error writing DevTools active port to file";
- }
-}
-
-void DevToolsHttpHandler::SendJson(int connection_id,
- net::HttpStatusCode status_code,
- base::Value* value,
- const std::string& message) {
- if (!thread_)
- 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;
- base::JSONWriter::Write(base::StringValue(message), &json_message);
-
- net::HttpServerResponseInfo response(status_code);
- response.SetBody(json_value + message, "application/json; charset=UTF-8");
-
- thread_->task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&ServerWrapper::SendResponse,
- base::Unretained(server_wrapper_), connection_id, response));
-}
-
-void DevToolsHttpHandler::Send200(int connection_id,
- const std::string& data,
- const std::string& mime_type) {
- if (!thread_)
- return;
- thread_->task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&ServerWrapper::Send200, base::Unretained(server_wrapper_),
- connection_id, data, mime_type));
-}
-
-void DevToolsHttpHandler::Send404(int connection_id) {
- if (!thread_)
- return;
- thread_->task_runner()->PostTask(
- FROM_HERE, base::Bind(&ServerWrapper::Send404,
- base::Unretained(server_wrapper_), connection_id));
-}
-
-void DevToolsHttpHandler::Send500(int connection_id,
- const std::string& message) {
- if (!thread_)
- return;
- thread_->task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&ServerWrapper::Send500, base::Unretained(server_wrapper_),
- connection_id, message));
-}
-
-void DevToolsHttpHandler::AcceptWebSocket(
- int connection_id,
- const net::HttpServerRequestInfo& request) {
- if (!thread_)
- return;
- thread_->task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&ServerWrapper::AcceptWebSocket,
- base::Unretained(server_wrapper_), connection_id, request));
-}
-
-std::unique_ptr<base::DictionaryValue> DevToolsHttpHandler::SerializeDescriptor(
- scoped_refptr<DevToolsAgentHost> agent_host,
- const std::string& host) {
- std::unique_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue);
- std::string id = agent_host->GetId();
- dictionary->SetString(kTargetIdField, id);
- std::string parent_id = agent_host->GetParentId();
- if (!parent_id.empty())
- dictionary->SetString(kTargetParentIdField, parent_id);
- dictionary->SetString(kTargetTypeField, agent_host->GetType());
- dictionary->SetString(kTargetTitleField,
- net::EscapeForHTML(agent_host->GetTitle()));
- dictionary->SetString(kTargetDescriptionField, agent_host->GetDescription());
-
- GURL url = agent_host->GetURL();
- dictionary->SetString(kTargetUrlField, url.spec());
-
- GURL favicon_url = agent_host->GetFaviconURL();
- if (favicon_url.is_valid())
- dictionary->SetString(kTargetFaviconUrlField, favicon_url.spec());
-
- if (!agent_host->IsAttached()) {
- dictionary->SetString(kTargetWebSocketDebuggerUrlField,
- base::StringPrintf("ws://%s%s%s",
- host.c_str(),
- kPageUrlPrefix,
- id.c_str()));
- std::string devtools_frontend_url = GetFrontendURLInternal(
- id.c_str(),
- host);
- dictionary->SetString(
- kTargetDevtoolsFrontendUrlField, devtools_frontend_url);
- }
-
- return dictionary;
-}
-
-} // namespace devtools_http_handler

Powered by Google App Engine
This is Rietveld 408576698