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

Side by Side Diff: chrome_frame/np_proxy_service.cc

Issue 218019: Initial import of the Chrome Frame codebase. Integration in chrome.gyp coming... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 11 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 | Annotate | Revision Log
« no previous file with comments | « chrome_frame/np_proxy_service.h ('k') | chrome_frame/npapi_url_request.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/string_util.h"
6 #include "chrome/common/automation_constants.h"
7 #include "chrome/common/json_value_serializer.h"
8 #include "chrome_frame/np_proxy_service.h"
9 #include "chrome_frame/np_browser_functions.h"
10
11 #include "net/proxy/proxy_config.h"
12
13 #include "third_party/xulrunner-sdk/win/include/xpcom/nsXPCOM.h"
14 #include "third_party/xulrunner-sdk/win/include/xpcom/nsIObserverService.h"
15 #include "third_party/xulrunner-sdk/win/include/xpcom/nsISupportsUtils.h"
16 #include "third_party/xulrunner-sdk/win/include/xpcom/nsStringAPI.h"
17
18 ASSOCIATE_IID(NS_IOBSERVERSERVICE_IID_STR, nsIObserverService);
19 ASSOCIATE_IID(NS_IPREFBRANCH_IID_STR, nsIPrefBranch);
20
21 // Firefox preference names.
22 const char* kProxyObserverRoot = "network.";
23 const char* kProxyObserverBranch = "proxy.";
24 const char* kProxyType = "proxy.type";
25 const char* kProxyAutoconfigUrl = "proxy.autoconfig_url";
26 const char* kProxyBypassList = "proxy.no_proxies_on";
27
28 const int kInvalidIntPref = -1;
29
30 // These are the proxy schemes that Chrome knows about at the moment.
31 // SOCKS is a notable ommission here, this will need to be updated when
32 // Chrome supports SOCKS proxies.
33 const NpProxyService::ProxyNames NpProxyService::kProxyInfo[] = {
34 {"http", "proxy.http", "proxy.http_port"},
35 {"https", "proxy.ssl", "proxy.ssl_port"},
36 {"ftp", "proxy.ftp", "proxy.ftp_port"} };
37
38 NpProxyService::NpProxyService(void)
39 : type_(PROXY_CONFIG_LAST), auto_detect_(false), no_proxy_(false),
40 system_config_(false), automation_client_(NULL) {
41 }
42
43 NpProxyService::~NpProxyService(void) {
44 }
45
46 bool NpProxyService::Initialize(NPP instance,
47 ChromeFrameAutomationClient* automation_client) {
48 DCHECK(automation_client);
49 automation_client_ = automation_client;
50
51 // Get the pref service
52 bool result = false;
53 ScopedNsPtr<nsISupports> service_manager_base;
54 npapi::GetValue(instance, NPNVserviceManager, service_manager_base.Receive());
55 if (service_manager_base != NULL) {
56 service_manager_.QueryFrom(service_manager_base);
57 if (service_manager_.get() == NULL) {
58 DLOG(ERROR) << "Failed to create ServiceManager. This only works in FF.";
59 } else {
60 service_manager_->GetServiceByContractID(
61 NS_PREFSERVICE_CONTRACTID, NS_GET_IID(nsIPrefService),
62 reinterpret_cast<void**>(pref_service_.Receive()));
63 if (!pref_service_) {
64 DLOG(ERROR) << "Failed to create PreferencesService";
65 } else {
66 result = InitializePrefBranch(pref_service_);
67 }
68 }
69 }
70 return result;
71 }
72
73 bool NpProxyService::InitializePrefBranch(nsIPrefService* pref_service) {
74 DCHECK(pref_service);
75 // Note that we cannot persist a reference to the pref branch because we
76 // also act as an observer of changes to the branch. As per
77 // nsIPrefBranch2.h, this would result in a circular reference between us
78 // and the pref branch, which can impede cleanup. There are workarounds,
79 // but let's try just not caching the branch reference for now.
80 bool result = false;
81 ScopedNsPtr<nsIPrefBranch> pref_branch;
82
83 pref_service->ReadUserPrefs(nsnull);
84 pref_service->GetBranch(kProxyObserverRoot, pref_branch.Receive());
85
86 if (!pref_branch) {
87 DLOG(ERROR) << "Failed to get nsIPrefBranch";
88 } else {
89 if (!ReadProxySettings(pref_branch.get())) {
90 DLOG(ERROR) << "Could not read proxy settings.";
91 } else {
92 observer_pref_branch_.QueryFrom(pref_branch);
93 if (!observer_pref_branch_) {
94 DLOG(ERROR) << "Failed to get observer nsIPrefBranch2";
95 } else {
96 nsresult res = observer_pref_branch_->AddObserver(kProxyObserverBranch,
97 this, PR_FALSE);
98 result = NS_SUCCEEDED(res);
99 }
100 }
101 }
102 return result;
103 }
104
105 bool NpProxyService::UnInitialize() {
106 // Fail early if this was never created - we may not be running on FF.
107 if (!pref_service_)
108 return false;
109
110 // Unhook ourselves as an observer.
111 nsresult res = NS_ERROR_FAILURE;
112 if (observer_pref_branch_)
113 res = observer_pref_branch_->RemoveObserver(kProxyObserverBranch, this);
114
115 return NS_SUCCEEDED(res);
116 }
117
118 NS_IMETHODIMP NpProxyService::Observe(nsISupports* subject, const char* topic,
119 const PRUnichar* data) {
120 if (!subject || !topic) {
121 NOTREACHED();
122 return NS_ERROR_UNEXPECTED;
123 }
124
125 std::string topic_str(topic);
126 nsresult res = NS_OK;
127 if (topic_str == NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) {
128 // Looks like our proxy settings changed. We need to reload!
129 // I have observed some extremely strange behaviour here. Specifically,
130 // we are supposed to be able to QI |subject| and get from it an
131 // nsIPrefBranch from which we can query new values. This has erratic
132 // behaviour, specifically subject starts returning null on all member
133 // queries. So I am using the cached nsIPrefBranch2 (that we used to add
134 // the observer) to do the querying.
135 if (NS_SUCCEEDED(res)) {
136 if (!ReadProxySettings(observer_pref_branch_)) {
137 res = NS_ERROR_UNEXPECTED;
138 } else {
139 std::string proxy_settings;
140 if (GetProxyValueJSONString(&proxy_settings))
141 automation_client_->SetProxySettings(proxy_settings);
142 }
143 }
144 } else {
145 NOTREACHED();
146 }
147
148 return res;
149 }
150
151 std::string NpProxyService::GetStringPref(nsIPrefBranch* pref_branch,
152 const char* pref_name) {
153 nsCString pref_string;
154 std::string result;
155 nsresult rv = pref_branch->GetCharPref(pref_name, getter_Copies(pref_string));
156 if (SUCCEEDED(rv) && pref_string.get()) {
157 result = pref_string.get();
158 }
159 return result;
160 }
161
162 int NpProxyService::GetIntPref(nsIPrefBranch* pref_branch,
163 const char* pref_name) {
164 PRInt32 pref_int;
165 int result = kInvalidIntPref;
166 nsresult rv = pref_branch->GetIntPref(pref_name, &pref_int);
167 if (SUCCEEDED(rv)) {
168 result = pref_int;
169 }
170 return result;
171 }
172
173 bool NpProxyService::GetBoolPref(nsIPrefBranch* pref_branch,
174 const char* pref_name) {
175 PRBool pref_bool;
176 bool result = false;
177 nsresult rv = pref_branch->GetBoolPref(pref_name, &pref_bool);
178 if (SUCCEEDED(rv)) {
179 result = pref_bool == PR_TRUE;
180 }
181 return result;
182 }
183
184 void NpProxyService::Reset() {
185 type_ = PROXY_CONFIG_LAST;
186 auto_detect_ = false;
187 no_proxy_ = false;
188 system_config_ = false;
189 manual_proxies_.clear();
190 pac_url_.clear();
191 proxy_bypass_list_.clear();
192 }
193
194 bool NpProxyService::ReadProxySettings(nsIPrefBranch* pref_branch) {
195 DCHECK(pref_branch);
196
197 // Clear our current settings.
198 Reset();
199 type_ = GetIntPref(pref_branch, kProxyType);
200 if (type_ == kInvalidIntPref) {
201 NOTREACHED();
202 return false;
203 }
204
205 switch (type_) {
206 case PROXY_CONFIG_DIRECT:
207 case PROXY_CONFIG_DIRECT4X:
208 no_proxy_ = true;
209 break;
210 case PROXY_CONFIG_SYSTEM:
211 // _SYSTEM is documented as "Use system settings if available, otherwise
212 // DIRECT". It isn't clear under what circumstances system settings would
213 // be unavailable, but I'll special-case this nonetheless and have
214 // GetProxyValueJSONString() return empty if we get this proxy type.
215 DLOG(WARNING) << "Received PROXY_CONFIG_SYSTEM proxy type.";
216 system_config_ = true;
217 break;
218 case PROXY_CONFIG_WPAD:
219 auto_detect_ = true;
220 break;
221 case PROXY_CONFIG_PAC:
222 pac_url_ = GetStringPref(pref_branch, kProxyAutoconfigUrl);
223 break;
224 case PROXY_CONFIG_MANUAL:
225 // Read in the values for each of the known schemes.
226 for (int i = 0; i < arraysize(kProxyInfo); i++) {
227 ManualProxyEntry entry;
228 entry.url = GetStringPref(pref_branch, kProxyInfo[i].pref_name);
229 entry.port = GetIntPref(pref_branch, kProxyInfo[i].port_pref_name);
230 if (!entry.url.empty() && entry.port != kInvalidIntPref) {
231 entry.scheme = kProxyInfo[i].chrome_scheme;
232 manual_proxies_.push_back(entry);
233 }
234 }
235
236 // Also pick up the list of URLs we bypass proxies for.
237 proxy_bypass_list_ = GetStringPref(pref_branch, kProxyBypassList);
238 break;
239 default:
240 NOTREACHED();
241 return false;
242 }
243 return true;
244 }
245
246 DictionaryValue* NpProxyService::BuildProxyValueSet() {
247 scoped_ptr<DictionaryValue> proxy_settings_value(new DictionaryValue);
248
249 if (auto_detect_) {
250 proxy_settings_value->SetBoolean(automation::kJSONProxyAutoconfig,
251 auto_detect_);
252 }
253
254 if (no_proxy_) {
255 proxy_settings_value->SetBoolean(automation::kJSONProxyNoProxy, no_proxy_);
256 }
257
258 if (!pac_url_.empty()) {
259 proxy_settings_value->SetString(automation::kJSONProxyPacUrl, pac_url_);
260 }
261
262 if (!proxy_bypass_list_.empty()) {
263 proxy_settings_value->SetString(automation::kJSONProxyBypassList,
264 proxy_bypass_list_);
265 }
266
267 // Fill in the manual proxy settings. Build a string representation that
268 // corresponds to the format of the input parameter to
269 // ProxyConfig::ProxyRules::ParseFromString.
270 std::string manual_proxy_settings;
271 ManualProxyList::const_iterator iter(manual_proxies_.begin());
272 for (; iter != manual_proxies_.end(); iter++) {
273 DCHECK(!iter->scheme.empty());
274 DCHECK(!iter->url.empty());
275 DCHECK(iter->port != kInvalidIntPref);
276 manual_proxy_settings += iter->scheme;
277 manual_proxy_settings += "=";
278 manual_proxy_settings += iter->url;
279 manual_proxy_settings += ":";
280 manual_proxy_settings += IntToString(iter->port);
281 manual_proxy_settings += ";";
282 }
283
284 if (!manual_proxy_settings.empty()) {
285 proxy_settings_value->SetString(automation::kJSONProxyServer,
286 manual_proxy_settings);
287 }
288
289 return proxy_settings_value.release();
290 }
291
292 bool NpProxyService::GetProxyValueJSONString(std::string* output) {
293 DCHECK(output);
294 output->empty();
295
296 // If we detected a PROXY_CONFIG_SYSTEM config type or failed to obtain the
297 // pref service then return false here to make Chrome continue using its
298 // default proxy settings.
299 if (system_config_ || !pref_service_)
300 return false;
301
302 scoped_ptr<DictionaryValue> proxy_settings_value(BuildProxyValueSet());
303
304 JSONStringValueSerializer serializer(output);
305 return serializer.Serialize(*static_cast<Value*>(proxy_settings_value.get()));
306 }
OLDNEW
« no previous file with comments | « chrome_frame/np_proxy_service.h ('k') | chrome_frame/npapi_url_request.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698