diff -up xulrunner-10.0/mozilla-beta/toolkit/system/gnome/nsGSettingsService.cpp.682832 xulrunner-10.0/mozilla-beta/toolkit/system/gnome/nsGSettingsService.cpp --- xulrunner-10.0/mozilla-beta/toolkit/system/gnome/nsGSettingsService.cpp.682832 2012-01-18 17:25:24.000000000 +0100 +++ xulrunner-10.0/mozilla-beta/toolkit/system/gnome/nsGSettingsService.cpp 2012-01-23 15:40:14.803170842 +0100 @@ -44,6 +44,8 @@ #include "nsMemory.h" #include "prlink.h" #include "nsComponentManagerUtils.h" +#include "nsIMutableArray.h" +#include "nsISupportsPrimitives.h" #include #include @@ -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 @@ -267,6 +272,49 @@ nsGSettingsCollection::GetInt(const nsAC return NS_OK; } +NS_IMETHODIMP +nsGSettingsCollection::GetStringList(const nsACString& aKey, nsIArray** aResult) +{ + if (!KeyExists(aKey)) + return NS_ERROR_INVALID_ARG; + + nsCOMPtr 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 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; +} + // These types are local to nsGSettingsService::Init, but ISO C++98 doesn't // allow a template (ArrayLength) to be instantiated based on a local type. // Boo-urns! diff -up xulrunner-10.0/mozilla-beta/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp.682832 xulrunner-10.0/mozilla-beta/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp --- xulrunner-10.0/mozilla-beta/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp.682832 2012-01-18 17:25:24.000000000 +0100 +++ xulrunner-10.0/mozilla-beta/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp 2012-01-23 15:39:23.083172529 +0100 @@ -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 mGConf; + nsCOMPtr 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(c nsresult nsUnixSystemProxySettings::GetPACURI(nsACString& aResult) { - if (!mGConf || !IsProxyMode("auto")) { - // Return an empty string in this case - aResult.Truncate(); - return NS_OK; + if (mGSettings) { + nsCOMPtr 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::SetProxyResul 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 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 nsAC 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 nsAC 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 nsACSt 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::GetProxyFromG 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; } @@ -392,6 +446,71 @@ nsUnixSystemProxySettings::GetProxyFromG } nsresult +nsUnixSystemProxySettings::GetProxyFromGSettings(const nsACString& aScheme, + const nsACString& aHost, + PRInt32 aPort, + nsACString& aResult) +{ + nsCOMPtr 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 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 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) { nsCAutoString scheme; @@ -406,10 +525,15 @@ nsUnixSystemProxySettings::GetProxyForUR 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 */\ diff -up xulrunner-10.0/mozilla-beta/xpcom/system/nsIGSettingsService.idl.682832 xulrunner-10.0/mozilla-beta/xpcom/system/nsIGSettingsService.idl --- xulrunner-10.0/mozilla-beta/xpcom/system/nsIGSettingsService.idl.682832 2012-01-18 17:25:28.000000000 +0100 +++ xulrunner-10.0/mozilla-beta/xpcom/system/nsIGSettingsService.idl 2012-01-23 15:32:29.890186340 +0100 @@ -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 : nsISu 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)]