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

Unified Diff: content/browser/debugger/devtools_http_protocol_handler.cc

Issue 8554008: Add content API for DevTools HTTP handler (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Removed unnecessary comment from the public interface Created 9 years 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
« no previous file with comments | « content/browser/debugger/devtools_http_protocol_handler.h ('k') | content/content_browser.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/debugger/devtools_http_protocol_handler.cc
diff --git a/content/browser/debugger/devtools_http_protocol_handler.cc b/content/browser/debugger/devtools_http_protocol_handler.cc
deleted file mode 100644
index df85974f4097cd841fffbc7a9dd62497da38d1a5..0000000000000000000000000000000000000000
--- a/content/browser/debugger/devtools_http_protocol_handler.cc
+++ /dev/null
@@ -1,548 +0,0 @@
-// Copyright (c) 2011 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_protocol_handler.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/compiler_specific.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/tab_contents/tab_contents.h"
-#include "content/browser/tab_contents/tab_contents_observer.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_manager.h"
-#include "googleurl/src/gurl.h"
-#include "net/base/escape.h"
-#include "net/base/io_buffer.h"
-#include "net/server/http_server_request_info.h"
-#include "net/url_request/url_request_context.h"
-
-using content::BrowserThread;
-using content::DevToolsAgentHost;
-using content::DevToolsAgentHostRegistry;
-using content::DevToolsClientHost;
-using content::DevToolsManager;
-
-const int kBufferSize = 16 * 1024;
-
-namespace {
-
-// An internal implementation of DevToolsClientHost that delegates
-// messages sent for DevToolsClient to a DebuggerShell instance.
-class DevToolsClientHostImpl : public DevToolsClientHost {
- public:
- DevToolsClientHostImpl(
- net::HttpServer* server,
- int connection_id)
- : server_(server),
- connection_id_(connection_id) {
- }
- ~DevToolsClientHostImpl() {}
-
- // DevToolsClientHost interface
- virtual void InspectedTabClosing() {
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&net::HttpServer::Close, server_, connection_id_));
- }
-
- virtual void DispatchOnInspectorFrontend(const std::string& data) {
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&net::HttpServer::SendOverWebSocket,
- server_,
- connection_id_,
- data));
- }
-
- virtual void TabReplaced(TabContents* new_tab) {
- }
-
- private:
- virtual void FrameNavigating(const std::string& url) {}
- net::HttpServer* server_;
- int connection_id_;
-};
-
-static int next_id = 1;
-
-class TabContentsIDHelper : public TabContentsObserver {
- public:
-
- static int GetID(TabContents* tab) {
- TabContentsToIdMap::iterator it = tabcontents_to_id_.Get().find(tab);
- if (it != tabcontents_to_id_.Get().end())
- return it->second;
- TabContentsIDHelper* wrapper = new TabContentsIDHelper(tab);
- return wrapper->id_;
- }
-
- static TabContents* GetTabContents(int id) {
- IdToTabContentsMap::iterator it = id_to_tabcontents_.Get().find(id);
- if (it != id_to_tabcontents_.Get().end())
- return it->second;
- return NULL;
- }
-
- private:
- explicit TabContentsIDHelper(TabContents* tab)
- : TabContentsObserver(tab),
- id_(next_id++) {
- id_to_tabcontents_.Get()[id_] = tab;
- tabcontents_to_id_.Get()[tab] = id_;
- }
-
- virtual ~TabContentsIDHelper() {}
-
- virtual void TabContentsDestroyed(TabContents* tab) {
- id_to_tabcontents_.Get().erase(id_);
- tabcontents_to_id_.Get().erase(tab);
- delete this;
- }
-
- int id_;
- typedef std::map<int, TabContents*> IdToTabContentsMap;
- static base::LazyInstance<IdToTabContentsMap,
- base::LeakyLazyInstanceTraits<IdToTabContentsMap> >
- id_to_tabcontents_;
- typedef std::map<TabContents*, int> TabContentsToIdMap;
- static base::LazyInstance<TabContentsToIdMap,
- base::LeakyLazyInstanceTraits<TabContentsToIdMap> >
- tabcontents_to_id_;
-};
-
-base::LazyInstance<
- TabContentsIDHelper::IdToTabContentsMap,
- base::LeakyLazyInstanceTraits<TabContentsIDHelper::IdToTabContentsMap> >
- TabContentsIDHelper::id_to_tabcontents_ = LAZY_INSTANCE_INITIALIZER;
-base::LazyInstance<
- TabContentsIDHelper::TabContentsToIdMap,
- base::LeakyLazyInstanceTraits<TabContentsIDHelper::TabContentsToIdMap> >
- TabContentsIDHelper::tabcontents_to_id_ = LAZY_INSTANCE_INITIALIZER;
-
-} // namespace
-
-// static
-scoped_refptr<DevToolsHttpProtocolHandler> DevToolsHttpProtocolHandler::Start(
- const std::string& ip,
- int port,
- const std::string& frontend_url,
- Delegate* delegate) {
- scoped_refptr<DevToolsHttpProtocolHandler> http_handler =
- new DevToolsHttpProtocolHandler(ip, port, frontend_url, delegate);
- http_handler->Start();
- return http_handler;
-}
-
-DevToolsHttpProtocolHandler::~DevToolsHttpProtocolHandler() {
- // Stop() must be called prior to this being called
- DCHECK(server_.get() == NULL);
-}
-
-void DevToolsHttpProtocolHandler::Start() {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&DevToolsHttpProtocolHandler::Init, this));
-}
-
-void DevToolsHttpProtocolHandler::Stop() {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&DevToolsHttpProtocolHandler::Teardown, this));
-}
-
-void DevToolsHttpProtocolHandler::OnHttpRequest(
- int connection_id,
- const net::HttpServerRequestInfo& info) {
- if (info.path == "/json") {
- // Pages discovery json request.
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(&DevToolsHttpProtocolHandler::OnJsonRequestUI,
- this,
- connection_id,
- info));
- return;
- }
-
- // Proxy static files from chrome-devtools://devtools/*.
- net::URLRequestContext* request_context = delegate_->GetURLRequestContext();
- if (!request_context) {
- server_->Send404(connection_id);
- return;
- }
-
- if (info.path == "" || info.path == "/") {
- std::string response = delegate_->GetDiscoveryPageHTML();
- server_->Send200(connection_id, response, "text/html; charset=UTF-8");
- return;
- }
-
- net::URLRequest* request;
-
- if (info.path.find("/devtools/") == 0) {
- request = new net::URLRequest(GURL("chrome-devtools:/" + info.path), this);
- } else if (info.path.find("/thumb/") == 0) {
- request = new net::URLRequest(GURL("chrome:/" + info.path), this);
- } else {
- server_->Send404(connection_id);
- return;
- }
-
- Bind(request, connection_id);
- request->set_context(request_context);
- request->Start();
-}
-
-void DevToolsHttpProtocolHandler::OnWebSocketRequest(
- int connection_id,
- const net::HttpServerRequestInfo& request) {
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(
- &DevToolsHttpProtocolHandler::OnWebSocketRequestUI,
- this,
- connection_id,
- request));
-}
-
-void DevToolsHttpProtocolHandler::OnWebSocketMessage(
- int connection_id,
- const std::string& data) {
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(
- &DevToolsHttpProtocolHandler::OnWebSocketMessageUI,
- this,
- connection_id,
- data));
-}
-
-void DevToolsHttpProtocolHandler::OnClose(int connection_id) {
- ConnectionToRequestsMap::iterator it =
- connection_to_requests_io_.find(connection_id);
- if (it != connection_to_requests_io_.end()) {
- // Dispose delegating socket.
- for (std::set<net::URLRequest*>::iterator it2 = it->second.begin();
- it2 != it->second.end(); ++it2) {
- net::URLRequest* request = *it2;
- request->Cancel();
- request_to_connection_io_.erase(request);
- request_to_buffer_io_.erase(request);
- delete request;
- }
- connection_to_requests_io_.erase(connection_id);
- }
-
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(
- &DevToolsHttpProtocolHandler::OnCloseUI,
- this,
- connection_id));
-}
-
-struct PageInfo
-{
- int id;
- std::string url;
- bool attached;
- std::string title;
- std::string thumbnail_url;
- std::string favicon_url;
-};
-typedef std::vector<PageInfo> PageList;
-
-static PageList GeneratePageList(
- DevToolsHttpProtocolHandler::Delegate* delegate,
- int connection_id,
- const net::HttpServerRequestInfo& info) {
- typedef DevToolsHttpProtocolHandler::InspectableTabs Tabs;
- Tabs inspectable_tabs = delegate->GetInspectableTabs();
-
- PageList page_list;
- for (Tabs::iterator it = inspectable_tabs.begin();
- it != inspectable_tabs.end(); ++it) {
-
- TabContents* tab_contents = *it;
- NavigationController& controller = tab_contents->controller();
-
- NavigationEntry* entry = controller.GetActiveEntry();
- if (entry == NULL || !entry->url().is_valid())
- continue;
-
- DevToolsAgentHost* agent = DevToolsAgentHostRegistry::GetDevToolsAgentHost(
- tab_contents->render_view_host());
- DevToolsClientHost* client_host = DevToolsManager::GetInstance()->
- GetDevToolsClientHostFor(agent);
- PageInfo page_info;
- page_info.id = TabContentsIDHelper::GetID(tab_contents);
- page_info.attached = client_host != NULL;
- page_info.url = entry->url().spec();
- page_info.title = UTF16ToUTF8(net::EscapeForHTML(entry->title()));
- page_info.thumbnail_url = "/thumb/" + entry->url().spec();
- page_info.favicon_url = entry->favicon().url().spec();
- page_list.push_back(page_info);
- }
- return page_list;
-}
-
-void DevToolsHttpProtocolHandler::OnJsonRequestUI(
- int connection_id,
- const net::HttpServerRequestInfo& info) {
- PageList page_list = GeneratePageList(delegate_.get(),
- connection_id, info);
- ListValue json_pages_list;
- std::string host = info.headers["Host"];
- for (PageList::iterator i = page_list.begin();
- i != page_list.end(); ++i) {
-
- DictionaryValue* page_info = new DictionaryValue;
- json_pages_list.Append(page_info);
- page_info->SetString("title", i->title);
- page_info->SetString("url", i->url);
- page_info->SetString("thumbnailUrl", i->thumbnail_url);
- page_info->SetString("faviconUrl", i->favicon_url);
- if (!i->attached) {
- page_info->SetString("webSocketDebuggerUrl",
- base::StringPrintf("ws://%s/devtools/page/%d",
- host.c_str(),
- i->id));
- page_info->SetString("devtoolsFrontendUrl",
- base::StringPrintf("%s?host=%s&page=%d",
- overridden_frontend_url_.c_str(),
- host.c_str(),
- i->id));
- }
- }
-
- std::string response;
- base::JSONWriter::Write(&json_pages_list, true, &response);
- Send200(connection_id, response, "application/json; charset=UTF-8");
-}
-
-void DevToolsHttpProtocolHandler::OnWebSocketRequestUI(
- int connection_id,
- const net::HttpServerRequestInfo& request) {
- std::string prefix = "/devtools/page/";
- size_t pos = request.path.find(prefix);
- if (pos != 0) {
- Send404(connection_id);
- return;
- }
- std::string page_id = request.path.substr(prefix.length());
- int id = 0;
- if (!base::StringToInt(page_id, &id)) {
- Send500(connection_id, "Invalid page id: " + page_id);
- return;
- }
-
- TabContents* tab_contents = TabContentsIDHelper::GetTabContents(id);
- if (tab_contents == NULL) {
- Send500(connection_id, "No such page id: " + page_id);
- return;
- }
-
- DevToolsManager* manager = DevToolsManager::GetInstance();
- DevToolsAgentHost* agent = DevToolsAgentHostRegistry::GetDevToolsAgentHost(
- tab_contents->render_view_host());
- if (manager->GetDevToolsClientHostFor(agent)) {
- Send500(connection_id, "Page with given id is being inspected: " + page_id);
- return;
- }
-
- DevToolsClientHostImpl* client_host =
- new DevToolsClientHostImpl(server_, connection_id);
- connection_to_client_host_ui_[connection_id] = client_host;
-
- manager->RegisterDevToolsClientHostFor(agent, client_host);
-
- AcceptWebSocket(connection_id, request);
-}
-
-void DevToolsHttpProtocolHandler::OnWebSocketMessageUI(
- int connection_id,
- const std::string& data) {
- 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 DevToolsHttpProtocolHandler::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);
- }
-}
-
-void DevToolsHttpProtocolHandler::OnResponseStarted(net::URLRequest* request) {
- RequestToSocketMap::iterator it = request_to_connection_io_.find(request);
- if (it == request_to_connection_io_.end())
- return;
-
- int connection_id = it->second;
-
- std::string content_type;
- request->GetMimeType(&content_type);
-
- if (request->status().is_success()) {
- server_->Send(connection_id,
- base::StringPrintf("HTTP/1.1 200 OK\r\n"
- "Content-Type:%s\r\n"
- "Transfer-Encoding: chunked\r\n"
- "\r\n",
- content_type.c_str()));
- } else {
- server_->Send404(connection_id);
- }
-
- int bytes_read = 0;
- // Some servers may treat HEAD requests as GET requests. To free up the
- // network connection as soon as possible, signal that the request has
- // completed immediately, without trying to read any data back (all we care
- // about is the response code and headers, which we already have).
- net::IOBuffer* buffer = request_to_buffer_io_[request].get();
- if (request->status().is_success())
- request->Read(buffer, kBufferSize, &bytes_read);
- OnReadCompleted(request, bytes_read);
-}
-
-void DevToolsHttpProtocolHandler::OnReadCompleted(net::URLRequest* request,
- int bytes_read) {
- RequestToSocketMap::iterator it = request_to_connection_io_.find(request);
- if (it == request_to_connection_io_.end())
- return;
-
- int connection_id = it->second;
-
- net::IOBuffer* buffer = request_to_buffer_io_[request].get();
- do {
- if (!request->status().is_success() || bytes_read <= 0)
- break;
- std::string chunk_size = base::StringPrintf("%X\r\n", bytes_read);
- server_->Send(connection_id, chunk_size);
- server_->Send(connection_id, buffer->data(), bytes_read);
- server_->Send(connection_id, "\r\n");
- } while (request->Read(buffer, kBufferSize, &bytes_read));
-
-
- // See comments re: HEAD requests in OnResponseStarted().
- if (!request->status().is_io_pending()) {
- server_->Send(connection_id, "0\r\n\r\n");
- RequestCompleted(request);
- }
-}
-
-DevToolsHttpProtocolHandler::DevToolsHttpProtocolHandler(
- const std::string& ip,
- int port,
- const std::string& frontend_host,
- Delegate* delegate)
- : ip_(ip),
- port_(port),
- overridden_frontend_url_(frontend_host),
- delegate_(delegate) {
- if (overridden_frontend_url_.empty())
- overridden_frontend_url_ = "/devtools/devtools.html";
-}
-
-void DevToolsHttpProtocolHandler::Init() {
- server_ = new net::HttpServer(ip_, port_, this);
-}
-
-// Run on I/O thread
-void DevToolsHttpProtocolHandler::Teardown() {
- server_ = NULL;
-}
-
-void DevToolsHttpProtocolHandler::Bind(net::URLRequest* request,
- int connection_id) {
- request_to_connection_io_[request] = connection_id;
- ConnectionToRequestsMap::iterator it =
- connection_to_requests_io_.find(connection_id);
- if (it == connection_to_requests_io_.end()) {
- std::pair<int, std::set<net::URLRequest*> > value(
- connection_id,
- std::set<net::URLRequest*>());
- it = connection_to_requests_io_.insert(value).first;
- }
- it->second.insert(request);
- request_to_buffer_io_[request] = new net::IOBuffer(kBufferSize);
-}
-
-void DevToolsHttpProtocolHandler::RequestCompleted(net::URLRequest* request) {
- RequestToSocketMap::iterator it = request_to_connection_io_.find(request);
- if (it == request_to_connection_io_.end())
- return;
-
- int connection_id = it->second;
- request_to_connection_io_.erase(request);
- ConnectionToRequestsMap::iterator it2 =
- connection_to_requests_io_.find(connection_id);
- it2->second.erase(request);
- request_to_buffer_io_.erase(request);
- delete request;
-}
-
-void DevToolsHttpProtocolHandler::Send200(int connection_id,
- const std::string& data,
- const std::string& mime_type) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&net::HttpServer::Send200,
- server_.get(),
- connection_id,
- data,
- mime_type));
-}
-
-void DevToolsHttpProtocolHandler::Send404(int connection_id) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&net::HttpServer::Send404, server_.get(), connection_id));
-}
-
-void DevToolsHttpProtocolHandler::Send500(int connection_id,
- const std::string& message) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&net::HttpServer::Send500, server_.get(), connection_id,
- message));
-}
-
-void DevToolsHttpProtocolHandler::AcceptWebSocket(
- int connection_id,
- const net::HttpServerRequestInfo& request) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&net::HttpServer::AcceptWebSocket, server_.get(),
- connection_id, request));
-}
« no previous file with comments | « content/browser/debugger/devtools_http_protocol_handler.h ('k') | content/content_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698