Bug 66057 - "Proxy: $http_proxy should influence proxy settings" [p=roc@ocallahan.org (Robert O'Callahan [roc]) / diane@ghic.org (Diane Trout) / ventnor.bugzilla@yahoo.com.au (Michael Ventnor) r=josh r+sr=biesi a1.9=damons]

This commit is contained in:
reed@reedloden.com 2008-01-29 07:58:38 -08:00
Родитель 57365d8d93
Коммит 750557e74d
14 изменённых файлов: 686 добавлений и 21 удалений

Просмотреть файл

@ -104,6 +104,7 @@ XPIDLSRCS = \
nsIStreamTransportService.idl \
nsIStreamLoader.idl \
nsISyncStreamListener.idl \
nsISystemProxySettings.idl \
nsIUnicharStreamLoader.idl \
nsIStandardURL.idl \
nsINestedURI.idl \

Просмотреть файл

@ -0,0 +1,61 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Novell code.
*
* The Initial Developer of the Original Code is Novell.
* Portions created by the Initial Developer are Copyright (C) 2005
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Robert O'Callahan (robert@ocallahan.org)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "nsIURI.idl"
/**
* This interface allows the proxy code to use platform-specific proxy
* settings when the proxy preference is set to "automatic discovery". This service
* acts like a PAC parser to netwerk, but it will actually read the system settings and
* either return the proper proxy data from the autoconfig URL specified in the system proxy,
* or generate proxy data based on the system's manual proxy settings.
*/
[scriptable, uuid(a9f3ae38-b769-4e0b-9317-578388e326c9)]
interface nsISystemProxySettings : nsISupports
{
/**
* If non-empty, use this PAC file. If empty, call getProxyForURI instead.
*/
readonly attribute AUTF8String PACURI;
/**
* See nsIProxyAutoConfig::getProxyForURI; this function behaves exactly
* the same way.
*/
AUTF8String getProxyForURI(in nsIURI aURI);
};

Просмотреть файл

@ -128,6 +128,14 @@ public:
*/
PRBool IsLoading() { return mLoader != nsnull; }
/**
* Returns true if the given URI matches the URI of our PAC file.
*/
PRBool IsPACURI(nsIURI *uri) {
PRBool result;
return mPACURI && NS_SUCCEEDED(mPACURI->Equals(uri, &result)) && result;
}
private:
NS_DECL_NSISTREAMLOADEROBSERVER
NS_DECL_NSIINTERFACEREQUESTOR
@ -162,14 +170,6 @@ private:
*/
void OnLoadFailure();
/**
* Returns true if the given URI matches the URI of our PAC file.
*/
PRBool IsPACURI(nsIURI *uri) {
PRBool result;
return mPACURI && NS_SUCCEEDED(mPACURI->Equals(uri, &result)) && result;
}
private:
nsCOMPtr<nsIProxyAutoConfig> mPAC;
nsCOMPtr<nsIURI> mPACURI;

Просмотреть файл

@ -404,6 +404,12 @@ nsProtocolProxyService::PrefsChanged(nsIPrefBranch *prefBranch,
mProxyConfig = static_cast<ProxyConfig>(type);
reloadPAC = PR_TRUE;
}
if (mProxyConfig == eProxyConfig_System) {
mSystemProxySettings = do_GetService(NS_SYSTEMPROXYSETTINGS_CONTRACTID);
} else {
mSystemProxySettings = nsnull;
}
}
if (!pref || !strcmp(pref, PROXY_PREF("http")))
@ -461,8 +467,10 @@ nsProtocolProxyService::PrefsChanged(nsIPrefBranch *prefBranch,
LoadHostFilters(tempString.get());
}
// We're done if not using PAC or WPAD
if (mProxyConfig != eProxyConfig_PAC && mProxyConfig != eProxyConfig_WPAD)
// We're done if not using something that could give us a PAC URL
// (PAC, WPAD or System)
if (mProxyConfig != eProxyConfig_PAC && mProxyConfig != eProxyConfig_WPAD &&
mProxyConfig != eProxyConfig_System)
return;
// OK, we need to reload the PAC file if:
@ -477,17 +485,20 @@ nsProtocolProxyService::PrefsChanged(nsIPrefBranch *prefBranch,
if (mProxyConfig == eProxyConfig_PAC) {
prefBranch->GetCharPref(PROXY_PREF("autoconfig_url"),
getter_Copies(tempString));
}
else if (mProxyConfig == eProxyConfig_WPAD) {
} else {
// We diverge from the WPAD spec here in that we don't walk the
// hosts's FQDN, stripping components until we hit a TLD. Doing so
// is dangerous in the face of an incomplete list of TLDs, and TLDs
// get added over time. We could consider doing only a single
// substitution of the first component, if that proves to help
// compatibility.
tempString.AssignLiteral(WPAD_URL);
if (mSystemProxySettings)
mSystemProxySettings->GetPACURI(tempString);
else
tempString.AssignLiteral(WPAD_URL);
}
ConfigureFromPAC(tempString);
if (!tempString.IsEmpty())
ConfigureFromPAC(tempString);
}
}
@ -755,13 +766,16 @@ nsProtocolProxyService::ConfigureFromPAC(const nsCString &spec)
return NS_ERROR_OUT_OF_MEMORY;
}
mFailedProxies.Clear();
nsCOMPtr<nsIURI> pacURI;
nsresult rv = NS_NewURI(getter_AddRefs(pacURI), spec);
if (NS_FAILED(rv))
return rv;
if (mPACMan->IsPACURI(pacURI))
return NS_OK;
mFailedProxies.Clear();
return mPACMan->LoadPACFromURI(pacURI);
}
@ -936,8 +950,10 @@ nsProtocolProxyService::GetFailoverForProxy(nsIProxyInfo *aProxy,
nsresult aStatus,
nsIProxyInfo **aResult)
{
// We only support failover when a PAC file is configured.
if (mProxyConfig != eProxyConfig_PAC && mProxyConfig != eProxyConfig_WPAD)
// We only support failover when a PAC file is configured, either
// directly or via system settings
if (mProxyConfig != eProxyConfig_PAC && mProxyConfig != eProxyConfig_WPAD &&
mProxyConfig != eProxyConfig_System)
return NS_ERROR_NOT_AVAILABLE;
// Verify that |aProxy| is one of our nsProxyInfo objects.
@ -1234,15 +1250,37 @@ nsProtocolProxyService::Resolve_Internal(nsIURI *uri,
if (!(info.flags & nsIProtocolHandler::ALLOWS_PROXY))
return NS_OK; // Can't proxy this (filters may not override)
if (mSystemProxySettings) {
nsCAutoString PACURI;
if (NS_SUCCEEDED(mSystemProxySettings->GetPACURI(PACURI)) &&
!PACURI.IsEmpty()) {
// Switch to new PAC file if that setting has changed. If the setting
// hasn't changed, ConfigureFromPAC will exit early.
nsresult rv = ConfigureFromPAC(PACURI);
if (NS_FAILED(rv))
return rv;
} else {
nsCAutoString proxy;
nsresult rv = mSystemProxySettings->GetProxyForURI(uri, proxy);
if (NS_SUCCEEDED(rv)) {
ProcessPACString(proxy, result);
return NS_OK;
}
// no proxy, stop search
return NS_OK;
}
}
// if proxies are enabled and this host:port combo is supposed to use a
// proxy, check for a proxy.
if (mProxyConfig == eProxyConfig_Direct ||
(mProxyConfig == eProxyConfig_Manual &&
!CanUseProxy(uri, info.defaultPort)))
return NS_OK;
// Proxy auto config magic...
if (mProxyConfig == eProxyConfig_PAC || mProxyConfig == eProxyConfig_WPAD) {
if (mProxyConfig == eProxyConfig_PAC || mProxyConfig == eProxyConfig_WPAD ||
mProxyConfig == eProxyConfig_System) {
// Do not query PAC now.
*usePAC = PR_TRUE;
return NS_OK;

Просмотреть файл

@ -47,6 +47,7 @@
#include "nsIProtocolProxyService2.h"
#include "nsIProtocolProxyFilter.h"
#include "nsIProxyAutoConfig.h"
#include "nsISystemProxySettings.h"
#include "nsIProxyInfo.h"
#include "nsIObserver.h"
#include "nsDataHashtable.h"
@ -315,6 +316,7 @@ protected:
eProxyConfig_PAC,
eProxyConfig_Direct4x,
eProxyConfig_WPAD,
eProxyConfig_System, // use system proxy settings if available, otherwise DIRECT
eProxyConfig_Last
};
@ -376,6 +378,7 @@ protected:
PRBool mSOCKSProxyRemoteDNS;
nsRefPtr<nsPACMan> mPACMan; // non-null if we are using PAC
nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;
PRTime mSessionStart;
nsFailedProxyTable mFailedProxies;

Просмотреть файл

@ -326,6 +326,10 @@
#define NS_INCREMENTALDOWNLOAD_CONTRACTID \
"@mozilla.org/network/incremental-download;1"
// component implementing nsISystemProxySettings.
#define NS_SYSTEMPROXYSETTINGS_CONTRACTID \
"@mozilla.org/system-proxy-settings;1"
// service implementing nsIStreamTransportService
#define NS_STREAMTRANSPORTSERVICE_CLASSNAME \
"nsStreamTransportService"

Просмотреть файл

@ -51,6 +51,10 @@ DIRS = \
themes \
$(NULL)
ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT)))
DIRS += system/unixproxy
endif
ifdef MOZ_CRASHREPORTER
DIRS += crashreporter
endif

