From: Wolfgang Rosenauer <wr@rosenauer.org>
Subject: Add the option to use libproxy for system proxy settings
References:
https://bugzilla.mozilla.org/show_bug.cgi?id=517655

diff --git a/config/autoconf.mk.in b/config/autoconf.mk.in
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -537,16 +537,20 @@ FT2_CFLAGS             = @FT2_CFLAGS@
 FT2_LIBS               = @FT2_LIBS@
 
 MOZ_PANGO_CFLAGS        = @MOZ_PANGO_CFLAGS@
 MOZ_PANGO_LIBS          = @MOZ_PANGO_LIBS@
 
 MOZ_XIE_LIBS		= @MOZ_XIE_LIBS@
 XT_LIBS			= @XT_LIBS@
 
+MOZ_LIBPROXY_CFLAGS     = @MOZ_LIBPROXY_CFLAGS@
+MOZ_LIBPROXY_LIBS       = @MOZ_LIBPROXY_LIBS@
+MOZ_ENABLE_LIBPROXY     = @MOZ_ENABLE_LIBPROXY@
+
 MOZ_LIBNOTIFY_CFLAGS	= @MOZ_LIBNOTIFY_CFLAGS@
 MOZ_LIBNOTIFY_LIBS	= @MOZ_LIBNOTIFY_LIBS@
 MOZ_ENABLE_LIBNOTIFY	= @MOZ_ENABLE_LIBNOTIFY@
 
 GLIB_CFLAGS	= @GLIB_CFLAGS@
 GLIB_LIBS	= @GLIB_LIBS@
 GLIB_GMODULE_LIBS	= @GLIB_GMODULE_LIBS@
 LIBIDL_CFLAGS = @LIBIDL_CFLAGS@
diff --git a/config/system-headers b/config/system-headers
--- a/config/system-headers
+++ b/config/system-headers
@@ -1012,8 +1012,11 @@ hunspell.hxx
 #if MOZ_NATIVE_BZ2==1
 bzlib.h
 #endif
 #if MOZ_PLATFORM_MAEMO==5
 hildon-uri.h
 hildon-mime.h
 libosso.h
 #endif
+#ifdef MOZ_ENABLE_LIBPROXY
+proxy.h
+#endif
diff --git a/configure.in b/configure.in
--- a/configure.in
+++ b/configure.in
@@ -5289,16 +5289,39 @@ then
         AC_DEFINE(MOZ_ENABLE_DBUS)
     fi
 fi
 AC_SUBST(MOZ_ENABLE_DBUS)
 AC_SUBST(MOZ_DBUS_GLIB_CFLAGS)
 AC_SUBST(MOZ_DBUS_GLIB_LIBS)
 
 dnl ========================================================
+dnl = libproxy support
+dnl ========================================================
+
+if test "$MOZ_ENABLE_GTK2"
+then
+    MOZ_ENABLE_LIBPROXY=
+
+    MOZ_ARG_ENABLE_BOOL(libproxy,
+    [  --enable-libproxy         Enable libproxy support ],
+    MOZ_ENABLE_LIBPROXY=1,
+    MOZ_ENABLE_LIBPROXY=)
+
+    if test "$MOZ_ENABLE_LIBPROXY"
+    then
+        PKG_CHECK_MODULES(MOZ_LIBPROXY, libproxy-1.0)
+        AC_DEFINE(MOZ_ENABLE_LIBPROXY)
+    fi
+fi
+AC_SUBST(MOZ_ENABLE_LIBPROXY)
+AC_SUBST(MOZ_LIBPROXY_CFLAGS)
+AC_SUBST(MOZ_LIBPROXY_LIBS)
+
+dnl ========================================================
 dnl = libnotify support
 dnl ========================================================
 
 if test "$MOZ_ENABLE_GTK2"
 then
     MOZ_ENABLE_LIBNOTIFY=1
 
     MOZ_ARG_DISABLE_BOOL(libnotify,
diff --git a/toolkit/library/Makefile.in b/toolkit/library/Makefile.in
--- a/toolkit/library/Makefile.in
+++ b/toolkit/library/Makefile.in
@@ -243,16 +243,20 @@ endif
 ifdef MOZ_TREE_FREETYPE
 EXTRA_DSO_LDOPTS += $(FT2_LIBS)
 endif
 
 ifdef MOZ_ENABLE_STARTUP_NOTIFICATION
 EXTRA_DSO_LDOPTS += $(MOZ_STARTUP_NOTIFICATION_LIBS)
 endif
 
+ifdef MOZ_ENABLE_LIBPROXY
+EXTRA_DSO_LDOPTS += $(MOZ_LIBPROXY_LIBS)
+endif
+
 ifeq ($(OS_ARCH),BeOS)
 EXTRA_DSO_LDOPTS += -lbe -ltracker
 endif
 
 ifeq ($(OS_ARCH),SunOS)
 EXTRA_DSO_LDOPTS += -lelf -ldemangle -lCstd
 endif
 
diff --git a/toolkit/system/unixproxy/Makefile.in b/toolkit/system/unixproxy/Makefile.in
--- a/toolkit/system/unixproxy/Makefile.in
+++ b/toolkit/system/unixproxy/Makefile.in
@@ -15,16 +15,17 @@
 #
 # 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>
+#  Wolfgang Rosenauer <wr@rosenauer.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
@@ -53,15 +54,30 @@ LIBXUL_LIBRARY  = 1
 
 REQUIRES = \
         xpcom \
         string \
         necko \
         mozgnome \
         $(NULL)
 
-EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS)
+EXTRA_DSO_LDOPTS += \
+               $(MOZ_LIBPROXY_LIBS) \
+               $(MOZ_COMPONENT_LIBS) \
+               $(NULL)
+
+ifdef MOZ_ENABLE_LIBPROXY
+
+CPPSRCS = \
+       nsLibProxySettings.cpp \
+        $(NULL)
+
+CXXFLAGS += $(MOZ_LIBPROXY_CFLAGS)
+
+else # MOZ_ENABLE_LIBPROXY
 
 CPPSRCS = \
         nsUnixSystemProxySettings.cpp \
         $(NULL)
 
