toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial