зеркало из https://github.com/mozilla/gecko-dev.git
Bug 682832 - Don't ignore Gnome 3 proxy settings. r=karlt
This commit is contained in:
Родитель
7e1051e6b3
Коммит
22ddfbac75
|
@ -44,6 +44,8 @@
|
|||
#include "nsMemory.h"
|
||||
#include "prlink.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
@ -60,6 +62,7 @@ typedef struct _GVariant GVariant;
|
|||
# define G_VARIANT_TYPE_STRING ((const GVariantType *) "s")
|
||||
# define G_VARIANT_TYPE_OBJECT_PATH ((const GVariantType *) "o")
|
||||
# define G_VARIANT_TYPE_SIGNATURE ((const GVariantType *) "g")
|
||||
# define G_VARIANT_TYPE_STRING_ARRAY ((const GVariantType *) "as")
|
||||
#endif
|
||||
|
||||
#define GSETTINGS_FUNCTIONS \
|
||||
|
@ -72,6 +75,7 @@ typedef struct _GVariant GVariant;
|
|||
FUNC(g_variant_get_int32, gint32, (GVariant* variant)) \
|
||||
FUNC(g_variant_get_boolean, gboolean, (GVariant* variant)) \
|
||||
FUNC(g_variant_get_string, const char *, (GVariant* value, gsize* length)) \
|
||||
FUNC(g_variant_get_strv, const char **, (GVariant* value, gsize* length)) \
|
||||
FUNC(g_variant_is_of_type, gboolean, (GVariant* value, const GVariantType* type)) \
|
||||
FUNC(g_variant_new_int32, GVariant *, (gint32 value)) \
|
||||
FUNC(g_variant_new_boolean, GVariant *, (gboolean value)) \
|
||||
|
@ -95,6 +99,7 @@ GSETTINGS_FUNCTIONS
|
|||
#define g_variant_get_int32 _g_variant_get_int32
|
||||
#define g_variant_get_boolean _g_variant_get_boolean
|
||||
#define g_variant_get_string _g_variant_get_string
|
||||
#define g_variant_get_strv _g_variant_get_strv
|
||||
#define g_variant_is_of_type _g_variant_is_of_type
|
||||
#define g_variant_new_int32 _g_variant_new_int32
|
||||
#define g_variant_new_boolean _g_variant_new_boolean
|
||||
|
@ -276,6 +281,49 @@ struct nsGSettingsDynamicFunction {
|
|||
nsGSettingsFunc *function;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGSettingsCollection::GetStringList(const nsACString& aKey, nsIArray** aResult)
|
||||
{
|
||||
if (!KeyExists(aKey))
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsCOMPtr<nsIMutableArray> items(do_CreateInstance(NS_ARRAY_CONTRACTID));
|
||||
if (!items) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
GVariant *value = g_settings_get_value(mSettings,
|
||||
PromiseFlatCString(aKey).get());
|
||||
|
||||
if (!g_variant_is_of_type(value, G_VARIANT_TYPE_STRING_ARRAY)) {
|
||||
g_variant_unref(value);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
const gchar ** gs_strings = g_variant_get_strv(value, NULL);
|
||||
if (!gs_strings) {
|
||||
// empty array
|
||||
NS_ADDREF(*aResult = items);
|
||||
g_variant_unref(value);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
const gchar** p_gs_strings = gs_strings;
|
||||
while (*p_gs_strings != NULL)
|
||||
{
|
||||
nsCOMPtr<nsISupportsCString> obj(do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID));
|
||||
if (obj) {
|
||||
obj->SetData(nsDependentCString(*p_gs_strings));
|
||||
items->AppendElement(obj, false);
|
||||
}
|
||||
p_gs_strings++;
|
||||
}
|
||||
g_free(gs_strings);
|
||||
NS_ADDREF(*aResult = items);
|
||||
g_variant_unref(value);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGSettingsService::Init()
|
||||
{
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "nsPrintfCString.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIGSettingsService.h"
|
||||
|
||||
class nsUnixSystemProxySettings : public nsISystemProxySettings {
|
||||
public:
|
||||
|
@ -62,9 +63,12 @@ private:
|
|||
~nsUnixSystemProxySettings() {}
|
||||
|
||||
nsCOMPtr<nsIGConfService> mGConf;
|
||||
nsCOMPtr<nsIGSettingsService> mGSettings;
|
||||
bool 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);
|
||||
nsresult GetProxyFromGSettings(const nsACString& aScheme, const nsACString& aHost, PRInt32 aPort, nsACString& aResult);
|
||||
nsresult SetProxyResultFromGSettings(const char* aKeyBase, const char* aType, nsACString& aResult);
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsUnixSystemProxySettings, nsISystemProxySettings)
|
||||
|
@ -73,6 +77,7 @@ nsresult
|
|||
nsUnixSystemProxySettings::Init()
|
||||
{
|
||||
mGConf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
|
||||
mGSettings = do_GetService(NS_GSETTINGSSERVICE_CONTRACTID);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -87,14 +92,31 @@ nsUnixSystemProxySettings::IsProxyMode(const char* aMode)
|
|||
nsresult
|
||||
nsUnixSystemProxySettings::GetPACURI(nsACString& aResult)
|
||||
{
|
||||
if (!mGConf || !IsProxyMode("auto")) {
|
||||
// Return an empty string in this case
|
||||
aResult.Truncate();
|
||||
return NS_OK;
|
||||
if (mGSettings) {
|
||||
nsCOMPtr<nsIGSettingsCollection> proxy_settings;
|
||||
mGSettings->GetCollectionForSchema(NS_LITERAL_CSTRING("org.gnome.system.proxy"),
|
||||
getter_AddRefs(proxy_settings));
|
||||
if (proxy_settings) {
|
||||
nsCString proxyMode;
|
||||
// Check if mode is auto
|
||||
nsresult rv = proxy_settings->GetString(NS_LITERAL_CSTRING("mode"), proxyMode);
|
||||
if (rv == NS_OK && proxyMode.Equals("auto")) {
|
||||
return proxy_settings->GetString(NS_LITERAL_CSTRING("autoconfig-url"), aResult);
|
||||
}
|
||||
/* The org.gnome.system.proxy schema has been found, but auto mode is not set.
|
||||
* Don't try the GConf and return empty string. */
|
||||
aResult.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return mGConf->GetString(NS_LITERAL_CSTRING("/system/proxy/autoconfig_url"),
|
||||
aResult);
|
||||
if (mGConf && IsProxyMode("auto")) {
|
||||
return mGConf->GetString(NS_LITERAL_CSTRING("/system/proxy/autoconfig_url"),
|
||||
aResult);
|
||||
}
|
||||
// Return an empty string when auto mode is not set.
|
||||
aResult.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -231,7 +253,38 @@ nsUnixSystemProxySettings::SetProxyResultFromGConf(const char* aKeyBase, const c
|
|||
PRInt32 port;
|
||||
rv = mGConf->GetInt(portKey, &port);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
/* When port is 0, proxy is not considered as enabled even if host is set. */
|
||||
if (port == 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
SetProxyResult(aType, host, port, aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsUnixSystemProxySettings::SetProxyResultFromGSettings(const char* aKeyBase, const char* aType,
|
||||
nsACString& aResult)
|
||||
{
|
||||
nsCOMPtr<nsIGSettingsCollection> proxy_settings;
|
||||
nsresult rv = mGSettings->GetCollectionForSchema(nsDependentCString(aKeyBase),
|
||||
getter_AddRefs(proxy_settings));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString host;
|
||||
rv = proxy_settings->GetString(NS_LITERAL_CSTRING("host"), host);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (host.IsEmpty())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRInt32 port;
|
||||
rv = proxy_settings->GetInt(NS_LITERAL_CSTRING("port"), &port);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
/* When port is 0, proxy is not considered as enabled even if host is set. */
|
||||
if (port == 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
SetProxyResult(aType, host, port, aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -271,17 +324,17 @@ static bool ConvertToIPV6Addr(const nsACString& aName,
|
|||
PRIPv6Addr* aAddr)
|
||||
{
|
||||
PRNetAddr addr;
|
||||
// try to convert hostname to IP
|
||||
if (PR_StringToNetAddr(PromiseFlatCString(aName).get(), &addr) != PR_SUCCESS)
|
||||
return 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);
|
||||
PR_ConvertIPv4AddrToIPv6(addr.inet.ip, aAddr);
|
||||
} else if (addr.raw.family == PR_AF_INET6) {
|
||||
// copy the address
|
||||
memcpy(&ipv6, &addr.ipv6.ip, sizeof(PRIPv6Addr));
|
||||
memcpy(aAddr, &addr.ipv6.ip, sizeof(PRIPv6Addr));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -289,8 +342,8 @@ static bool ConvertToIPV6Addr(const nsACString& aName,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool GConfIgnoreHost(const nsACString& aIgnore,
|
||||
const nsACString& aHost)
|
||||
static bool HostIgnoredByProxy(const nsACString& aIgnore,
|
||||
const nsACString& aHost)
|
||||
{
|
||||
if (aIgnore.Equals(aHost, nsCaseInsensitiveCStringComparator()))
|
||||
return true;
|
||||
|
@ -321,8 +374,9 @@ static bool GConfIgnoreHost(const nsACString& aIgnore,
|
|||
slash = end;
|
||||
}
|
||||
|
||||
nsDependentCSubstring ignoreStripped(start, slash);
|
||||
PRIPv6Addr ignoreAddr, hostAddr;
|
||||
if (!ConvertToIPV6Addr(aIgnore, &ignoreAddr) ||
|
||||
if (!ConvertToIPV6Addr(ignoreStripped, &ignoreAddr) ||
|
||||
!ConvertToIPV6Addr(aHost, &hostAddr))
|
||||
return false;
|
||||
|
||||
|
@ -355,7 +409,7 @@ nsUnixSystemProxySettings::GetProxyFromGConf(const nsACString& aScheme,
|
|||
if (str) {
|
||||
nsAutoString s;
|
||||
if (NS_SUCCEEDED(str->GetData(s)) && !s.IsEmpty()) {
|
||||
if (GConfIgnoreHost(NS_ConvertUTF16toUTF8(s), aHost)) {
|
||||
if (HostIgnoredByProxy(NS_ConvertUTF16toUTF8(s), aHost)) {
|
||||
aResult.AppendLiteral("DIRECT");
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -391,6 +445,71 @@ nsUnixSystemProxySettings::GetProxyFromGConf(const nsACString& aScheme,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsUnixSystemProxySettings::GetProxyFromGSettings(const nsACString& aScheme,
|
||||
const nsACString& aHost,
|
||||
PRInt32 aPort,
|
||||
nsACString& aResult)
|
||||
{
|
||||
nsCOMPtr<nsIGSettingsCollection> proxy_settings;
|
||||
nsresult rv;
|
||||
|
||||
rv = mGSettings->GetCollectionForSchema(NS_LITERAL_CSTRING("org.gnome.system.proxy"),
|
||||
getter_AddRefs(proxy_settings));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCString proxyMode;
|
||||
rv = proxy_settings->GetString(NS_LITERAL_CSTRING("mode"), proxyMode);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!proxyMode.Equals("manual")) {
|
||||
aResult.AppendLiteral("DIRECT");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIArray> ignoreList;
|
||||
if (NS_SUCCEEDED(proxy_settings->GetStringList(NS_LITERAL_CSTRING("ignore-hosts"),
|
||||
getter_AddRefs(ignoreList))) && ignoreList) {
|
||||
PRUint32 len = 0;
|
||||
ignoreList->GetLength(&len);
|
||||
for (PRUint32 i = 0; i < len; ++i) {
|
||||
nsCOMPtr<nsISupportsCString> str = do_QueryElementAt(ignoreList, i);
|
||||
if (str) {
|
||||
nsCString s;
|
||||
if (NS_SUCCEEDED(str->GetData(s)) && !s.IsEmpty()) {
|
||||
if (HostIgnoredByProxy(s, aHost)) {
|
||||
aResult.AppendLiteral("DIRECT");
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aScheme.LowerCaseEqualsLiteral("http")) {
|
||||
rv = SetProxyResultFromGSettings("org.gnome.system.proxy.http", "PROXY", aResult);
|
||||
} else if (aScheme.LowerCaseEqualsLiteral("https")) {
|
||||
rv = SetProxyResultFromGSettings("org.gnome.system.proxy.https", "PROXY", aResult);
|
||||
/* Try to use HTTP proxy when HTTPS proxy is not explicitly defined */
|
||||
if (rv != NS_OK)
|
||||
rv = SetProxyResultFromGSettings("org.gnome.system.proxy.http", "PROXY", aResult);
|
||||
} else if (aScheme.LowerCaseEqualsLiteral("ftp")) {
|
||||
rv = SetProxyResultFromGSettings("org.gnome.system.proxy.ftp", "PROXY", aResult);
|
||||
} else {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
if (rv != NS_OK) {
|
||||
/* If proxy for scheme is not specified, use SOCKS proxy for all schemes */
|
||||
rv = SetProxyResultFromGSettings("org.gnome.system.proxy.socks", "SOCKS", aResult);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
aResult.AppendLiteral("DIRECT");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsUnixSystemProxySettings::GetProxyForURI(nsIURI* aURI, nsACString& aResult)
|
||||
{
|
||||
|
@ -406,10 +525,15 @@ nsUnixSystemProxySettings::GetProxyForURI(nsIURI* aURI, nsACString& aResult)
|
|||
rv = aURI->GetPort(&port);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!mGConf)
|
||||
return GetProxyFromEnvironment(scheme, host, port, aResult);
|
||||
if (mGSettings) {
|
||||
rv = GetProxyFromGSettings(scheme, host, port, aResult);
|
||||
if (rv == NS_OK)
|
||||
return rv;
|
||||
}
|
||||
if (mGConf)
|
||||
return GetProxyFromGConf(scheme, host, port, aResult);
|
||||
|
||||
return GetProxyFromGConf(scheme, host, port, aResult);
|
||||
return GetProxyFromEnvironment(scheme, host, port, aResult);
|
||||
}
|
||||
|
||||
#define NS_UNIXSYSTEMPROXYSERVICE_CID /* 0fa3158c-d5a7-43de-9181-a285e74cf1d4 */\
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include "nsISupports.idl"
|
||||
#include "nsIArray.idl"
|
||||
|
||||
[scriptable, uuid(09637d3c-3c07-40b4-aff9-1d2a0f046f3c)]
|
||||
[scriptable, uuid(16d5b0ed-e756-4f1b-a8ce-9132e869acd8)]
|
||||
interface nsIGSettingsCollection : nsISupports
|
||||
{
|
||||
void setString(in AUTF8String key, in AUTF8String value);
|
||||
|
@ -48,6 +48,7 @@ interface nsIGSettingsCollection : nsISupports
|
|||
AUTF8String getString(in AUTF8String key);
|
||||
boolean getBoolean(in AUTF8String key);
|
||||
long getInt(in AUTF8String key);
|
||||
nsIArray getStringList(in AUTF8String key);
|
||||
};
|
||||
|
||||
[scriptable, uuid(849c088b-57d1-4f24-b7b2-3dc4acb04c0a)]
|
||||
|
|
Загрузка…
Ссылка в новой задаче