зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
57365d8d93
Коммит
750557e74d
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче