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

Side by Side Diff: chrome/browser/extensions/extension_web_socket_proxy_private_api.cc

Issue 8586027: Move DNS resolution from websocket-to-TCP proxy to ExtensionFunction (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nits Created 9 years, 1 month 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 | Annotate | Revision Log
OLDNEW
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/extensions/extension_web_socket_proxy_private_api.h" 5 #include "chrome/browser/extensions/extension_web_socket_proxy_private_api.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/stl_util.h"
9 #include "base/string_number_conversions.h"
8 #include "base/values.h" 10 #include "base/values.h"
9 #include "base/string_number_conversions.h" 11 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/internal_auth.h" 12 #include "chrome/browser/internal_auth.h"
13 #include "chrome/browser/io_thread.h"
11 #include "chrome/common/chrome_notification_types.h" 14 #include "chrome/common/chrome_notification_types.h"
12 #include "chrome/common/extensions/extension.h" 15 #include "chrome/common/extensions/extension.h"
16 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/notification_service.h" 17 #include "content/public/browser/notification_service.h"
14 #include "content/public/browser/notification_details.h" 18 #include "content/public/browser/notification_details.h"
15 #include "net/base/escape.h" 19 #include "net/base/escape.h"
20 #include "net/base/net_errors.h"
21 #include "net/base/net_log.h"
22 #include "net/base/net_util.h"
23 #include "net/base/single_request_host_resolver.h"
16 24
17 #if defined(OS_CHROMEOS) 25 #if defined(OS_CHROMEOS)
18 #include "chrome/browser/chromeos/web_socket_proxy_controller.h" 26 #include "chrome/browser/chromeos/web_socket_proxy_controller.h"
19 #endif 27 #endif
20 28
21 namespace { 29 namespace {
22 const char kPermissionDeniedError[] = 30 const char kPermissionDeniedError[] =
23 "Extension does not have permission to use this method."; 31 "Extension does not have permission to use this method.";
24 } 32 }
25 33
26 WebSocketProxyPrivate::WebSocketProxyPrivate() 34 WebSocketProxyPrivate::WebSocketProxyPrivate()
27 : is_finalized_(false), listening_port_(-1) { 35 : listening_port_(-1), do_tls_(false), is_finalized_(false){
28 } 36 }
29 37
30 WebSocketProxyPrivate::~WebSocketProxyPrivate() { 38 WebSocketProxyPrivate::~WebSocketProxyPrivate() {
31 } 39 }
32 40
33 void WebSocketProxyPrivate::Observe( 41 void WebSocketProxyPrivate::Finalize() {
34 int type, const content::NotificationSource& source, 42 CustomFinalize();
35 const content::NotificationDetails& details) {
36 #if defined(OS_CHROMEOS)
37 DCHECK_EQ(chrome::NOTIFICATION_WEB_SOCKET_PROXY_STARTED, type);
38 #else
39 NOTREACHED();
40 #endif
41 timer_.Stop(); // Cancel timeout timer.
42 Finalize();
43 }
44 43
45 void WebSocketProxyPrivate::Finalize() {
46 if (is_finalized_) 44 if (is_finalized_)
47 return; 45 return;
48 is_finalized_ = true; 46 is_finalized_ = true;
49 SendResponse(listening_port_ > 0); 47 SendResponse(listening_port_ > 0);
50 Release(); 48 Release();
51 } 49 }
52 50
53 void WebSocketProxyPrivateGetURLForTCPFunction::Observe( 51 void WebSocketProxyPrivate::Observe(
54 int type, const content::NotificationSource& source, 52 int type, const content::NotificationSource& source,
55 const content::NotificationDetails& details) { 53 const content::NotificationDetails& details) {
56 listening_port_ = *content::Details<int>(details).ptr(); 54 #if defined(OS_CHROMEOS)
57 WebSocketProxyPrivate::Observe(type, source, details); 55 DCHECK_EQ(chrome::NOTIFICATION_WEB_SOCKET_PROXY_STARTED, type);
56 #else
57 NOTREACHED();
58 #endif
59
60 timer_.Stop(); // Cancel timeout timer.
61 ResolveHost();
58 } 62 }
59 63
60 void WebSocketProxyPrivateGetURLForTCPFunction::Finalize() { 64 void WebSocketProxyPrivate::ResolveHost() {
61 #if defined(OS_CHROMEOS) 65 #if defined(OS_CHROMEOS)
62 if (listening_port_ < 1) 66 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
63 listening_port_ = chromeos::WebSocketProxyController::GetPort(); 67 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
64 StringValue* url = Value::CreateStringValue(std::string( 68 base::Bind(&WebSocketProxyPrivate::ResolveHost, this));
65 "ws://127.0.0.1:" + base::IntToString(listening_port_) + 69 return;
66 "/tcpproxy?" + query_)); 70 }
67 result_.reset(url); 71 DCHECK(resolver_ == NULL);
72 if (g_browser_process) {
73 IOThread* io_thread = g_browser_process->io_thread();
74 if (io_thread && io_thread->globals()) {
75 net::HostResolver* host_resolver =
76 io_thread->globals()->host_resolver.get();
77 if (host_resolver) {
78 resolver_.reset(new net::SingleRequestHostResolver(host_resolver));
79 net::HostResolver::RequestInfo info(net::HostPortPair(
80 hostname_, port_));
81 int result = resolver_->Resolve(info, &addr_,
82 base::Bind(&WebSocketProxyPrivate::OnHostResolution, this),
83 net::BoundNetLog());
84 if (result != net::ERR_IO_PENDING)
85 OnHostResolution(result);
86 return;
87 }
88 }
89 }
90 NOTREACHED();
91 OnHostResolution(net::ERR_UNEXPECTED);
68 #endif 92 #endif
69 WebSocketProxyPrivate::Finalize();
70 } 93 }
71 94
72 bool WebSocketProxyPrivateGetURLForTCPFunction::RunImpl() { 95 bool WebSocketProxyPrivate::RunImpl() {
73 AddRef(); 96 AddRef();
74 bool delay_response = false;
75 result_.reset(Value::CreateStringValue("")); 97 result_.reset(Value::CreateStringValue(""));
76 98
77 #if defined(OS_CHROMEOS) 99 #if defined(OS_CHROMEOS)
78 std::string hostname; 100 bool delay_response = false;
79 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &hostname)); 101
80 int port = -1; 102 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &hostname_));
81 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, &port)); 103 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, &port_));
82 bool do_tls = false; 104
83 DictionaryValue* qualification = NULL;
84 if (args_->GetDictionary(2, &qualification)) {
85 const char kTlsOption[] = "tls";
86 if (qualification->HasKey(kTlsOption)) {
87 EXTENSION_FUNCTION_VALIDATE(qualification->GetBoolean(
88 kTlsOption, &do_tls));
89 }
90 }
91 if (chromeos::WebSocketProxyController::CheckCredentials( 105 if (chromeos::WebSocketProxyController::CheckCredentials(
92 extension_id(), hostname, port, 106 extension_id(), hostname_, port_,
93 do_tls ? chromeos::WebSocketProxyController::TLS_OVER_TCP : 107 do_tls_ ? chromeos::WebSocketProxyController::TLS_OVER_TCP :
94 chromeos::WebSocketProxyController::PLAIN_TCP)) { 108 chromeos::WebSocketProxyController::PLAIN_TCP)) {
95 listening_port_ = chromeos::WebSocketProxyController::GetPort(); 109 listening_port_ = chromeos::WebSocketProxyController::GetPort();
96 if (listening_port_ < 1) { 110 if (listening_port_ < 1) {
97 delay_response = true; 111 delay_response = true;
98 registrar_.Add( 112 registrar_.Add(
99 this, chrome::NOTIFICATION_WEB_SOCKET_PROXY_STARTED, 113 this, chrome::NOTIFICATION_WEB_SOCKET_PROXY_STARTED,
100 content::NotificationService::AllSources()); 114 content::NotificationService::AllSources());
101 } 115 }
102 116 map_["hostname"] = hostname_;
103 std::map<std::string, std::string> map; 117 map_["port"] = base::IntToString(port_);
104 map["hostname"] = hostname; 118 map_["extension_id"] = extension_id();
105 map["port"] = base::IntToString(port);
106 map["extension_id"] = extension_id();
107 map["tls"] = do_tls ? "true" : "false";
108 std::string passport = browser::InternalAuthGeneration::GeneratePassport(
109 "web_socket_proxy", map);
110 query_ = std::string("hostname=") +
111 net::EscapeQueryParamValue(hostname, false) + "&port=" + map["port"] +
112 "&tls=" + map["tls"] + "&passport=" +
113 net::EscapeQueryParamValue(passport, false);
114 } else { 119 } else {
115 error_ = kPermissionDeniedError; 120 error_ = kPermissionDeniedError;
116 return false; 121 return false;
117 } 122 }
118 #endif // defined(OS_CHROMEOS)
119 123
120 if (delay_response) { 124 if (delay_response) {
121 const int kTimeout = 12; 125 const int kTimeout = 12;
122 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(kTimeout), 126 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(kTimeout),
123 this, &WebSocketProxyPrivate::Finalize); 127 this, &WebSocketProxyPrivate::ResolveHost);
124 } else { 128 } else {
125 Finalize(); 129 ResolveHost();
126 } 130 }
131 #else
132 Finalize();
133 #endif
134
127 return true; 135 return true;
128 } 136 }
129 137
138 void WebSocketProxyPrivate::OnHostResolution(int result) {
139 #if defined(OS_CHROMEOS)
140 if (result == 0 && addr_.head() != NULL) {
141 std::string ip = net::NetAddressToString(addr_.head());
142 if (!ip.empty() && ip.find(':') != std::string::npos && ip[0] != '[')
143 ip = '[' + ip + ']';
144 map_["addr"] = ip;
145 }
146 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
147 base::Bind(&WebSocketProxyPrivate::Finalize, this));
148 #endif
149 }
150
151 WebSocketProxyPrivateGetURLForTCPFunction::
152 WebSocketProxyPrivateGetURLForTCPFunction() {
153 }
154
155 WebSocketProxyPrivateGetURLForTCPFunction::
156 ~WebSocketProxyPrivateGetURLForTCPFunction() {
157 }
158
159 void WebSocketProxyPrivateGetURLForTCPFunction::CustomFinalize() {
160 #if defined(OS_CHROMEOS)
161 std::string passport = browser::InternalAuthGeneration::GeneratePassport(
162 "web_socket_proxy", map_);
163 std::string query = std::string("hostname=") +
164 net::EscapeQueryParamValue(hostname_, false) + "&port=" + map_["port"] +
165 "&tls=" + map_["tls"] + "&passport=" +
166 net::EscapeQueryParamValue(passport, false);
167 if (ContainsKey(map_, "addr"))
168 query += std::string("&addr=") + map_["addr"];
169
170 if (listening_port_ < 1)
171 listening_port_ = chromeos::WebSocketProxyController::GetPort();
172 StringValue* url = Value::CreateStringValue(std::string(
173 "ws://127.0.0.1:" + base::IntToString(listening_port_) +
174 "/tcpproxy?" + query));
175 result_.reset(url);
176 #endif
177 }
178
179 bool WebSocketProxyPrivateGetURLForTCPFunction::RunImpl() {
180 #if defined(OS_CHROMEOS)
181 DictionaryValue* qualification = NULL;
182 if (args_->GetDictionary(2, &qualification)) {
183 const char kTlsOption[] = "tls";
184 if (qualification->HasKey(kTlsOption)) {
185 EXTENSION_FUNCTION_VALIDATE(qualification->GetBoolean(
186 kTlsOption, &do_tls_));
187 }
188 }
189 map_["tls"] = do_tls_ ? "true" : "false";
190 #endif
191
192 return WebSocketProxyPrivate::RunImpl();
193 }
194
130 WebSocketProxyPrivateGetPassportForTCPFunction:: 195 WebSocketProxyPrivateGetPassportForTCPFunction::
131 WebSocketProxyPrivateGetPassportForTCPFunction() { 196 WebSocketProxyPrivateGetPassportForTCPFunction() {
132 // This obsolete API uses fixed port to listen websocket connections. 197 // This obsolete API uses fixed port to listen websocket connections.
133 listening_port_ = 10101; 198 listening_port_ = 10101;
134 } 199 }
135 200
136 bool WebSocketProxyPrivateGetPassportForTCPFunction::RunImpl() { 201 WebSocketProxyPrivateGetPassportForTCPFunction::
137 AddRef(); 202 ~WebSocketProxyPrivateGetPassportForTCPFunction() {
138 bool delay_response = false;
139 result_.reset(Value::CreateStringValue(""));
140
141 #if defined(OS_CHROMEOS)
142 std::string hostname;
143 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &hostname));
144 int port = -1;
145 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, &port));
146
147 if (chromeos::WebSocketProxyController::CheckCredentials(
148 extension_id(), hostname, port,
149 chromeos::WebSocketProxyController::PLAIN_TCP)) {
150 listening_port_ = chromeos::WebSocketProxyController::GetPort();
151 if (listening_port_ < 1) {
152 delay_response = true;
153 registrar_.Add(
154 this, chrome::NOTIFICATION_WEB_SOCKET_PROXY_STARTED,
155 content::NotificationService::AllSources());
156 }
157
158 std::map<std::string, std::string> map;
159 map["hostname"] = hostname;
160 map["port"] = base::IntToString(port);
161 map["extension_id"] = extension_id();
162 StringValue* passport = Value::CreateStringValue(
163 browser::InternalAuthGeneration::GeneratePassport(
164 "web_socket_proxy", map));
165 result_.reset(passport);
166 } else {
167 error_ = kPermissionDeniedError;
168 return false;
169 }
170 #endif // defined(OS_CHROMEOS)
171
172 if (delay_response) {
173 const int kTimeout = 3;
174 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(kTimeout),
175 this, &WebSocketProxyPrivateGetPassportForTCPFunction::Finalize);
176 } else {
177 Finalize();
178 }
179 return true;
180 } 203 }
181 204
205 void WebSocketProxyPrivateGetPassportForTCPFunction::CustomFinalize() {
206 #if defined(OS_CHROMEOS)
207 std::string passport =
208 browser::InternalAuthGeneration::GeneratePassport(
209 "web_socket_proxy", map_) + std::string(":");
210 if (ContainsKey(map_, "addr"))
211 passport += map_["addr"];
212 result_.reset(Value::CreateStringValue(passport));
213 #endif
214 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_web_socket_proxy_private_api.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698