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

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: Use base::StringPiece in some places not to copy data. Created 6 years, 6 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/content_client.h" 32 #include "content/public/common/content_client.h"
33 #include "content/public/common/url_constants.h" 33 #include "content/public/common/url_constants.h"
34 #include "content/public/common/user_agent.h" 34 #include "content/public/common/user_agent.h"
35 #include "content/public/common/user_agent.h" 35 #include "content/public/common/user_agent.h"
36 #include "grit/devtools_resources_map.h" 36 #include "grit/devtools_resources_map.h"
37 #include "net/base/escape.h" 37 #include "net/base/escape.h"
38 #include "net/base/io_buffer.h" 38 #include "net/base/io_buffer.h"
39 #include "net/base/ip_endpoint.h" 39 #include "net/base/ip_endpoint.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 char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread"; 52 const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread";
52 53
53 const char kThumbUrlPrefix[] = "/thumb/"; 54 const char kThumbUrlPrefix[] = "/thumb/";
54 const char kPageUrlPrefix[] = "/devtools/page/"; 55 const char kPageUrlPrefix[] = "/devtools/page/";
55 56
56 const char kTargetIdField[] = "id"; 57 const char kTargetIdField[] = "id";
57 const char kTargetTypeField[] = "type"; 58 const char kTargetTypeField[] = "type";
58 const char kTargetTitleField[] = "title"; 59 const char kTargetTitleField[] = "title";
59 const char kTargetDescriptionField[] = "description"; 60 const char kTargetDescriptionField[] = "description";
60 const char kTargetUrlField[] = "url"; 61 const char kTargetUrlField[] = "url";
61 const char kTargetThumbnailUrlField[] = "thumbnailUrl"; 62 const char kTargetThumbnailUrlField[] = "thumbnailUrl";
62 const char kTargetFaviconUrlField[] = "faviconUrl"; 63 const char kTargetFaviconUrlField[] = "faviconUrl";
63 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl"; 64 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl";
64 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl"; 65 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl";
65 66
67 // Maximum write buffer size of devtools websocket.
68 const int32 kSendBufferSizeForDevToolsWebSocket = 100 * 1024 * 1024; // 100Mb
69
66 // An internal implementation of DevToolsClientHost that delegates 70 // An internal implementation of DevToolsClientHost that delegates
67 // messages sent for DevToolsClient to a DebuggerShell instance. 71 // messages sent for DevToolsClient to a DebuggerShell instance.
68 class DevToolsClientHostImpl : public DevToolsClientHost { 72 class DevToolsClientHostImpl : public DevToolsClientHost {
69 public: 73 public:
70 DevToolsClientHostImpl(base::MessageLoop* message_loop, 74 DevToolsClientHostImpl(base::MessageLoop* message_loop,
71 net::HttpServer* server, 75 base::WeakPtr<net::HttpServer> server,
72 int connection_id) 76 int connection_id)
73 : message_loop_(message_loop), 77 : message_loop_(message_loop),
74 server_(server), 78 server_(server),
75 connection_id_(connection_id), 79 connection_id_(connection_id),
76 is_closed_(false), 80 is_closed_(false),
77 detach_reason_("target_closed") {} 81 detach_reason_("target_closed") {}
78 82
79 virtual ~DevToolsClientHostImpl() {} 83 virtual ~DevToolsClientHostImpl() {}
80 84
81 // DevToolsClientHost interface 85 // DevToolsClientHost interface
(...skipping 28 matching lines...) Expand all
110 connection_id_, 114 connection_id_,
111 data)); 115 data));
112 } 116 }
113 117
114 virtual void ReplacedWithAnotherClient() OVERRIDE { 118 virtual void ReplacedWithAnotherClient() OVERRIDE {
115 detach_reason_ = "replaced_with_devtools"; 119 detach_reason_ = "replaced_with_devtools";
116 } 120 }
117 121
118 private: 122 private:
119 base::MessageLoop* message_loop_; 123 base::MessageLoop* message_loop_;
120 net::HttpServer* server_; 124 base::WeakPtr<net::HttpServer> server_;
121 int connection_id_; 125 int connection_id_;
122 bool is_closed_; 126 bool is_closed_;
123 std::string detach_reason_; 127 std::string detach_reason_;
124 }; 128 };
125 129
126 static bool TimeComparator(const DevToolsTarget* target1, 130 static bool TimeComparator(const DevToolsTarget* target1,
127 const DevToolsTarget* target2) { 131 const DevToolsTarget* target2) {
128 return target1->GetLastActivityTime() > target2->GetLastActivityTime(); 132 return target1->GetLastActivityTime() > target2->GetLastActivityTime();
129 } 133 }
130 134
131 } // namespace 135 } // namespace
132 136
133 // static 137 // static
134 bool DevToolsHttpHandler::IsSupportedProtocolVersion( 138 bool DevToolsHttpHandler::IsSupportedProtocolVersion(
135 const std::string& version) { 139 const std::string& version) {
136 return devtools::IsSupportedProtocolVersion(version); 140 return devtools::IsSupportedProtocolVersion(version);
137 } 141 }
138 142
139 // static 143 // static
140 int DevToolsHttpHandler::GetFrontendResourceId(const std::string& name) { 144 int DevToolsHttpHandler::GetFrontendResourceId(const std::string& name) {
141 for (size_t i = 0; i < kDevtoolsResourcesSize; ++i) { 145 for (size_t i = 0; i < kDevtoolsResourcesSize; ++i) {
142 if (name == kDevtoolsResources[i].name) 146 if (name == kDevtoolsResources[i].name)
143 return kDevtoolsResources[i].value; 147 return kDevtoolsResources[i].value;
144 } 148 }
145 return -1; 149 return -1;
146 } 150 }
147 151
148 // static 152 // static
149 DevToolsHttpHandler* DevToolsHttpHandler::Start( 153 DevToolsHttpHandler* DevToolsHttpHandler::Start(
150 const net::StreamListenSocketFactory* socket_factory, 154 scoped_ptr<net::ServerSocketFactory> server_socket_factory,
151 const std::string& frontend_url, 155 const std::string& frontend_url,
152 DevToolsHttpHandlerDelegate* delegate) { 156 DevToolsHttpHandlerDelegate* delegate) {
153 DevToolsHttpHandlerImpl* http_handler = 157 DevToolsHttpHandlerImpl* http_handler =
154 new DevToolsHttpHandlerImpl(socket_factory, 158 new DevToolsHttpHandlerImpl(server_socket_factory.Pass(),
155 frontend_url, 159 frontend_url,
156 delegate); 160 delegate);
157 http_handler->Start(); 161 http_handler->Start();
158 return http_handler; 162 return http_handler;
159 } 163 }
160 164
161 DevToolsHttpHandlerImpl::~DevToolsHttpHandlerImpl() { 165 DevToolsHttpHandlerImpl::~DevToolsHttpHandlerImpl() {
162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 166 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
163 // Stop() must be called prior to destruction. 167 // Stop() must be called prior to destruction.
164 DCHECK(server_.get() == NULL); 168 DCHECK(server_.get() == NULL);
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 void DevToolsHttpHandlerImpl::OnWebSocketRequest( 321 void DevToolsHttpHandlerImpl::OnWebSocketRequest(
318 int connection_id, 322 int connection_id,
319 const net::HttpServerRequestInfo& request) { 323 const net::HttpServerRequestInfo& request) {
320 std::string browser_prefix = "/devtools/browser"; 324 std::string browser_prefix = "/devtools/browser";
321 size_t browser_pos = request.path.find(browser_prefix); 325 size_t browser_pos = request.path.find(browser_prefix);
322 if (browser_pos == 0) { 326 if (browser_pos == 0) {
323 if (browser_target_) { 327 if (browser_target_) {
324 server_->Send500(connection_id, "Another client already attached"); 328 server_->Send500(connection_id, "Another client already attached");
325 return; 329 return;
326 } 330 }
327 browser_target_ = new DevToolsBrowserTarget(server_.get(), connection_id); 331 browser_target_ = new DevToolsBrowserTarget(server_->GetWeakPtr(),
332 connection_id);
328 browser_target_->RegisterDomainHandler( 333 browser_target_->RegisterDomainHandler(
329 devtools::Tracing::kName, 334 devtools::Tracing::kName,
330 new DevToolsTracingHandler(DevToolsTracingHandler::Browser), 335 new DevToolsTracingHandler(DevToolsTracingHandler::Browser),
331 true /* handle on UI thread */); 336 true /* handle on UI thread */);
332 browser_target_->RegisterDomainHandler( 337 browser_target_->RegisterDomainHandler(
333 TetheringHandler::kDomain, 338 TetheringHandler::kDomain,
334 new TetheringHandler(delegate_.get()), 339 new TetheringHandler(delegate_.get()),
335 false /* handle on this thread */); 340 false /* handle on this thread */);
336 browser_target_->RegisterDomainHandler( 341 browser_target_->RegisterDomainHandler(
337 devtools::SystemInfo::kName, 342 devtools::SystemInfo::kName,
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 return; 603 return;
599 } 604 }
600 605
601 if (agent->IsAttached()) { 606 if (agent->IsAttached()) {
602 Send500(connection_id, 607 Send500(connection_id,
603 "Target with given id is being inspected: " + page_id); 608 "Target with given id is being inspected: " + page_id);
604 return; 609 return;
605 } 610 }
606 611
607 DevToolsClientHostImpl* client_host = new DevToolsClientHostImpl( 612 DevToolsClientHostImpl* client_host = new DevToolsClientHostImpl(
608 thread_->message_loop(), server_.get(), connection_id); 613 thread_->message_loop(), server_->GetWeakPtr(), connection_id);
609 connection_to_client_host_ui_[connection_id] = client_host; 614 connection_to_client_host_ui_[connection_id] = client_host;
610 615
611 DevToolsManager::GetInstance()-> 616 DevToolsManager::GetInstance()->
612 RegisterDevToolsClientHostFor(agent, client_host); 617 RegisterDevToolsClientHostFor(agent, client_host);
613 618
614 AcceptWebSocket(connection_id, request); 619 AcceptWebSocket(connection_id, request);
615 } 620 }
616 621
617 void DevToolsHttpHandlerImpl::OnWebSocketMessageUI( 622 void DevToolsHttpHandlerImpl::OnWebSocketMessageUI(
618 int connection_id, 623 int connection_id,
(...skipping 13 matching lines...) Expand all
632 if (it != connection_to_client_host_ui_.end()) { 637 if (it != connection_to_client_host_ui_.end()) {
633 DevToolsClientHostImpl* client_host = 638 DevToolsClientHostImpl* client_host =
634 static_cast<DevToolsClientHostImpl*>(it->second); 639 static_cast<DevToolsClientHostImpl*>(it->second);
635 DevToolsManager::GetInstance()->ClientHostClosing(client_host); 640 DevToolsManager::GetInstance()->ClientHostClosing(client_host);
636 delete client_host; 641 delete client_host;
637 connection_to_client_host_ui_.erase(connection_id); 642 connection_to_client_host_ui_.erase(connection_id);
638 } 643 }
639 } 644 }
640 645
641 DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl( 646 DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl(
642 const net::StreamListenSocketFactory* socket_factory, 647 scoped_ptr<net::ServerSocketFactory> server_socket_factory,
643 const std::string& frontend_url, 648 const std::string& frontend_url,
644 DevToolsHttpHandlerDelegate* delegate) 649 DevToolsHttpHandlerDelegate* delegate)
645 : frontend_url_(frontend_url), 650 : frontend_url_(frontend_url),
646 socket_factory_(socket_factory), 651 server_socket_factory_(server_socket_factory.Pass()),
647 delegate_(delegate) { 652 delegate_(delegate) {
648 if (frontend_url_.empty()) 653 if (frontend_url_.empty())
649 frontend_url_ = "/devtools/devtools.html"; 654 frontend_url_ = "/devtools/devtools.html";
650 655
651 // Balanced in ResetHandlerThreadAndRelease(). 656 // Balanced in ResetHandlerThreadAndRelease().
652 AddRef(); 657 AddRef();
653 } 658 }
654 659
655 // Runs on the handler thread 660 // Runs on the handler thread
656 void DevToolsHttpHandlerImpl::Init() { 661 void DevToolsHttpHandlerImpl::Init() {
657 server_ = new net::HttpServer(*socket_factory_.get(), this); 662 server_.reset(new net::HttpServer(server_socket_factory_->CreateAndListen(),
663 this));
658 } 664 }
659 665
660 // Runs on the handler thread 666 // Runs on the handler thread
661 void DevToolsHttpHandlerImpl::Teardown() { 667 void DevToolsHttpHandlerImpl::Teardown() {
662 server_ = NULL; 668 server_.reset(NULL);
663 } 669 }
664 670
665 // Runs on FILE thread to make sure that it is serialized against 671 // Runs on FILE thread to make sure that it is serialized against
666 // {Start|Stop}HandlerThread and to allow calling pthread_join. 672 // {Start|Stop}HandlerThread and to allow calling pthread_join.
667 void DevToolsHttpHandlerImpl::StopHandlerThread() { 673 void DevToolsHttpHandlerImpl::StopHandlerThread() {
668 if (!thread_->message_loop()) 674 if (!thread_->message_loop())
669 return; 675 return;
670 thread_->message_loop()->PostTask( 676 thread_->message_loop()->PostTask(
671 FROM_HERE, 677 FROM_HERE,
672 base::Bind(&DevToolsHttpHandlerImpl::Teardown, this)); 678 base::Bind(&DevToolsHttpHandlerImpl::Teardown, this));
(...skipping 18 matching lines...) Expand all
691 std::string json_message; 697 std::string json_message;
692 scoped_ptr<base::Value> message_object(new base::StringValue(message)); 698 scoped_ptr<base::Value> message_object(new base::StringValue(message));
693 base::JSONWriter::Write(message_object.get(), &json_message); 699 base::JSONWriter::Write(message_object.get(), &json_message);
694 700
695 net::HttpServerResponseInfo response(status_code); 701 net::HttpServerResponseInfo response(status_code);
696 response.SetBody(json_value + message, "application/json; charset=UTF-8"); 702 response.SetBody(json_value + message, "application/json; charset=UTF-8");
697 703
698 thread_->message_loop()->PostTask( 704 thread_->message_loop()->PostTask(
699 FROM_HERE, 705 FROM_HERE,
700 base::Bind(&net::HttpServer::SendResponse, 706 base::Bind(&net::HttpServer::SendResponse,
701 server_.get(), 707 server_->GetWeakPtr(),
702 connection_id, 708 connection_id,
703 response)); 709 response));
704 } 710 }
705 711
706 void DevToolsHttpHandlerImpl::Send200(int connection_id, 712 void DevToolsHttpHandlerImpl::Send200(int connection_id,
707 const std::string& data, 713 const std::string& data,
708 const std::string& mime_type) { 714 const std::string& mime_type) {
709 if (!thread_) 715 if (!thread_)
710 return; 716 return;
711 thread_->message_loop()->PostTask( 717 thread_->message_loop()->PostTask(
712 FROM_HERE, 718 FROM_HERE,
713 base::Bind(&net::HttpServer::Send200, 719 base::Bind(&net::HttpServer::Send200,
714 server_.get(), 720 server_->GetWeakPtr(),
715 connection_id, 721 connection_id,
716 data, 722 data,
717 mime_type)); 723 mime_type));
718 } 724 }
719 725
720 void DevToolsHttpHandlerImpl::Send404(int connection_id) { 726 void DevToolsHttpHandlerImpl::Send404(int connection_id) {
721 if (!thread_) 727 if (!thread_)
722 return; 728 return;
723 thread_->message_loop()->PostTask( 729 thread_->message_loop()->PostTask(
724 FROM_HERE, 730 FROM_HERE,
725 base::Bind(&net::HttpServer::Send404, server_.get(), connection_id)); 731 base::Bind(&net::HttpServer::Send404,
732 server_->GetWeakPtr(),
733 connection_id));
726 } 734 }
727 735
728 void DevToolsHttpHandlerImpl::Send500(int connection_id, 736 void DevToolsHttpHandlerImpl::Send500(int connection_id,
729 const std::string& message) { 737 const std::string& message) {
730 if (!thread_) 738 if (!thread_)
731 return; 739 return;
732 thread_->message_loop()->PostTask( 740 thread_->message_loop()->PostTask(
733 FROM_HERE, 741 FROM_HERE,
734 base::Bind(&net::HttpServer::Send500, server_.get(), connection_id, 742 base::Bind(&net::HttpServer::Send500,
743 server_->GetWeakPtr(),
744 connection_id,
735 message)); 745 message));
736 } 746 }
737 747
738 void DevToolsHttpHandlerImpl::AcceptWebSocket( 748 void DevToolsHttpHandlerImpl::AcceptWebSocket(
739 int connection_id, 749 int connection_id,
740 const net::HttpServerRequestInfo& request) { 750 const net::HttpServerRequestInfo& request) {
741 if (!thread_) 751 if (!thread_)
742 return; 752 return;
743 thread_->message_loop()->PostTask( 753 thread_->message_loop()->PostTask(
744 FROM_HERE, 754 FROM_HERE,
745 base::Bind(&net::HttpServer::AcceptWebSocket, server_.get(), 755 base::Bind(&net::HttpServer::SetSendBufferSize,
746 connection_id, request)); 756 server_->GetWeakPtr(),
757 connection_id,
758 kSendBufferSizeForDevToolsWebSocket));
759 thread_->message_loop()->PostTask(
760 FROM_HERE,
761 base::Bind(&net::HttpServer::AcceptWebSocket,
762 server_->GetWeakPtr(),
763 connection_id,
764 request));
747 } 765 }
748 766
749 base::DictionaryValue* DevToolsHttpHandlerImpl::SerializeTarget( 767 base::DictionaryValue* DevToolsHttpHandlerImpl::SerializeTarget(
750 const DevToolsTarget& target, 768 const DevToolsTarget& target,
751 const std::string& host) { 769 const std::string& host) {
752 base::DictionaryValue* dictionary = new base::DictionaryValue; 770 base::DictionaryValue* dictionary = new base::DictionaryValue;
753 771
754 std::string id = target.GetId(); 772 std::string id = target.GetId();
755 dictionary->SetString(kTargetIdField, id); 773 dictionary->SetString(kTargetIdField, id);
756 dictionary->SetString(kTargetTypeField, target.GetType()); 774 dictionary->SetString(kTargetTypeField, target.GetType());
(...skipping 23 matching lines...) Expand all
780 id.c_str(), 798 id.c_str(),
781 host); 799 host);
782 dictionary->SetString( 800 dictionary->SetString(
783 kTargetDevtoolsFrontendUrlField, devtools_frontend_url); 801 kTargetDevtoolsFrontendUrlField, devtools_frontend_url);
784 } 802 }
785 803
786 return dictionary; 804 return dictionary;
787 } 805 }
788 806
789 } // namespace content 807 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698