OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/devtools/devtools_http_handler_impl.h" | 5 #include "content/browser/devtools/devtools_http_handler_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 const char kTargetDescriptionField[] = "description"; | 64 const char kTargetDescriptionField[] = "description"; |
65 const char kTargetUrlField[] = "url"; | 65 const char kTargetUrlField[] = "url"; |
66 const char kTargetThumbnailUrlField[] = "thumbnailUrl"; | 66 const char kTargetThumbnailUrlField[] = "thumbnailUrl"; |
67 const char kTargetFaviconUrlField[] = "faviconUrl"; | 67 const char kTargetFaviconUrlField[] = "faviconUrl"; |
68 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl"; | 68 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl"; |
69 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl"; | 69 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl"; |
70 | 70 |
71 // Maximum write buffer size of devtools http/websocket connectinos. | 71 // Maximum write buffer size of devtools http/websocket connectinos. |
72 const int32 kSendBufferSizeForDevTools = 100 * 1024 * 1024; // 100Mb | 72 const int32 kSendBufferSizeForDevTools = 100 * 1024 * 1024; // 100Mb |
73 | 73 |
74 // DevToolsAgentHostClientImpl ----------------------------------------------- | 74 // Runs on FILE thread. |
| 75 static scoped_ptr<base::Thread> StartHandlerThread() { |
| 76 scoped_ptr<base::Thread> thread(new base::Thread(kDevToolsHandlerThreadName)); |
| 77 base::Thread::Options options; |
| 78 options.message_loop_type = base::MessageLoop::TYPE_IO; |
| 79 if (!thread->StartWithOptions(options)) |
| 80 return nullptr; |
75 | 81 |
| 82 return thread.Pass(); |
| 83 } |
| 84 |
| 85 } // namespace |
| 86 |
| 87 // DevToolsHttpHandlerImpl::ServerWrapper ------------------------------------ |
| 88 |
| 89 class DevToolsHttpHandlerImpl::ServerWrapper : net::HttpServer::Delegate { |
| 90 public: |
| 91 static void StartServer( |
| 92 base::WeakPtr<DevToolsHttpHandlerImpl> handler, |
| 93 scoped_ptr<ServerSocketFactory> server_socket_factory, |
| 94 const base::FilePath& output_directory, |
| 95 const base::FilePath& frontend_dir, |
| 96 bool bundles_resources); |
| 97 |
| 98 void AcceptWebSocket(int connection_id, |
| 99 const net::HttpServerRequestInfo& request); |
| 100 void SendOverWebSocket(int connection_id, const std::string& message); |
| 101 void SendResponse(int connection_id, |
| 102 const net::HttpServerResponseInfo& response); |
| 103 void Send200(int connection_id, |
| 104 const std::string& data, |
| 105 const std::string& mime_type); |
| 106 void Send404(int connection_id); |
| 107 void Send500(int connection_id, const std::string& message); |
| 108 void Close(int connection_id); |
| 109 |
| 110 virtual ~ServerWrapper() {} |
| 111 |
| 112 private: |
| 113 ServerWrapper(base::WeakPtr<DevToolsHttpHandlerImpl> handler, |
| 114 scoped_ptr<net::ServerSocket> socket, |
| 115 const base::FilePath& frontend_dir, |
| 116 bool bundles_resources); |
| 117 |
| 118 // net::HttpServer::Delegate implementation. |
| 119 void OnConnect(int connection_id) override {} |
| 120 void OnHttpRequest(int connection_id, |
| 121 const net::HttpServerRequestInfo& info) override; |
| 122 void OnWebSocketRequest(int connection_id, |
| 123 const net::HttpServerRequestInfo& info) override; |
| 124 void OnWebSocketMessage(int connection_id, |
| 125 const std::string& data) override; |
| 126 void OnClose(int connection_id) override; |
| 127 |
| 128 void WriteActivePortToUserProfile(const base::FilePath& output_directory); |
| 129 |
| 130 base::WeakPtr<DevToolsHttpHandlerImpl> handler_; |
| 131 scoped_ptr<net::HttpServer> server_; |
| 132 base::FilePath frontend_dir_; |
| 133 bool bundles_resources_; |
| 134 }; |
| 135 |
| 136 void DevToolsHttpHandlerImpl::ServerWrapper::AcceptWebSocket( |
| 137 int connection_id, |
| 138 const net::HttpServerRequestInfo& request) { |
| 139 server_->SetSendBufferSize(connection_id, kSendBufferSizeForDevTools); |
| 140 server_->AcceptWebSocket(connection_id, request); |
| 141 } |
| 142 |
| 143 void DevToolsHttpHandlerImpl::ServerWrapper::SendOverWebSocket( |
| 144 int connection_id, |
| 145 const std::string& message) { |
| 146 server_->SendOverWebSocket(connection_id, message); |
| 147 } |
| 148 |
| 149 void DevToolsHttpHandlerImpl::ServerWrapper::SendResponse( |
| 150 int connection_id, |
| 151 const net::HttpServerResponseInfo& response) { |
| 152 server_->SendResponse(connection_id, response); |
| 153 } |
| 154 |
| 155 void DevToolsHttpHandlerImpl::ServerWrapper::Send200( |
| 156 int connection_id, |
| 157 const std::string& data, |
| 158 const std::string& mime_type) { |
| 159 server_->Send200(connection_id, data, mime_type); |
| 160 } |
| 161 |
| 162 void DevToolsHttpHandlerImpl::ServerWrapper::Send404(int connection_id) { |
| 163 server_->Send404(connection_id); |
| 164 } |
| 165 |
| 166 void DevToolsHttpHandlerImpl::ServerWrapper::Send500( |
| 167 int connection_id, |
| 168 const std::string& message) { |
| 169 server_->Send500(connection_id, message); |
| 170 } |
| 171 |
| 172 void DevToolsHttpHandlerImpl::ServerWrapper::Close(int connection_id) { |
| 173 server_->Close(connection_id); |
| 174 } |
| 175 |
| 176 // DevToolsHttpHandlerImpl::AgentHostClientImpl ------------------------------ |
76 // An internal implementation of DevToolsAgentHostClient that delegates | 177 // An internal implementation of DevToolsAgentHostClient that delegates |
77 // messages sent to a DebuggerShell instance. | 178 // messages sent to a DebuggerShell instance. |
78 class DevToolsAgentHostClientImpl : public DevToolsAgentHostClient { | 179 class DevToolsHttpHandlerImpl::AgentHostClientImpl |
| 180 : public DevToolsAgentHostClient { |
79 public: | 181 public: |
80 DevToolsAgentHostClientImpl(base::MessageLoop* message_loop, | 182 AgentHostClientImpl(base::MessageLoop* message_loop, |
81 net::HttpServer* server, | 183 ServerWrapper* server, |
82 int connection_id, | 184 int connection_id, |
83 DevToolsAgentHost* agent_host) | 185 DevToolsAgentHost* agent_host) |
84 : message_loop_(message_loop), | 186 : message_loop_(message_loop), |
85 server_(server), | 187 server_(server), |
86 connection_id_(connection_id), | 188 connection_id_(connection_id), |
87 agent_host_(agent_host) { | 189 agent_host_(agent_host) { |
88 agent_host_->AttachClient(this); | 190 agent_host_->AttachClient(this); |
89 } | 191 } |
90 | 192 |
91 ~DevToolsAgentHostClientImpl() override { | 193 ~AgentHostClientImpl() override { |
92 if (agent_host_.get()) | 194 if (agent_host_.get()) |
93 agent_host_->DetachClient(); | 195 agent_host_->DetachClient(); |
94 } | 196 } |
95 | 197 |
96 void AgentHostClosed(DevToolsAgentHost* agent_host, | 198 void AgentHostClosed(DevToolsAgentHost* agent_host, |
97 bool replaced_with_another_client) override { | 199 bool replaced_with_another_client) override { |
98 DCHECK(agent_host == agent_host_.get()); | 200 DCHECK(agent_host == agent_host_.get()); |
99 agent_host_ = NULL; | 201 agent_host_ = NULL; |
100 | 202 |
101 base::DictionaryValue notification; | 203 base::DictionaryValue notification; |
102 notification.SetString( | 204 notification.SetString( |
103 devtools::Inspector::detached::kParamReason, | 205 devtools::Inspector::detached::kParamReason, |
104 replaced_with_another_client ? | 206 replaced_with_another_client ? |
105 "replaced_with_devtools" : "target_closed"); | 207 "replaced_with_devtools" : "target_closed"); |
106 std::string response = DevToolsProtocol::CreateNotification( | 208 std::string response = DevToolsProtocol::CreateNotification( |
107 devtools::Inspector::detached::kName, | 209 devtools::Inspector::detached::kName, |
108 notification.DeepCopy())->Serialize(); | 210 notification.DeepCopy())->Serialize(); |
109 message_loop_->PostTask( | 211 message_loop_->PostTask( |
110 FROM_HERE, | 212 FROM_HERE, |
111 base::Bind(&net::HttpServer::SendOverWebSocket, | 213 base::Bind(&ServerWrapper::SendOverWebSocket, |
112 base::Unretained(server_), | 214 base::Unretained(server_), |
113 connection_id_, | 215 connection_id_, |
114 response)); | 216 response)); |
115 | 217 |
116 message_loop_->PostTask( | 218 message_loop_->PostTask( |
117 FROM_HERE, | 219 FROM_HERE, |
118 base::Bind(&net::HttpServer::Close, | 220 base::Bind(&ServerWrapper::Close, |
119 base::Unretained(server_), | 221 base::Unretained(server_), |
120 connection_id_)); | 222 connection_id_)); |
121 } | 223 } |
122 | 224 |
123 void DispatchProtocolMessage(DevToolsAgentHost* agent_host, | 225 void DispatchProtocolMessage(DevToolsAgentHost* agent_host, |
124 const std::string& message) override { | 226 const std::string& message) override { |
125 DCHECK(agent_host == agent_host_.get()); | 227 DCHECK(agent_host == agent_host_.get()); |
126 message_loop_->PostTask( | 228 message_loop_->PostTask( |
127 FROM_HERE, | 229 FROM_HERE, |
128 base::Bind(&net::HttpServer::SendOverWebSocket, | 230 base::Bind(&ServerWrapper::SendOverWebSocket, |
129 base::Unretained(server_), | 231 base::Unretained(server_), |
130 connection_id_, | 232 connection_id_, |
131 message)); | 233 message)); |
132 } | 234 } |
133 | 235 |
134 void OnMessage(const std::string& message) { | 236 void OnMessage(const std::string& message) { |
135 if (agent_host_.get()) | 237 if (agent_host_.get()) |
136 agent_host_->DispatchProtocolMessage(message); | 238 agent_host_->DispatchProtocolMessage(message); |
137 } | 239 } |
138 | 240 |
139 private: | 241 private: |
140 base::MessageLoop* const message_loop_; | 242 base::MessageLoop* const message_loop_; |
141 net::HttpServer* const server_; | 243 ServerWrapper* const server_; |
142 const int connection_id_; | 244 const int connection_id_; |
143 scoped_refptr<DevToolsAgentHost> agent_host_; | 245 scoped_refptr<DevToolsAgentHost> agent_host_; |
144 }; | 246 }; |
145 | 247 |
146 static bool TimeComparator(const DevToolsTarget* target1, | 248 static bool TimeComparator(const DevToolsTarget* target1, |
147 const DevToolsTarget* target2) { | 249 const DevToolsTarget* target2) { |
148 return target1->GetLastActivityTime() > target2->GetLastActivityTime(); | 250 return target1->GetLastActivityTime() > target2->GetLastActivityTime(); |
149 } | 251 } |
150 | 252 |
151 } // namespace | |
152 | |
153 // DevToolsHttpHandlerImpl::BrowserTarget ------------------------------------ | 253 // DevToolsHttpHandlerImpl::BrowserTarget ------------------------------------ |
154 | 254 |
155 class DevToolsHttpHandlerImpl::BrowserTarget { | 255 class DevToolsHttpHandlerImpl::BrowserTarget { |
156 public: | 256 public: |
157 BrowserTarget(base::MessageLoop* message_loop, | 257 BrowserTarget(base::MessageLoop* message_loop, |
158 net::HttpServer* server, | 258 ServerWrapper* server, |
159 int connection_id) | 259 int connection_id) |
160 : message_loop_(message_loop), | 260 : message_loop_(message_loop), |
161 server_(server), | 261 server_(server), |
162 connection_id_(connection_id), | 262 connection_id_(connection_id), |
163 tracing_handler_(new devtools::tracing::TracingHandler( | 263 tracing_handler_(new devtools::tracing::TracingHandler( |
164 devtools::tracing::TracingHandler::Browser)), | 264 devtools::tracing::TracingHandler::Browser)), |
165 protocol_handler_(new DevToolsProtocolHandlerImpl()) { | 265 protocol_handler_(new DevToolsProtocolHandlerImpl()) { |
166 protocol_handler_->SetNotifier( | 266 protocol_handler_->SetNotifier( |
167 base::Bind(&BrowserTarget::Respond, base::Unretained(this))); | 267 base::Bind(&BrowserTarget::Respond, base::Unretained(this))); |
168 protocol_handler_->SetTracingHandler(tracing_handler_.get()); | 268 protocol_handler_->SetTracingHandler(tracing_handler_.get()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 Respond(response->Serialize()); | 303 Respond(response->Serialize()); |
204 } else { | 304 } else { |
205 Respond(command->NoSuchMethodErrorResponse()->Serialize()); | 305 Respond(command->NoSuchMethodErrorResponse()->Serialize()); |
206 } | 306 } |
207 } | 307 } |
208 | 308 |
209 void Respond(const std::string& message) { | 309 void Respond(const std::string& message) { |
210 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 310 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
211 message_loop_->PostTask( | 311 message_loop_->PostTask( |
212 FROM_HERE, | 312 FROM_HERE, |
213 base::Bind(&net::HttpServer::SendOverWebSocket, | 313 base::Bind(&ServerWrapper::SendOverWebSocket, |
214 base::Unretained(server_), | 314 base::Unretained(server_), |
215 connection_id_, | 315 connection_id_, |
216 message)); | 316 message)); |
217 } | 317 } |
218 | 318 |
219 private: | 319 private: |
220 base::MessageLoop* const message_loop_; | 320 base::MessageLoop* const message_loop_; |
221 net::HttpServer* const server_; | 321 ServerWrapper* const server_; |
222 const int connection_id_; | 322 const int connection_id_; |
223 scoped_ptr<devtools::tracing::TracingHandler> tracing_handler_; | 323 scoped_ptr<devtools::tracing::TracingHandler> tracing_handler_; |
224 scoped_ptr<DevToolsProtocolHandlerImpl> protocol_handler_; | 324 scoped_ptr<DevToolsProtocolHandlerImpl> protocol_handler_; |
225 std::vector<DevToolsProtocol::Handler*> handlers_; | 325 std::vector<DevToolsProtocol::Handler*> handlers_; |
226 }; | 326 }; |
227 | 327 |
228 // DevToolsHttpHandler ------------------------------------------------------- | 328 // DevToolsHttpHandler ------------------------------------------------------- |
229 | 329 |
230 // static | 330 // static |
231 bool DevToolsHttpHandler::IsSupportedProtocolVersion( | 331 bool DevToolsHttpHandler::IsSupportedProtocolVersion( |
(...skipping 14 matching lines...) Expand all Loading... |
246 DevToolsHttpHandler* DevToolsHttpHandler::Start( | 346 DevToolsHttpHandler* DevToolsHttpHandler::Start( |
247 scoped_ptr<ServerSocketFactory> server_socket_factory, | 347 scoped_ptr<ServerSocketFactory> server_socket_factory, |
248 const std::string& frontend_url, | 348 const std::string& frontend_url, |
249 DevToolsHttpHandlerDelegate* delegate, | 349 DevToolsHttpHandlerDelegate* delegate, |
250 const base::FilePath& active_port_output_directory) { | 350 const base::FilePath& active_port_output_directory) { |
251 DevToolsHttpHandlerImpl* http_handler = | 351 DevToolsHttpHandlerImpl* http_handler = |
252 new DevToolsHttpHandlerImpl(server_socket_factory.Pass(), | 352 new DevToolsHttpHandlerImpl(server_socket_factory.Pass(), |
253 frontend_url, | 353 frontend_url, |
254 delegate, | 354 delegate, |
255 active_port_output_directory); | 355 active_port_output_directory); |
256 http_handler->Start(); | |
257 return http_handler; | 356 return http_handler; |
258 } | 357 } |
259 | 358 |
260 // DevToolsHttpHandler::ServerSocketFactory ---------------------------------- | 359 // DevToolsHttpHandler::ServerSocketFactory ---------------------------------- |
261 | 360 |
262 DevToolsHttpHandler::ServerSocketFactory::ServerSocketFactory( | 361 DevToolsHttpHandler::ServerSocketFactory::ServerSocketFactory( |
263 const std::string& address, | 362 const std::string& address, |
264 int port, | 363 int port, |
265 int backlog) | 364 int backlog) |
266 : address_(address), | 365 : address_(address), |
(...skipping 10 matching lines...) Expand all Loading... |
277 if (socket && | 376 if (socket && |
278 socket->ListenWithAddressAndPort(address_, port_, backlog_) == net::OK) { | 377 socket->ListenWithAddressAndPort(address_, port_, backlog_) == net::OK) { |
279 return socket.Pass(); | 378 return socket.Pass(); |
280 } | 379 } |
281 return scoped_ptr<net::ServerSocket>(); | 380 return scoped_ptr<net::ServerSocket>(); |
282 } | 381 } |
283 | 382 |
284 // DevToolsHttpHandlerImpl --------------------------------------------------- | 383 // DevToolsHttpHandlerImpl --------------------------------------------------- |
285 | 384 |
286 DevToolsHttpHandlerImpl::~DevToolsHttpHandlerImpl() { | 385 DevToolsHttpHandlerImpl::~DevToolsHttpHandlerImpl() { |
287 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
288 // Stop() must be called prior to destruction. | |
289 DCHECK(server_.get() == NULL); | |
290 DCHECK(thread_.get() == NULL); | |
291 STLDeleteValues(&target_map_); | 386 STLDeleteValues(&target_map_); |
292 } | 387 STLDeleteValues(&browser_targets_); |
293 | 388 STLDeleteValues(&connection_to_client_); |
294 void DevToolsHttpHandlerImpl::Start() { | |
295 if (thread_) | |
296 return; | |
297 thread_.reset(new base::Thread(kDevToolsHandlerThreadName)); | |
298 BrowserThread::PostTask( | |
299 BrowserThread::FILE, FROM_HERE, | |
300 base::Bind(&DevToolsHttpHandlerImpl::StartHandlerThread, this)); | |
301 } | |
302 | |
303 // Runs on FILE thread. | |
304 void DevToolsHttpHandlerImpl::StartHandlerThread() { | |
305 base::Thread::Options options; | |
306 options.message_loop_type = base::MessageLoop::TYPE_IO; | |
307 if (!thread_->StartWithOptions(options)) { | |
308 BrowserThread::PostTask( | |
309 BrowserThread::UI, FROM_HERE, | |
310 base::Bind(&DevToolsHttpHandlerImpl::ResetHandlerThread, this)); | |
311 return; | |
312 } | |
313 | |
314 thread_->message_loop()->PostTask( | |
315 FROM_HERE, | |
316 base::Bind(&DevToolsHttpHandlerImpl::Init, this)); | |
317 } | |
318 | |
319 void DevToolsHttpHandlerImpl::ResetHandlerThread() { | |
320 thread_.reset(); | |
321 server_ip_address_.reset(); | |
322 } | |
323 | |
324 void DevToolsHttpHandlerImpl::ResetHandlerThreadAndRelease() { | |
325 ResetHandlerThread(); | |
326 Release(); | |
327 } | 389 } |
328 | 390 |
329 void DevToolsHttpHandlerImpl::Stop() { | 391 void DevToolsHttpHandlerImpl::Stop() { |
330 if (!thread_) | 392 if (server_) { |
331 return; | 393 DCHECK(thread_); |
332 BrowserThread::PostTaskAndReply( | 394 thread_->message_loop()->DeleteSoon(FROM_HERE, server_.release()); |
333 BrowserThread::FILE, FROM_HERE, | 395 } |
334 base::Bind(&DevToolsHttpHandlerImpl::StopHandlerThread, this), | 396 StopHandlerThread(); |
335 base::Bind(&DevToolsHttpHandlerImpl::ResetHandlerThreadAndRelease, this)); | 397 delete this; |
336 } | |
337 | |
338 void DevToolsHttpHandlerImpl::StopWithoutRelease() { | |
339 if (!thread_) | |
340 return; | |
341 BrowserThread::PostTaskAndReply( | |
342 BrowserThread::FILE, FROM_HERE, | |
343 base::Bind(&DevToolsHttpHandlerImpl::StopHandlerThread, this), | |
344 base::Bind(&DevToolsHttpHandlerImpl::ResetHandlerThread, this)); | |
345 } | 398 } |
346 | 399 |
347 GURL DevToolsHttpHandlerImpl::GetFrontendURL() { | 400 GURL DevToolsHttpHandlerImpl::GetFrontendURL() { |
348 if (!server_ip_address_) | 401 if (!server_ip_address_) |
349 return GURL(); | 402 return GURL(); |
350 return GURL(std::string("http://") + server_ip_address_->ToString() + frontend
_url_); | 403 return GURL(std::string("http://") + server_ip_address_->ToString() + frontend
_url_); |
351 } | 404 } |
352 | 405 |
353 static std::string PathWithoutParams(const std::string& path) { | 406 static std::string PathWithoutParams(const std::string& path) { |
354 size_t query_position = path.find("?"); | 407 size_t query_position = path.find("?"); |
(...skipping 16 matching lines...) Expand all Loading... |
371 } else if (EndsWith(filename, ".json", false)) { | 424 } else if (EndsWith(filename, ".json", false)) { |
372 return "application/json"; | 425 return "application/json"; |
373 } | 426 } |
374 LOG(ERROR) << "GetMimeType doesn't know mime type for: " | 427 LOG(ERROR) << "GetMimeType doesn't know mime type for: " |
375 << filename | 428 << filename |
376 << " text/plain will be returned"; | 429 << " text/plain will be returned"; |
377 NOTREACHED(); | 430 NOTREACHED(); |
378 return "text/plain"; | 431 return "text/plain"; |
379 } | 432 } |
380 | 433 |
381 void DevToolsHttpHandlerImpl::OnHttpRequest( | 434 void DevToolsHttpHandlerImpl::ServerWrapper::OnHttpRequest( |
382 int connection_id, | 435 int connection_id, |
383 const net::HttpServerRequestInfo& info) { | 436 const net::HttpServerRequestInfo& info) { |
384 server_->SetSendBufferSize(connection_id, kSendBufferSizeForDevTools); | 437 server_->SetSendBufferSize(connection_id, kSendBufferSizeForDevTools); |
385 | 438 |
386 if (info.path.find("/json") == 0) { | 439 if (info.path.find("/json") == 0) { |
387 BrowserThread::PostTask( | 440 BrowserThread::PostTask( |
388 BrowserThread::UI, | 441 BrowserThread::UI, |
389 FROM_HERE, | 442 FROM_HERE, |
390 base::Bind(&DevToolsHttpHandlerImpl::OnJsonRequestUI, | 443 base::Bind(&DevToolsHttpHandlerImpl::OnJsonRequest, |
391 this, | 444 handler_, |
392 connection_id, | 445 connection_id, |
393 info)); | 446 info)); |
394 return; | 447 return; |
395 } | 448 } |
396 | 449 |
397 if (info.path.find(kThumbUrlPrefix) == 0) { | 450 if (info.path.find(kThumbUrlPrefix) == 0) { |
398 // Thumbnail request. | 451 // Thumbnail request. |
399 const std::string target_id = info.path.substr(strlen(kThumbUrlPrefix)); | 452 const std::string target_id = info.path.substr(strlen(kThumbUrlPrefix)); |
400 DevToolsTarget* target = GetTarget(target_id); | |
401 GURL page_url; | |
402 if (target) | |
403 page_url = target->GetURL(); | |
404 BrowserThread::PostTask( | 453 BrowserThread::PostTask( |
405 BrowserThread::UI, | 454 BrowserThread::UI, |
406 FROM_HERE, | 455 FROM_HERE, |
407 base::Bind(&DevToolsHttpHandlerImpl::OnThumbnailRequestUI, | 456 base::Bind(&DevToolsHttpHandlerImpl::OnThumbnailRequest, |
408 this, | 457 handler_, |
409 connection_id, | 458 connection_id, |
410 page_url)); | 459 target_id)); |
411 return; | 460 return; |
412 } | 461 } |
413 | 462 |
414 if (info.path == "" || info.path == "/") { | 463 if (info.path == "" || info.path == "/") { |
415 // Discovery page request. | 464 // Discovery page request. |
416 BrowserThread::PostTask( | 465 BrowserThread::PostTask( |
417 BrowserThread::UI, | 466 BrowserThread::UI, |
418 FROM_HERE, | 467 FROM_HERE, |
419 base::Bind(&DevToolsHttpHandlerImpl::OnDiscoveryPageRequestUI, | 468 base::Bind(&DevToolsHttpHandlerImpl::OnDiscoveryPageRequest, |
420 this, | 469 handler_, |
421 connection_id)); | 470 connection_id)); |
422 return; | 471 return; |
423 } | 472 } |
424 | 473 |
425 if (info.path.find("/devtools/") != 0) { | 474 if (info.path.find("/devtools/") != 0) { |
426 server_->Send404(connection_id); | 475 server_->Send404(connection_id); |
427 return; | 476 return; |
428 } | 477 } |
429 | 478 |
430 std::string filename = PathWithoutParams(info.path.substr(10)); | 479 std::string filename = PathWithoutParams(info.path.substr(10)); |
431 std::string mime_type = GetMimeType(filename); | 480 std::string mime_type = GetMimeType(filename); |
432 | 481 |
433 base::FilePath frontend_dir = delegate_->GetDebugFrontendDir(); | 482 if (!frontend_dir_.empty()) { |
434 if (!frontend_dir.empty()) { | 483 base::FilePath path = frontend_dir_.AppendASCII(filename); |
435 base::FilePath path = frontend_dir.AppendASCII(filename); | |
436 std::string data; | 484 std::string data; |
437 base::ReadFileToString(path, &data); | 485 base::ReadFileToString(path, &data); |
438 server_->Send200(connection_id, data, mime_type); | 486 server_->Send200(connection_id, data, mime_type); |
439 return; | 487 return; |
440 } | 488 } |
441 if (delegate_->BundlesFrontendResources()) { | 489 if (bundles_resources_) { |
442 int resource_id = DevToolsHttpHandler::GetFrontendResourceId(filename); | 490 int resource_id = DevToolsHttpHandler::GetFrontendResourceId(filename); |
443 if (resource_id != -1) { | 491 if (resource_id != -1) { |
444 base::StringPiece data = GetContentClient()->GetDataResource( | 492 base::StringPiece data = GetContentClient()->GetDataResource( |
445 resource_id, ui::SCALE_FACTOR_NONE); | 493 resource_id, ui::SCALE_FACTOR_NONE); |
446 server_->Send200(connection_id, data.as_string(), mime_type); | 494 server_->Send200(connection_id, data.as_string(), mime_type); |
447 return; | 495 return; |
448 } | 496 } |
449 } | 497 } |
450 server_->Send404(connection_id); | 498 server_->Send404(connection_id); |
451 } | 499 } |
452 | 500 |
453 void DevToolsHttpHandlerImpl::OnWebSocketRequest( | 501 void DevToolsHttpHandlerImpl::ServerWrapper::OnWebSocketRequest( |
454 int connection_id, | 502 int connection_id, |
455 const net::HttpServerRequestInfo& request) { | 503 const net::HttpServerRequestInfo& request) { |
456 BrowserThread::PostTask( | 504 BrowserThread::PostTask( |
457 BrowserThread::UI, | 505 BrowserThread::UI, |
458 FROM_HERE, | 506 FROM_HERE, |
459 base::Bind( | 507 base::Bind( |
460 &DevToolsHttpHandlerImpl::OnWebSocketRequestUI, | 508 &DevToolsHttpHandlerImpl::OnWebSocketRequest, |
461 this, | 509 handler_, |
462 connection_id, | 510 connection_id, |
463 request)); | 511 request)); |
464 } | 512 } |
465 | 513 |
466 void DevToolsHttpHandlerImpl::OnWebSocketMessage( | 514 void DevToolsHttpHandlerImpl::ServerWrapper::OnWebSocketMessage( |
467 int connection_id, | 515 int connection_id, |
468 const std::string& data) { | 516 const std::string& data) { |
469 BrowserThread::PostTask( | 517 BrowserThread::PostTask( |
470 BrowserThread::UI, | 518 BrowserThread::UI, |
471 FROM_HERE, | 519 FROM_HERE, |
472 base::Bind( | 520 base::Bind( |
473 &DevToolsHttpHandlerImpl::OnWebSocketMessageUI, | 521 &DevToolsHttpHandlerImpl::OnWebSocketMessage, |
474 this, | 522 handler_, |
475 connection_id, | 523 connection_id, |
476 data)); | 524 data)); |
477 } | 525 } |
478 | 526 |
479 void DevToolsHttpHandlerImpl::OnClose(int connection_id) { | 527 void DevToolsHttpHandlerImpl::ServerWrapper::OnClose(int connection_id) { |
480 BrowserThread::PostTask( | 528 BrowserThread::PostTask( |
481 BrowserThread::UI, | 529 BrowserThread::UI, |
482 FROM_HERE, | 530 FROM_HERE, |
483 base::Bind( | 531 base::Bind( |
484 &DevToolsHttpHandlerImpl::OnCloseUI, | 532 &DevToolsHttpHandlerImpl::OnClose, |
485 this, | 533 handler_, |
486 connection_id)); | 534 connection_id)); |
487 } | 535 } |
488 | 536 |
489 std::string DevToolsHttpHandlerImpl::GetFrontendURLInternal( | 537 std::string DevToolsHttpHandlerImpl::GetFrontendURLInternal( |
490 const std::string id, | 538 const std::string id, |
491 const std::string& host) { | 539 const std::string& host) { |
492 return base::StringPrintf( | 540 return base::StringPrintf( |
493 "%s%sws=%s%s%s", | 541 "%s%sws=%s%s%s", |
494 frontend_url_.c_str(), | 542 frontend_url_.c_str(), |
495 frontend_url_.find("?") == std::string::npos ? "?" : "&", | 543 frontend_url_.find("?") == std::string::npos ? "?" : "&", |
(...skipping 20 matching lines...) Expand all Loading... |
516 *command = path.substr(1); | 564 *command = path.substr(1); |
517 | 565 |
518 size_t separator_pos = command->find("/"); | 566 size_t separator_pos = command->find("/"); |
519 if (separator_pos != std::string::npos) { | 567 if (separator_pos != std::string::npos) { |
520 *target_id = command->substr(separator_pos + 1); | 568 *target_id = command->substr(separator_pos + 1); |
521 *command = command->substr(0, separator_pos); | 569 *command = command->substr(0, separator_pos); |
522 } | 570 } |
523 return true; | 571 return true; |
524 } | 572 } |
525 | 573 |
526 void DevToolsHttpHandlerImpl::OnJsonRequestUI( | 574 void DevToolsHttpHandlerImpl::OnJsonRequest( |
527 int connection_id, | 575 int connection_id, |
528 const net::HttpServerRequestInfo& info) { | 576 const net::HttpServerRequestInfo& info) { |
529 // Trim /json | 577 // Trim /json |
530 std::string path = info.path.substr(5); | 578 std::string path = info.path.substr(5); |
531 | 579 |
532 // Trim fragment and query | 580 // Trim fragment and query |
533 std::string query; | 581 std::string query; |
534 size_t query_pos = path.find("?"); | 582 size_t query_pos = path.find("?"); |
535 if (query_pos != std::string::npos) { | 583 if (query_pos != std::string::npos) { |
536 query = path.substr(query_pos + 1); | 584 query = path.substr(query_pos + 1); |
(...skipping 23 matching lines...) Expand all Loading... |
560 #if defined(OS_ANDROID) | 608 #if defined(OS_ANDROID) |
561 version.SetString("Android-Package", | 609 version.SetString("Android-Package", |
562 base::android::BuildInfo::GetInstance()->package_name()); | 610 base::android::BuildInfo::GetInstance()->package_name()); |
563 #endif | 611 #endif |
564 SendJson(connection_id, net::HTTP_OK, &version, std::string()); | 612 SendJson(connection_id, net::HTTP_OK, &version, std::string()); |
565 return; | 613 return; |
566 } | 614 } |
567 | 615 |
568 if (command == "list") { | 616 if (command == "list") { |
569 std::string host = info.headers["host"]; | 617 std::string host = info.headers["host"]; |
570 AddRef(); // Balanced in OnTargetListReceived. | |
571 DevToolsManagerDelegate* manager_delegate = | 618 DevToolsManagerDelegate* manager_delegate = |
572 DevToolsManager::GetInstance()->delegate(); | 619 DevToolsManager::GetInstance()->delegate(); |
573 if (manager_delegate) { | 620 if (manager_delegate) { |
574 manager_delegate->EnumerateTargets( | 621 manager_delegate->EnumerateTargets( |
575 base::Bind(&DevToolsHttpHandlerImpl::OnTargetListReceived, | 622 base::Bind(&DevToolsHttpHandlerImpl::OnTargetListReceivedWeak, |
576 this, connection_id, host)); | 623 weak_factory_.GetWeakPtr(), connection_id, host)); |
577 } else { | 624 } else { |
578 DevToolsManagerDelegate::TargetList empty_list; | 625 DevToolsManagerDelegate::TargetList empty_list; |
579 OnTargetListReceived(connection_id, host, empty_list); | 626 OnTargetListReceived(connection_id, host, empty_list); |
580 } | 627 } |
581 return; | 628 return; |
582 } | 629 } |
583 | 630 |
584 if (command == "new") { | 631 if (command == "new") { |
585 GURL url(net::UnescapeURLComponent( | 632 GURL url(net::UnescapeURLComponent( |
586 query, net::UnescapeRule::URL_SPECIAL_CHARS)); | 633 query, net::UnescapeRule::URL_SPECIAL_CHARS)); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 return; | 688 return; |
642 } | 689 } |
643 } | 690 } |
644 SendJson(connection_id, | 691 SendJson(connection_id, |
645 net::HTTP_NOT_FOUND, | 692 net::HTTP_NOT_FOUND, |
646 NULL, | 693 NULL, |
647 "Unknown command: " + command); | 694 "Unknown command: " + command); |
648 return; | 695 return; |
649 } | 696 } |
650 | 697 |
| 698 // static |
| 699 void DevToolsHttpHandlerImpl::OnTargetListReceivedWeak( |
| 700 base::WeakPtr<DevToolsHttpHandlerImpl> handler, |
| 701 int connection_id, |
| 702 const std::string& host, |
| 703 const DevToolsManagerDelegate::TargetList& targets) { |
| 704 if (handler) { |
| 705 handler->OnTargetListReceived(connection_id, host, targets); |
| 706 } else { |
| 707 STLDeleteContainerPointers(targets.begin(), targets.end()); |
| 708 } |
| 709 } |
| 710 |
651 void DevToolsHttpHandlerImpl::OnTargetListReceived( | 711 void DevToolsHttpHandlerImpl::OnTargetListReceived( |
652 int connection_id, | 712 int connection_id, |
653 const std::string& host, | 713 const std::string& host, |
654 const DevToolsManagerDelegate::TargetList& targets) { | 714 const DevToolsManagerDelegate::TargetList& targets) { |
655 DevToolsManagerDelegate::TargetList sorted_targets = targets; | 715 DevToolsManagerDelegate::TargetList sorted_targets = targets; |
656 std::sort(sorted_targets.begin(), sorted_targets.end(), TimeComparator); | 716 std::sort(sorted_targets.begin(), sorted_targets.end(), TimeComparator); |
657 | 717 |
658 STLDeleteValues(&target_map_); | 718 STLDeleteValues(&target_map_); |
659 base::ListValue list_value; | 719 base::ListValue list_value; |
660 for (DevToolsManagerDelegate::TargetList::const_iterator it = | 720 for (DevToolsManagerDelegate::TargetList::const_iterator it = |
661 sorted_targets.begin(); it != sorted_targets.end(); ++it) { | 721 sorted_targets.begin(); it != sorted_targets.end(); ++it) { |
662 DevToolsTarget* target = *it; | 722 DevToolsTarget* target = *it; |
663 target_map_[target->GetId()] = target; | 723 target_map_[target->GetId()] = target; |
664 list_value.Append(SerializeTarget(*target, host)); | 724 list_value.Append(SerializeTarget(*target, host)); |
665 } | 725 } |
666 SendJson(connection_id, net::HTTP_OK, &list_value, std::string()); | 726 SendJson(connection_id, net::HTTP_OK, &list_value, std::string()); |
667 Release(); // Balanced in OnJsonRequestUI. | |
668 } | 727 } |
669 | 728 |
670 DevToolsTarget* DevToolsHttpHandlerImpl::GetTarget(const std::string& id) { | 729 DevToolsTarget* DevToolsHttpHandlerImpl::GetTarget(const std::string& id) { |
671 TargetMap::const_iterator it = target_map_.find(id); | 730 TargetMap::const_iterator it = target_map_.find(id); |
672 if (it == target_map_.end()) | 731 if (it == target_map_.end()) |
673 return NULL; | 732 return NULL; |
674 return it->second; | 733 return it->second; |
675 } | 734 } |
676 | 735 |
677 void DevToolsHttpHandlerImpl::OnThumbnailRequestUI( | 736 void DevToolsHttpHandlerImpl::OnThumbnailRequest( |
678 int connection_id, const GURL& page_url) { | 737 int connection_id, const std::string& target_id) { |
| 738 DevToolsTarget* target = GetTarget(target_id); |
| 739 GURL page_url; |
| 740 if (target) |
| 741 page_url = target->GetURL(); |
679 DevToolsManagerDelegate* manager_delegate = | 742 DevToolsManagerDelegate* manager_delegate = |
680 DevToolsManager::GetInstance()->delegate(); | 743 DevToolsManager::GetInstance()->delegate(); |
681 std::string data = | 744 std::string data = |
682 manager_delegate ? manager_delegate->GetPageThumbnailData(page_url) : ""; | 745 manager_delegate ? manager_delegate->GetPageThumbnailData(page_url) : ""; |
683 if (!data.empty()) | 746 if (!data.empty()) |
684 Send200(connection_id, data, "image/png"); | 747 Send200(connection_id, data, "image/png"); |
685 else | 748 else |
686 Send404(connection_id); | 749 Send404(connection_id); |
687 } | 750 } |
688 | 751 |
689 void DevToolsHttpHandlerImpl::OnDiscoveryPageRequestUI(int connection_id) { | 752 void DevToolsHttpHandlerImpl::OnDiscoveryPageRequest(int connection_id) { |
690 std::string response = delegate_->GetDiscoveryPageHTML(); | 753 std::string response = delegate_->GetDiscoveryPageHTML(); |
691 Send200(connection_id, response, "text/html; charset=UTF-8"); | 754 Send200(connection_id, response, "text/html; charset=UTF-8"); |
692 } | 755 } |
693 | 756 |
694 void DevToolsHttpHandlerImpl::OnWebSocketRequestUI( | 757 void DevToolsHttpHandlerImpl::OnWebSocketRequest( |
695 int connection_id, | 758 int connection_id, |
696 const net::HttpServerRequestInfo& request) { | 759 const net::HttpServerRequestInfo& request) { |
697 if (!thread_) | 760 if (!thread_) |
698 return; | 761 return; |
699 | 762 |
700 std::string browser_prefix = "/devtools/browser"; | 763 std::string browser_prefix = "/devtools/browser"; |
701 size_t browser_pos = request.path.find(browser_prefix); | 764 size_t browser_pos = request.path.find(browser_prefix); |
702 if (browser_pos == 0) { | 765 if (browser_pos == 0) { |
703 BrowserTarget* browser_target = new BrowserTarget( | 766 BrowserTarget* browser_target = new BrowserTarget( |
704 thread_->message_loop(), server_.get(), connection_id); | 767 thread_->message_loop(), server_.get(), connection_id); |
(...skipping 20 matching lines...) Expand all Loading... |
725 Send500(connection_id, "No such target id: " + page_id); | 788 Send500(connection_id, "No such target id: " + page_id); |
726 return; | 789 return; |
727 } | 790 } |
728 | 791 |
729 if (agent->IsAttached()) { | 792 if (agent->IsAttached()) { |
730 Send500(connection_id, | 793 Send500(connection_id, |
731 "Target with given id is being inspected: " + page_id); | 794 "Target with given id is being inspected: " + page_id); |
732 return; | 795 return; |
733 } | 796 } |
734 | 797 |
735 DevToolsAgentHostClientImpl* client_host = new DevToolsAgentHostClientImpl( | 798 AgentHostClientImpl* client_host = new AgentHostClientImpl( |
736 thread_->message_loop(), server_.get(), connection_id, agent.get()); | 799 thread_->message_loop(), server_.get(), connection_id, agent.get()); |
737 connection_to_client_ui_[connection_id] = client_host; | 800 connection_to_client_[connection_id] = client_host; |
738 | 801 |
739 AcceptWebSocket(connection_id, request); | 802 AcceptWebSocket(connection_id, request); |
740 } | 803 } |
741 | 804 |
742 void DevToolsHttpHandlerImpl::OnWebSocketMessageUI( | 805 void DevToolsHttpHandlerImpl::OnWebSocketMessage( |
743 int connection_id, | 806 int connection_id, |
744 const std::string& data) { | 807 const std::string& data) { |
745 BrowserTargets::iterator browser_it = browser_targets_.find(connection_id); | 808 BrowserTargets::iterator browser_it = browser_targets_.find(connection_id); |
746 if (browser_it != browser_targets_.end()) { | 809 if (browser_it != browser_targets_.end()) { |
747 browser_it->second->HandleMessage(data); | 810 browser_it->second->HandleMessage(data); |
748 return; | 811 return; |
749 } | 812 } |
750 | 813 |
751 ConnectionToClientMap::iterator it = | 814 ConnectionToClientMap::iterator it = |
752 connection_to_client_ui_.find(connection_id); | 815 connection_to_client_.find(connection_id); |
753 if (it == connection_to_client_ui_.end()) | 816 if (it != connection_to_client_.end()) |
754 return; | 817 it->second->OnMessage(data); |
755 | |
756 DevToolsAgentHostClientImpl* client = | |
757 static_cast<DevToolsAgentHostClientImpl*>(it->second); | |
758 client->OnMessage(data); | |
759 } | 818 } |
760 | 819 |
761 void DevToolsHttpHandlerImpl::OnCloseUI(int connection_id) { | 820 void DevToolsHttpHandlerImpl::OnClose(int connection_id) { |
762 BrowserTargets::iterator browser_it = browser_targets_.find(connection_id); | 821 BrowserTargets::iterator browser_it = browser_targets_.find(connection_id); |
763 if (browser_it != browser_targets_.end()) { | 822 if (browser_it != browser_targets_.end()) { |
764 delete browser_it->second; | 823 delete browser_it->second; |
765 browser_targets_.erase(connection_id); | 824 browser_targets_.erase(connection_id); |
766 return; | 825 return; |
767 } | 826 } |
768 | 827 |
769 ConnectionToClientMap::iterator it = | 828 ConnectionToClientMap::iterator it = |
770 connection_to_client_ui_.find(connection_id); | 829 connection_to_client_.find(connection_id); |
771 if (it != connection_to_client_ui_.end()) { | 830 if (it != connection_to_client_.end()) { |
772 DevToolsAgentHostClientImpl* client = | 831 delete it->second; |
773 static_cast<DevToolsAgentHostClientImpl*>(it->second); | 832 connection_to_client_.erase(connection_id); |
774 delete client; | |
775 connection_to_client_ui_.erase(connection_id); | |
776 } | 833 } |
777 } | 834 } |
778 | 835 |
779 void DevToolsHttpHandlerImpl::OnHttpServerInitialized( | |
780 const net::IPEndPoint& ip_address) { | |
781 server_ip_address_.reset(new net::IPEndPoint(ip_address)); | |
782 } | |
783 | |
784 DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl( | 836 DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl( |
785 scoped_ptr<ServerSocketFactory> server_socket_factory, | 837 scoped_ptr<ServerSocketFactory> server_socket_factory, |
786 const std::string& frontend_url, | 838 const std::string& frontend_url, |
787 DevToolsHttpHandlerDelegate* delegate, | 839 DevToolsHttpHandlerDelegate* delegate, |
788 const base::FilePath& active_port_output_directory) | 840 const base::FilePath& output_directory) |
789 : frontend_url_(frontend_url), | 841 : frontend_url_(frontend_url), |
790 server_socket_factory_(server_socket_factory.Pass()), | |
791 delegate_(delegate), | 842 delegate_(delegate), |
792 active_port_output_directory_(active_port_output_directory) { | 843 weak_factory_(this) { |
793 if (frontend_url_.empty()) | 844 if (frontend_url_.empty()) |
794 frontend_url_ = "/devtools/devtools.html"; | 845 frontend_url_ = "/devtools/devtools.html"; |
795 | 846 |
796 // Balanced in ResetHandlerThreadAndRelease(). | 847 BrowserThread::PostTaskAndReplyWithResult( |
797 AddRef(); | 848 BrowserThread::FILE, FROM_HERE, |
| 849 base::Bind(&StartHandlerThread), |
| 850 base::Bind(&DevToolsHttpHandlerImpl::ThreadStarted, |
| 851 weak_factory_.GetWeakPtr(), |
| 852 base::Passed(&server_socket_factory), |
| 853 output_directory)); |
798 } | 854 } |
799 | 855 |
800 // Runs on the handler thread | 856 void DevToolsHttpHandlerImpl::ThreadStarted( |
801 void DevToolsHttpHandlerImpl::Init() { | 857 scoped_ptr<ServerSocketFactory> server_socket_factory, |
802 scoped_ptr<net::ServerSocket> server_socket = | 858 const base::FilePath& output_directory, |
803 server_socket_factory_->CreateAndListen(); | 859 scoped_ptr<base::Thread> thread) { |
804 if (!server_socket) { | 860 thread_.swap(thread); |
805 LOG(ERROR) << "Cannot start http server for devtools. Stop devtools."; | 861 thread_->message_loop()->PostTask(FROM_HERE, |
806 BrowserThread::PostTask( | 862 base::Bind(&DevToolsHttpHandlerImpl::ServerWrapper::StartServer, |
807 BrowserThread::UI, FROM_HERE, | 863 weak_factory_.GetWeakPtr(), |
808 base::Bind(&DevToolsHttpHandlerImpl::StopWithoutRelease, this)); | 864 base::Passed(&server_socket_factory), |
809 return; | 865 output_directory, |
810 } | 866 delegate_->GetDebugFrontendDir(), |
811 | 867 delegate_->BundlesFrontendResources())); |
812 server_.reset(new net::HttpServer(server_socket.Pass(), this)); | |
813 net::IPEndPoint ip_address; | |
814 server_->GetLocalAddress(&ip_address); | |
815 BrowserThread::PostTask( | |
816 BrowserThread::UI, FROM_HERE, | |
817 base::Bind(&DevToolsHttpHandlerImpl::OnHttpServerInitialized, | |
818 this, ip_address)); | |
819 if (!active_port_output_directory_.empty()) | |
820 WriteActivePortToUserProfile(); | |
821 } | 868 } |
822 | 869 |
823 // Runs on the handler thread | 870 // static |
824 void DevToolsHttpHandlerImpl::Teardown() { | 871 void DevToolsHttpHandlerImpl::ServerWrapper::StartServer( |
825 server_.reset(); | 872 base::WeakPtr<DevToolsHttpHandlerImpl> handler, |
| 873 scoped_ptr<ServerSocketFactory> server_socket_factory, |
| 874 const base::FilePath& output_directory, |
| 875 const base::FilePath& frontend_dir, |
| 876 bool bundles_resources) { |
| 877 scoped_ptr<ServerWrapper> server; |
| 878 scoped_ptr<net::ServerSocket> server_socket = |
| 879 server_socket_factory->CreateAndListen(); |
| 880 scoped_ptr<net::IPEndPoint> ip_address(new net::IPEndPoint); |
| 881 if (server_socket) { |
| 882 server.reset(new ServerWrapper(handler, server_socket.Pass(), |
| 883 frontend_dir, bundles_resources)); |
| 884 if (!output_directory.empty()) |
| 885 server->WriteActivePortToUserProfile(output_directory); |
| 886 |
| 887 if (server->server_->GetLocalAddress(ip_address.get()) != net::OK) |
| 888 ip_address.reset(); |
| 889 } else { |
| 890 ip_address.reset(); |
| 891 LOG(ERROR) << "Cannot start http server for devtools. Stop devtools."; |
| 892 } |
| 893 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 894 base::Bind(&DevToolsHttpHandlerImpl::ServerStarted, |
| 895 handler, base::Passed(&server), base::Passed(&ip_address))); |
826 } | 896 } |
827 | 897 |
828 // Runs on FILE thread to make sure that it is serialized against | 898 DevToolsHttpHandlerImpl::ServerWrapper::ServerWrapper( |
829 // {Start|Stop}HandlerThread and to allow calling pthread_join. | 899 base::WeakPtr<DevToolsHttpHandlerImpl> handler, |
830 void DevToolsHttpHandlerImpl::StopHandlerThread() { | 900 scoped_ptr<net::ServerSocket> socket, |
831 if (!thread_->message_loop()) | 901 const base::FilePath& frontend_dir, |
832 return; | 902 bool bundles_resources) |
833 thread_->message_loop()->PostTask( | 903 : handler_(handler), |
834 FROM_HERE, | 904 server_(new net::HttpServer(socket.Pass(), this)), |
835 base::Bind(&DevToolsHttpHandlerImpl::Teardown, this)); | 905 frontend_dir_(frontend_dir), |
836 // Thread::Stop joins the thread. | 906 bundles_resources_(bundles_resources) { |
837 thread_->Stop(); | |
838 } | 907 } |
839 | 908 |
840 void DevToolsHttpHandlerImpl::WriteActivePortToUserProfile() { | 909 void DevToolsHttpHandlerImpl::ServerStarted( |
841 DCHECK(!active_port_output_directory_.empty()); | 910 scoped_ptr<ServerWrapper> server, |
| 911 scoped_ptr<net::IPEndPoint> ip_address) { |
| 912 if (server) { |
| 913 server_.swap(server); |
| 914 server_ip_address_.swap(ip_address); |
| 915 } else { |
| 916 StopHandlerThread(); |
| 917 } |
| 918 } |
| 919 |
| 920 void DevToolsHttpHandlerImpl::StopHandlerThread() { |
| 921 if (thread_) { |
| 922 BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, |
| 923 thread_.release()); |
| 924 } |
| 925 } |
| 926 |
| 927 void DevToolsHttpHandlerImpl::ServerWrapper::WriteActivePortToUserProfile( |
| 928 const base::FilePath& output_directory) { |
| 929 DCHECK(!output_directory.empty()); |
842 net::IPEndPoint endpoint; | 930 net::IPEndPoint endpoint; |
843 int err; | 931 int err; |
844 if ((err = server_->GetLocalAddress(&endpoint)) != net::OK) { | 932 if ((err = server_->GetLocalAddress(&endpoint)) != net::OK) { |
845 LOG(ERROR) << "Error " << err << " getting local address"; | 933 LOG(ERROR) << "Error " << err << " getting local address"; |
846 return; | 934 return; |
847 } | 935 } |
848 | 936 |
849 // Write this port to a well-known file in the profile directory | 937 // Write this port to a well-known file in the profile directory |
850 // so Telemetry can pick it up. | 938 // so Telemetry can pick it up. |
851 base::FilePath path = active_port_output_directory_.Append( | 939 base::FilePath path = output_directory.Append(kDevToolsActivePortFileName); |
852 kDevToolsActivePortFileName); | |
853 std::string port_string = base::IntToString(endpoint.port()); | 940 std::string port_string = base::IntToString(endpoint.port()); |
854 if (base::WriteFile(path, port_string.c_str(), port_string.length()) < 0) { | 941 if (base::WriteFile(path, port_string.c_str(), port_string.length()) < 0) { |
855 LOG(ERROR) << "Error writing DevTools active port to file"; | 942 LOG(ERROR) << "Error writing DevTools active port to file"; |
856 } | 943 } |
857 } | 944 } |
858 | 945 |
859 void DevToolsHttpHandlerImpl::SendJson(int connection_id, | 946 void DevToolsHttpHandlerImpl::SendJson(int connection_id, |
860 net::HttpStatusCode status_code, | 947 net::HttpStatusCode status_code, |
861 base::Value* value, | 948 base::Value* value, |
862 const std::string& message) { | 949 const std::string& message) { |
863 if (!thread_) | 950 if (!thread_) |
864 return; | 951 return; |
865 | 952 |
866 // Serialize value and message. | 953 // Serialize value and message. |
867 std::string json_value; | 954 std::string json_value; |
868 if (value) { | 955 if (value) { |
869 base::JSONWriter::WriteWithOptions(value, | 956 base::JSONWriter::WriteWithOptions(value, |
870 base::JSONWriter::OPTIONS_PRETTY_PRINT, | 957 base::JSONWriter::OPTIONS_PRETTY_PRINT, |
871 &json_value); | 958 &json_value); |
872 } | 959 } |
873 std::string json_message; | 960 std::string json_message; |
874 scoped_ptr<base::Value> message_object(new base::StringValue(message)); | 961 scoped_ptr<base::Value> message_object(new base::StringValue(message)); |
875 base::JSONWriter::Write(message_object.get(), &json_message); | 962 base::JSONWriter::Write(message_object.get(), &json_message); |
876 | 963 |
877 net::HttpServerResponseInfo response(status_code); | 964 net::HttpServerResponseInfo response(status_code); |
878 response.SetBody(json_value + message, "application/json; charset=UTF-8"); | 965 response.SetBody(json_value + message, "application/json; charset=UTF-8"); |
879 | 966 |
880 thread_->message_loop()->PostTask( | 967 thread_->message_loop()->PostTask( |
881 FROM_HERE, | 968 FROM_HERE, |
882 base::Bind(&net::HttpServer::SendResponse, | 969 base::Bind(&ServerWrapper::SendResponse, |
883 base::Unretained(server_.get()), | 970 base::Unretained(server_.get()), |
884 connection_id, | 971 connection_id, |
885 response)); | 972 response)); |
886 } | 973 } |
887 | 974 |
888 void DevToolsHttpHandlerImpl::Send200(int connection_id, | 975 void DevToolsHttpHandlerImpl::Send200(int connection_id, |
889 const std::string& data, | 976 const std::string& data, |
890 const std::string& mime_type) { | 977 const std::string& mime_type) { |
891 if (!thread_) | 978 if (!thread_) |
892 return; | 979 return; |
893 thread_->message_loop()->PostTask( | 980 thread_->message_loop()->PostTask( |
894 FROM_HERE, | 981 FROM_HERE, |
895 base::Bind(&net::HttpServer::Send200, | 982 base::Bind(&ServerWrapper::Send200, |
896 base::Unretained(server_.get()), | 983 base::Unretained(server_.get()), |
897 connection_id, | 984 connection_id, |
898 data, | 985 data, |
899 mime_type)); | 986 mime_type)); |
900 } | 987 } |
901 | 988 |
902 void DevToolsHttpHandlerImpl::Send404(int connection_id) { | 989 void DevToolsHttpHandlerImpl::Send404(int connection_id) { |
903 if (!thread_) | 990 if (!thread_) |
904 return; | 991 return; |
905 thread_->message_loop()->PostTask( | 992 thread_->message_loop()->PostTask( |
906 FROM_HERE, | 993 FROM_HERE, |
907 base::Bind(&net::HttpServer::Send404, | 994 base::Bind(&ServerWrapper::Send404, |
908 base::Unretained(server_.get()), | 995 base::Unretained(server_.get()), |
909 connection_id)); | 996 connection_id)); |
910 } | 997 } |
911 | 998 |
912 void DevToolsHttpHandlerImpl::Send500(int connection_id, | 999 void DevToolsHttpHandlerImpl::Send500(int connection_id, |
913 const std::string& message) { | 1000 const std::string& message) { |
914 if (!thread_) | 1001 if (!thread_) |
915 return; | 1002 return; |
916 thread_->message_loop()->PostTask( | 1003 thread_->message_loop()->PostTask( |
917 FROM_HERE, | 1004 FROM_HERE, |
918 base::Bind(&net::HttpServer::Send500, | 1005 base::Bind(&ServerWrapper::Send500, |
919 base::Unretained(server_.get()), | 1006 base::Unretained(server_.get()), |
920 connection_id, | 1007 connection_id, |
921 message)); | 1008 message)); |
922 } | 1009 } |
923 | 1010 |
924 void DevToolsHttpHandlerImpl::AcceptWebSocket( | 1011 void DevToolsHttpHandlerImpl::AcceptWebSocket( |
925 int connection_id, | 1012 int connection_id, |
926 const net::HttpServerRequestInfo& request) { | 1013 const net::HttpServerRequestInfo& request) { |
927 if (!thread_) | 1014 if (!thread_) |
928 return; | 1015 return; |
929 thread_->message_loop()->PostTask( | 1016 thread_->message_loop()->PostTask( |
930 FROM_HERE, | 1017 FROM_HERE, |
931 base::Bind(&net::HttpServer::SetSendBufferSize, | 1018 base::Bind(&ServerWrapper::AcceptWebSocket, |
932 base::Unretained(server_.get()), | |
933 connection_id, | |
934 kSendBufferSizeForDevTools)); | |
935 thread_->message_loop()->PostTask( | |
936 FROM_HERE, | |
937 base::Bind(&net::HttpServer::AcceptWebSocket, | |
938 base::Unretained(server_.get()), | 1019 base::Unretained(server_.get()), |
939 connection_id, | 1020 connection_id, |
940 request)); | 1021 request)); |
941 } | 1022 } |
942 | 1023 |
943 base::DictionaryValue* DevToolsHttpHandlerImpl::SerializeTarget( | 1024 base::DictionaryValue* DevToolsHttpHandlerImpl::SerializeTarget( |
944 const DevToolsTarget& target, | 1025 const DevToolsTarget& target, |
945 const std::string& host) { | 1026 const std::string& host) { |
946 base::DictionaryValue* dictionary = new base::DictionaryValue; | 1027 base::DictionaryValue* dictionary = new base::DictionaryValue; |
947 | 1028 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 id.c_str(), | 1061 id.c_str(), |
981 host); | 1062 host); |
982 dictionary->SetString( | 1063 dictionary->SetString( |
983 kTargetDevtoolsFrontendUrlField, devtools_frontend_url); | 1064 kTargetDevtoolsFrontendUrlField, devtools_frontend_url); |
984 } | 1065 } |
985 | 1066 |
986 return dictionary; | 1067 return dictionary; |
987 } | 1068 } |
988 | 1069 |
989 } // namespace content | 1070 } // namespace content |
OLD | NEW |