/src/mozilla-central/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | | |
6 | | #include "nsISystemProxySettings.h" |
7 | | #include "mozilla/ModuleUtils.h" |
8 | | #include "nsIServiceManager.h" |
9 | | #include "nsIGConfService.h" |
10 | | #include "nsIURI.h" |
11 | | #include "nsReadableUtils.h" |
12 | | #include "nsArrayUtils.h" |
13 | | #include "prnetdb.h" |
14 | | #include "prenv.h" |
15 | | #include "nsPrintfCString.h" |
16 | | #include "nsNetCID.h" |
17 | | #include "nsNetUtil.h" |
18 | | #include "nsISupportsPrimitives.h" |
19 | | #include "nsIGSettingsService.h" |
20 | | #include "nsInterfaceHashtable.h" |
21 | | #include "mozilla/Attributes.h" |
22 | | #include "nsIURI.h" |
23 | | |
24 | | class nsUnixSystemProxySettings final : public nsISystemProxySettings { |
25 | | public: |
26 | | NS_DECL_ISUPPORTS |
27 | | NS_DECL_NSISYSTEMPROXYSETTINGS |
28 | | |
29 | | nsUnixSystemProxySettings() |
30 | | : mSchemeProxySettings(4) |
31 | 0 | { |
32 | 0 | } |
33 | | nsresult Init(); |
34 | | |
35 | | private: |
36 | 0 | ~nsUnixSystemProxySettings() = default; |
37 | | |
38 | | nsCOMPtr<nsIGConfService> mGConf; |
39 | | nsCOMPtr<nsIGSettingsService> mGSettings; |
40 | | nsCOMPtr<nsIGSettingsCollection> mProxySettings; |
41 | | nsInterfaceHashtable<nsCStringHashKey, nsIGSettingsCollection> mSchemeProxySettings; |
42 | | bool IsProxyMode(const char* aMode); |
43 | | nsresult SetProxyResultFromGConf(const char* aKeyBase, const char* aType, nsACString& aResult); |
44 | | nsresult GetProxyFromGConf(const nsACString& aScheme, const nsACString& aHost, int32_t aPort, nsACString& aResult); |
45 | | nsresult GetProxyFromGSettings(const nsACString& aScheme, const nsACString& aHost, int32_t aPort, nsACString& aResult); |
46 | | nsresult SetProxyResultFromGSettings(const char* aKeyBase, const char* aType, nsACString& aResult); |
47 | | }; |
48 | | |
49 | | NS_IMPL_ISUPPORTS(nsUnixSystemProxySettings, nsISystemProxySettings) |
50 | | |
51 | | NS_IMETHODIMP |
52 | | nsUnixSystemProxySettings::GetMainThreadOnly(bool *aMainThreadOnly) |
53 | 0 | { |
54 | 0 | // dbus prevents us from being threadsafe, but this routine should not block anyhow |
55 | 0 | *aMainThreadOnly = true; |
56 | 0 | return NS_OK; |
57 | 0 | } |
58 | | |
59 | | nsresult |
60 | | nsUnixSystemProxySettings::Init() |
61 | 0 | { |
62 | 0 | mGSettings = do_GetService(NS_GSETTINGSSERVICE_CONTRACTID); |
63 | 0 | if (mGSettings) { |
64 | 0 | mGSettings->GetCollectionForSchema(NS_LITERAL_CSTRING("org.gnome.system.proxy"), |
65 | 0 | getter_AddRefs(mProxySettings)); |
66 | 0 | } |
67 | 0 | if (!mProxySettings) { |
68 | 0 | mGConf = do_GetService(NS_GCONFSERVICE_CONTRACTID); |
69 | 0 | } |
70 | 0 |
|
71 | 0 | return NS_OK; |
72 | 0 | } |
73 | | |
74 | | bool |
75 | | nsUnixSystemProxySettings::IsProxyMode(const char* aMode) |
76 | 0 | { |
77 | 0 | nsAutoCString mode; |
78 | 0 | return NS_SUCCEEDED(mGConf->GetString(NS_LITERAL_CSTRING("/system/proxy/mode"), mode)) && |
79 | 0 | mode.EqualsASCII(aMode); |
80 | 0 | } |
81 | | |
82 | | nsresult |
83 | | nsUnixSystemProxySettings::GetPACURI(nsACString& aResult) |
84 | 0 | { |
85 | 0 | if (mProxySettings) { |
86 | 0 | nsCString proxyMode; |
87 | 0 | // Check if mode is auto |
88 | 0 | nsresult rv = mProxySettings->GetString(NS_LITERAL_CSTRING("mode"), proxyMode); |
89 | 0 | if (rv == NS_OK && proxyMode.EqualsLiteral("auto")) { |
90 | 0 | return mProxySettings->GetString(NS_LITERAL_CSTRING("autoconfig-url"), aResult); |
91 | 0 | } |
92 | 0 | /* The org.gnome.system.proxy schema has been found, but auto mode is not set. |
93 | 0 | * Don't try the GConf and return empty string. */ |
94 | 0 | aResult.Truncate(); |
95 | 0 | return NS_OK; |
96 | 0 | } |
97 | 0 | |
98 | 0 | if (mGConf && IsProxyMode("auto")) { |
99 | 0 | return mGConf->GetString(NS_LITERAL_CSTRING("/system/proxy/autoconfig_url"), |
100 | 0 | aResult); |
101 | 0 | } |
102 | 0 | // Return an empty string when auto mode is not set. |
103 | 0 | aResult.Truncate(); |
104 | 0 | return NS_OK; |
105 | 0 | } |
106 | | |
107 | | static bool |
108 | | IsInNoProxyList(const nsACString& aHost, int32_t aPort, const char* noProxyVal) |
109 | 0 | { |
110 | 0 | NS_ASSERTION(aPort >= 0, "Negative port?"); |
111 | 0 |
|
112 | 0 | nsAutoCString noProxy(noProxyVal); |
113 | 0 | if (noProxy.EqualsLiteral("*")) |
114 | 0 | return true; |
115 | 0 | |
116 | 0 | noProxy.StripWhitespace(); |
117 | 0 |
|
118 | 0 | nsReadingIterator<char> pos; |
119 | 0 | nsReadingIterator<char> end; |
120 | 0 | noProxy.BeginReading(pos); |
121 | 0 | noProxy.EndReading(end); |
122 | 0 | while (pos != end) { |
123 | 0 | nsReadingIterator<char> last = pos; |
124 | 0 | nsReadingIterator<char> nextPos; |
125 | 0 | if (FindCharInReadable(',', last, end)) { |
126 | 0 | nextPos = last; |
127 | 0 | ++nextPos; |
128 | 0 | } else { |
129 | 0 | last = end; |
130 | 0 | nextPos = end; |
131 | 0 | } |
132 | 0 |
|
133 | 0 | nsReadingIterator<char> colon = pos; |
134 | 0 | int32_t port = -1; |
135 | 0 | if (FindCharInReadable(':', colon, last)) { |
136 | 0 | ++colon; |
137 | 0 | nsDependentCSubstring portStr(colon, last); |
138 | 0 | nsAutoCString portStr2(portStr); // We need this for ToInteger. String API's suck. |
139 | 0 | nsresult err; |
140 | 0 | port = portStr2.ToInteger(&err); |
141 | 0 | if (NS_FAILED(err)) { |
142 | 0 | port = -2; // don't match any port, so we ignore this pattern |
143 | 0 | } |
144 | 0 | --colon; |
145 | 0 | } else { |
146 | 0 | colon = last; |
147 | 0 | } |
148 | 0 |
|
149 | 0 | if (port == -1 || port == aPort) { |
150 | 0 | nsDependentCSubstring hostStr(pos, colon); |
151 | 0 | // By using StringEndsWith instead of an equality comparator, we can include sub-domains |
152 | 0 | if (StringEndsWith(aHost, hostStr, nsCaseInsensitiveCStringComparator())) |
153 | 0 | return true; |
154 | 0 | } |
155 | 0 | |
156 | 0 | pos = nextPos; |
157 | 0 | } |
158 | 0 |
|
159 | 0 | return false; |
160 | 0 | } |
161 | | |
162 | | static void SetProxyResult(const char* aType, const nsACString& aHost, |
163 | | int32_t aPort, nsACString& aResult) |
164 | 0 | { |
165 | 0 | aResult.AppendASCII(aType); |
166 | 0 | aResult.Append(' '); |
167 | 0 | aResult.Append(aHost); |
168 | 0 | if (aPort > 0) { |
169 | 0 | aResult.Append(':'); |
170 | 0 | aResult.Append(nsPrintfCString("%d", aPort)); |
171 | 0 | } |
172 | 0 | } |
173 | | |
174 | | static nsresult |
175 | | GetProxyFromEnvironment(const nsACString& aScheme, |
176 | | const nsACString& aHost, |
177 | | int32_t aPort, |
178 | | nsACString& aResult) |
179 | 0 | { |
180 | 0 | nsAutoCString envVar; |
181 | 0 | envVar.Append(aScheme); |
182 | 0 | envVar.AppendLiteral("_proxy"); |
183 | 0 | const char* proxyVal = PR_GetEnv(envVar.get()); |
184 | 0 | if (!proxyVal) { |
185 | 0 | proxyVal = PR_GetEnv("all_proxy"); |
186 | 0 | if (!proxyVal) { |
187 | 0 | // Return failure so that the caller can detect the failure and |
188 | 0 | // fall back to other proxy detection (e.g., WPAD) |
189 | 0 | return NS_ERROR_FAILURE; |
190 | 0 | } |
191 | 0 | } |
192 | 0 | |
193 | 0 | const char* noProxyVal = PR_GetEnv("no_proxy"); |
194 | 0 | if (noProxyVal && IsInNoProxyList(aHost, aPort, noProxyVal)) { |
195 | 0 | aResult.AppendLiteral("DIRECT"); |
196 | 0 | return NS_OK; |
197 | 0 | } |
198 | 0 | |
199 | 0 | // Use our URI parser to crack the proxy URI |
200 | 0 | nsCOMPtr<nsIURI> proxyURI; |
201 | 0 | nsresult rv = NS_NewURI(getter_AddRefs(proxyURI), proxyVal); |
202 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
203 | 0 |
|
204 | 0 | // Is there a way to specify "socks://" or something in these environment |
205 | 0 | // variables? I can't find any documentation. |
206 | 0 | bool isHTTP; |
207 | 0 | rv = proxyURI->SchemeIs("http", &isHTTP); |
208 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
209 | 0 | if (!isHTTP) |
210 | 0 | return NS_ERROR_UNKNOWN_PROTOCOL; |
211 | 0 | |
212 | 0 | nsAutoCString proxyHost; |
213 | 0 | rv = proxyURI->GetHost(proxyHost); |
214 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
215 | 0 |
|
216 | 0 | int32_t proxyPort; |
217 | 0 | rv = proxyURI->GetPort(&proxyPort); |
218 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
219 | 0 |
|
220 | 0 | SetProxyResult("PROXY", proxyHost, proxyPort, aResult); |
221 | 0 | return NS_OK; |
222 | 0 | } |
223 | | |
224 | | nsresult |
225 | | nsUnixSystemProxySettings::SetProxyResultFromGConf(const char* aKeyBase, const char* aType, |
226 | | nsACString& aResult) |
227 | 0 | { |
228 | 0 | nsAutoCString hostKey; |
229 | 0 | hostKey.AppendASCII(aKeyBase); |
230 | 0 | hostKey.AppendLiteral("host"); |
231 | 0 | nsAutoCString host; |
232 | 0 | nsresult rv = mGConf->GetString(hostKey, host); |
233 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
234 | 0 | if (host.IsEmpty()) |
235 | 0 | return NS_ERROR_FAILURE; |
236 | 0 | |
237 | 0 | nsAutoCString portKey; |
238 | 0 | portKey.AppendASCII(aKeyBase); |
239 | 0 | portKey.AppendLiteral("port"); |
240 | 0 | int32_t port; |
241 | 0 | rv = mGConf->GetInt(portKey, &port); |
242 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
243 | 0 |
|
244 | 0 | /* When port is 0, proxy is not considered as enabled even if host is set. */ |
245 | 0 | if (port == 0) |
246 | 0 | return NS_ERROR_FAILURE; |
247 | 0 | |
248 | 0 | SetProxyResult(aType, host, port, aResult); |
249 | 0 | return NS_OK; |
250 | 0 | } |
251 | | |
252 | | nsresult |
253 | | nsUnixSystemProxySettings::SetProxyResultFromGSettings(const char* aKeyBase, const char* aType, |
254 | | nsACString& aResult) |
255 | 0 | { |
256 | 0 | nsDependentCString key(aKeyBase); |
257 | 0 |
|
258 | 0 | nsCOMPtr<nsIGSettingsCollection> proxy_settings = mSchemeProxySettings.Get(key); |
259 | 0 | nsresult rv; |
260 | 0 | if (!proxy_settings) { |
261 | 0 | rv = mGSettings->GetCollectionForSchema(key, getter_AddRefs(proxy_settings)); |
262 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
263 | 0 |
|
264 | 0 | mSchemeProxySettings.Put(key, proxy_settings); |
265 | 0 | } |
266 | 0 |
|
267 | 0 | nsAutoCString host; |
268 | 0 | rv = proxy_settings->GetString(NS_LITERAL_CSTRING("host"), host); |
269 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
270 | 0 | if (host.IsEmpty()) |
271 | 0 | return NS_ERROR_FAILURE; |
272 | 0 | |
273 | 0 | int32_t port; |
274 | 0 | rv = proxy_settings->GetInt(NS_LITERAL_CSTRING("port"), &port); |
275 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
276 | 0 |
|
277 | 0 | /* When port is 0, proxy is not considered as enabled even if host is set. */ |
278 | 0 | if (port == 0) |
279 | 0 | return NS_ERROR_FAILURE; |
280 | 0 | |
281 | 0 | SetProxyResult(aType, host, port, aResult); |
282 | 0 | return NS_OK; |
283 | 0 | } |
284 | | |
285 | | /* copied from nsProtocolProxyService.cpp --- we should share this! */ |
286 | | static void |
287 | | proxy_MaskIPv6Addr(PRIPv6Addr &addr, uint16_t mask_len) |
288 | 0 | { |
289 | 0 | if (mask_len == 128) |
290 | 0 | return; |
291 | 0 | |
292 | 0 | if (mask_len > 96) { |
293 | 0 | addr.pr_s6_addr32[3] = PR_htonl( |
294 | 0 | PR_ntohl(addr.pr_s6_addr32[3]) & (~0L << (128 - mask_len))); |
295 | 0 | } |
296 | 0 | else if (mask_len > 64) { |
297 | 0 | addr.pr_s6_addr32[3] = 0; |
298 | 0 | addr.pr_s6_addr32[2] = PR_htonl( |
299 | 0 | PR_ntohl(addr.pr_s6_addr32[2]) & (~0L << (96 - mask_len))); |
300 | 0 | } |
301 | 0 | else if (mask_len > 32) { |
302 | 0 | addr.pr_s6_addr32[3] = 0; |
303 | 0 | addr.pr_s6_addr32[2] = 0; |
304 | 0 | addr.pr_s6_addr32[1] = PR_htonl( |
305 | 0 | PR_ntohl(addr.pr_s6_addr32[1]) & (~0L << (64 - mask_len))); |
306 | 0 | } |
307 | 0 | else { |
308 | 0 | addr.pr_s6_addr32[3] = 0; |
309 | 0 | addr.pr_s6_addr32[2] = 0; |
310 | 0 | addr.pr_s6_addr32[1] = 0; |
311 | 0 | addr.pr_s6_addr32[0] = PR_htonl( |
312 | 0 | PR_ntohl(addr.pr_s6_addr32[0]) & (~0L << (32 - mask_len))); |
313 | 0 | } |
314 | 0 | } |
315 | | |
316 | | static bool ConvertToIPV6Addr(const nsACString& aName, |
317 | | PRIPv6Addr* aAddr, int32_t* aMask) |
318 | 0 | { |
319 | 0 | PRNetAddr addr; |
320 | 0 | // try to convert hostname to IP |
321 | 0 | if (PR_StringToNetAddr(PromiseFlatCString(aName).get(), &addr) != PR_SUCCESS) |
322 | 0 | return false; |
323 | 0 | |
324 | 0 | // convert parsed address to IPv6 |
325 | 0 | if (addr.raw.family == PR_AF_INET) { |
326 | 0 | // convert to IPv4-mapped address |
327 | 0 | PR_ConvertIPv4AddrToIPv6(addr.inet.ip, aAddr); |
328 | 0 | if (aMask) { |
329 | 0 | if (*aMask <= 32) |
330 | 0 | *aMask += 96; |
331 | 0 | else |
332 | 0 | return false; |
333 | 0 | } |
334 | 0 | } else if (addr.raw.family == PR_AF_INET6) { |
335 | 0 | // copy the address |
336 | 0 | memcpy(aAddr, &addr.ipv6.ip, sizeof(PRIPv6Addr)); |
337 | 0 | } else { |
338 | 0 | return false; |
339 | 0 | } |
340 | 0 | |
341 | 0 | return true; |
342 | 0 | } |
343 | | |
344 | | static bool HostIgnoredByProxy(const nsACString& aIgnore, |
345 | | const nsACString& aHost) |
346 | 0 | { |
347 | 0 | if (aIgnore.Equals(aHost, nsCaseInsensitiveCStringComparator())) |
348 | 0 | return true; |
349 | 0 | |
350 | 0 | if (aIgnore.First() == '*' && |
351 | 0 | StringEndsWith(aHost, nsDependentCSubstring(aIgnore, 1), |
352 | 0 | nsCaseInsensitiveCStringComparator())) |
353 | 0 | return true; |
354 | 0 | |
355 | 0 | int32_t mask = 128; |
356 | 0 | nsReadingIterator<char> start; |
357 | 0 | nsReadingIterator<char> slash; |
358 | 0 | nsReadingIterator<char> end; |
359 | 0 | aIgnore.BeginReading(start); |
360 | 0 | aIgnore.BeginReading(slash); |
361 | 0 | aIgnore.EndReading(end); |
362 | 0 | if (FindCharInReadable('/', slash, end)) { |
363 | 0 | ++slash; |
364 | 0 | nsDependentCSubstring maskStr(slash, end); |
365 | 0 | nsAutoCString maskStr2(maskStr); |
366 | 0 | nsresult err; |
367 | 0 | mask = maskStr2.ToInteger(&err); |
368 | 0 | if (NS_FAILED(err)) { |
369 | 0 | mask = 128; |
370 | 0 | } |
371 | 0 | --slash; |
372 | 0 | } else { |
373 | 0 | slash = end; |
374 | 0 | } |
375 | 0 |
|
376 | 0 | nsDependentCSubstring ignoreStripped(start, slash); |
377 | 0 | PRIPv6Addr ignoreAddr, hostAddr; |
378 | 0 | if (!ConvertToIPV6Addr(ignoreStripped, &ignoreAddr, &mask) || |
379 | 0 | !ConvertToIPV6Addr(aHost, &hostAddr, nullptr)) |
380 | 0 | return false; |
381 | 0 | |
382 | 0 | proxy_MaskIPv6Addr(ignoreAddr, mask); |
383 | 0 | proxy_MaskIPv6Addr(hostAddr, mask); |
384 | 0 |
|
385 | 0 | return memcmp(&ignoreAddr, &hostAddr, sizeof(PRIPv6Addr)) == 0; |
386 | 0 | } |
387 | | |
388 | | nsresult |
389 | | nsUnixSystemProxySettings::GetProxyFromGConf(const nsACString& aScheme, |
390 | | const nsACString& aHost, |
391 | | int32_t aPort, |
392 | | nsACString& aResult) |
393 | 0 | { |
394 | 0 | bool masterProxySwitch = false; |
395 | 0 | mGConf->GetBool(NS_LITERAL_CSTRING("/system/http_proxy/use_http_proxy"), &masterProxySwitch); |
396 | 0 | // if no proxy is set in GConf return NS_ERROR_FAILURE |
397 | 0 | if (!(IsProxyMode("manual") || masterProxySwitch)) { |
398 | 0 | return NS_ERROR_FAILURE; |
399 | 0 | } |
400 | 0 | |
401 | 0 | nsCOMPtr<nsIArray> ignoreList; |
402 | 0 | if (NS_SUCCEEDED(mGConf->GetStringList(NS_LITERAL_CSTRING("/system/http_proxy/ignore_hosts"), |
403 | 0 | getter_AddRefs(ignoreList))) && ignoreList) { |
404 | 0 | uint32_t len = 0; |
405 | 0 | ignoreList->GetLength(&len); |
406 | 0 | for (uint32_t i = 0; i < len; ++i) { |
407 | 0 | nsCOMPtr<nsISupportsString> str = do_QueryElementAt(ignoreList, i); |
408 | 0 | if (str) { |
409 | 0 | nsAutoString s; |
410 | 0 | if (NS_SUCCEEDED(str->GetData(s)) && !s.IsEmpty()) { |
411 | 0 | if (HostIgnoredByProxy(NS_ConvertUTF16toUTF8(s), aHost)) { |
412 | 0 | aResult.AppendLiteral("DIRECT"); |
413 | 0 | return NS_OK; |
414 | 0 | } |
415 | 0 | } |
416 | 0 | } |
417 | 0 | } |
418 | 0 | } |
419 | 0 |
|
420 | 0 | bool useHttpProxyForAll = false; |
421 | 0 | // This setting sometimes doesn't exist, don't bail on failure |
422 | 0 | mGConf->GetBool(NS_LITERAL_CSTRING("/system/http_proxy/use_same_proxy"), &useHttpProxyForAll); |
423 | 0 |
|
424 | 0 | nsresult rv; |
425 | 0 | if (!useHttpProxyForAll) { |
426 | 0 | rv = SetProxyResultFromGConf("/system/proxy/socks_", "SOCKS", aResult); |
427 | 0 | if (NS_SUCCEEDED(rv)) |
428 | 0 | return rv; |
429 | 0 | } |
430 | 0 | |
431 | 0 | if (aScheme.LowerCaseEqualsLiteral("http") || useHttpProxyForAll) { |
432 | 0 | rv = SetProxyResultFromGConf("/system/http_proxy/", "PROXY", aResult); |
433 | 0 | } else if (aScheme.LowerCaseEqualsLiteral("https")) { |
434 | 0 | rv = SetProxyResultFromGConf("/system/proxy/secure_", "PROXY", aResult); |
435 | 0 | } else if (aScheme.LowerCaseEqualsLiteral("ftp")) { |
436 | 0 | rv = SetProxyResultFromGConf("/system/proxy/ftp_", "PROXY", aResult); |
437 | 0 | } else { |
438 | 0 | rv = NS_ERROR_FAILURE; |
439 | 0 | } |
440 | 0 |
|
441 | 0 | return rv; |
442 | 0 | } |
443 | | |
444 | | nsresult |
445 | | nsUnixSystemProxySettings::GetProxyFromGSettings(const nsACString& aScheme, |
446 | | const nsACString& aHost, |
447 | | int32_t aPort, |
448 | | nsACString& aResult) |
449 | 0 | { |
450 | 0 | nsCString proxyMode; |
451 | 0 | nsresult rv = mProxySettings->GetString(NS_LITERAL_CSTRING("mode"), proxyMode); |
452 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
453 | 0 |
|
454 | 0 | // return NS_ERROR_FAILURE when no proxy is set |
455 | 0 | if (!proxyMode.EqualsLiteral("manual")) { |
456 | 0 | return NS_ERROR_FAILURE; |
457 | 0 | } |
458 | 0 | |
459 | 0 | nsCOMPtr<nsIArray> ignoreList; |
460 | 0 | if (NS_SUCCEEDED(mProxySettings->GetStringList(NS_LITERAL_CSTRING("ignore-hosts"), |
461 | 0 | getter_AddRefs(ignoreList))) && ignoreList) { |
462 | 0 | uint32_t len = 0; |
463 | 0 | ignoreList->GetLength(&len); |
464 | 0 | for (uint32_t i = 0; i < len; ++i) { |
465 | 0 | nsCOMPtr<nsISupportsCString> str = do_QueryElementAt(ignoreList, i); |
466 | 0 | if (str) { |
467 | 0 | nsCString s; |
468 | 0 | if (NS_SUCCEEDED(str->GetData(s)) && !s.IsEmpty()) { |
469 | 0 | if (HostIgnoredByProxy(s, aHost)) { |
470 | 0 | aResult.AppendLiteral("DIRECT"); |
471 | 0 | return NS_OK; |
472 | 0 | } |
473 | 0 | } |
474 | 0 | } |
475 | 0 | } |
476 | 0 | } |
477 | 0 |
|
478 | 0 | if (aScheme.LowerCaseEqualsLiteral("http")) { |
479 | 0 | rv = SetProxyResultFromGSettings("org.gnome.system.proxy.http", "PROXY", aResult); |
480 | 0 | } else if (aScheme.LowerCaseEqualsLiteral("https")) { |
481 | 0 | rv = SetProxyResultFromGSettings("org.gnome.system.proxy.https", "PROXY", aResult); |
482 | 0 | /* Try to use HTTP proxy when HTTPS proxy is not explicitly defined */ |
483 | 0 | if (rv != NS_OK) |
484 | 0 | rv = SetProxyResultFromGSettings("org.gnome.system.proxy.http", "PROXY", aResult); |
485 | 0 | } else if (aScheme.LowerCaseEqualsLiteral("ftp")) { |
486 | 0 | rv = SetProxyResultFromGSettings("org.gnome.system.proxy.ftp", "PROXY", aResult); |
487 | 0 | } else { |
488 | 0 | rv = NS_ERROR_FAILURE; |
489 | 0 | } |
490 | 0 | if (rv != NS_OK) { |
491 | 0 | /* If proxy for scheme is not specified, use SOCKS proxy for all schemes */ |
492 | 0 | rv = SetProxyResultFromGSettings("org.gnome.system.proxy.socks", "SOCKS", aResult); |
493 | 0 | } |
494 | 0 |
|
495 | 0 | if (NS_FAILED(rv)) { |
496 | 0 | aResult.AppendLiteral("DIRECT"); |
497 | 0 | } |
498 | 0 |
|
499 | 0 | return NS_OK; |
500 | 0 | } |
501 | | |
502 | | nsresult |
503 | | nsUnixSystemProxySettings::GetProxyForURI(const nsACString & aSpec, |
504 | | const nsACString & aScheme, |
505 | | const nsACString & aHost, |
506 | | const int32_t aPort, |
507 | | nsACString & aResult) |
508 | 0 | { |
509 | 0 | if (mProxySettings) { |
510 | 0 | nsresult rv = GetProxyFromGSettings(aScheme, aHost, aPort, aResult); |
511 | 0 | if (NS_SUCCEEDED(rv)) |
512 | 0 | return rv; |
513 | 0 | } |
514 | 0 | if (mGConf) |
515 | 0 | return GetProxyFromGConf(aScheme, aHost, aPort, aResult); |
516 | 0 | |
517 | 0 | return GetProxyFromEnvironment(aScheme, aHost, aPort, aResult); |
518 | 0 | } |
519 | | |
520 | | #define NS_UNIXSYSTEMPROXYSERVICE_CID /* 0fa3158c-d5a7-43de-9181-a285e74cf1d4 */\ |
521 | | { 0x0fa3158c, 0xd5a7, 0x43de, \ |
522 | | {0x91, 0x81, 0xa2, 0x85, 0xe7, 0x4c, 0xf1, 0xd4 } } |
523 | | |
524 | | NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUnixSystemProxySettings, Init) |
525 | | NS_DEFINE_NAMED_CID(NS_UNIXSYSTEMPROXYSERVICE_CID); |
526 | | |
527 | | static const mozilla::Module::CIDEntry kUnixProxyCIDs[] = { |
528 | | { &kNS_UNIXSYSTEMPROXYSERVICE_CID, false, nullptr, nsUnixSystemProxySettingsConstructor }, |
529 | | { nullptr } |
530 | | }; |
531 | | |
532 | | static const mozilla::Module::ContractIDEntry kUnixProxyContracts[] = { |
533 | | { NS_SYSTEMPROXYSETTINGS_CONTRACTID, &kNS_UNIXSYSTEMPROXYSERVICE_CID }, |
534 | | { nullptr } |
535 | | }; |
536 | | |
537 | | static const mozilla::Module kUnixProxyModule = { |
538 | | mozilla::Module::kVersion, |
539 | | kUnixProxyCIDs, |
540 | | kUnixProxyContracts |
541 | | }; |
542 | | |
543 | | NSMODULE_DEFN(nsUnixProxyModule) = &kUnixProxyModule; |