Index: content/browser/devtools/devtools_http_handler_impl.cc |
diff --git a/content/browser/devtools/devtools_http_handler_impl.cc b/content/browser/devtools/devtools_http_handler_impl.cc |
index e7b7fb9b99e68f17eff500742b76addccf88e3e3..996eedb6d78ca28376ea674171080a900ed2c325 100644 |
--- a/content/browser/devtools/devtools_http_handler_impl.cc |
+++ b/content/browser/devtools/devtools_http_handler_impl.cc |
@@ -71,16 +71,118 @@ const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl"; |
// Maximum write buffer size of devtools http/websocket connectinos. |
const int32 kSendBufferSizeForDevTools = 100 * 1024 * 1024; // 100Mb |
-// DevToolsAgentHostClientImpl ----------------------------------------------- |
+// Runs on FILE thread. |
+static scoped_ptr<base::Thread> StartHandlerThread() { |
+ scoped_ptr<base::Thread> thread(new base::Thread(kDevToolsHandlerThreadName)); |
+ base::Thread::Options options; |
+ options.message_loop_type = base::MessageLoop::TYPE_IO; |
+ if (!thread->StartWithOptions(options)) |
+ return nullptr; |
+ |
+ return thread.Pass(); |
+} |
+ |
+} // namespace |
+ |
+// DevToolsHttpHandlerImpl::ServerWrapper ------------------------------------ |
+ |
+class DevToolsHttpHandlerImpl::ServerWrapper : net::HttpServer::Delegate { |
+ public: |
+ static void StartServer( |
+ base::WeakPtr<DevToolsHttpHandlerImpl> handler, |
+ scoped_ptr<ServerSocketFactory> server_socket_factory, |
+ const base::FilePath& output_directory, |
+ const base::FilePath& frontend_dir, |
+ bool bundles_resources); |
+ |
+ 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); |
+ |
+ virtual ~ServerWrapper() {} |
+ |
+ private: |
+ ServerWrapper(base::WeakPtr<DevToolsHttpHandlerImpl> handler, |
+ scoped_ptr<net::ServerSocket> socket, |
+ const base::FilePath& frontend_dir, |
+ bool bundles_resources); |
+ |
+ // 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; |
+ |
+ void WriteActivePortToUserProfile(const base::FilePath& output_directory); |
+ |
+ base::WeakPtr<DevToolsHttpHandlerImpl> handler_; |
+ scoped_ptr<net::HttpServer> server_; |
+ base::FilePath frontend_dir_; |
+ bool bundles_resources_; |
+}; |
+ |
+void DevToolsHttpHandlerImpl::ServerWrapper::AcceptWebSocket( |
+ int connection_id, |
+ const net::HttpServerRequestInfo& request) { |
+ server_->SetSendBufferSize(connection_id, kSendBufferSizeForDevTools); |
+ server_->AcceptWebSocket(connection_id, request); |
+} |
+ |
+void DevToolsHttpHandlerImpl::ServerWrapper::SendOverWebSocket( |
+ int connection_id, |
+ const std::string& message) { |
+ server_->SendOverWebSocket(connection_id, message); |
+} |
+ |
+void DevToolsHttpHandlerImpl::ServerWrapper::SendResponse( |
+ int connection_id, |
+ const net::HttpServerResponseInfo& response) { |
+ server_->SendResponse(connection_id, response); |
+} |
+ |
+void DevToolsHttpHandlerImpl::ServerWrapper::Send200( |
+ int connection_id, |
+ const std::string& data, |
+ const std::string& mime_type) { |
+ server_->Send200(connection_id, data, mime_type); |
+} |
+ |
+void DevToolsHttpHandlerImpl::ServerWrapper::Send404(int connection_id) { |
+ server_->Send404(connection_id); |
+} |
+ |
+void DevToolsHttpHandlerImpl::ServerWrapper::Send500( |
+ int connection_id, |
+ const std::string& message) { |
+ server_->Send500(connection_id, message); |
+} |
+void DevToolsHttpHandlerImpl::ServerWrapper::Close(int connection_id) { |
+ server_->Close(connection_id); |
+} |
+ |
+// DevToolsHttpHandlerImpl::AgentHostClientImpl ------------------------------ |
// An internal implementation of DevToolsAgentHostClient that delegates |
// messages sent to a DebuggerShell instance. |
-class DevToolsAgentHostClientImpl : public DevToolsAgentHostClient { |
+class DevToolsHttpHandlerImpl::AgentHostClientImpl |
+ : public DevToolsAgentHostClient { |
public: |
- DevToolsAgentHostClientImpl(base::MessageLoop* message_loop, |
- net::HttpServer* server, |
- int connection_id, |
- DevToolsAgentHost* agent_host) |
+ AgentHostClientImpl(base::MessageLoop* message_loop, |
+ ServerWrapper* server, |
+ int connection_id, |
+ DevToolsAgentHost* agent_host) |
: message_loop_(message_loop), |
server_(server), |
connection_id_(connection_id), |
@@ -88,7 +190,7 @@ class DevToolsAgentHostClientImpl : public DevToolsAgentHostClient { |
agent_host_->AttachClient(this); |
} |
- ~DevToolsAgentHostClientImpl() override { |
+ ~AgentHostClientImpl() override { |
if (agent_host_.get()) |
agent_host_->DetachClient(); |
} |
@@ -108,14 +210,14 @@ class DevToolsAgentHostClientImpl : public DevToolsAgentHostClient { |
notification.DeepCopy())->Serialize(); |
message_loop_->PostTask( |
FROM_HERE, |
- base::Bind(&net::HttpServer::SendOverWebSocket, |
+ base::Bind(&ServerWrapper::SendOverWebSocket, |
base::Unretained(server_), |
connection_id_, |
response)); |
message_loop_->PostTask( |
FROM_HERE, |
- base::Bind(&net::HttpServer::Close, |
+ base::Bind(&ServerWrapper::Close, |
base::Unretained(server_), |
connection_id_)); |
} |
@@ -125,7 +227,7 @@ class DevToolsAgentHostClientImpl : public DevToolsAgentHostClient { |
DCHECK(agent_host == agent_host_.get()); |
message_loop_->PostTask( |
FROM_HERE, |
- base::Bind(&net::HttpServer::SendOverWebSocket, |
+ base::Bind(&ServerWrapper::SendOverWebSocket, |
base::Unretained(server_), |
connection_id_, |
message)); |
@@ -138,7 +240,7 @@ class DevToolsAgentHostClientImpl : public DevToolsAgentHostClient { |
private: |
base::MessageLoop* const message_loop_; |
- net::HttpServer* const server_; |
+ ServerWrapper* const server_; |
const int connection_id_; |
scoped_refptr<DevToolsAgentHost> agent_host_; |
}; |
@@ -148,14 +250,12 @@ static bool TimeComparator(const DevToolsTarget* target1, |
return target1->GetLastActivityTime() > target2->GetLastActivityTime(); |
} |
-} // namespace |
- |
// DevToolsHttpHandlerImpl::BrowserTarget ------------------------------------ |
class DevToolsHttpHandlerImpl::BrowserTarget { |
public: |
BrowserTarget(base::MessageLoop* message_loop, |
- net::HttpServer* server, |
+ ServerWrapper* server, |
int connection_id) |
: message_loop_(message_loop), |
server_(server), |
@@ -210,7 +310,7 @@ class DevToolsHttpHandlerImpl::BrowserTarget { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
message_loop_->PostTask( |
FROM_HERE, |
- base::Bind(&net::HttpServer::SendOverWebSocket, |
+ base::Bind(&ServerWrapper::SendOverWebSocket, |
base::Unretained(server_), |
connection_id_, |
message)); |
@@ -218,7 +318,7 @@ class DevToolsHttpHandlerImpl::BrowserTarget { |
private: |
base::MessageLoop* const message_loop_; |
- net::HttpServer* const server_; |
+ ServerWrapper* const server_; |
const int connection_id_; |
scoped_ptr<devtools::tracing::TracingHandler> tracing_handler_; |
scoped_ptr<DevToolsProtocolHandlerImpl> protocol_handler_; |
@@ -253,7 +353,6 @@ DevToolsHttpHandler* DevToolsHttpHandler::Start( |
frontend_url, |
delegate, |
active_port_output_directory); |
- http_handler->Start(); |
return http_handler; |
} |
@@ -284,64 +383,18 @@ DevToolsHttpHandler::ServerSocketFactory::CreateAndListen() const { |
// DevToolsHttpHandlerImpl --------------------------------------------------- |
DevToolsHttpHandlerImpl::~DevToolsHttpHandlerImpl() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- // Stop() must be called prior to destruction. |
- DCHECK(server_.get() == NULL); |
- DCHECK(thread_.get() == NULL); |
STLDeleteValues(&target_map_); |
-} |
- |
-void DevToolsHttpHandlerImpl::Start() { |
- if (thread_) |
- 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 = base::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(); |
- server_ip_address_.reset(); |
-} |
- |
-void DevToolsHttpHandlerImpl::ResetHandlerThreadAndRelease() { |
- ResetHandlerThread(); |
- Release(); |
+ STLDeleteValues(&browser_targets_); |
+ STLDeleteValues(&connection_to_client_); |
} |
void DevToolsHttpHandlerImpl::Stop() { |
- if (!thread_) |
- return; |
- BrowserThread::PostTaskAndReply( |
- BrowserThread::FILE, FROM_HERE, |
- base::Bind(&DevToolsHttpHandlerImpl::StopHandlerThread, this), |
- base::Bind(&DevToolsHttpHandlerImpl::ResetHandlerThreadAndRelease, this)); |
-} |
- |
-void DevToolsHttpHandlerImpl::StopWithoutRelease() { |
- if (!thread_) |
- return; |
- BrowserThread::PostTaskAndReply( |
- BrowserThread::FILE, FROM_HERE, |
- base::Bind(&DevToolsHttpHandlerImpl::StopHandlerThread, this), |
- base::Bind(&DevToolsHttpHandlerImpl::ResetHandlerThread, this)); |
+ if (server_) { |
+ DCHECK(thread_); |
+ thread_->message_loop()->DeleteSoon(FROM_HERE, server_.release()); |
+ } |
+ StopHandlerThread(); |
+ delete this; |
} |
GURL DevToolsHttpHandlerImpl::GetFrontendURL() { |
@@ -378,7 +431,7 @@ static std::string GetMimeType(const std::string& filename) { |
return "text/plain"; |
} |
-void DevToolsHttpHandlerImpl::OnHttpRequest( |
+void DevToolsHttpHandlerImpl::ServerWrapper::OnHttpRequest( |
int connection_id, |
const net::HttpServerRequestInfo& info) { |
server_->SetSendBufferSize(connection_id, kSendBufferSizeForDevTools); |
@@ -387,8 +440,8 @@ void DevToolsHttpHandlerImpl::OnHttpRequest( |
BrowserThread::PostTask( |
BrowserThread::UI, |
FROM_HERE, |
- base::Bind(&DevToolsHttpHandlerImpl::OnJsonRequestUI, |
- this, |
+ base::Bind(&DevToolsHttpHandlerImpl::OnJsonRequest, |
+ handler_, |
connection_id, |
info)); |
return; |
@@ -397,17 +450,13 @@ void DevToolsHttpHandlerImpl::OnHttpRequest( |
if (info.path.find(kThumbUrlPrefix) == 0) { |
// Thumbnail request. |
const std::string target_id = info.path.substr(strlen(kThumbUrlPrefix)); |
- DevToolsTarget* target = GetTarget(target_id); |
- GURL page_url; |
- if (target) |
- page_url = target->GetURL(); |
BrowserThread::PostTask( |
BrowserThread::UI, |
FROM_HERE, |
- base::Bind(&DevToolsHttpHandlerImpl::OnThumbnailRequestUI, |
- this, |
+ base::Bind(&DevToolsHttpHandlerImpl::OnThumbnailRequest, |
+ handler_, |
connection_id, |
- page_url)); |
+ target_id)); |
return; |
} |
@@ -416,8 +465,8 @@ void DevToolsHttpHandlerImpl::OnHttpRequest( |
BrowserThread::PostTask( |
BrowserThread::UI, |
FROM_HERE, |
- base::Bind(&DevToolsHttpHandlerImpl::OnDiscoveryPageRequestUI, |
- this, |
+ base::Bind(&DevToolsHttpHandlerImpl::OnDiscoveryPageRequest, |
+ handler_, |
connection_id)); |
return; |
} |
@@ -430,15 +479,14 @@ void DevToolsHttpHandlerImpl::OnHttpRequest( |
std::string filename = PathWithoutParams(info.path.substr(10)); |
std::string mime_type = GetMimeType(filename); |
- base::FilePath frontend_dir = delegate_->GetDebugFrontendDir(); |
- if (!frontend_dir.empty()) { |
- base::FilePath path = frontend_dir.AppendASCII(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 (delegate_->BundlesFrontendResources()) { |
+ if (bundles_resources_) { |
int resource_id = DevToolsHttpHandler::GetFrontendResourceId(filename); |
if (resource_id != -1) { |
base::StringPiece data = GetContentClient()->GetDataResource( |
@@ -450,39 +498,39 @@ void DevToolsHttpHandlerImpl::OnHttpRequest( |
server_->Send404(connection_id); |
} |
-void DevToolsHttpHandlerImpl::OnWebSocketRequest( |
+void DevToolsHttpHandlerImpl::ServerWrapper::OnWebSocketRequest( |
int connection_id, |
const net::HttpServerRequestInfo& request) { |
BrowserThread::PostTask( |
BrowserThread::UI, |
FROM_HERE, |
base::Bind( |
- &DevToolsHttpHandlerImpl::OnWebSocketRequestUI, |
- this, |
+ &DevToolsHttpHandlerImpl::OnWebSocketRequest, |
+ handler_, |
connection_id, |
request)); |
} |
-void DevToolsHttpHandlerImpl::OnWebSocketMessage( |
+void DevToolsHttpHandlerImpl::ServerWrapper::OnWebSocketMessage( |
int connection_id, |
const std::string& data) { |
BrowserThread::PostTask( |
BrowserThread::UI, |
FROM_HERE, |
base::Bind( |
- &DevToolsHttpHandlerImpl::OnWebSocketMessageUI, |
- this, |
+ &DevToolsHttpHandlerImpl::OnWebSocketMessage, |
+ handler_, |
connection_id, |
data)); |
} |
-void DevToolsHttpHandlerImpl::OnClose(int connection_id) { |
+void DevToolsHttpHandlerImpl::ServerWrapper::OnClose(int connection_id) { |
BrowserThread::PostTask( |
BrowserThread::UI, |
FROM_HERE, |
base::Bind( |
- &DevToolsHttpHandlerImpl::OnCloseUI, |
- this, |
+ &DevToolsHttpHandlerImpl::OnClose, |
+ handler_, |
connection_id)); |
} |
@@ -523,7 +571,7 @@ static bool ParseJsonPath( |
return true; |
} |
-void DevToolsHttpHandlerImpl::OnJsonRequestUI( |
+void DevToolsHttpHandlerImpl::OnJsonRequest( |
int connection_id, |
const net::HttpServerRequestInfo& info) { |
// Trim /json |
@@ -567,13 +615,12 @@ void DevToolsHttpHandlerImpl::OnJsonRequestUI( |
if (command == "list") { |
std::string host = info.headers["host"]; |
- AddRef(); // Balanced in OnTargetListReceived. |
DevToolsManagerDelegate* manager_delegate = |
DevToolsManager::GetInstance()->delegate(); |
if (manager_delegate) { |
manager_delegate->EnumerateTargets( |
- base::Bind(&DevToolsHttpHandlerImpl::OnTargetListReceived, |
- this, connection_id, host)); |
+ base::Bind(&DevToolsHttpHandlerImpl::OnTargetListReceivedWeak, |
+ weak_factory_.GetWeakPtr(), connection_id, host)); |
} else { |
DevToolsManagerDelegate::TargetList empty_list; |
OnTargetListReceived(connection_id, host, empty_list); |
@@ -648,6 +695,19 @@ void DevToolsHttpHandlerImpl::OnJsonRequestUI( |
return; |
} |
+// static |
+void DevToolsHttpHandlerImpl::OnTargetListReceivedWeak( |
+ base::WeakPtr<DevToolsHttpHandlerImpl> handler, |
+ int connection_id, |
+ const std::string& host, |
+ const DevToolsManagerDelegate::TargetList& targets) { |
+ if (handler) { |
+ handler->OnTargetListReceived(connection_id, host, targets); |
+ } else { |
+ STLDeleteContainerPointers(targets.begin(), targets.end()); |
+ } |
+} |
+ |
void DevToolsHttpHandlerImpl::OnTargetListReceived( |
int connection_id, |
const std::string& host, |
@@ -664,7 +724,6 @@ void DevToolsHttpHandlerImpl::OnTargetListReceived( |
list_value.Append(SerializeTarget(*target, host)); |
} |
SendJson(connection_id, net::HTTP_OK, &list_value, std::string()); |
- Release(); // Balanced in OnJsonRequestUI. |
} |
DevToolsTarget* DevToolsHttpHandlerImpl::GetTarget(const std::string& id) { |
@@ -674,8 +733,12 @@ DevToolsTarget* DevToolsHttpHandlerImpl::GetTarget(const std::string& id) { |
return it->second; |
} |
-void DevToolsHttpHandlerImpl::OnThumbnailRequestUI( |
- int connection_id, const GURL& page_url) { |
+void DevToolsHttpHandlerImpl::OnThumbnailRequest( |
+ int connection_id, const std::string& target_id) { |
+ DevToolsTarget* target = GetTarget(target_id); |
+ GURL page_url; |
+ if (target) |
+ page_url = target->GetURL(); |
DevToolsManagerDelegate* manager_delegate = |
DevToolsManager::GetInstance()->delegate(); |
std::string data = |
@@ -686,12 +749,12 @@ void DevToolsHttpHandlerImpl::OnThumbnailRequestUI( |
Send404(connection_id); |
} |
-void DevToolsHttpHandlerImpl::OnDiscoveryPageRequestUI(int connection_id) { |
+void DevToolsHttpHandlerImpl::OnDiscoveryPageRequest(int connection_id) { |
std::string response = delegate_->GetDiscoveryPageHTML(); |
Send200(connection_id, response, "text/html; charset=UTF-8"); |
} |
-void DevToolsHttpHandlerImpl::OnWebSocketRequestUI( |
+void DevToolsHttpHandlerImpl::OnWebSocketRequest( |
int connection_id, |
const net::HttpServerRequestInfo& request) { |
if (!thread_) |
@@ -732,14 +795,14 @@ void DevToolsHttpHandlerImpl::OnWebSocketRequestUI( |
return; |
} |
- DevToolsAgentHostClientImpl* client_host = new DevToolsAgentHostClientImpl( |
+ AgentHostClientImpl* client_host = new AgentHostClientImpl( |
thread_->message_loop(), server_.get(), connection_id, agent.get()); |
- connection_to_client_ui_[connection_id] = client_host; |
+ connection_to_client_[connection_id] = client_host; |
AcceptWebSocket(connection_id, request); |
} |
-void DevToolsHttpHandlerImpl::OnWebSocketMessageUI( |
+void DevToolsHttpHandlerImpl::OnWebSocketMessage( |
int connection_id, |
const std::string& data) { |
BrowserTargets::iterator browser_it = browser_targets_.find(connection_id); |
@@ -749,16 +812,12 @@ void DevToolsHttpHandlerImpl::OnWebSocketMessageUI( |
} |
ConnectionToClientMap::iterator it = |
- connection_to_client_ui_.find(connection_id); |
- if (it == connection_to_client_ui_.end()) |
- return; |
- |
- DevToolsAgentHostClientImpl* client = |
- static_cast<DevToolsAgentHostClientImpl*>(it->second); |
- client->OnMessage(data); |
+ connection_to_client_.find(connection_id); |
+ if (it != connection_to_client_.end()) |
+ it->second->OnMessage(data); |
} |
-void DevToolsHttpHandlerImpl::OnCloseUI(int connection_id) { |
+void DevToolsHttpHandlerImpl::OnClose(int connection_id) { |
BrowserTargets::iterator browser_it = browser_targets_.find(connection_id); |
if (browser_it != browser_targets_.end()) { |
delete browser_it->second; |
@@ -767,78 +826,107 @@ void DevToolsHttpHandlerImpl::OnCloseUI(int connection_id) { |
} |
ConnectionToClientMap::iterator it = |
- connection_to_client_ui_.find(connection_id); |
- if (it != connection_to_client_ui_.end()) { |
- DevToolsAgentHostClientImpl* client = |
- static_cast<DevToolsAgentHostClientImpl*>(it->second); |
- delete client; |
- connection_to_client_ui_.erase(connection_id); |
+ connection_to_client_.find(connection_id); |
+ if (it != connection_to_client_.end()) { |
+ delete it->second; |
+ connection_to_client_.erase(connection_id); |
} |
} |
-void DevToolsHttpHandlerImpl::OnHttpServerInitialized( |
- const net::IPEndPoint& ip_address) { |
- server_ip_address_.reset(new net::IPEndPoint(ip_address)); |
-} |
- |
DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl( |
scoped_ptr<ServerSocketFactory> server_socket_factory, |
const std::string& frontend_url, |
DevToolsHttpHandlerDelegate* delegate, |
- const base::FilePath& active_port_output_directory) |
+ const base::FilePath& output_directory) |
: frontend_url_(frontend_url), |
- server_socket_factory_(server_socket_factory.Pass()), |
delegate_(delegate), |
- active_port_output_directory_(active_port_output_directory) { |
+ weak_factory_(this) { |
if (frontend_url_.empty()) |
frontend_url_ = "/devtools/devtools.html"; |
- // Balanced in ResetHandlerThreadAndRelease(). |
- AddRef(); |
+ BrowserThread::PostTaskAndReplyWithResult( |
+ BrowserThread::FILE, FROM_HERE, |
+ base::Bind(&StartHandlerThread), |
+ base::Bind(&DevToolsHttpHandlerImpl::ThreadStarted, |
+ weak_factory_.GetWeakPtr(), |
+ base::Passed(&server_socket_factory), |
+ output_directory)); |
} |
-// Runs on the handler thread |
-void DevToolsHttpHandlerImpl::Init() { |
+void DevToolsHttpHandlerImpl::ThreadStarted( |
+ scoped_ptr<ServerSocketFactory> server_socket_factory, |
+ const base::FilePath& output_directory, |
+ scoped_ptr<base::Thread> thread) { |
+ thread_.swap(thread); |
+ thread_->message_loop()->PostTask(FROM_HERE, |
+ base::Bind(&DevToolsHttpHandlerImpl::ServerWrapper::StartServer, |
+ weak_factory_.GetWeakPtr(), |
+ base::Passed(&server_socket_factory), |
+ output_directory, |
+ delegate_->GetDebugFrontendDir(), |
+ delegate_->BundlesFrontendResources())); |
+} |
+ |
+// static |
+void DevToolsHttpHandlerImpl::ServerWrapper::StartServer( |
+ base::WeakPtr<DevToolsHttpHandlerImpl> handler, |
+ scoped_ptr<ServerSocketFactory> server_socket_factory, |
+ const base::FilePath& output_directory, |
+ const base::FilePath& frontend_dir, |
+ bool bundles_resources) { |
+ scoped_ptr<ServerWrapper> server; |
scoped_ptr<net::ServerSocket> server_socket = |
- server_socket_factory_->CreateAndListen(); |
- if (!server_socket) { |
+ server_socket_factory->CreateAndListen(); |
+ scoped_ptr<net::IPEndPoint> ip_address(new net::IPEndPoint); |
+ if (server_socket) { |
+ server.reset(new ServerWrapper(handler, server_socket.Pass(), |
+ frontend_dir, bundles_resources)); |
+ if (!output_directory.empty()) |
+ server->WriteActivePortToUserProfile(output_directory); |
+ |
+ if (server->server_->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(&DevToolsHttpHandlerImpl::StopWithoutRelease, this)); |
- return; |
} |
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
+ base::Bind(&DevToolsHttpHandlerImpl::ServerStarted, |
+ handler, base::Passed(&server), base::Passed(&ip_address))); |
+} |
- server_.reset(new net::HttpServer(server_socket.Pass(), this)); |
- net::IPEndPoint ip_address; |
- server_->GetLocalAddress(&ip_address); |
- BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
- base::Bind(&DevToolsHttpHandlerImpl::OnHttpServerInitialized, |
- this, ip_address)); |
- if (!active_port_output_directory_.empty()) |
- WriteActivePortToUserProfile(); |
+DevToolsHttpHandlerImpl::ServerWrapper::ServerWrapper( |
+ base::WeakPtr<DevToolsHttpHandlerImpl> handler, |
+ scoped_ptr<net::ServerSocket> socket, |
+ const base::FilePath& frontend_dir, |
+ bool bundles_resources) |
+ : handler_(handler), |
+ server_(new net::HttpServer(socket.Pass(), this)), |
+ frontend_dir_(frontend_dir), |
+ bundles_resources_(bundles_resources) { |
} |
-// Runs on the handler thread |
-void DevToolsHttpHandlerImpl::Teardown() { |
- server_.reset(); |
+void DevToolsHttpHandlerImpl::ServerStarted( |
+ scoped_ptr<ServerWrapper> server, |
+ scoped_ptr<net::IPEndPoint> ip_address) { |
+ if (server) { |
+ server_.swap(server); |
+ server_ip_address_.swap(ip_address); |
+ } else { |
+ StopHandlerThread(); |
+ } |
} |
-// 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(); |
+ if (thread_) { |
+ BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, |
+ thread_.release()); |
+ } |
} |
-void DevToolsHttpHandlerImpl::WriteActivePortToUserProfile() { |
- DCHECK(!active_port_output_directory_.empty()); |
+void DevToolsHttpHandlerImpl::ServerWrapper::WriteActivePortToUserProfile( |
+ const base::FilePath& output_directory) { |
+ DCHECK(!output_directory.empty()); |
net::IPEndPoint endpoint; |
int err; |
if ((err = server_->GetLocalAddress(&endpoint)) != net::OK) { |
@@ -848,8 +936,7 @@ void DevToolsHttpHandlerImpl::WriteActivePortToUserProfile() { |
// Write this port to a well-known file in the profile directory |
// so Telemetry can pick it up. |
- base::FilePath path = active_port_output_directory_.Append( |
- kDevToolsActivePortFileName); |
+ base::FilePath path = output_directory.Append(kDevToolsActivePortFileName); |
std::string port_string = base::IntToString(endpoint.port()); |
if (base::WriteFile(path, port_string.c_str(), port_string.length()) < 0) { |
LOG(ERROR) << "Error writing DevTools active port to file"; |
@@ -879,7 +966,7 @@ void DevToolsHttpHandlerImpl::SendJson(int connection_id, |
thread_->message_loop()->PostTask( |
FROM_HERE, |
- base::Bind(&net::HttpServer::SendResponse, |
+ base::Bind(&ServerWrapper::SendResponse, |
base::Unretained(server_.get()), |
connection_id, |
response)); |
@@ -892,7 +979,7 @@ void DevToolsHttpHandlerImpl::Send200(int connection_id, |
return; |
thread_->message_loop()->PostTask( |
FROM_HERE, |
- base::Bind(&net::HttpServer::Send200, |
+ base::Bind(&ServerWrapper::Send200, |
base::Unretained(server_.get()), |
connection_id, |
data, |
@@ -904,7 +991,7 @@ void DevToolsHttpHandlerImpl::Send404(int connection_id) { |
return; |
thread_->message_loop()->PostTask( |
FROM_HERE, |
- base::Bind(&net::HttpServer::Send404, |
+ base::Bind(&ServerWrapper::Send404, |
base::Unretained(server_.get()), |
connection_id)); |
} |
@@ -915,7 +1002,7 @@ void DevToolsHttpHandlerImpl::Send500(int connection_id, |
return; |
thread_->message_loop()->PostTask( |
FROM_HERE, |
- base::Bind(&net::HttpServer::Send500, |
+ base::Bind(&ServerWrapper::Send500, |
base::Unretained(server_.get()), |
connection_id, |
message)); |
@@ -928,13 +1015,7 @@ void DevToolsHttpHandlerImpl::AcceptWebSocket( |
return; |
thread_->message_loop()->PostTask( |
FROM_HERE, |
- base::Bind(&net::HttpServer::SetSendBufferSize, |
- base::Unretained(server_.get()), |
- connection_id, |
- kSendBufferSizeForDevTools)); |
- thread_->message_loop()->PostTask( |
- FROM_HERE, |
- base::Bind(&net::HttpServer::AcceptWebSocket, |
+ base::Bind(&ServerWrapper::AcceptWebSocket, |
base::Unretained(server_.get()), |
connection_id, |
request)); |