Просмотреть файл

@ -147,6 +147,14 @@ COMPONENT_LIBS += \
$(NULL)
endif
ifdef MOZ_XUL
ifdef MOZ_ENABLE_GTK2
COMPONENT_LIBS += \
unixproxy \
$(NULL)
endif
endif
ifdef MOZ_PERF_METRICS
EXTRA_DSO_LIBS += mozutil_s
endif

Просмотреть файл

@ -262,6 +262,15 @@
#define XMLEXTRAS_MODULE
#endif
#ifdef MOZ_XUL
#ifdef MOZ_ENABLE_GTK2
#define UNIXPROXY_MODULE MODULE(nsUnixProxyModule)
#endif
#endif
#ifndef UNIXPROXY_MODULE
#define UNIXPROXY_MODULE
#endif
#define XUL_MODULES \
MODULE(xpconnect) \
MATHML_MODULES \
@ -313,6 +322,7 @@
SPELLCHECK_MODULE \
XMLEXTRAS_MODULE \
LAYOUT_DEBUG_MODULE \
UNIXPROXY_MODULE \
/* end of list */
#define MODULE(_name) \

Просмотреть файл

@ -38,6 +38,10 @@
#include "nsGConfService.h"
#include "nsStringAPI.h"
#include "nsCOMPtr.h"
#include "nsComponentManagerUtils.h"
#include "nsISupportsPrimitives.h"
#include "nsIMutableArray.h"
#include <gconf/gconf-client.h>
@ -123,6 +127,37 @@ nsGConfService::GetFloat(const nsACString &aKey, float* aResult)
return NS_OK;
}
NS_IMETHODIMP
nsGConfService::GetStringList(const nsACString &aKey, nsIArray** aResult)
{
nsCOMPtr<nsIMutableArray> items(do_CreateInstance(NS_ARRAY_CONTRACTID));
if (!items)
return NS_ERROR_OUT_OF_MEMORY;
GError* error = nsnull;
GSList* list = gconf_client_get_list(mClient, PromiseFlatCString(aKey).get(),
GCONF_VALUE_STRING, &error);
if (error) {
g_error_free(error);
return NS_ERROR_FAILURE;
}
for (GSList* l = list; l; l = l->next) {
nsCOMPtr<nsISupportsString> obj(do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID));
if (!obj) {
g_slist_free(list);
return NS_ERROR_OUT_OF_MEMORY;
}
obj->SetData(NS_ConvertUTF8toUTF16((const char*)l->data));
items->AppendElement(obj, PR_FALSE);
g_free(l->data);
}
g_slist_free(list);
NS_ADDREF(*aResult = items);
return NS_OK;
}
NS_IMETHODIMP
nsGConfService::SetBool(const nsACString &aKey, PRBool aValue)
{

Просмотреть файл

@ -0,0 +1,65 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is the Mozilla GNOME integration code.
#
# The Initial Developer of the Original Code is
# IBM Corporation.
# Portions created by the Initial Developer are Copyright (C) 2004
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Brian Ryner <bryner@brianryner.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = unixproxy
LIBRARY_NAME = unixproxy
EXPORT_LIBRARY = 1
IS_COMPONENT = 1
MODULE_NAME = nsUnixProxyModule
GRE_MODULE = 1
LIBXUL_LIBRARY = 1
REQUIRES = \
xpcom \
string \
necko \
mozgnome \
$(NULL)
CPPSRCS = \
nsUnixSystemProxySettings.cpp \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -0,0 +1,428 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Robert O'Callahan (robert@ocallahan.org)
* Michael Ventnor (m.ventnor@gmail.com)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISystemProxySettings.h"
#include "nsIGenericFactory.h"
#include "nsIServiceManager.h"
#include "nsIGConfService.h"
#include "nsIURI.h"
#include "nsReadableUtils.h"
#include "nsArrayUtils.h"
#include "prnetdb.h"
#include "prenv.h"
#include "nsPrintfCString.h"
#include "nsNetUtil.h"
#include "nsISupportsPrimitives.h"
class nsUnixSystemProxySettings : public nsISystemProxySettings {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISYSTEMPROXYSETTINGS
nsUnixSystemProxySettings() {}
nsresult Init();
private:
~nsUnixSystemProxySettings() {}
nsCOMPtr<nsIGConfService> mGConf;
PRBool IsProxyMode(const char* aMode);
nsresult SetProxyResultFromGConf(const char* aKeyBase, const char* aType, nsACString& aResult);
nsresult GetProxyFromGConf(const nsACString& aScheme, const nsACString& aHost, PRInt32 aPort, nsACString& aResult);
};
NS_IMPL_ISUPPORTS1(nsUnixSystemProxySettings, nsISystemProxySettings)
nsresult
nsUnixSystemProxySettings::Init()
{
mGConf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
return NS_OK;
}
PRBool
nsUnixSystemProxySettings::IsProxyMode(const char* aMode)
{
nsCAutoString mode;
return NS_SUCCEEDED(mGConf->GetString(NS_LITERAL_CSTRING("/system/proxy/mode"), mode)) &&
mode.EqualsASCII(aMode);
}
nsresult
nsUnixSystemProxySettings::GetPACURI(nsACString& aResult)
{
if (!mGConf || !IsProxyMode("auto")) {
// Return an empty string in this case
aResult.Truncate();
return NS_OK;
}
return mGConf->GetString(NS_LITERAL_CSTRING("/system/proxy/autoconfig_url"),
aResult);
}
static PRBool
IsInNoProxyList(const nsACString& aHost, PRInt32 aPort, const char* noProxyVal)
{
NS_ASSERTION(aPort >= 0, "Negative port?");
nsCAutoString noProxy(noProxyVal);
if (noProxy.EqualsLiteral("*"))
return PR_TRUE;
noProxy.StripWhitespace();
nsReadingIterator<char> pos;
nsReadingIterator<char> end;
noProxy.BeginReading(pos);
noProxy.EndReading(end);
while (pos != end) {
nsReadingIterator<char> last = pos;
nsReadingIterator<char> nextPos;
if (FindCharInReadable(',', last, end)) {
nextPos = last;
++nextPos;
} else {
last = end;
nextPos = end;
}
nsReadingIterator<char> colon = pos;
PRInt32 port = -1;
if (FindCharInReadable(':', colon, last)) {
++colon;
nsDependentCSubstring portStr(colon, last);
nsCAutoString portStr2(portStr); // We need this for ToInteger. String API's suck.
PRInt32 err;
port = portStr2.ToInteger(&err);
if (NS_FAILED(err)) {
port = -2; // don't match any port, so we ignore this pattern
}
--colon;
} else {
colon = last;
}
if (port == -1 || port == aPort) {
nsDependentCSubstring hostStr(pos, colon);
// By using StringEndsWith instead of an equality comparator, we can include sub-domains
if (StringEndsWith(aHost, hostStr, nsCaseInsensitiveCStringComparator()))
return PR_TRUE;
}
pos = nextPos;
}
return PR_FALSE;
}
static void SetProxyResult(const char* aType, const nsACString& aHost,
PRInt32 aPort, nsACString& aResult)
{
aResult.AppendASCII(aType);
aResult.Append(' ');
aResult.Append(aHost);
aResult.Append(':');
aResult.Append(nsPrintfCString("%d", aPort));
}
static nsresult
GetProxyFromEnvironment(const nsACString& aScheme,
const nsACString& aHost,
PRInt32 aPort,
nsACString& aResult)
{
nsCAutoString envVar;
envVar.Append(aScheme);
envVar.AppendLiteral("_proxy");
const char* proxyVal = PR_GetEnv(envVar.get());
if (!proxyVal) {
proxyVal = PR_GetEnv("all_proxy");
if (!proxyVal) {
// Return failure so that the caller can detect the failure and
// fall back to other proxy detection (e.g., WPAD)
return NS_ERROR_FAILURE;
}
}
const char* noProxyVal = PR_GetEnv("no_proxy");
if (noProxyVal && IsInNoProxyList(aHost, aPort, noProxyVal)) {
aResult.AppendLiteral("DIRECT");
return NS_OK;
}
// Use our URI parser to crack the proxy URI
nsCOMPtr<nsIURI> proxyURI;
nsresult rv = NS_NewURI(getter_AddRefs(proxyURI), proxyVal);
NS_ENSURE_SUCCESS(rv, rv);
// Is there a way to specify "socks://" or something in these environment
// variables? I can't find any documentation.
PRBool isHTTP;
rv = proxyURI->SchemeIs("http", &isHTTP);
NS_ENSURE_SUCCESS(rv, rv);
if (!isHTTP)
return NS_ERROR_UNKNOWN_PROTOCOL;
nsCAutoString proxyHost;
rv = proxyURI->GetHost(proxyHost);
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 proxyPort;
rv = proxyURI->GetPort(&proxyPort);
NS_ENSURE_SUCCESS(rv, rv);
SetProxyResult("PROXY", proxyHost, proxyPort, aResult);
return NS_OK;
}
nsresult
nsUnixSystemProxySettings::SetProxyResultFromGConf(const char* aKeyBase, const char* aType,
nsACString& aResult)
{
nsCAutoString hostKey;
hostKey.AppendASCII(aKeyBase);
hostKey.AppendLiteral("host");
nsCAutoString host;
nsresult rv = mGConf->GetString(hostKey, host);
NS_ENSURE_SUCCESS(rv, rv);
if (host.IsEmpty())
return NS_ERROR_FAILURE;
nsCAutoString portKey;
portKey.AppendASCII(aKeyBase);
portKey.AppendLiteral("port");
PRInt32 port;
rv = mGConf->GetInt(portKey, &port);
NS_ENSURE_SUCCESS(rv, rv);
SetProxyResult(aType, host, port, aResult);
return NS_OK;
}
/* copied from nsProtocolProxyService.cpp --- we should share this! */
static void
proxy_MaskIPv6Addr(PRIPv6Addr &addr, PRUint16 mask_len)
{
if (mask_len == 128)
return;
if (mask_len > 96) {
addr.pr_s6_addr32[3] = PR_htonl(
PR_ntohl(addr.pr_s6_addr32[3]) & (~0L << (128 - mask_len)));
}
else if (mask_len > 64) {
addr.pr_s6_addr32[3] = 0;
addr.pr_s6_addr32[2] = PR_htonl(
PR_ntohl(addr.pr_s6_addr32[2]) & (~0L << (96 - mask_len)));
}
else if (mask_len > 32) {
addr.pr_s6_addr32[3] = 0;
addr.pr_s6_addr32[2] = 0;
addr.pr_s6_addr32[1] = PR_htonl(
PR_ntohl(addr.pr_s6_addr32[1]) & (~0L << (64 - mask_len)));
}
else {
addr.pr_s6_addr32[3] = 0;
addr.pr_s6_addr32[2] = 0;
addr.pr_s6_addr32[1] = 0;
addr.pr_s6_addr32[0] = PR_htonl(
PR_ntohl(addr.pr_s6_addr32[0]) & (~0L << (32 - mask_len)));
}
}
static PRBool ConvertToIPV6Addr(const nsACString& aName,
PRIPv6Addr* aAddr)
{
PRNetAddr addr;
if (PR_StringToNetAddr(PromiseFlatCString(aName).get(), &addr) != PR_SUCCESS)
return PR_FALSE;
PRIPv6Addr ipv6;
// convert parsed address to IPv6
if (addr.raw.family == PR_AF_INET) {
// convert to IPv4-mapped address
PR_ConvertIPv4AddrToIPv6(addr.inet.ip, &ipv6);
} else if (addr.raw.family == PR_AF_INET6) {
// copy the address
memcpy(&ipv6, &addr.ipv6.ip, sizeof(PRIPv6Addr));
} else {
return PR_FALSE;
}
return PR_TRUE;
}
static PRBool GConfIgnoreHost(const nsACString& aIgnore,
const nsACString& aHost)
{
if (aIgnore.Equals(aHost, nsCaseInsensitiveCStringComparator()))
return PR_TRUE;
if (aIgnore.First() == '*' &&
StringEndsWith(aHost, nsDependentCSubstring(aIgnore, 1),
nsCaseInsensitiveCStringComparator()))
return PR_TRUE;
PRInt32 mask = 128;
nsReadingIterator<char> start;
nsReadingIterator<char> slash;
nsReadingIterator<char> end;
aIgnore.BeginReading(start);
aIgnore.BeginReading(slash);
aIgnore.EndReading(end);
if (FindCharInReadable('/', slash, end)) {
++slash;
nsDependentCSubstring maskStr(slash, end);
nsCAutoString maskStr2(maskStr);
PRInt32 err;
mask = maskStr2.ToInteger(&err);
if (err != 0) {
mask = 128;
}
--slash;
} else {
slash = end;
}
PRIPv6Addr ignoreAddr, hostAddr;
if (!ConvertToIPV6Addr(aIgnore, &ignoreAddr) ||
!ConvertToIPV6Addr(aHost, &hostAddr))
return PR_FALSE;
proxy_MaskIPv6Addr(ignoreAddr, mask);
proxy_MaskIPv6Addr(hostAddr, mask);
return memcmp(&ignoreAddr, &hostAddr, sizeof(PRIPv6Addr)) == 0;
}
nsresult
nsUnixSystemProxySettings::GetProxyFromGConf(const nsACString& aScheme,
const nsACString& aHost,
PRInt32 aPort,
nsACString& aResult)
{
PRBool masterProxySwitch = PR_FALSE;
mGConf->GetBool(NS_LITERAL_CSTRING("/system/http_proxy/use_http_proxy"), &masterProxySwitch);
if (!IsProxyMode("manual") || !masterProxySwitch) {
aResult.AppendLiteral("DIRECT");
return NS_OK;
}
nsCOMPtr<nsIArray> ignoreList;
if (NS_SUCCEEDED(mGConf->GetStringList(NS_LITERAL_CSTRING("/system/http_proxy/ignore_hosts"),
getter_AddRefs(ignoreList))) && ignoreList) {
PRUint32 len = 0;
ignoreList->GetLength(&len);
for (PRUint32 i = 0; i < len; ++i) {
nsCOMPtr<nsISupportsString> str = do_QueryElementAt(ignoreList, i);
if (str) {
nsAutoString s;
if (NS_SUCCEEDED(str->GetData(s)) && !s.IsEmpty()) {
if (GConfIgnoreHost(NS_ConvertUTF16toUTF8(s), aHost)) {
aResult.AppendLiteral("DIRECT");
return NS_OK;
}
}
}
}
}
PRBool useHttpProxyForAll = PR_FALSE;
// This setting sometimes doesn't exist, don't bail on failure
mGConf->GetBool(NS_LITERAL_CSTRING("/system/http_proxy/use_same_proxy"), &useHttpProxyForAll);
nsresult rv;
if (!useHttpProxyForAll) {
rv = SetProxyResultFromGConf("/system/proxy/socks_", "SOCKS", aResult);
if (NS_SUCCEEDED(rv))
return rv;
}
if (aScheme.LowerCaseEqualsLiteral("http") || useHttpProxyForAll) {
rv = SetProxyResultFromGConf("/system/http_proxy/", "PROXY", aResult);
} else if (aScheme.LowerCaseEqualsLiteral("https")) {
rv = SetProxyResultFromGConf("/system/proxy/secure_", "PROXY", aResult);
} else if (aScheme.LowerCaseEqualsLiteral("ftp")) {
rv = SetProxyResultFromGConf("/system/proxy/ftp_", "PROXY", aResult);
} else {
rv = NS_ERROR_FAILURE;
}
if (NS_FAILED(rv)) {
aResult.AppendLiteral("DIRECT");
}
return NS_OK;
}
nsresult
nsUnixSystemProxySettings::GetProxyForURI(nsIURI* aURI, nsACString& aResult)
{
nsCAutoString scheme;
nsresult rv = aURI->GetScheme(scheme);
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString host;
rv = aURI->GetHost(host);
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 port;
rv = aURI->GetPort(&port);
NS_ENSURE_SUCCESS(rv, rv);
if (!mGConf)
return GetProxyFromEnvironment(scheme, host, port, aResult);
return GetProxyFromGConf(scheme, host, port, aResult);
}
#define NS_UNIXSYSTEMPROXYSERVICE_CID /* 0fa3158c-d5a7-43de-9181-a285e74cf1d4 */\
{ 0x0fa3158c, 0xd5a7, 0x43de, \
{0x91, 0x81, 0xa2, 0x85, 0xe7, 0x4c, 0xf1, 0xd4 } }
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUnixSystemProxySettings, Init)
static const nsModuleComponentInfo components[] = {
{ "Unix System Proxy Settings Service",
NS_UNIXSYSTEMPROXYSERVICE_CID,
NS_SYSTEMPROXYSETTINGS_CONTRACTID,
nsUnixSystemProxySettingsConstructor }
};
NS_IMPL_NSGETMODULE(nsUnixProxyModule, components)

Просмотреть файл

@ -661,6 +661,7 @@ MAKEFILES_xulapp="
toolkit/components/downloads/src/Makefile
toolkit/components/filepicker/Makefile
toolkit/system/gnome/Makefile
toolkit/system/unixproxy/Makefile
toolkit/components/help/Makefile
toolkit/components/history/Makefile
toolkit/components/history/public/Makefile

Просмотреть файл

@ -37,8 +37,9 @@
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "nsIArray.idl"
[scriptable, uuid(01ac7b2e-c07c-465f-b35c-542eaef420a9)]
[scriptable, uuid(5009acae-6973-48c3-b6d6-52c692cc5d9d)]
interface nsIGConfService : nsISupports
{
/* Basic registry access */
@ -47,6 +48,12 @@ interface nsIGConfService : nsISupports
long getInt(in AUTF8String key);
float getFloat(in AUTF8String key);
/*
* Use this to return any list items in GConf, this will return
* an array of UTF16 nsISupportsString's.
*/
nsIArray getStringList(in AUTF8String key);
void setBool(in AUTF8String key, in boolean value);
void setString(in AUTF8String key, in AUTF8String value);
void setInt(in AUTF8String key, in long value);