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

Side by Side Diff: content/browser/devtools/devtools_http_handler_impl.cc

Issue 296053012: Replace StreamListenSocket with StreamSocket in HttpServer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed unittest errors. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 23 matching lines...) Expand all
34 #include "content/public/common/url_constants.h" 34 #include "content/public/common/url_constants.h"
35 #include "content/public/common/user_agent.h" 35 #include "content/public/common/user_agent.h"
36 #include "content/public/common/user_agent.h" 36 #include "content/public/common/user_agent.h"
37 #include "grit/devtools_resources_map.h" 37 #include "grit/devtools_resources_map.h"
38 #include "net/base/escape.h" 38 #include "net/base/escape.h"
39 #include "net/base/io_buffer.h" 39 #include "net/base/io_buffer.h"
40 #include "net/base/ip_endpoint.h" 40 #include "net/base/ip_endpoint.h"
41 #include "net/base/net_errors.h" 41 #include "net/base/net_errors.h"
42 #include "net/server/http_server_request_info.h" 42 #include "net/server/http_server_request_info.h"
43 #include "net/server/http_server_response_info.h" 43 #include "net/server/http_server_response_info.h"
44 #include "net/socket/server_socket.h"
44 45
45 #if defined(OS_ANDROID) 46 #if defined(OS_ANDROID)
46 #include "base/android/build_info.h" 47 #include "base/android/build_info.h"
47 #endif 48 #endif
48 49
49 namespace content { 50 namespace content {
50 51
51 namespace { 52 namespace {
52 53
53 const base::FilePath::CharType kDevToolsActivePortFileName[] = 54 const base::FilePath::CharType kDevToolsActivePortFileName[] =
54 FILE_PATH_LITERAL("DevToolsActivePort"); 55 FILE_PATH_LITERAL("DevToolsActivePort");
55 56
56 const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread"; 57 const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread";
57 58
58 const char kThumbUrlPrefix[] = "/thumb/"; 59 const char kThumbUrlPrefix[] = "/thumb/";
59 const char kPageUrlPrefix[] = "/devtools/page/"; 60 const char kPageUrlPrefix[] = "/devtools/page/";
60 61
61 const char kTargetIdField[] = "id"; 62 const char kTargetIdField[] = "id";
62 const char kTargetParentIdField[] = "parentId"; 63 const char kTargetParentIdField[] = "parentId";
63 const char kTargetTypeField[] = "type"; 64 const char kTargetTypeField[] = "type";
64 const char kTargetTitleField[] = "title"; 65 const char kTargetTitleField[] = "title";
65 const char kTargetDescriptionField[] = "description"; 66 const char kTargetDescriptionField[] = "description";
66 const char kTargetUrlField[] = "url"; 67 const char kTargetUrlField[] = "url";
67 const char kTargetThumbnailUrlField[] = "thumbnailUrl"; 68 const char kTargetThumbnailUrlField[] = "thumbnailUrl";
68 const char kTargetFaviconUrlField[] = "faviconUrl"; 69 const char kTargetFaviconUrlField[] = "faviconUrl";
69 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl"; 70 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl";
70 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl"; 71 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl";
71 72
73 // Maximum write buffer size of devtools http/websocket connectinos.
74 const int32 kSendBufferSizeForDevTools = 100 * 1024 * 1024; // 100Mb
75
72 // An internal implementation of DevToolsClientHost that delegates 76 // An internal implementation of DevToolsClientHost that delegates
73 // messages sent for DevToolsClient to a DebuggerShell instance. 77 // messages sent for DevToolsClient to a DebuggerShell instance.
74 class DevToolsClientHostImpl : public DevToolsClientHost { 78 class DevToolsClientHostImpl : public DevToolsClientHost {
75 public: 79 public:
76 DevToolsClientHostImpl(base::MessageLoop* message_loop, 80 DevToolsClientHostImpl(base::MessageLoop* message_loop,
77 net::HttpServer* server, 81 net::HttpServer* server,
78 int connection_id) 82 int connection_id)
79 : message_loop_(message_loop), 83 : message_loop_(message_loop),
80 server_(server), 84 server_(server),
81 connection_id_(connection_id), 85 connection_id_(connection_id),
(...skipping 10 matching lines...) Expand all
92 96
93 base::DictionaryValue notification; 97 base::DictionaryValue notification;
94 notification.SetString( 98 notification.SetString(
95 devtools::Inspector::detached::kParamReason, detach_reason_); 99 devtools::Inspector::detached::kParamReason, detach_reason_);
96 std::string response = DevToolsProtocol::CreateNotification( 100 std::string response = DevToolsProtocol::CreateNotification(
97 devtools::Inspector::detached::kName, 101 devtools::Inspector::detached::kName,
98 notification.DeepCopy())->Serialize(); 102 notification.DeepCopy())->Serialize();
99 message_loop_->PostTask( 103 message_loop_->PostTask(
100 FROM_HERE, 104 FROM_HERE,
101 base::Bind(&net::HttpServer::SendOverWebSocket, 105 base::Bind(&net::HttpServer::SendOverWebSocket,
102 server_, 106 base::Unretained(server_),
103 connection_id_, 107 connection_id_,
104 response)); 108 response));
105 109
106 message_loop_->PostTask( 110 message_loop_->PostTask(
107 FROM_HERE, 111 FROM_HERE,
108 base::Bind(&net::HttpServer::Close, server_, connection_id_)); 112 base::Bind(&net::HttpServer::Close,
113 base::Unretained(server_),
114 connection_id_));
109 } 115 }
110 116
111 virtual void DispatchOnInspectorFrontend(const std::string& data) OVERRIDE { 117 virtual void DispatchOnInspectorFrontend(const std::string& data) OVERRIDE {
112 message_loop_->PostTask( 118 message_loop_->PostTask(
113 FROM_HERE, 119 FROM_HERE,
114 base::Bind(&net::HttpServer::SendOverWebSocket, 120 base::Bind(&net::HttpServer::SendOverWebSocket,
115 server_, 121 base::Unretained(server_),
116 connection_id_, 122 connection_id_,
117 data)); 123 data));
118 } 124 }
119 125
120 virtual void ReplacedWithAnotherClient() OVERRIDE { 126 virtual void ReplacedWithAnotherClient() OVERRIDE {
121 detach_reason_ = "replaced_with_devtools"; 127 detach_reason_ = "replaced_with_devtools";
122 } 128 }
123 129
124 private: 130 private:
125 base::MessageLoop* message_loop_; 131 base::MessageLoop* const message_loop_;
126 net::HttpServer* server_; 132 net::HttpServer* const server_;
127 int connection_id_; 133 const int connection_id_;
128 bool is_closed_; 134 bool is_closed_;
129 std::string detach_reason_; 135 std::string detach_reason_;
130 }; 136 };
131 137
132 static bool TimeComparator(const DevToolsTarget* target1, 138 static bool TimeComparator(const DevToolsTarget* target1,
133 const DevToolsTarget* target2) { 139 const DevToolsTarget* target2) {
134 return target1->GetLastActivityTime() > target2->GetLastActivityTime(); 140 return target1->GetLastActivityTime() > target2->GetLastActivityTime();
135 } 141 }
136 142
137 } // namespace 143 } // namespace
138 144
139 // static 145 // static
140 bool DevToolsHttpHandler::IsSupportedProtocolVersion( 146 bool DevToolsHttpHandler::IsSupportedProtocolVersion(
141 const std::string& version) { 147 const std::string& version) {
142 return devtools::IsSupportedProtocolVersion(version); 148 return devtools::IsSupportedProtocolVersion(version);
143 } 149 }
144 150
145 // static 151 // static
146 int DevToolsHttpHandler::GetFrontendResourceId(const std::string& name) { 152 int DevToolsHttpHandler::GetFrontendResourceId(const std::string& name) {
147 for (size_t i = 0; i < kDevtoolsResourcesSize; ++i) { 153 for (size_t i = 0; i < kDevtoolsResourcesSize; ++i) {
148 if (name == kDevtoolsResources[i].name) 154 if (name == kDevtoolsResources[i].name)
149 return kDevtoolsResources[i].value; 155 return kDevtoolsResources[i].value;
150 } 156 }
151 return -1; 157 return -1;
152 } 158 }
153 159
154 // static 160 // static
155 DevToolsHttpHandler* DevToolsHttpHandler::Start( 161 DevToolsHttpHandler* DevToolsHttpHandler::Start(
156 const net::StreamListenSocketFactory* socket_factory, 162 scoped_ptr<ServerSocketFactory> server_socket_factory,
157 const std::string& frontend_url, 163 const std::string& frontend_url,
158 DevToolsHttpHandlerDelegate* delegate, 164 DevToolsHttpHandlerDelegate* delegate,
159 const base::FilePath& active_port_output_directory) { 165 const base::FilePath& active_port_output_directory) {
160 DevToolsHttpHandlerImpl* http_handler = 166 DevToolsHttpHandlerImpl* http_handler =
161 new DevToolsHttpHandlerImpl(socket_factory, 167 new DevToolsHttpHandlerImpl(server_socket_factory.Pass(),
162 frontend_url, 168 frontend_url,
163 delegate, 169 delegate,
164 active_port_output_directory); 170 active_port_output_directory);
165 http_handler->Start(); 171 http_handler->Start();
166 return http_handler; 172 return http_handler;
167 } 173 }
168 174
175 DevToolsHttpHandler::ServerSocketFactory::ServerSocketFactory(
176 const std::string& address,
177 int port,
178 int backlog)
179 : address_(address),
180 port_(port),
181 backlog_(backlog) {
182 }
183
184 DevToolsHttpHandler::ServerSocketFactory::~ServerSocketFactory() {
185 }
186
187 scoped_ptr<net::ServerSocket>
188 DevToolsHttpHandler::ServerSocketFactory::CreateAndListen() const {
189 scoped_ptr<net::ServerSocket> socket = Create();
190 if (socket &&
191 socket->ListenWithAddressAndPort(address_, port_, backlog_) == net::OK) {
192 return socket.Pass();
193 }
194 return scoped_ptr<net::ServerSocket>();
195 }
196
169 DevToolsHttpHandlerImpl::~DevToolsHttpHandlerImpl() { 197 DevToolsHttpHandlerImpl::~DevToolsHttpHandlerImpl() {
170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 198 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
171 // Stop() must be called prior to destruction. 199 // Stop() must be called prior to destruction.
172 DCHECK(server_.get() == NULL); 200 DCHECK(server_.get() == NULL);
173 DCHECK(thread_.get() == NULL); 201 DCHECK(thread_.get() == NULL);
174 STLDeleteValues(&target_map_); 202 STLDeleteValues(&target_map_);
175 } 203 }
176 204
177 void DevToolsHttpHandlerImpl::Start() { 205 void DevToolsHttpHandlerImpl::Start() {
178 if (thread_) 206 if (thread_)
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 LOG(ERROR) << "GetMimeType doesn't know mime type for: " 276 LOG(ERROR) << "GetMimeType doesn't know mime type for: "
249 << filename 277 << filename
250 << " text/plain will be returned"; 278 << " text/plain will be returned";
251 NOTREACHED(); 279 NOTREACHED();
252 return "text/plain"; 280 return "text/plain";
253 } 281 }
254 282
255 void DevToolsHttpHandlerImpl::OnHttpRequest( 283 void DevToolsHttpHandlerImpl::OnHttpRequest(
256 int connection_id, 284 int connection_id,
257 const net::HttpServerRequestInfo& info) { 285 const net::HttpServerRequestInfo& info) {
286 server_->SetSendBufferSize(connection_id, kSendBufferSizeForDevTools);
287
258 if (info.path.find("/json") == 0) { 288 if (info.path.find("/json") == 0) {
259 BrowserThread::PostTask( 289 BrowserThread::PostTask(
260 BrowserThread::UI, 290 BrowserThread::UI,
261 FROM_HERE, 291 FROM_HERE,
262 base::Bind(&DevToolsHttpHandlerImpl::OnJsonRequestUI, 292 base::Bind(&DevToolsHttpHandlerImpl::OnJsonRequestUI,
263 this, 293 this,
264 connection_id, 294 connection_id,
265 info)); 295 info));
266 return; 296 return;
267 } 297 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 browser_target->RegisterDomainHandler( 367 browser_target->RegisterDomainHandler(
338 TetheringHandler::kDomain, 368 TetheringHandler::kDomain,
339 new TetheringHandler(delegate_.get()), 369 new TetheringHandler(delegate_.get()),
340 false /* handle on this thread */); 370 false /* handle on this thread */);
341 browser_target->RegisterDomainHandler( 371 browser_target->RegisterDomainHandler(
342 devtools::SystemInfo::kName, 372 devtools::SystemInfo::kName,
343 new DevToolsSystemInfoHandler(), 373 new DevToolsSystemInfoHandler(),
344 true /* handle on UI thread */); 374 true /* handle on UI thread */);
345 browser_targets_[connection_id] = browser_target; 375 browser_targets_[connection_id] = browser_target;
346 376
377 server_->SetSendBufferSize(connection_id, kSendBufferSizeForDevTools);
347 server_->AcceptWebSocket(connection_id, request); 378 server_->AcceptWebSocket(connection_id, request);
348 return; 379 return;
349 } 380 }
350 381
351 BrowserThread::PostTask( 382 BrowserThread::PostTask(
352 BrowserThread::UI, 383 BrowserThread::UI,
353 FROM_HERE, 384 FROM_HERE,
354 base::Bind( 385 base::Bind(
355 &DevToolsHttpHandlerImpl::OnWebSocketRequestUI, 386 &DevToolsHttpHandlerImpl::OnWebSocketRequestUI,
356 this, 387 this,
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 if (it != connection_to_client_host_ui_.end()) { 671 if (it != connection_to_client_host_ui_.end()) {
641 DevToolsClientHostImpl* client_host = 672 DevToolsClientHostImpl* client_host =
642 static_cast<DevToolsClientHostImpl*>(it->second); 673 static_cast<DevToolsClientHostImpl*>(it->second);
643 DevToolsManager::GetInstance()->ClientHostClosing(client_host); 674 DevToolsManager::GetInstance()->ClientHostClosing(client_host);
644 delete client_host; 675 delete client_host;
645 connection_to_client_host_ui_.erase(connection_id); 676 connection_to_client_host_ui_.erase(connection_id);
646 } 677 }
647 } 678 }
648 679
649 DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl( 680 DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl(
650 const net::StreamListenSocketFactory* socket_factory, 681 scoped_ptr<ServerSocketFactory> server_socket_factory,
651 const std::string& frontend_url, 682 const std::string& frontend_url,
652 DevToolsHttpHandlerDelegate* delegate, 683 DevToolsHttpHandlerDelegate* delegate,
653 const base::FilePath& active_port_output_directory) 684 const base::FilePath& active_port_output_directory)
654 : frontend_url_(frontend_url), 685 : frontend_url_(frontend_url),
655 socket_factory_(socket_factory), 686 server_socket_factory_(server_socket_factory.Pass()),
656 delegate_(delegate), 687 delegate_(delegate),
657 active_port_output_directory_(active_port_output_directory) { 688 active_port_output_directory_(active_port_output_directory) {
658 if (frontend_url_.empty()) 689 if (frontend_url_.empty())
659 frontend_url_ = "/devtools/devtools.html"; 690 frontend_url_ = "/devtools/devtools.html";
660 691
661 // Balanced in ResetHandlerThreadAndRelease(). 692 // Balanced in ResetHandlerThreadAndRelease().
662 AddRef(); 693 AddRef();
663 } 694 }
664 695
665 // Runs on the handler thread 696 // Runs on the handler thread
666 void DevToolsHttpHandlerImpl::Init() { 697 void DevToolsHttpHandlerImpl::Init() {
667 server_ = new net::HttpServer(*socket_factory_.get(), this); 698 server_.reset(new net::HttpServer(server_socket_factory_->CreateAndListen(),
699 this));
668 if (!active_port_output_directory_.empty()) 700 if (!active_port_output_directory_.empty())
669 WriteActivePortToUserProfile(); 701 WriteActivePortToUserProfile();
670 } 702 }
671 703
672 // Runs on the handler thread 704 // Runs on the handler thread
673 void DevToolsHttpHandlerImpl::Teardown() { 705 void DevToolsHttpHandlerImpl::Teardown() {
674 server_ = NULL; 706 server_.reset(NULL);
675 } 707 }
676 708
677 // Runs on FILE thread to make sure that it is serialized against 709 // Runs on FILE thread to make sure that it is serialized against
678 // {Start|Stop}HandlerThread and to allow calling pthread_join. 710 // {Start|Stop}HandlerThread and to allow calling pthread_join.
679 void DevToolsHttpHandlerImpl::StopHandlerThread() { 711 void DevToolsHttpHandlerImpl::StopHandlerThread() {
680 if (!thread_->message_loop()) 712 if (!thread_->message_loop())
681 return; 713 return;
682 thread_->message_loop()->PostTask( 714 thread_->message_loop()->PostTask(
683 FROM_HERE, 715 FROM_HERE,
684 base::Bind(&DevToolsHttpHandlerImpl::Teardown, this)); 716 base::Bind(&DevToolsHttpHandlerImpl::Teardown, this));
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 std::string json_message; 754 std::string json_message;
723 scoped_ptr<base::Value> message_object(new base::StringValue(message)); 755 scoped_ptr<base::Value> message_object(new base::StringValue(message));
724 base::JSONWriter::Write(message_object.get(), &json_message); 756 base::JSONWriter::Write(message_object.get(), &json_message);
725 757
726 net::HttpServerResponseInfo response(status_code); 758 net::HttpServerResponseInfo response(status_code);
727 response.SetBody(json_value + message, "application/json; charset=UTF-8"); 759 response.SetBody(json_value + message, "application/json; charset=UTF-8");
728 760
729 thread_->message_loop()->PostTask( 761 thread_->message_loop()->PostTask(
730 FROM_HERE, 762 FROM_HERE,
731 base::Bind(&net::HttpServer::SendResponse, 763 base::Bind(&net::HttpServer::SendResponse,
732 server_.get(), 764 base::Unretained(server_.get()),
733 connection_id, 765 connection_id,
734 response)); 766 response));
735 } 767 }
736 768
737 void DevToolsHttpHandlerImpl::Send200(int connection_id, 769 void DevToolsHttpHandlerImpl::Send200(int connection_id,
738 const std::string& data, 770 const std::string& data,
739 const std::string& mime_type) { 771 const std::string& mime_type) {
740 if (!thread_) 772 if (!thread_)
741 return; 773 return;
742 thread_->message_loop()->PostTask( 774 thread_->message_loop()->PostTask(
743 FROM_HERE, 775 FROM_HERE,
744 base::Bind(&net::HttpServer::Send200, 776 base::Bind(&net::HttpServer::Send200,
745 server_.get(), 777 base::Unretained(server_.get()),
746 connection_id, 778 connection_id,
747 data, 779 data,
748 mime_type)); 780 mime_type));
749 } 781 }
750 782
751 void DevToolsHttpHandlerImpl::Send404(int connection_id) { 783 void DevToolsHttpHandlerImpl::Send404(int connection_id) {
752 if (!thread_) 784 if (!thread_)
753 return; 785 return;
754 thread_->message_loop()->PostTask( 786 thread_->message_loop()->PostTask(
755 FROM_HERE, 787 FROM_HERE,
756 base::Bind(&net::HttpServer::Send404, server_.get(), connection_id)); 788 base::Bind(&net::HttpServer::Send404,
789 base::Unretained(server_.get()),
790 connection_id));
757 } 791 }
758 792
759 void DevToolsHttpHandlerImpl::Send500(int connection_id, 793 void DevToolsHttpHandlerImpl::Send500(int connection_id,
760 const std::string& message) { 794 const std::string& message) {
761 if (!thread_) 795 if (!thread_)
762 return; 796 return;
763 thread_->message_loop()->PostTask( 797 thread_->message_loop()->PostTask(
764 FROM_HERE, 798 FROM_HERE,
765 base::Bind(&net::HttpServer::Send500, server_.get(), connection_id, 799 base::Bind(&net::HttpServer::Send500,
800 base::Unretained(server_.get()),
801 connection_id,
766 message)); 802 message));
767 } 803 }
768 804
769 void DevToolsHttpHandlerImpl::AcceptWebSocket( 805 void DevToolsHttpHandlerImpl::AcceptWebSocket(
770 int connection_id, 806 int connection_id,
771 const net::HttpServerRequestInfo& request) { 807 const net::HttpServerRequestInfo& request) {
772 if (!thread_) 808 if (!thread_)
773 return; 809 return;
774 thread_->message_loop()->PostTask( 810 thread_->message_loop()->PostTask(
775 FROM_HERE, 811 FROM_HERE,
776 base::Bind(&net::HttpServer::AcceptWebSocket, server_.get(), 812 base::Bind(&net::HttpServer::SetSendBufferSize,
777 connection_id, request)); 813 base::Unretained(server_.get()),
814 connection_id,
815 kSendBufferSizeForDevTools));
816 thread_->message_loop()->PostTask(
817 FROM_HERE,
818 base::Bind(&net::HttpServer::AcceptWebSocket,
819 base::Unretained(server_.get()),
820 connection_id,
821 request));
778 } 822 }
779 823
780 base::DictionaryValue* DevToolsHttpHandlerImpl::SerializeTarget( 824 base::DictionaryValue* DevToolsHttpHandlerImpl::SerializeTarget(
781 const DevToolsTarget& target, 825 const DevToolsTarget& target,
782 const std::string& host) { 826 const std::string& host) {
783 base::DictionaryValue* dictionary = new base::DictionaryValue; 827 base::DictionaryValue* dictionary = new base::DictionaryValue;
784 828
785 std::string id = target.GetId(); 829 std::string id = target.GetId();
786 dictionary->SetString(kTargetIdField, id); 830 dictionary->SetString(kTargetIdField, id);
787 std::string parent_id = target.GetParentId(); 831 std::string parent_id = target.GetParentId();
(...skipping 26 matching lines...) Expand all
814 id.c_str(), 858 id.c_str(),
815 host); 859 host);
816 dictionary->SetString( 860 dictionary->SetString(
817 kTargetDevtoolsFrontendUrlField, devtools_frontend_url); 861 kTargetDevtoolsFrontendUrlField, devtools_frontend_url);
818 } 862 }
819 863
820 return dictionary; 864 return dictionary;
821 } 865 }
822 866
823 } // namespace content 867 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698