OLD | NEW |
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_proxy_api.h" | 5 #include "chrome/browser/extensions/extension_proxy_api.h" |
6 | 6 |
7 #include "base/string_util.h" | 7 #include "base/string_util.h" |
8 #include "base/stringprintf.h" | |
9 #include "base/values.h" | 8 #include "base/values.h" |
10 #include "chrome/browser/prefs/proxy_config_dictionary.h" | 9 #include "chrome/browser/prefs/proxy_config_dictionary.h" |
11 #include "chrome/browser/profiles/profile.h" | 10 #include "chrome/browser/profiles/profile.h" |
12 #include "chrome/browser/extensions/extension_service.h" | 11 #include "chrome/browser/extensions/extension_service.h" |
13 #include "chrome/common/pref_names.h" | 12 #include "chrome/common/pref_names.h" |
| 13 #include "net/base/host_port_pair.h" |
| 14 #include "net/proxy/proxy_server.h" |
14 | 15 |
15 namespace { | 16 namespace { |
16 | 17 |
17 // The scheme for which to use a manually specified proxy, not of the proxy URI | 18 // The scheme for which to use a manually specified proxy, not of the proxy URI |
18 // itself. | 19 // itself. |
19 enum { | 20 enum { |
20 SCHEME_ALL = 0, | 21 SCHEME_ALL = 0, |
21 SCHEME_HTTP, | 22 SCHEME_HTTP, |
22 SCHEME_HTTPS, | 23 SCHEME_HTTPS, |
23 SCHEME_FTP, | 24 SCHEME_FTP, |
(...skipping 11 matching lines...) Expand all Loading... |
35 | 36 |
36 // The names of the schemes to be used to build the preference value string | 37 // The names of the schemes to be used to build the preference value string |
37 // for manual proxy settings. These must be kept in sync with the SCHEME_* | 38 // for manual proxy settings. These must be kept in sync with the SCHEME_* |
38 // constants. | 39 // constants. |
39 const char* scheme_name[] = { "*error*", | 40 const char* scheme_name[] = { "*error*", |
40 "http", | 41 "http", |
41 "https", | 42 "https", |
42 "ftp", | 43 "ftp", |
43 "socks" }; | 44 "socks" }; |
44 | 45 |
45 } // namespace | |
46 | |
47 COMPILE_ASSERT(SCHEME_MAX == SCHEME_SOCKS, SCHEME_MAX_must_equal_SCHEME_SOCKS); | 46 COMPILE_ASSERT(SCHEME_MAX == SCHEME_SOCKS, SCHEME_MAX_must_equal_SCHEME_SOCKS); |
48 COMPILE_ASSERT(arraysize(field_name) == SCHEME_MAX + 1, | 47 COMPILE_ASSERT(arraysize(field_name) == SCHEME_MAX + 1, |
49 field_name_array_is_wrong_size); | 48 field_name_array_is_wrong_size); |
50 COMPILE_ASSERT(arraysize(scheme_name) == SCHEME_MAX + 1, | 49 COMPILE_ASSERT(arraysize(scheme_name) == SCHEME_MAX + 1, |
51 scheme_name_array_is_wrong_size); | 50 scheme_name_array_is_wrong_size); |
52 COMPILE_ASSERT(SCHEME_ALL == 0, singleProxy_must_be_first_option); | 51 COMPILE_ASSERT(SCHEME_ALL == 0, singleProxy_must_be_first_option); |
53 | 52 |
| 53 // Converts a proxy server description |dict| as passed by the API caller |
| 54 // (e.g. for the http proxy in the rules element) and converts it to a |
| 55 // ProxyServer. Returns true if successful. |
| 56 bool GetProxyServer(const DictionaryValue* dict, |
| 57 net::ProxyServer::Scheme default_scheme, |
| 58 net::ProxyServer* proxy_server) { |
| 59 std::string scheme_string; // optional. |
| 60 dict->GetString("scheme", &scheme_string); |
| 61 |
| 62 net::ProxyServer::Scheme scheme = |
| 63 net::ProxyServer::GetSchemeFromURI(scheme_string); |
| 64 if (scheme == net::ProxyServer::SCHEME_INVALID) |
| 65 scheme = default_scheme; |
| 66 |
| 67 std::string host; |
| 68 if (!dict->GetString("host", &host)) |
| 69 return false; |
| 70 |
| 71 int port; // optional. |
| 72 if (!dict->GetInteger("port", &port)) |
| 73 port = net::ProxyServer::GetDefaultPortForScheme(scheme); |
| 74 |
| 75 *proxy_server = net::ProxyServer(scheme, net::HostPortPair(host, port)); |
| 76 |
| 77 return true; |
| 78 } |
| 79 |
| 80 // Converts a proxy "rules" element passed by the API caller into a proxy |
| 81 // configuration string that can be used by the proxy subsystem (see |
| 82 // proxy_config.h). Returns true if successful. |
| 83 bool GetProxyRules(DictionaryValue* proxy_rules, std::string* out) { |
| 84 if (!proxy_rules) |
| 85 return false; |
| 86 |
| 87 // Local data into which the parameters will be parsed. has_proxy describes |
| 88 // whether a setting was found for the scheme; proxy_dict holds the |
| 89 // DictionaryValues which in turn contain proxy server descriptions, and |
| 90 // proxy_server holds ProxyServer structs containing those descriptions. |
| 91 bool has_proxy[SCHEME_MAX + 1]; |
| 92 DictionaryValue* proxy_dict[SCHEME_MAX + 1]; |
| 93 net::ProxyServer proxy_server[SCHEME_MAX + 1]; |
| 94 |
| 95 // Looking for all possible proxy types is inefficient if we have a |
| 96 // singleProxy that will supersede per-URL proxies, but it's worth it to keep |
| 97 // the code simple and extensible. |
| 98 for (size_t i = 0; i <= SCHEME_MAX; ++i) { |
| 99 has_proxy[i] = proxy_rules->GetDictionary(field_name[i], &proxy_dict[i]); |
| 100 if (has_proxy[i]) { |
| 101 net::ProxyServer::Scheme default_scheme = |
| 102 (i != SCHEME_SOCKS) ? net::ProxyServer::SCHEME_HTTP |
| 103 : net::ProxyServer::SCHEME_SOCKS5; |
| 104 if (!GetProxyServer(proxy_dict[i], default_scheme, &proxy_server[i])) |
| 105 return false; |
| 106 } |
| 107 } |
| 108 |
| 109 // Handle case that only singleProxy is specified. |
| 110 if (has_proxy[SCHEME_ALL]) { |
| 111 for (size_t i = 1; i <= SCHEME_MAX; ++i) { |
| 112 if (has_proxy[i]) { |
| 113 LOG(ERROR) << "Proxy rule for " << field_name[SCHEME_ALL] << " and " |
| 114 << field_name[i] << " cannot be set at the same time."; |
| 115 return false; |
| 116 } |
| 117 } |
| 118 *out = proxy_server[SCHEME_ALL].ToURI(); |
| 119 return true; |
| 120 } |
| 121 |
| 122 // Handle case that anything but singleProxy is specified. |
| 123 |
| 124 // Build the proxy preference string. |
| 125 std::string proxy_pref; |
| 126 for (size_t i = 1; i <= SCHEME_MAX; ++i) { |
| 127 if (has_proxy[i]) { |
| 128 // http=foopy:4010;ftp=socks://foopy2:80 |
| 129 if (!proxy_pref.empty()) |
| 130 proxy_pref.append(";"); |
| 131 proxy_pref.append(scheme_name[i]); |
| 132 proxy_pref.append("="); |
| 133 proxy_pref.append(proxy_server[i].ToURI()); |
| 134 } |
| 135 } |
| 136 |
| 137 *out = proxy_pref; |
| 138 return true; |
| 139 } |
| 140 |
| 141 } // namespace |
| 142 |
54 void ProxySettingsFunction::ApplyPreference(const char* pref_path, | 143 void ProxySettingsFunction::ApplyPreference(const char* pref_path, |
55 Value* pref_value, | 144 Value* pref_value, |
56 bool incognito) { | 145 bool incognito) { |
57 profile()->GetExtensionService()->extension_prefs()-> | 146 profile()->GetExtensionService()->extension_prefs()-> |
58 SetExtensionControlledPref(extension_id(), pref_path, incognito, | 147 SetExtensionControlledPref(extension_id(), pref_path, incognito, |
59 pref_value); | 148 pref_value); |
60 } | 149 } |
61 | 150 |
62 void ProxySettingsFunction::RemovePreference(const char* pref_path, | 151 void ProxySettingsFunction::RemovePreference(const char* pref_path, |
63 bool incognito) { | 152 bool incognito) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 case ProxyPrefs::kModeCount: | 226 case ProxyPrefs::kModeCount: |
138 NOTREACHED(); | 227 NOTREACHED(); |
139 } | 228 } |
140 if (!result_proxy_config) | 229 if (!result_proxy_config) |
141 return false; | 230 return false; |
142 | 231 |
143 ApplyPreference(prefs::kProxy, result_proxy_config, incognito); | 232 ApplyPreference(prefs::kProxy, result_proxy_config, incognito); |
144 return true; | 233 return true; |
145 } | 234 } |
146 | 235 |
147 bool UseCustomProxySettingsFunction::GetProxyServer( | |
148 const DictionaryValue* dict, ProxyServer* proxy_server) { | |
149 dict->GetString("scheme", &proxy_server->scheme); | |
150 EXTENSION_FUNCTION_VALIDATE(dict->GetString("host", &proxy_server->host)); | |
151 dict->GetInteger("port", &proxy_server->port); | |
152 return true; | |
153 } | |
154 | |
155 bool UseCustomProxySettingsFunction::GetProxyRules( | |
156 DictionaryValue* proxy_rules, | |
157 std::string* out) { | |
158 if (!proxy_rules) | |
159 return false; | |
160 | |
161 // Local data into which the parameters will be parsed. has_proxy describes | |
162 // whether a setting was found for the scheme; proxy_dict holds the | |
163 // DictionaryValues which in turn contain proxy server descriptions, and | |
164 // proxy_server holds ProxyServer structs containing those descriptions. | |
165 bool has_proxy[SCHEME_MAX + 1]; | |
166 DictionaryValue* proxy_dict[SCHEME_MAX + 1]; | |
167 ProxyServer proxy_server[SCHEME_MAX + 1]; | |
168 | |
169 // Looking for all possible proxy types is inefficient if we have a | |
170 // singleProxy that will supersede per-URL proxies, but it's worth it to keep | |
171 // the code simple and extensible. | |
172 for (size_t i = 0; i <= SCHEME_MAX; ++i) { | |
173 has_proxy[i] = proxy_rules->GetDictionary(field_name[i], &proxy_dict[i]); | |
174 if (has_proxy[i]) { | |
175 if (!GetProxyServer(proxy_dict[i], &proxy_server[i])) | |
176 return false; | |
177 } | |
178 } | |
179 | |
180 // Handle case that only singleProxy is specified. | |
181 if (has_proxy[SCHEME_ALL]) { | |
182 for (size_t i = 1; i <= SCHEME_MAX; ++i) { | |
183 if (has_proxy[i]) { | |
184 LOG(ERROR) << "Proxy rule for " << field_name[SCHEME_ALL] << " and " | |
185 << field_name[i] << " cannot be set at the same time."; | |
186 return false; | |
187 } | |
188 } | |
189 if (!proxy_server[SCHEME_ALL].scheme.empty()) | |
190 LOG(WARNING) << "Ignoring scheme attribute from proxy server."; | |
191 // Build the proxy preference string. | |
192 std::string proxy_pref; | |
193 proxy_pref.append(proxy_server[SCHEME_ALL].host); | |
194 if (proxy_server[SCHEME_ALL].port != ProxyServer::INVALID_PORT) { | |
195 proxy_pref.append(":"); | |
196 proxy_pref.append(base::StringPrintf("%d", | |
197 proxy_server[SCHEME_ALL].port)); | |
198 } | |
199 *out = proxy_pref; | |
200 return true; | |
201 } | |
202 | |
203 // Handle case the anything but singleProxy is specified. | |
204 | |
205 // Build the proxy preference string. | |
206 std::string proxy_pref; | |
207 for (size_t i = 1; i <= SCHEME_MAX; ++i) { | |
208 if (has_proxy[i]) { | |
209 // http=foopy:4010;ftp=socks://foopy2:80 | |
210 if (!proxy_pref.empty()) | |
211 proxy_pref.append(";"); | |
212 proxy_pref.append(scheme_name[i]); | |
213 proxy_pref.append("="); | |
214 proxy_pref.append(proxy_server[i].scheme); | |
215 proxy_pref.append("://"); | |
216 proxy_pref.append(proxy_server[i].host); | |
217 if (proxy_server[i].port != ProxyServer::INVALID_PORT) { | |
218 proxy_pref.append(":"); | |
219 proxy_pref.append(base::StringPrintf("%d", proxy_server[i].port)); | |
220 } | |
221 } | |
222 } | |
223 | |
224 *out = proxy_pref; | |
225 return true; | |
226 } | |
227 | |
228 bool RemoveCustomProxySettingsFunction::RunImpl() { | 236 bool RemoveCustomProxySettingsFunction::RunImpl() { |
229 bool incognito = false; | 237 bool incognito = false; |
230 args_->GetBoolean(0, &incognito); | 238 if (HasOptionalArgument(0)) { |
| 239 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &incognito)); |
| 240 } |
231 | 241 |
232 RemovePreference(prefs::kProxy, incognito); | 242 RemovePreference(prefs::kProxy, incognito); |
233 return true; | 243 return true; |
234 } | 244 } |
OLD | NEW |