| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/debugger/devtools_http_protocol_handler.h" | 5 #include "chrome/browser/debugger/devtools_http_protocol_handler.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 | 30 |
| 31 const int kBufferSize = 16 * 1024; | 31 const int kBufferSize = 16 * 1024; |
| 32 | 32 |
| 33 namespace { | 33 namespace { |
| 34 | 34 |
| 35 // An internal implementation of DevToolsClientHost that delegates | 35 // An internal implementation of DevToolsClientHost that delegates |
| 36 // messages sent for DevToolsClient to a DebuggerShell instance. | 36 // messages sent for DevToolsClient to a DebuggerShell instance. |
| 37 class DevToolsClientHostImpl : public DevToolsClientHost { | 37 class DevToolsClientHostImpl : public DevToolsClientHost { |
| 38 public: | 38 public: |
| 39 DevToolsClientHostImpl( | 39 DevToolsClientHostImpl( |
| 40 HttpServer* server, | 40 net::HttpServer* server, |
| 41 int connection_id) | 41 int connection_id) |
| 42 : server_(server), | 42 : server_(server), |
| 43 connection_id_(connection_id) { | 43 connection_id_(connection_id) { |
| 44 } | 44 } |
| 45 ~DevToolsClientHostImpl() {} | 45 ~DevToolsClientHostImpl() {} |
| 46 | 46 |
| 47 // DevToolsClientHost interface | 47 // DevToolsClientHost interface |
| 48 virtual void InspectedTabClosing() { | 48 virtual void InspectedTabClosing() { |
| 49 BrowserThread::PostTask( | 49 BrowserThread::PostTask( |
| 50 BrowserThread::IO, | 50 BrowserThread::IO, |
| 51 FROM_HERE, | 51 FROM_HERE, |
| 52 NewRunnableMethod(server_, | 52 NewRunnableMethod(server_, |
| 53 &HttpServer::Close, | 53 &net::HttpServer::Close, |
| 54 connection_id_)); | 54 connection_id_)); |
| 55 } | 55 } |
| 56 | 56 |
| 57 virtual void SendMessageToClient(const IPC::Message& msg) { | 57 virtual void SendMessageToClient(const IPC::Message& msg) { |
| 58 IPC_BEGIN_MESSAGE_MAP(DevToolsClientHostImpl, msg) | 58 IPC_BEGIN_MESSAGE_MAP(DevToolsClientHostImpl, msg) |
| 59 IPC_MESSAGE_HANDLER(DevToolsClientMsg_DispatchOnInspectorFrontend, | 59 IPC_MESSAGE_HANDLER(DevToolsClientMsg_DispatchOnInspectorFrontend, |
| 60 OnDispatchOnInspectorFrontend); | 60 OnDispatchOnInspectorFrontend); |
| 61 IPC_MESSAGE_UNHANDLED_ERROR() | 61 IPC_MESSAGE_UNHANDLED_ERROR() |
| 62 IPC_END_MESSAGE_MAP() | 62 IPC_END_MESSAGE_MAP() |
| 63 } | 63 } |
| 64 | 64 |
| 65 virtual void TabReplaced(TabContentsWrapper* new_tab) { | 65 virtual void TabReplaced(TabContentsWrapper* new_tab) { |
| 66 } | 66 } |
| 67 | 67 |
| 68 void NotifyCloseListener() { | 68 void NotifyCloseListener() { |
| 69 DevToolsClientHost::NotifyCloseListener(); | 69 DevToolsClientHost::NotifyCloseListener(); |
| 70 } | 70 } |
| 71 private: | 71 private: |
| 72 // Message handling routines | 72 // Message handling routines |
| 73 void OnDispatchOnInspectorFrontend(const std::string& data) { | 73 void OnDispatchOnInspectorFrontend(const std::string& data) { |
| 74 BrowserThread::PostTask( | 74 BrowserThread::PostTask( |
| 75 BrowserThread::IO, | 75 BrowserThread::IO, |
| 76 FROM_HERE, | 76 FROM_HERE, |
| 77 NewRunnableMethod(server_, | 77 NewRunnableMethod(server_, |
| 78 &HttpServer::SendOverWebSocket, | 78 &net::HttpServer::SendOverWebSocket, |
| 79 connection_id_, | 79 connection_id_, |
| 80 data)); | 80 data)); |
| 81 } | 81 } |
| 82 | 82 |
| 83 virtual void FrameNavigating(const std::string& url) {} | 83 virtual void FrameNavigating(const std::string& url) {} |
| 84 HttpServer* server_; | 84 net::HttpServer* server_; |
| 85 int connection_id_; | 85 int connection_id_; |
| 86 }; | 86 }; |
| 87 | 87 |
| 88 } // namespace | 88 } // namespace |
| 89 | 89 |
| 90 | 90 |
| 91 // static | 91 // static |
| 92 scoped_refptr<DevToolsHttpProtocolHandler> DevToolsHttpProtocolHandler::Start( | 92 scoped_refptr<DevToolsHttpProtocolHandler> DevToolsHttpProtocolHandler::Start( |
| 93 const std::string& ip, | 93 const std::string& ip, |
| 94 int port, | 94 int port, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 112 } | 112 } |
| 113 | 113 |
| 114 void DevToolsHttpProtocolHandler::Stop() { | 114 void DevToolsHttpProtocolHandler::Stop() { |
| 115 BrowserThread::PostTask( | 115 BrowserThread::PostTask( |
| 116 BrowserThread::IO, FROM_HERE, | 116 BrowserThread::IO, FROM_HERE, |
| 117 NewRunnableMethod(this, &DevToolsHttpProtocolHandler::Teardown)); | 117 NewRunnableMethod(this, &DevToolsHttpProtocolHandler::Teardown)); |
| 118 } | 118 } |
| 119 | 119 |
| 120 void DevToolsHttpProtocolHandler::OnHttpRequest( | 120 void DevToolsHttpProtocolHandler::OnHttpRequest( |
| 121 int connection_id, | 121 int connection_id, |
| 122 const HttpServerRequestInfo& info) { | 122 const net::HttpServerRequestInfo& info) { |
| 123 if (info.path == "" || info.path == "/") { | 123 if (info.path == "" || info.path == "/") { |
| 124 // Pages discovery request. | 124 // Pages discovery request. |
| 125 BrowserThread::PostTask( | 125 BrowserThread::PostTask( |
| 126 BrowserThread::UI, | 126 BrowserThread::UI, |
| 127 FROM_HERE, | 127 FROM_HERE, |
| 128 NewRunnableMethod(this, | 128 NewRunnableMethod(this, |
| 129 &DevToolsHttpProtocolHandler::OnRootRequestUI, | 129 &DevToolsHttpProtocolHandler::OnRootRequestUI, |
| 130 connection_id, | 130 connection_id, |
| 131 info)); | 131 info)); |
| 132 return; | 132 return; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 162 net::URLRequest* request = new net::URLRequest( | 162 net::URLRequest* request = new net::URLRequest( |
| 163 GURL("chrome-devtools:/" + info.path), this); | 163 GURL("chrome-devtools:/" + info.path), this); |
| 164 Bind(request, connection_id); | 164 Bind(request, connection_id); |
| 165 request->set_context( | 165 request->set_context( |
| 166 Profile::GetDefaultRequestContext()->GetURLRequestContext()); | 166 Profile::GetDefaultRequestContext()->GetURLRequestContext()); |
| 167 request->Start(); | 167 request->Start(); |
| 168 } | 168 } |
| 169 | 169 |
| 170 void DevToolsHttpProtocolHandler::OnWebSocketRequest( | 170 void DevToolsHttpProtocolHandler::OnWebSocketRequest( |
| 171 int connection_id, | 171 int connection_id, |
| 172 const HttpServerRequestInfo& request) { | 172 const net::HttpServerRequestInfo& request) { |
| 173 BrowserThread::PostTask( | 173 BrowserThread::PostTask( |
| 174 BrowserThread::UI, | 174 BrowserThread::UI, |
| 175 FROM_HERE, | 175 FROM_HERE, |
| 176 NewRunnableMethod( | 176 NewRunnableMethod( |
| 177 this, | 177 this, |
| 178 &DevToolsHttpProtocolHandler::OnWebSocketRequestUI, | 178 &DevToolsHttpProtocolHandler::OnWebSocketRequestUI, |
| 179 connection_id, | 179 connection_id, |
| 180 request)); | 180 request)); |
| 181 } | 181 } |
| 182 | 182 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 std::string url; | 224 std::string url; |
| 225 bool attached; | 225 bool attached; |
| 226 std::string title; | 226 std::string title; |
| 227 std::string favicon_url; | 227 std::string favicon_url; |
| 228 }; | 228 }; |
| 229 typedef std::vector<PageInfo> PageList; | 229 typedef std::vector<PageInfo> PageList; |
| 230 | 230 |
| 231 static PageList GeneratePageList( | 231 static PageList GeneratePageList( |
| 232 DevToolsHttpProtocolHandler::TabContentsProvider* tab_contents_provider, | 232 DevToolsHttpProtocolHandler::TabContentsProvider* tab_contents_provider, |
| 233 int connection_id, | 233 int connection_id, |
| 234 const HttpServerRequestInfo& info) { | 234 const net::HttpServerRequestInfo& info) { |
| 235 typedef DevToolsHttpProtocolHandler::InspectableTabs Tabs; | 235 typedef DevToolsHttpProtocolHandler::InspectableTabs Tabs; |
| 236 Tabs inspectable_tabs = tab_contents_provider->GetInspectableTabs(); | 236 Tabs inspectable_tabs = tab_contents_provider->GetInspectableTabs(); |
| 237 | 237 |
| 238 PageList page_list; | 238 PageList page_list; |
| 239 for (Tabs::iterator it = inspectable_tabs.begin(); | 239 for (Tabs::iterator it = inspectable_tabs.begin(); |
| 240 it != inspectable_tabs.end(); ++it) { | 240 it != inspectable_tabs.end(); ++it) { |
| 241 | 241 |
| 242 TabContentsWrapper* tab_contents = *it; | 242 TabContentsWrapper* tab_contents = *it; |
| 243 NavigationController& controller = tab_contents->controller(); | 243 NavigationController& controller = tab_contents->controller(); |
| 244 | 244 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 255 page_info.url = entry->url().spec(); | 255 page_info.url = entry->url().spec(); |
| 256 page_info.title = UTF16ToUTF8(entry->title()); | 256 page_info.title = UTF16ToUTF8(entry->title()); |
| 257 page_info.favicon_url = entry->favicon().url().spec(); | 257 page_info.favicon_url = entry->favicon().url().spec(); |
| 258 page_list.push_back(page_info); | 258 page_list.push_back(page_info); |
| 259 } | 259 } |
| 260 return page_list; | 260 return page_list; |
| 261 } | 261 } |
| 262 | 262 |
| 263 void DevToolsHttpProtocolHandler::OnRootRequestUI( | 263 void DevToolsHttpProtocolHandler::OnRootRequestUI( |
| 264 int connection_id, | 264 int connection_id, |
| 265 const HttpServerRequestInfo& info) { | 265 const net::HttpServerRequestInfo& info) { |
| 266 std::string host = info.headers["Host"]; | 266 std::string host = info.headers["Host"]; |
| 267 std::string response = "<html><body>"; | 267 std::string response = "<html><body>"; |
| 268 PageList page_list = GeneratePageList(tab_contents_provider_.get(), | 268 PageList page_list = GeneratePageList(tab_contents_provider_.get(), |
| 269 connection_id, info); | 269 connection_id, info); |
| 270 for (PageList::iterator i = page_list.begin(); | 270 for (PageList::iterator i = page_list.begin(); |
| 271 i != page_list.end(); ++i) { | 271 i != page_list.end(); ++i) { |
| 272 | 272 |
| 273 std::string frontendURL = StringPrintf("%s?host=%s&page=%d", | 273 std::string frontendURL = StringPrintf("%s?host=%s&page=%d", |
| 274 overriden_frontend_url_.c_str(), | 274 overriden_frontend_url_.c_str(), |
| 275 host.c_str(), | 275 host.c_str(), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 287 i->url.c_str()); | 287 i->url.c_str()); |
| 288 } | 288 } |
| 289 response += "</div>"; | 289 response += "</div>"; |
| 290 } | 290 } |
| 291 response += "</body></html>"; | 291 response += "</body></html>"; |
| 292 Send200(connection_id, response, "text/html; charset=UTF-8"); | 292 Send200(connection_id, response, "text/html; charset=UTF-8"); |
| 293 } | 293 } |
| 294 | 294 |
| 295 void DevToolsHttpProtocolHandler::OnJsonRequestUI( | 295 void DevToolsHttpProtocolHandler::OnJsonRequestUI( |
| 296 int connection_id, | 296 int connection_id, |
| 297 const HttpServerRequestInfo& info) { | 297 const net::HttpServerRequestInfo& info) { |
| 298 PageList page_list = GeneratePageList(tab_contents_provider_.get(), | 298 PageList page_list = GeneratePageList(tab_contents_provider_.get(), |
| 299 connection_id, info); | 299 connection_id, info); |
| 300 ListValue json_pages_list; | 300 ListValue json_pages_list; |
| 301 std::string host = info.headers["Host"]; | 301 std::string host = info.headers["Host"]; |
| 302 for (PageList::iterator i = page_list.begin(); | 302 for (PageList::iterator i = page_list.begin(); |
| 303 i != page_list.end(); ++i) { | 303 i != page_list.end(); ++i) { |
| 304 | 304 |
| 305 DictionaryValue* page_info = new DictionaryValue; | 305 DictionaryValue* page_info = new DictionaryValue; |
| 306 json_pages_list.Append(page_info); | 306 json_pages_list.Append(page_info); |
| 307 page_info->SetString("title", i->title); | 307 page_info->SetString("title", i->title); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 320 } | 320 } |
| 321 } | 321 } |
| 322 | 322 |
| 323 std::string response; | 323 std::string response; |
| 324 base::JSONWriter::Write(&json_pages_list, true, &response); | 324 base::JSONWriter::Write(&json_pages_list, true, &response); |
| 325 Send200(connection_id, response, "application/json; charset=UTF-8"); | 325 Send200(connection_id, response, "application/json; charset=UTF-8"); |
| 326 } | 326 } |
| 327 | 327 |
| 328 void DevToolsHttpProtocolHandler::OnWebSocketRequestUI( | 328 void DevToolsHttpProtocolHandler::OnWebSocketRequestUI( |
| 329 int connection_id, | 329 int connection_id, |
| 330 const HttpServerRequestInfo& request) { | 330 const net::HttpServerRequestInfo& request) { |
| 331 std::string prefix = "/devtools/page/"; | 331 std::string prefix = "/devtools/page/"; |
| 332 size_t pos = request.path.find(prefix); | 332 size_t pos = request.path.find(prefix); |
| 333 if (pos != 0) { | 333 if (pos != 0) { |
| 334 Send404(connection_id); | 334 Send404(connection_id); |
| 335 return; | 335 return; |
| 336 } | 336 } |
| 337 std::string page_id = request.path.substr(prefix.length()); | 337 std::string page_id = request.path.substr(prefix.length()); |
| 338 int id = 0; | 338 int id = 0; |
| 339 if (!base::StringToInt(page_id, &id)) { | 339 if (!base::StringToInt(page_id, &id)) { |
| 340 Send500(connection_id, "Invalid page id: " + page_id); | 340 Send500(connection_id, "Invalid page id: " + page_id); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 TabContentsProvider* provider) | 457 TabContentsProvider* provider) |
| 458 : ip_(ip), | 458 : ip_(ip), |
| 459 port_(port), | 459 port_(port), |
| 460 overriden_frontend_url_(frontend_host), | 460 overriden_frontend_url_(frontend_host), |
| 461 tab_contents_provider_(provider) { | 461 tab_contents_provider_(provider) { |
| 462 if (overriden_frontend_url_.empty()) | 462 if (overriden_frontend_url_.empty()) |
| 463 overriden_frontend_url_ = "/devtools/devtools.html"; | 463 overriden_frontend_url_ = "/devtools/devtools.html"; |
| 464 } | 464 } |
| 465 | 465 |
| 466 void DevToolsHttpProtocolHandler::Init() { | 466 void DevToolsHttpProtocolHandler::Init() { |
| 467 server_ = new HttpServer(ip_, port_, this); | 467 server_ = new net::HttpServer(ip_, port_, this); |
| 468 } | 468 } |
| 469 | 469 |
| 470 // Run on I/O thread | 470 // Run on I/O thread |
| 471 void DevToolsHttpProtocolHandler::Teardown() { | 471 void DevToolsHttpProtocolHandler::Teardown() { |
| 472 server_ = NULL; | 472 server_ = NULL; |
| 473 } | 473 } |
| 474 | 474 |
| 475 void DevToolsHttpProtocolHandler::Bind(net::URLRequest* request, | 475 void DevToolsHttpProtocolHandler::Bind(net::URLRequest* request, |
| 476 int connection_id) { | 476 int connection_id) { |
| 477 request_to_connection_io_[request] = connection_id; | 477 request_to_connection_io_[request] = connection_id; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 500 request_to_buffer_io_.erase(request); | 500 request_to_buffer_io_.erase(request); |
| 501 delete request; | 501 delete request; |
| 502 } | 502 } |
| 503 | 503 |
| 504 void DevToolsHttpProtocolHandler::Send200(int connection_id, | 504 void DevToolsHttpProtocolHandler::Send200(int connection_id, |
| 505 const std::string& data, | 505 const std::string& data, |
| 506 const std::string& mime_type) { | 506 const std::string& mime_type) { |
| 507 BrowserThread::PostTask( | 507 BrowserThread::PostTask( |
| 508 BrowserThread::IO, FROM_HERE, | 508 BrowserThread::IO, FROM_HERE, |
| 509 NewRunnableMethod(server_.get(), | 509 NewRunnableMethod(server_.get(), |
| 510 &HttpServer::Send200, | 510 &net::HttpServer::Send200, |
| 511 connection_id, | 511 connection_id, |
| 512 data, | 512 data, |
| 513 mime_type)); | 513 mime_type)); |
| 514 } | 514 } |
| 515 | 515 |
| 516 void DevToolsHttpProtocolHandler::Send404(int connection_id) { | 516 void DevToolsHttpProtocolHandler::Send404(int connection_id) { |
| 517 BrowserThread::PostTask( | 517 BrowserThread::PostTask( |
| 518 BrowserThread::IO, FROM_HERE, | 518 BrowserThread::IO, FROM_HERE, |
| 519 NewRunnableMethod(server_.get(), | 519 NewRunnableMethod(server_.get(), |
| 520 &HttpServer::Send404, | 520 &net::HttpServer::Send404, |
| 521 connection_id)); | 521 connection_id)); |
| 522 } | 522 } |
| 523 | 523 |
| 524 void DevToolsHttpProtocolHandler::Send500(int connection_id, | 524 void DevToolsHttpProtocolHandler::Send500(int connection_id, |
| 525 const std::string& message) { | 525 const std::string& message) { |
| 526 BrowserThread::PostTask( | 526 BrowserThread::PostTask( |
| 527 BrowserThread::IO, FROM_HERE, | 527 BrowserThread::IO, FROM_HERE, |
| 528 NewRunnableMethod(server_.get(), | 528 NewRunnableMethod(server_.get(), |
| 529 &HttpServer::Send500, | 529 &net::HttpServer::Send500, |
| 530 connection_id, | 530 connection_id, |
| 531 message)); | 531 message)); |
| 532 } | 532 } |
| 533 | 533 |
| 534 void DevToolsHttpProtocolHandler::AcceptWebSocket( | 534 void DevToolsHttpProtocolHandler::AcceptWebSocket( |
| 535 int connection_id, | 535 int connection_id, |
| 536 const HttpServerRequestInfo& request) { | 536 const net::HttpServerRequestInfo& request) { |
| 537 BrowserThread::PostTask( | 537 BrowserThread::PostTask( |
| 538 BrowserThread::IO, FROM_HERE, | 538 BrowserThread::IO, FROM_HERE, |
| 539 NewRunnableMethod(server_.get(), | 539 NewRunnableMethod(server_.get(), |
| 540 &HttpServer::AcceptWebSocket, | 540 &net::HttpServer::AcceptWebSocket, |
| 541 connection_id, | 541 connection_id, |
| 542 request)); | 542 request)); |
| 543 } | 543 } |
| 544 | 544 |
| 545 TabContents* DevToolsHttpProtocolHandler::GetTabContents(int session_id) { | 545 TabContents* DevToolsHttpProtocolHandler::GetTabContents(int session_id) { |
| 546 InspectableTabs inspectable_tabs = | 546 InspectableTabs inspectable_tabs = |
| 547 tab_contents_provider_->GetInspectableTabs(); | 547 tab_contents_provider_->GetInspectableTabs(); |
| 548 | 548 |
| 549 for (InspectableTabs::iterator it = inspectable_tabs.begin(); | 549 for (InspectableTabs::iterator it = inspectable_tabs.begin(); |
| 550 it != inspectable_tabs.end(); ++it) { | 550 it != inspectable_tabs.end(); ++it) { |
| 551 TabContentsWrapper* tab_contents = *it; | 551 TabContentsWrapper* tab_contents = *it; |
| 552 NavigationController& controller = | 552 NavigationController& controller = |
| 553 tab_contents->controller(); | 553 tab_contents->controller(); |
| 554 if (controller.session_id().id() == session_id) | 554 if (controller.session_id().id() == session_id) |
| 555 return controller.tab_contents(); | 555 return controller.tab_contents(); |
| 556 } | 556 } |
| 557 return NULL; | 557 return NULL; |
| 558 } | 558 } |
| OLD | NEW |