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

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

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

Powered by Google App Engine
This is Rietveld 408576698