+endif # MOZ_ENABLE_LIBPROXY
+
 include $(topsrcdir)/config/rules.mk
diff --git a/toolkit/system/unixproxy/nsLibProxySettings.cpp b/toolkit/system/unixproxy/nsLibProxySettings.cpp
new file mode 100644
--- /dev/null
+++ b/toolkit/system/unixproxy/nsLibProxySettings.cpp
@@ -0,0 +1,162 @@
+/* -*- 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 libproxy integration code.
+ *
+ * The Initial Developer of the Original Code is
+ * Wolfgang Rosenauer <wr@rosenauer.org>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 "nsIIOService.h"
+#include "nsIURI.h"
+#include "nsString.h"
+#include "nsNetUtil.h"
+#include "nsCOMPtr.h"
+#include "nspr.h"
+
+#include <proxy.h>
+
+class nsUnixSystemProxySettings : public nsISystemProxySettings {
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSISYSTEMPROXYSETTINGS
+
+  nsUnixSystemProxySettings() {}
+  nsresult Init();
+
+private:
+  ~nsUnixSystemProxySettings() {
+    if (mProxyFactory) 
+      px_proxy_factory_free(mProxyFactory); 
+  }
+
+  pxProxyFactory *mProxyFactory;
+  nsCOMPtr<nsIIOService> mIOService;
+};
+
+NS_IMPL_ISUPPORTS1(nsUnixSystemProxySettings, nsISystemProxySettings)
+
+nsresult
+nsUnixSystemProxySettings::Init()
+{
+  mProxyFactory = nsnull;
+  return NS_OK;
+}
+
+nsresult
+nsUnixSystemProxySettings::GetPACURI(nsACString& aResult)
+{
+  // Make sure we return an empty result.
+  aResult.Truncate();
+  return NS_OK;
+}
+
+nsresult
+nsUnixSystemProxySettings::GetProxyForURI(nsIURI* aURI, nsACString& aResult)
+{
+  nsresult rv;
+
+  if (!mProxyFactory) {
+    mProxyFactory = px_proxy_factory_new();
+  }
+  NS_ENSURE_TRUE(mProxyFactory, NS_ERROR_OUT_OF_MEMORY);
+
+  if (!mIOService) {
+    mIOService = do_GetIOService();
+  }
+  NS_ENSURE_TRUE(mIOService, NS_ERROR_FAILURE);
+
+  nsCAutoString spec;
+  rv = aURI->GetSpec(spec);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  char **proxyArray = nsnull;
+  proxyArray = px_proxy_factory_get_proxies(mProxyFactory, (char*)(spec.get()));
+  NS_ENSURE_TRUE(proxyArray, NS_ERROR_FAILURE);
+
+  // PAC string accepts
+  // http, proxy, socks, socks4, socks5, direct, unknown
+  // example: "PROXY proxy1.foo.com:8080; PROXY proxy2.foo.com:8080; DIRECT"
+  int c = 0;
+  while (proxyArray[c] != NULL) {
+    if (c != 0) {
+      aResult.AppendLiteral("; ");
+    }
+
+    PRBool isScheme = PR_FALSE;
+    nsXPIDLCString schemeString;
+    nsXPIDLCString hostPortString;
+    nsCOMPtr<nsIURI> proxyURI;
+
+    rv = mIOService->NewURI(nsDependentCString(proxyArray[c]), 
+                                               nsnull, 
+                                               nsnull, 
+                                               getter_AddRefs(proxyURI));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    proxyURI->GetScheme(schemeString);
+    if (NS_SUCCEEDED(proxyURI->SchemeIs("http", &isScheme)) && isScheme) {
+      schemeString.AssignLiteral("proxy");
+    }
+    aResult.Append(schemeString);
+    if (NS_SUCCEEDED(proxyURI->SchemeIs("direct", &isScheme)) && !isScheme) {
+      // Add the proxy URI only if it's not DIRECT
+      proxyURI->GetHostPort(hostPortString);
+      aResult.AppendLiteral(" ");
+      aResult.Append(hostPortString);
+    }
+
+    c++;
+  }
+
+printf("returned PAC proxy string: %s\n", PromiseFlatCString(aResult).get());
+
+  PR_Free(proxyArray);
+  return NS_OK;
+}
+
+#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)
