[GTK] Provide API to set proxy settings
authorcarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jan 2017 09:03:25 +0000 (09:03 +0000)
committercarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jan 2017 09:03:25 +0000 (09:03 +0000)
https://bugs.webkit.org/show_bug.cgi?id=128674

Reviewed by Michael Catanzaro.

Source/WebCore:

Add SoupNetworkProxySettings struct to store proxy settings.

* platform/network/soup/SoupNetworkProxySettings.h: Added.
(WebCore::SoupNetworkProxySettings::SoupNetworkProxySettings):
(WebCore::SoupNetworkProxySettings::operator=):
(WebCore::SoupNetworkProxySettings::isEmpty):
* platform/network/soup/SoupNetworkSession.cpp:
(WebCore::SoupNetworkSession::SoupNetworkSession): Setup the proxy if user provided proxy settings.
(WebCore::SoupNetworkSession::setupProxy): Set the proxy-resolver property of the SoupSession according to the
global SoupNetworkProxySettings.
(WebCore::SoupNetworkSession::setProxySettingsFromEnvironment): Update the global SoupNetworkProxySettings with
values from environment.
(WebCore::SoupNetworkSession::setProxySettings): Set the global SoupNetworkProxySettings.
* platform/network/soup/SoupNetworkSession.h:

Source/WebKit2:

Add new method webkit_web_context_set_network_proxy_settings() that allows to set proxy settings in a
WebKitWebContext. It receives an enum WebKitNetworkProxyMode with modes Default, NoProxy and Custom, and an
optional WebKitNetworkProxySettings that is used when mode is Custom. WebKitNetworkProxySettings is a simple
boxed type that user can create to set proxy settins with a similar API to GSimpleProxyResolver.

* NetworkProcess/NetworkProcess.h:
* NetworkProcess/NetworkProcess.messages.in: Add SetNetworkProxySettings message.
* NetworkProcess/NetworkProcessCreationParameters.cpp:
(WebKit::NetworkProcessCreationParameters::encode): Encode proxy settings.
(WebKit::NetworkProcessCreationParameters::decode): Decode proxy settings.
* NetworkProcess/NetworkProcessCreationParameters.h:
* NetworkProcess/efl/NetworkProcessMainEfl.cpp: Use SoupNetworkSession::setProxySettingsFromEnvironment().
* NetworkProcess/soup/NetworkProcessSoup.cpp:
(WebKit::NetworkProcess::platformInitializeNetworkProcess): Set proxy settings if provided by the user.
(WebKit::NetworkProcess::setNetworkProxySettings): Set global proxy settings and setup the proxy for all
existing contexts.
* PlatformGTK.cmake: Add new files to compilation.
* Shared/WebCoreArgumentCoders.h:
* Shared/WebProcessCreationParameters.cpp:
(WebKit::WebProcessCreationParameters::encode): Encode proxy settings.
(WebKit::WebProcessCreationParameters::decode): Decode proxy settings.
* Shared/WebProcessCreationParameters.h:
* Shared/soup/WebCoreArgumentCodersSoup.cpp:
(IPC::ArgumentCoder<SoupNetworkProxySettings>::encode): Add encoder implementation for SoupNetworkProxySettings.
(IPC::ArgumentCoder<SoupNetworkProxySettings>::decode): add decoder implementation for SoupNetworkProxySettings.
* UIProcess/API/gtk/WebKitNetworkProxySettings.cpp: Added.
(_WebKitNetworkProxySettings::_WebKitNetworkProxySettings):
(webkitNetworkProxySettingsGetNetworkProxySettings):
(webkit_network_proxy_settings_new): Create a new WebKitNetworkProxySettings with optional default proxy uri and
ignore hosts list.
(webkit_network_proxy_settings_copy):
(webkit_network_proxy_settings_free):
(webkit_network_proxy_settings_add_proxy): Add a proxy uri for a given uri scheme.
* UIProcess/API/gtk/WebKitNetworkProxySettings.h: Added.
* UIProcess/API/gtk/WebKitNetworkProxySettingsPrivate.h: Added.
* UIProcess/API/gtk/WebKitWebContext.cpp:
(webkit_web_context_set_network_proxy_settings): Set proxy settings.
* UIProcess/API/gtk/WebKitWebContext.h:
* UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt: Add new symbols to the documentation.
* UIProcess/API/gtk/docs/webkit2gtk-docs.sgml: Add new section for WebKitNetworkProxySettings.
* UIProcess/API/gtk/webkit2.h: Include WebKitNetworkProxySettings.h.
* UIProcess/WebProcessPool.h: Add m_networkProxySettings and a setter for soup.
* UIProcess/efl/WebProcessPoolEfl.cpp:
(WebKit::WebProcessPool::platformInitializeWebProcess): Set m_networkProxySettings to parameters.
* UIProcess/gtk/WebProcessPoolGtk.cpp:
(WebKit::WebProcessPool::platformInitializeWebProcess): Ditto.
* UIProcess/soup/WebProcessPoolSoup.cpp:
(WebKit::WebProcessPool::platformInitializeNetworkProcess): Ditto.
(WebKit::WebProcessPool::setNetworkProxySettings): Update m_networkProxySettings and notify all processes.
* WebProcess/WebProcess.h:
* WebProcess/WebProcess.messages.in: Add SetNetworkProxySettings message.
* WebProcess/efl/WebProcessMainEfl.cpp: Use SoupNetworkSession::setProxySettingsFromEnvironment().
* WebProcess/soup/WebProcessSoup.cpp:
(WebKit::WebProcess::platformSetCacheModel): Remove comment that is no longer true.
(WebKit::WebProcess::platformInitializeWebProcess): Set proxy settings if provided by the user.
(WebKit::WebProcess::setNetworkProxySettings): Set global proxy settings and setup the proxy for all
existing contexts.

Tools:

Add tests for new proxy settings API.

* TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitWebContext.cpp:
(serverCallback):
(ProxyTest::ProxyTest):
(ProxyTest::~ProxyTest):
(ProxyTest::loadURIAndGetMainResourceData):
(ProxyTest::proxyServerPortAsString):
(testWebContextProxySettings):
(beforeAll):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@210921 268f45cc-cd09-0410-ab3c-d52691b4dbfc

34 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/network/soup/SoupNetworkProxySettings.h [new file with mode: 0644]
Source/WebCore/platform/network/soup/SoupNetworkSession.cpp
Source/WebCore/platform/network/soup/SoupNetworkSession.h
Source/WebKit2/ChangeLog
Source/WebKit2/NetworkProcess/NetworkProcess.h
Source/WebKit2/NetworkProcess/NetworkProcess.messages.in
Source/WebKit2/NetworkProcess/NetworkProcessCreationParameters.cpp
Source/WebKit2/NetworkProcess/NetworkProcessCreationParameters.h
Source/WebKit2/NetworkProcess/efl/NetworkProcessMainEfl.cpp
Source/WebKit2/NetworkProcess/soup/NetworkProcessSoup.cpp
Source/WebKit2/PlatformGTK.cmake
Source/WebKit2/Shared/WebCoreArgumentCoders.h
Source/WebKit2/Shared/WebProcessCreationParameters.cpp
Source/WebKit2/Shared/WebProcessCreationParameters.h
Source/WebKit2/Shared/soup/WebCoreArgumentCodersSoup.cpp
Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettings.cpp [new file with mode: 0644]
Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettings.h [new file with mode: 0644]
Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettingsPrivate.h [new file with mode: 0644]
Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp
Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h
Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt
Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml
Source/WebKit2/UIProcess/API/gtk/webkit2.h
Source/WebKit2/UIProcess/WebProcessPool.h
Source/WebKit2/UIProcess/efl/WebProcessPoolEfl.cpp
Source/WebKit2/UIProcess/gtk/WebProcessPoolGtk.cpp
Source/WebKit2/UIProcess/soup/WebProcessPoolSoup.cpp
Source/WebKit2/WebProcess/WebProcess.h
Source/WebKit2/WebProcess/WebProcess.messages.in
Source/WebKit2/WebProcess/efl/WebProcessMainEfl.cpp
Source/WebKit2/WebProcess/soup/WebProcessSoup.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitWebContext.cpp

index 2eb788b..1ea7ce2 100644 (file)
@@ -1,3 +1,25 @@
+2017-01-19  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [GTK] Provide API to set proxy settings
+        https://bugs.webkit.org/show_bug.cgi?id=128674
+
+        Reviewed by Michael Catanzaro.
+
+        Add SoupNetworkProxySettings struct to store proxy settings.
+
+        * platform/network/soup/SoupNetworkProxySettings.h: Added.
+        (WebCore::SoupNetworkProxySettings::SoupNetworkProxySettings):
+        (WebCore::SoupNetworkProxySettings::operator=):
+        (WebCore::SoupNetworkProxySettings::isEmpty):
+        * platform/network/soup/SoupNetworkSession.cpp:
+        (WebCore::SoupNetworkSession::SoupNetworkSession): Setup the proxy if user provided proxy settings.
+        (WebCore::SoupNetworkSession::setupProxy): Set the proxy-resolver property of the SoupSession according to the
+        global SoupNetworkProxySettings.
+        (WebCore::SoupNetworkSession::setProxySettingsFromEnvironment): Update the global SoupNetworkProxySettings with
+        values from environment.
+        (WebCore::SoupNetworkSession::setProxySettings): Set the global SoupNetworkProxySettings.
+        * platform/network/soup/SoupNetworkSession.h:
+
 2017-01-18  Sam Weinig  <sam@webkit.org>
 
         [WebIDL] Records should preserve javascript object order
diff --git a/Source/WebCore/platform/network/soup/SoupNetworkProxySettings.h b/Source/WebCore/platform/network/soup/SoupNetworkProxySettings.h
new file mode 100644 (file)
index 0000000..2732673
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2017 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/HashMap.h>
+#include <wtf/glib/GUniquePtr.h>
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+struct SoupNetworkProxySettings {
+    enum class Mode { Default, NoProxy, Custom };
+
+    SoupNetworkProxySettings() = default;
+
+    explicit SoupNetworkProxySettings(Mode proxyMode)
+        : mode(proxyMode)
+    {
+    }
+
+    SoupNetworkProxySettings(const WebCore::SoupNetworkProxySettings& other)
+        : mode(other.mode)
+        , defaultProxyURL(other.defaultProxyURL)
+        , ignoreHosts(g_strdupv(other.ignoreHosts.get()))
+        , proxyMap(other.proxyMap)
+    {
+    }
+
+    SoupNetworkProxySettings& operator=(const WebCore::SoupNetworkProxySettings& other)
+    {
+        mode = other.mode;
+        defaultProxyURL = other.defaultProxyURL;
+        ignoreHosts.reset(g_strdupv(other.ignoreHosts.get()));
+        proxyMap = other.proxyMap;
+        return *this;
+    }
+
+    bool isEmpty() const { return mode == Mode::Custom && defaultProxyURL.isNull() && !ignoreHosts && proxyMap.isEmpty(); }
+
+    Mode mode { Mode::Default };
+    CString defaultProxyURL;
+    GUniquePtr<char*> ignoreHosts;
+    HashMap<CString, CString> proxyMap;
+};
+
+} // namespace WebCore
index 5849676..852b9b8 100644 (file)
@@ -35,6 +35,7 @@
 #include "GUniquePtrSoup.h"
 #include "Logging.h"
 #include "ResourceHandle.h"
+#include "SoupNetworkProxySettings.h"
 #include <glib/gstdio.h>
 #include <libsoup/soup.h>
 #include <wtf/HashSet.h>
@@ -46,6 +47,7 @@ namespace WebCore {
 
 static bool gIgnoreTLSErrors;
 static CString gInitialAcceptLanguages;
+static SoupNetworkProxySettings gProxySettings;
 
 #if !LOG_DISABLED
 inline static void soupLogPrinter(SoupLogger*, SoupLoggerLogLevel, char direction, const char* data, gpointer)
@@ -149,6 +151,8 @@ SoupNetworkSession::SoupNetworkSession(SoupCookieJar* cookieJar)
     }
 #endif
 
+    if (gProxySettings.mode != SoupNetworkProxySettings::Mode::Default)
+        setupProxy();
     setupLogger();
 
     g_signal_connect(m_soupSession.get(), "authenticate", G_CALLBACK(authenticateCallback), nullptr);
@@ -217,39 +221,63 @@ void SoupNetworkSession::clearOldSoupCache(const String& cacheDirectory)
     }
 }
 
-void SoupNetworkSession::setHTTPProxy(const char* httpProxy, const char* httpProxyExceptions)
+void SoupNetworkSession::setupProxy()
 {
-#if PLATFORM(EFL)
-    // Only for EFL because GTK port uses the default resolver, which uses GIO's proxy resolver.
-    GProxyResolver* resolver = nullptr;
-    if (httpProxy) {
-        gchar** ignoreLists = nullptr;
-        if (httpProxyExceptions)
-            ignoreLists =  g_strsplit(httpProxyExceptions, ",", -1);
-
-        resolver = g_simple_proxy_resolver_new(httpProxy, ignoreLists);
-
-        g_strfreev(ignoreLists);
+    GRefPtr<GProxyResolver> resolver;
+    switch (gProxySettings.mode) {
+    case SoupNetworkProxySettings::Mode::Default: {
+        GRefPtr<GProxyResolver> currentResolver;
+        g_object_get(m_soupSession.get(), SOUP_SESSION_PROXY_RESOLVER, &currentResolver.outPtr(), nullptr);
+        GProxyResolver* defaultResolver = g_proxy_resolver_get_default();
+        if (currentResolver.get() == defaultResolver)
+            return;
+        resolver = defaultResolver;
+        break;
+    }
+    case SoupNetworkProxySettings::Mode::NoProxy:
+        // Do nothing in this case, resolver is nullptr so that when set it will disable proxies.
+        break;
+    case SoupNetworkProxySettings::Mode::Custom:
+        resolver = adoptGRef(g_simple_proxy_resolver_new(nullptr, nullptr));
+        if (!gProxySettings.defaultProxyURL.isNull())
+            g_simple_proxy_resolver_set_default_proxy(G_SIMPLE_PROXY_RESOLVER(resolver.get()), gProxySettings.defaultProxyURL.data());
+        if (gProxySettings.ignoreHosts)
+            g_simple_proxy_resolver_set_ignore_hosts(G_SIMPLE_PROXY_RESOLVER(resolver.get()), gProxySettings.ignoreHosts.get());
+        for (const auto& iter : gProxySettings.proxyMap)
+            g_simple_proxy_resolver_set_uri_proxy(G_SIMPLE_PROXY_RESOLVER(resolver.get()), iter.key.data(), iter.value.data());
+        break;
     }
 
-    g_object_set(m_soupSession.get(), SOUP_SESSION_PROXY_RESOLVER, resolver, nullptr);
-#else
-    UNUSED_PARAM(httpProxy);
-    UNUSED_PARAM(httpProxyExceptions);
-#endif
+    g_object_set(m_soupSession.get(), SOUP_SESSION_PROXY_RESOLVER, resolver.get(), nullptr);
+    soup_session_abort(m_soupSession.get());
 }
 
-void SoupNetworkSession::setupHTTPProxyFromEnvironment()
-{
 #if PLATFORM(EFL)
+// FIXME: This function should not exist at all and we don't want to accidentally use it in other ports.
+// The correct way to set proxy settings from the environment is to use a GProxyResolver that does so.
+// It also lacks the rather important https_proxy and ftp_proxy variables, and the uppercase versions of
+// all four variables, all of which you almost surely want to be respected if you're setting http_proxy,
+// and all of which would be supported via the default proxy resolver in non-GNOME/Ubuntu environments
+// (at least, I think that's right). Additionally, it is incorrect for WebKit to respect this environment
+// variable when running in a GNOME or Ubuntu environment, where GNOME proxy configuration should be
+// respected instead. The only reason to retain this function is to not alter the incorrect behavior for EFL.
+void SoupNetworkSession::setProxySettingsFromEnvironment()
+{
     const char* httpProxy = getenv("http_proxy");
     if (!httpProxy)
         return;
 
-    setHTTPProxy(httpProxy, getenv("no_proxy"));
-#endif
+    gProxySettings.defaultProxyURL = httpProxy;
+    const char* httpProxyExceptions = getenv("no_proxy");
+    if (httpProxyExceptions)
+        gProxySettings.ignoreHosts.reset(g_strsplit(httpProxyExceptions, ",", -1));
 }
+#endif
 
+void SoupNetworkSession::setProxySettings(const SoupNetworkProxySettings& settings)
+{
+    gProxySettings = settings;
+}
 
 void SoupNetworkSession::setInitialAcceptLanguages(const CString& languages)
 {
index 0c71497..9f2e8ce 100644 (file)
@@ -42,6 +42,7 @@ namespace WebCore {
 
 class CertificateInfo;
 class ResourceError;
+struct SoupNetworkProxySettings;
 
 class SoupNetworkSession {
     WTF_MAKE_NONCOPYABLE(SoupNetworkSession); WTF_MAKE_FAST_ALLOCATED;
@@ -56,7 +57,11 @@ public:
 
     static void clearOldSoupCache(const String& cacheDirectory);
 
-    void setupHTTPProxyFromEnvironment();
+#if PLATFORM(EFL)
+    static void setProxySettingsFromEnvironment();
+#endif
+    static void setProxySettings(const SoupNetworkProxySettings&);
+    void setupProxy();
 
     static void setInitialAcceptLanguages(const CString&);
     void setAcceptLanguages(const CString&);
@@ -66,8 +71,6 @@ public:
     static void allowSpecificHTTPSCertificateForHost(const CertificateInfo&, const String& host);
 
 private:
-    void setHTTPProxy(const char* httpProxy, const char* httpProxyExceptions);
-
     void setupLogger();
 
     GRefPtr<SoupSession> m_soupSession;
index 0c20c9d..9accf58 100644 (file)
@@ -1,5 +1,70 @@
 2017-01-19  Carlos Garcia Campos  <cgarcia@igalia.com>
 
+        [GTK] Provide API to set proxy settings
+        https://bugs.webkit.org/show_bug.cgi?id=128674
+
+        Reviewed by Michael Catanzaro.
+
+        Add new method webkit_web_context_set_network_proxy_settings() that allows to set proxy settings in a
+        WebKitWebContext. It receives an enum WebKitNetworkProxyMode with modes Default, NoProxy and Custom, and an
+        optional WebKitNetworkProxySettings that is used when mode is Custom. WebKitNetworkProxySettings is a simple
+        boxed type that user can create to set proxy settins with a similar API to GSimpleProxyResolver.
+
+        * NetworkProcess/NetworkProcess.h:
+        * NetworkProcess/NetworkProcess.messages.in: Add SetNetworkProxySettings message.
+        * NetworkProcess/NetworkProcessCreationParameters.cpp:
+        (WebKit::NetworkProcessCreationParameters::encode): Encode proxy settings.
+        (WebKit::NetworkProcessCreationParameters::decode): Decode proxy settings.
+        * NetworkProcess/NetworkProcessCreationParameters.h:
+        * NetworkProcess/efl/NetworkProcessMainEfl.cpp: Use SoupNetworkSession::setProxySettingsFromEnvironment().
+        * NetworkProcess/soup/NetworkProcessSoup.cpp:
+        (WebKit::NetworkProcess::platformInitializeNetworkProcess): Set proxy settings if provided by the user.
+        (WebKit::NetworkProcess::setNetworkProxySettings): Set global proxy settings and setup the proxy for all
+        existing contexts.
+        * PlatformGTK.cmake: Add new files to compilation.
+        * Shared/WebCoreArgumentCoders.h:
+        * Shared/WebProcessCreationParameters.cpp:
+        (WebKit::WebProcessCreationParameters::encode): Encode proxy settings.
+        (WebKit::WebProcessCreationParameters::decode): Decode proxy settings.
+        * Shared/WebProcessCreationParameters.h:
+        * Shared/soup/WebCoreArgumentCodersSoup.cpp:
+        (IPC::ArgumentCoder<SoupNetworkProxySettings>::encode): Add encoder implementation for SoupNetworkProxySettings.
+        (IPC::ArgumentCoder<SoupNetworkProxySettings>::decode): add decoder implementation for SoupNetworkProxySettings.
+        * UIProcess/API/gtk/WebKitNetworkProxySettings.cpp: Added.
+        (_WebKitNetworkProxySettings::_WebKitNetworkProxySettings):
+        (webkitNetworkProxySettingsGetNetworkProxySettings):
+        (webkit_network_proxy_settings_new): Create a new WebKitNetworkProxySettings with optional default proxy uri and
+        ignore hosts list.
+        (webkit_network_proxy_settings_copy):
+        (webkit_network_proxy_settings_free):
+        (webkit_network_proxy_settings_add_proxy): Add a proxy uri for a given uri scheme.
+        * UIProcess/API/gtk/WebKitNetworkProxySettings.h: Added.
+        * UIProcess/API/gtk/WebKitNetworkProxySettingsPrivate.h: Added.
+        * UIProcess/API/gtk/WebKitWebContext.cpp:
+        (webkit_web_context_set_network_proxy_settings): Set proxy settings.
+        * UIProcess/API/gtk/WebKitWebContext.h:
+        * UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt: Add new symbols to the documentation.
+        * UIProcess/API/gtk/docs/webkit2gtk-docs.sgml: Add new section for WebKitNetworkProxySettings.
+        * UIProcess/API/gtk/webkit2.h: Include WebKitNetworkProxySettings.h.
+        * UIProcess/WebProcessPool.h: Add m_networkProxySettings and a setter for soup.
+        * UIProcess/efl/WebProcessPoolEfl.cpp:
+        (WebKit::WebProcessPool::platformInitializeWebProcess): Set m_networkProxySettings to parameters.
+        * UIProcess/gtk/WebProcessPoolGtk.cpp:
+        (WebKit::WebProcessPool::platformInitializeWebProcess): Ditto.
+        * UIProcess/soup/WebProcessPoolSoup.cpp:
+        (WebKit::WebProcessPool::platformInitializeNetworkProcess): Ditto.
+        (WebKit::WebProcessPool::setNetworkProxySettings): Update m_networkProxySettings and notify all processes.
+        * WebProcess/WebProcess.h:
+        * WebProcess/WebProcess.messages.in: Add SetNetworkProxySettings message.
+        * WebProcess/efl/WebProcessMainEfl.cpp: Use SoupNetworkSession::setProxySettingsFromEnvironment().
+        * WebProcess/soup/WebProcessSoup.cpp:
+        (WebKit::WebProcess::platformSetCacheModel): Remove comment that is no longer true.
+        (WebKit::WebProcess::platformInitializeWebProcess): Set proxy settings if provided by the user.
+        (WebKit::WebProcess::setNetworkProxySettings): Set global proxy settings and setup the proxy for all
+        existing contexts.
+
+2017-01-19  Carlos Garcia Campos  <cgarcia@igalia.com>
+
         [GTK] Do not update the backing store state unnecessarily when page visibility changes
         https://bugs.webkit.org/show_bug.cgi?id=167195
 
index c96d082..dab3754 100644 (file)
@@ -50,6 +50,7 @@ class ProtectionSpace;
 class SecurityOrigin;
 class SessionID;
 struct SecurityOriginData;
+struct SoupNetworkProxySettings;
 }
 
 namespace WebKit {
@@ -192,6 +193,7 @@ private:
 #if USE(SOUP)
     void setIgnoreTLSErrors(bool);
     void userPreferredLanguagesChanged(const Vector<String>&);
+    void setNetworkProxySettings(const WebCore::SoupNetworkProxySettings&);
 #endif
 
     // Platform Helpers
index 2a482de..0a99169 100644 (file)
@@ -30,6 +30,7 @@ messages -> NetworkProcess LegacyReceiver {
 #if USE(SOUP)
     SetIgnoreTLSErrors(bool ignoreTLSErrors)
     UserPreferredLanguagesChanged(Vector<String> languages)
+    SetNetworkProxySettings(struct WebCore::SoupNetworkProxySettings settings)
 #endif
 
     ClearCachedCredentials()
index 099a3a4..1be9212 100644 (file)
 #include "ArgumentCodersCF.h"
 #endif
 
+#if USE(SOUP)
+#include "WebCoreArgumentCoders.h"
+#endif
+
 namespace WebKit {
 
 NetworkProcessCreationParameters::NetworkProcessCreationParameters()
@@ -89,6 +93,7 @@ void NetworkProcessCreationParameters::encode(IPC::Encoder& encoder) const
     encoder.encodeEnum(cookieAcceptPolicy);
     encoder << ignoreTLSErrors;
     encoder << languages;
+    encoder << proxySettings;
 #endif
 #if OS(LINUX)
     encoder << memoryPressureMonitorHandle;
@@ -185,6 +190,8 @@ bool NetworkProcessCreationParameters::decode(IPC::Decoder& decoder, NetworkProc
         return false;
     if (!decoder.decode(result.languages))
         return false;
+    if (!decoder.decode(result.proxySettings))
+        return false;
 #endif
 
 #if OS(LINUX)
index 330e3ba..36ee538 100644 (file)
@@ -33,6 +33,7 @@
 
 #if USE(SOUP)
 #include "HTTPCookieAcceptPolicy.h"
+#include <WebCore/SoupNetworkProxySettings.h>
 #endif
 
 namespace IPC {
@@ -101,6 +102,7 @@ struct NetworkProcessCreationParameters {
     HTTPCookieAcceptPolicy cookieAcceptPolicy;
     bool ignoreTLSErrors;
     Vector<String> languages;
+    WebCore::SoupNetworkProxySettings proxySettings;
 #endif
 
 #if OS(LINUX)
index f32ccf4..27dcd1f 100644 (file)
@@ -30,7 +30,6 @@
 #include "ChildProcessMain.h"
 #include "NetworkProcess.h"
 #include <Ecore.h>
-#include <WebCore/NetworkStorageSession.h>
 #include <WebCore/SoupNetworkSession.h>
 #include <libsoup/soup.h>
 
@@ -48,7 +47,7 @@ public:
         if (!ecore_main_loop_glib_integrate())
             return false;
 
-        NetworkStorageSession::defaultStorageSession().getOrCreateSoupNetworkSession().setupHTTPProxyFromEnvironment();
+        SoupNetworkSession::setProxySettingsFromEnvironment();
         return true;
     }
 
index 9ed33e4..d8dcde3 100644 (file)
@@ -104,6 +104,9 @@ void NetworkProcess::userPreferredLanguagesChanged(const Vector<String>& languag
 
 void NetworkProcess::platformInitializeNetworkProcess(const NetworkProcessCreationParameters& parameters)
 {
+    if (parameters.proxySettings.mode != SoupNetworkProxySettings::Mode::Default)
+        setNetworkProxySettings(parameters.proxySettings);
+
     ASSERT(!parameters.diskCacheDirectory.isEmpty());
     m_diskCacheDirectory = parameters.diskCacheDirectory;
 
@@ -161,4 +164,13 @@ void NetworkProcess::platformTerminate()
     notImplemented();
 }
 
+void NetworkProcess::setNetworkProxySettings(const SoupNetworkProxySettings& settings)
+{
+    SoupNetworkSession::setProxySettings(settings);
+    NetworkStorageSession::forEach([](const NetworkStorageSession& session) {
+        if (auto* soupSession = session.soupNetworkSession())
+            soupSession->setupProxy();
+    });
+}
+
 } // namespace WebKit
index 87a559a..5154117 100644 (file)
@@ -187,6 +187,9 @@ list(APPEND WebKit2_SOURCES
     UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp
     UIProcess/API/gtk/WebKitNavigationPolicyDecision.h
     UIProcess/API/gtk/WebKitNavigationPolicyDecisionPrivate.h
+    UIProcess/API/gtk/WebKitNetworkProxySettings.cpp
+    UIProcess/API/gtk/WebKitNetworkProxySettings.h
+    UIProcess/API/gtk/WebKitNetworkProxySettingsPrivate.h
     UIProcess/API/gtk/WebKitNotification.cpp
     UIProcess/API/gtk/WebKitNotification.h
     UIProcess/API/gtk/WebKitNotificationPermissionRequest.cpp
@@ -527,6 +530,7 @@ set(WebKit2GTK_INSTALLED_HEADERS
     ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitMimeInfo.h
     ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitNavigationAction.h
     ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitNavigationPolicyDecision.h
+    ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitNetworkProxySettings.h
     ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitNotificationPermissionRequest.h
     ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitNotification.h
     ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitPermissionRequest.h
index 4437cad..bcbeb2a 100644 (file)
@@ -120,6 +120,12 @@ struct ViewportArguments;
 }
 #endif
 
+#if USE(SOUP)
+namespace WebCore {
+struct SoupNetworkProxySettings;
+}
+#endif
+
 #if ENABLE(CONTENT_FILTERING)
 namespace WebCore {
 class ContentFilterUnblockHandler;
@@ -385,6 +391,13 @@ template<> struct ArgumentCoder<WebCore::PasteboardImage> {
 };
 #endif
 
+#if USE(SOUP)
+template<> struct ArgumentCoder<WebCore::SoupNetworkProxySettings> {
+    static void encode(Encoder&, const WebCore::SoupNetworkProxySettings&);
+    static bool decode(Decoder&, WebCore::SoupNetworkProxySettings&);
+};
+#endif
+
 template<> struct ArgumentCoder<WebCore::CompositionUnderline> {
     static void encode(Encoder&, const WebCore::CompositionUnderline&);
     static bool decode(Decoder&, WebCore::CompositionUnderline&);
index 1b00d74..929b7a9 100644 (file)
@@ -150,6 +150,10 @@ void WebProcessCreationParameters::encode(IPC::Encoder& encoder) const
 #if PLATFORM(WAYLAND)
     encoder << waylandCompositorDisplayName;
 #endif
+
+#if USE(SOUP)
+    encoder << proxySettings;
+#endif
 }
 
 bool WebProcessCreationParameters::decode(IPC::Decoder& decoder, WebProcessCreationParameters& parameters)
@@ -317,6 +321,11 @@ bool WebProcessCreationParameters::decode(IPC::Decoder& decoder, WebProcessCreat
         return false;
 #endif
 
+#if USE(SOUP)
+    if (!decoder.decode(parameters.proxySettings))
+        return false;
+#endif
+
     return true;
 }
 
index ec86e1e..56efb8c 100644 (file)
@@ -42,6 +42,7 @@
 
 #if USE(SOUP)
 #include "HTTPCookieAcceptPolicy.h"
+#include <WebCore/SoupNetworkProxySettings.h>
 #endif
 
 namespace API {
@@ -174,6 +175,10 @@ struct WebProcessCreationParameters {
 #if PLATFORM(WAYLAND)
     String waylandCompositorDisplayName;
 #endif
+
+#if USE(SOUP)
+    WebCore::SoupNetworkProxySettings proxySettings;
+#endif
 };
 
 } // namespace WebKit
index 92da1e9..49f4071 100644 (file)
@@ -33,6 +33,7 @@
 #include <WebCore/ResourceError.h>
 #include <WebCore/ResourceRequest.h>
 #include <WebCore/ResourceResponse.h>
+#include <WebCore/SoupNetworkProxySettings.h>
 #include <wtf/text/CString.h>
 
 using namespace WebCore;
@@ -151,6 +152,55 @@ bool ArgumentCoder<ResourceError>::decodePlatformData(Decoder& decoder, Resource
     return true;
 }
 
+void ArgumentCoder<SoupNetworkProxySettings>::encode(Encoder& encoder, const SoupNetworkProxySettings& settings)
+{
+    ASSERT(!settings.isEmpty());
+    encoder.encodeEnum(settings.mode);
+    if (settings.mode != SoupNetworkProxySettings::Mode::Custom)
+        return;
+
+    encoder << settings.defaultProxyURL;
+    uint32_t ignoreHostsCount = settings.ignoreHosts ? g_strv_length(settings.ignoreHosts.get()) : 0;
+    encoder << ignoreHostsCount;
+    if (ignoreHostsCount) {
+        for (uint32_t i = 0; settings.ignoreHosts.get()[i]; ++i)
+            encoder << CString(settings.ignoreHosts.get()[i]);
+    }
+    encoder << settings.proxyMap;
+}
+
+bool ArgumentCoder<SoupNetworkProxySettings>::decode(Decoder& decoder, SoupNetworkProxySettings& settings)
+{
+    if (!decoder.decodeEnum(settings.mode))
+        return false;
+
+    if (settings.mode != SoupNetworkProxySettings::Mode::Custom)
+        return true;
+
+    if (!decoder.decode(settings.defaultProxyURL))
+        return false;
+
+    uint32_t ignoreHostsCount;
+    if (!decoder.decode(ignoreHostsCount))
+        return false;
+
+    if (ignoreHostsCount) {
+        settings.ignoreHosts.reset(g_new0(char*, ignoreHostsCount + 1));
+        for (uint32_t i = 0; i < ignoreHostsCount; ++i) {
+            CString host;
+            if (!decoder.decode(host))
+                return false;
+
+            settings.ignoreHosts.get()[i] = g_strdup(host.data());
+        }
+    }
+
+    if (!decoder.decode(settings.proxyMap))
+        return false;
+
+    return !settings.isEmpty();
+}
+
 void ArgumentCoder<ProtectionSpace>::encodePlatformData(Encoder&, const ProtectionSpace&)
 {
     ASSERT_NOT_REACHED();
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettings.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettings.cpp
new file mode 100644 (file)
index 0000000..11cba33
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2017 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "WebKitNetworkProxySettings.h"
+
+#include "WebKitNetworkProxySettingsPrivate.h"
+#include <WebCore/SoupNetworkProxySettings.h>
+#include <wtf/text/WTFString.h>
+
+using namespace WebKit;
+using namespace WebCore;
+
+/**
+ * SECTION: WebKitNetworkProxySettings
+ * @Short_description: Network Proxy Settings
+ * @Title: WebKitNetworkProxySettings
+ * @See_also: #WebKitWebContext
+ *
+ * WebKitNetworkProxySettings can be used to provide a custom proxy configuration
+ * to a #WebKitWebContext. You need to call webkit_web_context_set_network_proxy_settings()
+ * with %WEBKIT_NETWORK_PROXY_MODE_CUSTOM and a WebKitNetworkProxySettings.
+ *
+ * Since: 2.16
+ */
+struct _WebKitNetworkProxySettings {
+    _WebKitNetworkProxySettings()
+        : settings(SoupNetworkProxySettings::Mode::Custom)
+    {
+    }
+
+    explicit _WebKitNetworkProxySettings(const SoupNetworkProxySettings& otherSettings)
+        : settings(otherSettings)
+    {
+    }
+
+    SoupNetworkProxySettings settings;
+};
+
+G_DEFINE_BOXED_TYPE(WebKitNetworkProxySettings, webkit_network_proxy_settings, webkit_network_proxy_settings_copy, webkit_network_proxy_settings_free)
+
+const SoupNetworkProxySettings& webkitNetworkProxySettingsGetNetworkProxySettings(WebKitNetworkProxySettings* proxySettings)
+{
+    ASSERT(proxySettings);
+    return proxySettings->settings;
+}
+
+/**
+ * webkit_network_proxy_settings_new:
+ * @default_proxy_uri: (allow-none): the default proxy URI to use, or %NULL.
+ * @ignore_hosts: (allow-none): an optional list of hosts/IP addresses to not use a proxy for.
+ *
+ * Create a new #WebKitNetworkProxySettings with the given @default_proxy_uri and @ignore_hosts.
+ *
+ * The default proxy URI will be used for any URI that doesn't match @ignore_hosts, and doesn't match any
+ * of the schemes added with webkit_network_proxy_settings_add_proxy_for_scheme().
+ * If @default_proxy_uri starts with "socks://", it will be treated as referring to all three of the
+ * socks5, socks4a, and socks4 proxy types.
+ *
+ * @ignore_hosts is a list of hostnames and IP addresses that the resolver should allow direct connections to.
+ * Entries can be in one of 4 formats:
+ * <itemizedlist>
+ * <listitem><para>
+ * A hostname, such as "example.com", ".example.com", or "*.example.com", any of which match "example.com" or
+ * any subdomain of it.
+ * </para></listitem>
+ * <listitem><para>
+ * An IPv4 or IPv6 address, such as "192.168.1.1", which matches only that address.
+ * </para></listitem>
+ * <listitem><para>
+ * A hostname or IP address followed by a port, such as "example.com:80", which matches whatever the hostname or IP
+ * address would match, but only for URLs with the (explicitly) indicated port. In the case of an IPv6 address, the address
+ * part must appear in brackets: "[::1]:443"
+ * </para></listitem>
+ * <listitem><para>
+ * An IP address range, given by a base address and prefix length, such as "fe80::/10", which matches any address in that range.
+ * </para></listitem>
+ * </itemizedlist>
+ *
+ * Note that when dealing with Unicode hostnames, the matching is done against the ASCII form of the name.
+ * Also note that hostname exclusions apply only to connections made to hosts identified by name, and IP address exclusions apply only
+ * to connections made to hosts identified by address. That is, if example.com has an address of 192.168.1.1, and @ignore_hosts
+ * contains only "192.168.1.1", then a connection to "example.com" will use the proxy, and a connection to 192.168.1.1" will not.
+ *
+ * Returns: (transfer full): A new #WebKitNetworkProxySettings.
+ *
+ * Since: 2.16
+ */
+WebKitNetworkProxySettings* webkit_network_proxy_settings_new(const char* defaultProxyURI, const char* const* ignoreHosts)
+{
+    WebKitNetworkProxySettings* proxySettings = static_cast<WebKitNetworkProxySettings*>(fastMalloc(sizeof(WebKitNetworkProxySettings)));
+    new (proxySettings) WebKitNetworkProxySettings;
+    if (defaultProxyURI)
+        proxySettings->settings.defaultProxyURL = defaultProxyURI;
+    if (ignoreHosts)
+        proxySettings->settings.ignoreHosts.reset(g_strdupv(const_cast<char**>(ignoreHosts)));
+    return proxySettings;
+}
+
+/**
+ * webkit_network_proxy_settings_copy:
+ * @proxy_settings: a #WebKitNetworkProxySettings
+ *
+ * Make a copy of the #WebKitNetworkProxySettings.
+ *
+ * Returns: (transfer full): A copy of passed in #WebKitNetworkProxySettings
+ *
+ * Since: 2.16
+ */
+WebKitNetworkProxySettings* webkit_network_proxy_settings_copy(WebKitNetworkProxySettings* proxySettings)
+{
+    g_return_val_if_fail(proxySettings, nullptr);
+
+    WebKitNetworkProxySettings* copy = static_cast<WebKitNetworkProxySettings*>(fastMalloc(sizeof(WebKitNetworkProxySettings)));
+    new (copy) WebKitNetworkProxySettings(webkitNetworkProxySettingsGetNetworkProxySettings(proxySettings));
+    return copy;
+}
+
+/**
+ * webkit_network_proxy_settings_free:
+ * @proxy_settings: A #WebKitNetworkProxySettings
+ *
+ * Free the #WebKitNetworkProxySettings.
+ *
+ * Since: 2.16
+ */
+void webkit_network_proxy_settings_free(WebKitNetworkProxySettings* proxySettings)
+{
+    g_return_if_fail(proxySettings);
+
+    proxySettings->~WebKitNetworkProxySettings();
+    fastFree(proxySettings);
+}
+
+/**
+ * webkit_network_proxy_settings_add_proxy_for_scheme:
+ * @proxy_settings: a #WebKitNetworkProxySettings
+ * @scheme: the URI scheme to add a proxy for
+ * @proxy_uri: the proxy URI to use for @uri_scheme
+ *
+ * Adds a URI-scheme-specific proxy. URIs whose scheme matches @uri_scheme will be proxied via @proxy_uri.
+ * As with the default proxy URI, if @proxy_uri starts with "socks://", it will be treated as referring to
+ * all three of the socks5, socks4a, and socks4 proxy types.
+ *
+ * Since: 2.16
+ */
+void webkit_network_proxy_settings_add_proxy_for_scheme(WebKitNetworkProxySettings* proxySettings, const char* scheme, const char* proxyURI)
+{
+    g_return_if_fail(proxySettings);
+    g_return_if_fail(scheme);
+    g_return_if_fail(proxyURI);
+
+    proxySettings->settings.proxyMap.add(scheme, proxyURI);
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettings.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettings.h
new file mode 100644 (file)
index 0000000..00c2b39
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
+#error "Only <webkit2/webkit2.h> can be included directly."
+#endif
+
+#ifndef WebKitNetworkProxySettings_h
+#define WebKitNetworkProxySettings_h
+
+#include <glib-object.h>
+#include <webkit2/WebKitDefines.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_NETWORK_NETWORK_PROXY_SETTINGS (webkit_network_proxy_settings_get_type())
+
+typedef struct _WebKitNetworkProxySettings WebKitNetworkProxySettings;
+
+WEBKIT_API GType
+webkit_network_proxy_settings_get_type             (void);
+
+WEBKIT_API WebKitNetworkProxySettings *
+webkit_network_proxy_settings_new                  (const gchar                *default_proxy_uri,
+                                                    const gchar* const         *ignore_hosts);
+
+WEBKIT_API WebKitNetworkProxySettings *
+webkit_network_proxy_settings_copy                 (WebKitNetworkProxySettings *proxy_settings);
+
+WEBKIT_API void
+webkit_network_proxy_settings_free                 (WebKitNetworkProxySettings *proxy_settings);
+
+WEBKIT_API void
+webkit_network_proxy_settings_add_proxy_for_scheme (WebKitNetworkProxySettings *proxy_settings,
+                                                    const gchar                *scheme,
+                                                    const gchar                *proxy_uri);
+
+G_END_DECLS
+
+#endif /* WebKitNetworkProxySettings_h */
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettingsPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettingsPrivate.h
new file mode 100644 (file)
index 0000000..9691226
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2017 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "WebKitNetworkProxySettings.h"
+#include "WebKitPrivate.h"
+#include <WebCore/SoupNetworkProxySettings.h>
+
+const WebCore::SoupNetworkProxySettings& webkitNetworkProxySettingsGetNetworkProxySettings(WebKitNetworkProxySettings*);
index a99260e..b93e643 100644 (file)
@@ -37,6 +37,7 @@
 #include "WebKitFaviconDatabasePrivate.h"
 #include "WebKitGeolocationProvider.h"
 #include "WebKitInjectedBundleClient.h"
+#include "WebKitNetworkProxySettingsPrivate.h"
 #include "WebKitNotificationProvider.h"
 #include "WebKitPluginPrivate.h"
 #include "WebKitPrivate.h"
@@ -575,6 +576,47 @@ void webkit_web_context_clear_cache(WebKitWebContext* context)
     websiteDataStore.removeData(websiteDataTypes, std::chrono::system_clock::time_point::min(), [] { });
 }
 
+/**
+ * webkit_web_context_set_network_proxy_settings:
+ * @context: a #WebKitWebContext
+ * @proxy_mode: a #WebKitNetworkProxyMode
+ * @proxy_settings: (allow-none): a #WebKitNetworkProxySettings, or %NULL
+ *
+ * Set the network proxy settings to be used by connections started in @context.
+ * By default %WEBKIT_NETWORK_PROXY_MODE_DEFAULT is used, which means that the
+ * system settings will be used (g_proxy_resolver_get_default()).
+ * If you want to override the system default settings, you can either use
+ * %WEBKIT_NETWORK_PROXY_MODE_NO_PROXY to make sure no proxies are used at all,
+ * or %WEBKIT_NETWORK_PROXY_MODE_CUSTOM to provide your own proxy settings.
+ * When @proxy_mode is %WEBKIT_NETWORK_PROXY_MODE_CUSTOM @proxy_settings must be
+ * a valid #WebKitNetworkProxySettings; otherwise, @proxy_settings must be %NULL.
+ *
+ * Since: 2.16
+ */
+void webkit_web_context_set_network_proxy_settings(WebKitWebContext* context, WebKitNetworkProxyMode proxyMode, WebKitNetworkProxySettings* proxySettings)
+{
+    g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context));
+    g_return_if_fail((proxyMode != WEBKIT_NETWORK_PROXY_MODE_CUSTOM && !proxySettings) || (proxyMode == WEBKIT_NETWORK_PROXY_MODE_CUSTOM && proxySettings));
+
+    WebKitWebContextPrivate* priv = context->priv;
+    switch (proxyMode) {
+    case WEBKIT_NETWORK_PROXY_MODE_DEFAULT:
+        priv->processPool->setNetworkProxySettings({ });
+        break;
+    case WEBKIT_NETWORK_PROXY_MODE_NO_PROXY:
+        priv->processPool->setNetworkProxySettings(WebCore::SoupNetworkProxySettings(WebCore::SoupNetworkProxySettings::Mode::NoProxy));
+        break;
+    case WEBKIT_NETWORK_PROXY_MODE_CUSTOM:
+        const auto& settings = webkitNetworkProxySettingsGetNetworkProxySettings(proxySettings);
+        if (settings.isEmpty()) {
+            g_warning("Invalid attempt to set custom network proxy settings with an empty WebKitNetworkProxySettings. Use "
+                "WEBKIT_NETWORK_PROXY_MODE_NO_PROXY to not use any proxy or WEBKIT_NETWORK_PROXY_MODE_DEFAULT to use the default system settings");
+        } else
+            priv->processPool->setNetworkProxySettings(settings);
+        break;
+    }
+}
+
 typedef HashMap<DownloadProxy*, GRefPtr<WebKitDownload> > DownloadsMap;
 
 static DownloadsMap& downloadsMap()
index fc3793a..a1c6f8b 100644 (file)
@@ -29,6 +29,7 @@
 #include <webkit2/WebKitDefines.h>
 #include <webkit2/WebKitDownload.h>
 #include <webkit2/WebKitFaviconDatabase.h>
+#include <webkit2/WebKitNetworkProxySettings.h>
 #include <webkit2/WebKitSecurityManager.h>
 #include <webkit2/WebKitURISchemeRequest.h>
 #include <webkit2/WebKitWebsiteDataManager.h>
@@ -104,6 +105,22 @@ typedef enum {
 } WebKitTLSErrorsPolicy;
 
 /**
+ * WebKitNetworkProxyMode:
+ * @WEBKIT_NETWORK_PROXY_MODE_DEFAULT: Use the default proxy of the system.
+ * @WEBKIT_NETWORK_PROXY_MODE_NO_PROXY: Do not use any proxy.
+ * @WEBKIT_NETWORK_PROXY_MODE_CUSTOM: Use custom proxy settings.
+ *
+ * Enum values used to set the network proxy mode.
+ *
+ * Since: 2.16
+ */
+typedef enum {
+    WEBKIT_NETWORK_PROXY_MODE_DEFAULT,
+    WEBKIT_NETWORK_PROXY_MODE_NO_PROXY,
+    WEBKIT_NETWORK_PROXY_MODE_CUSTOM
+} WebKitNetworkProxyMode;
+
+/**
  * WebKitURISchemeRequestCallback:
  * @request: the #WebKitURISchemeRequest
  * @user_data: user data passed to the callback
@@ -171,6 +188,11 @@ webkit_web_context_get_web_process_count_limit      (WebKitWebContext
 WEBKIT_API void
 webkit_web_context_clear_cache                      (WebKitWebContext              *context);
 
+WEBKIT_API void
+webkit_web_context_set_network_proxy_settings       (WebKitWebContext              *context,
+                                                     WebKitNetworkProxyMode         proxy_mode,
+                                                     WebKitNetworkProxySettings    *proxy_settings);
+
 WEBKIT_API WebKitDownload *
 webkit_web_context_download_uri                     (WebKitWebContext              *context,
                                                      const gchar                   *uri);
index 35a053e..a374c63 100644 (file)
@@ -27,6 +27,7 @@ WebKitWebContext
 WebKitCacheModel
 WebKitProcessModel
 WebKitTLSErrorsPolicy
+WebKitNetworkProxyMode
 webkit_web_context_get_default
 webkit_web_context_new
 webkit_web_context_new_with_website_data_manager
@@ -36,6 +37,7 @@ webkit_web_context_set_cache_model
 webkit_web_context_get_web_process_count_limit
 webkit_web_context_set_web_process_count_limit
 webkit_web_context_clear_cache
+webkit_web_context_set_network_proxy_settings
 webkit_web_context_download_uri
 webkit_web_context_get_cookie_manager
 webkit_web_context_get_favicon_database
@@ -1258,6 +1260,21 @@ webkit_website_data_manager_get_type
 </SECTION>
 
 <SECTION>
+<FILE>WebKitNetworkProxySettings</FILE>
+WebKitNetworkProxySettings
+webkit_network_proxy_settings_new
+webkit_network_proxy_settings_copy
+webkit_network_proxy_settings_free
+webkit_network_proxy_settings_add_proxy_for_scheme
+
+<SUBSECTION Private>
+webkit_network_proxy_settings_get_type
+
+<SUBSECTION Standard>
+WEBKIT_TYPE_NETWORK_NETWORK_PROXY_SETTINGS
+</SECTION>
+
+<SECTION>
 <FILE>WebKitWebExtension</FILE>
 WebKitWebExtension
 WebKitWebExtensionInitializeFunction
index 024e9b8..8dc3e61 100644 (file)
@@ -53,6 +53,7 @@
     <xi:include href="xml/WebKitNotificationPermissionRequest.xml"/>
     <xi:include href="xml/WebKitSecurityOrigin.xml"/>
     <xi:include href="xml/WebKitWebsiteDataManager.xml"/>
+    <xi:include href="xml/WebKitNetworkProxySettings.xml"/>
   </chapter>
 
   <chapter>
index fc0fa4e..98fe129 100644 (file)
@@ -53,6 +53,7 @@
 #include <webkit2/WebKitMimeInfo.h>
 #include <webkit2/WebKitNavigationAction.h>
 #include <webkit2/WebKitNavigationPolicyDecision.h>
+#include <webkit2/WebKitNetworkProxySettings.h>
 #include <webkit2/WebKitNotification.h>
 #include <webkit2/WebKitNotificationPermissionRequest.h>
 #include <webkit2/WebKitPermissionRequest.h>
index d30174f..d9b8603 100644 (file)
 #include "WebMediaSessionFocusManager.h"
 #endif
 
+#if USE(SOUP)
+#include <WebCore/SoupNetworkProxySettings.h>
+#endif
+
 #if PLATFORM(COCOA)
 OBJC_CLASS NSMutableDictionary;
 OBJC_CLASS NSObject;
@@ -221,6 +225,7 @@ public:
 
 #if USE(SOUP)
     void setInitialHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy policy) { m_initialHTTPCookieAcceptPolicy = policy; }
+    void setNetworkProxySettings(const WebCore::SoupNetworkProxySettings&);
 #endif
     void setEnhancedAccessibility(bool);
     
@@ -516,6 +521,7 @@ private:
 
 #if USE(SOUP)
     HTTPCookieAcceptPolicy m_initialHTTPCookieAcceptPolicy { HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain };
+    WebCore::SoupNetworkProxySettings m_networkProxySettings;
 #endif
 
 #if PLATFORM(MAC)
index 470f324..55ad2f4 100644 (file)
@@ -93,6 +93,7 @@ String WebProcessPool::legacyPlatformDefaultMediaCacheDirectory()
 void WebProcessPool::platformInitializeWebProcess(WebProcessCreationParameters& parameters)
 {
     initializeInspectorServer();
+    parameters.proxySettings = m_networkProxySettings;
 }
 
 void WebProcessPool::platformInvalidateContext()
index ac3687d..4daf672 100644 (file)
@@ -93,6 +93,7 @@ void WebProcessPool::platformInitializeWebProcess(WebProcessCreationParameters&
 {
     initInspectorServer();
     parameters.memoryCacheDisabled = m_memoryCacheDisabled || cacheModel() == CacheModelDocumentViewer;
+    parameters.proxySettings = m_networkProxySettings;
 }
 
 void WebProcessPool::platformInvalidateContext()
index 4e42c5a..65b09c4 100644 (file)
@@ -30,6 +30,8 @@
 #include "NetworkProcessCreationParameters.h"
 #include "NetworkProcessMessages.h"
 #include "WebCookieManagerProxy.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebProcessMessages.h"
 #include <WebCore/Language.h>
 
 namespace WebKit {
@@ -43,6 +45,7 @@ void WebProcessPool::platformInitializeNetworkProcess(NetworkProcessCreationPara
     for (const auto& scheme : m_urlSchemesRegisteredForCustomProtocols)
         parameters.urlSchemesRegisteredForCustomProtocols.append(scheme);
     parameters.shouldEnableNetworkCacheEfficacyLogging = false;
+    parameters.proxySettings = m_networkProxySettings;
 }
 
 void WebProcessPool::setIgnoreTLSErrors(bool ignoreTLSErrors)
@@ -60,4 +63,12 @@ void WebProcessPool::setCustomProtocolManagerClient(std::unique_ptr<API::CustomP
         m_customProtocolManagerClient = WTFMove(customProtocolManagerClient);
 }
 
+void WebProcessPool::setNetworkProxySettings(const WebCore::SoupNetworkProxySettings& settings)
+{
+    m_networkProxySettings = settings;
+    sendToAllProcesses(Messages::WebProcess::SetNetworkProxySettings(m_networkProxySettings));
+    if (m_networkProcess)
+        m_networkProcess->send(Messages::NetworkProcess::SetNetworkProxySettings(m_networkProxySettings), 0);
+}
+
 }
index 354464a..6ebccbb 100644 (file)
@@ -67,6 +67,7 @@ class SessionID;
 class UserGestureToken;
 struct PluginInfo;
 struct SecurityOriginData;
+struct SoupNetworkProxySettings;
 }
 
 namespace WebKit {
@@ -285,6 +286,10 @@ private:
     void gamepadDisconnected(unsigned index);
 #endif
 
+#if USE(SOUP)
+    void setNetworkProxySettings(const WebCore::SoupNetworkProxySettings&);
+#endif
+
     void releasePageCache();
 
     void fetchWebsiteData(WebCore::SessionID, OptionSet<WebsiteDataType>, WebsiteData&);
index 2c8f5fe..aa617ef 100644 (file)
@@ -108,4 +108,8 @@ messages -> WebProcess LegacyReceiver {
     GamepadConnected(WebKit::GamepadData gamepadData)
     GamepadDisconnected(unsigned index)
 #endif
+
+#if USE(SOUP)
+    SetNetworkProxySettings(struct WebCore::SoupNetworkProxySettings settings)
+#endif
 }
index 72e6af0..b7bca52 100644 (file)
@@ -32,7 +32,6 @@
 #include <Ecore_Evas.h>
 #include <Edje.h>
 #include <Efreet.h>
-#include <WebCore/NetworkStorageSession.h>
 #include <WebCore/SoupNetworkSession.h>
 #include <libsoup/soup.h>
 
@@ -99,7 +98,8 @@ public:
         if (!ecore_main_loop_glib_integrate())
             return false;
 
-        NetworkStorageSession::defaultStorageSession().getOrCreateSoupNetworkSession().setupHTTPProxyFromEnvironment();
+        SoupNetworkSession::setProxySettingsFromEnvironment();
+
         return true;
     }
 
index 0d69060..c854cd7 100644 (file)
 
 #include "WebProcessCreationParameters.h"
 #include <WebCore/MemoryCache.h>
+#include <WebCore/NetworkStorageSession.h>
+#include <WebCore/SoupNetworkSession.h>
 
 namespace WebKit {
 
 void WebProcess::platformSetCacheModel(CacheModel cacheModel)
 {
-    // FIXME: this is no longer soup specific, this file should be renamed.
     WebCore::MemoryCache::singleton().setDisabled(cacheModel == CacheModelDocumentViewer);
 }
 
-void WebProcess::platformInitializeWebProcess(WebProcessCreationParameters&&)
+void WebProcess::platformInitializeWebProcess(WebProcessCreationParameters&& parameters)
 {
+    if (parameters.proxySettings.mode != WebCore::SoupNetworkProxySettings::Mode::Default)
+        setNetworkProxySettings(parameters.proxySettings);
 }
 
 void WebProcess::platformTerminate()
 {
 }
 
+void WebProcess::setNetworkProxySettings(const WebCore::SoupNetworkProxySettings& settings)
+{
+    WebCore::SoupNetworkSession::setProxySettings(settings);
+    WebCore::NetworkStorageSession::forEach([](const WebCore::NetworkStorageSession& session) {
+        if (auto* soupSession = session.soupNetworkSession())
+            soupSession->setupProxy();
+    });
+}
+
 } // namespace WebKit
index ef4ad3f..f6903d5 100644 (file)
@@ -1,3 +1,21 @@
+2017-01-19  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [GTK] Provide API to set proxy settings
+        https://bugs.webkit.org/show_bug.cgi?id=128674
+
+        Reviewed by Michael Catanzaro.
+
+        Add tests for new proxy settings API.
+
+        * TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitWebContext.cpp:
+        (serverCallback):
+        (ProxyTest::ProxyTest):
+        (ProxyTest::~ProxyTest):
+        (ProxyTest::loadURIAndGetMainResourceData):
+        (ProxyTest::proxyServerPortAsString):
+        (testWebContextProxySettings):
+        (beforeAll):
+
 2017-01-19  Timothy Hatcher  <timothy@hatcher.name>
 
         Add back my old email address so old commits will still match it.
index a755a72..314e780 100644 (file)
@@ -550,6 +550,11 @@ static void serverCallback(SoupServer* server, SoupMessage* message, const char*
         soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, "foo", 3);
         soup_message_body_complete(message->response_body);
         soup_message_set_status(message, SOUP_STATUS_OK);
+    } else if (g_str_equal(path, "/echoPort")) {
+        char* port = g_strdup_printf("%u", soup_server_get_port(server));
+        soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, port, strlen(port));
+        soup_message_body_complete(message->response_body);
+        soup_message_set_status(message, SOUP_STATUS_OK);
     } else
         soup_message_set_status(message, SOUP_STATUS_NOT_FOUND);
 }
@@ -700,6 +705,90 @@ static void testWebContextSecurityFileXHR(WebViewTest* test, gconstpointer)
     webkit_settings_set_allow_file_access_from_file_urls(webkit_web_view_get_settings(test->m_webView), FALSE);
 }
 
+class ProxyTest : public WebViewTest {
+public:
+    MAKE_GLIB_TEST_FIXTURE(ProxyTest);
+
+    ProxyTest()
+    {
+        // This "proxy server" is actually just a different instance of the main
+        // test server (kServer), listening on a different port. Requests
+        // will not actually be proxied to kServer because proxyServer is not
+        // actually a proxy server. We're testing whether the proxy settings
+        // work, not whether we can write a soup proxy server.
+        m_proxyServer.run(serverCallback);
+        g_assert(m_proxyServer.baseURI());
+    }
+
+    CString loadURIAndGetMainResourceData(const char* uri)
+    {
+        loadURI(uri);
+        waitUntilLoadFinished();
+        size_t dataSize = 0;
+        const char* data = mainResourceData(dataSize);
+        return CString(data, dataSize);
+    }
+
+    GUniquePtr<char> proxyServerPortAsString()
+    {
+        GUniquePtr<char> port(g_strdup_printf("%u", soup_uri_get_port(m_proxyServer.baseURI())));
+        return port;
+    }
+
+    WebKitTestServer m_proxyServer;
+};
+
+static void testWebContextProxySettings(ProxyTest* test, gconstpointer)
+{
+    // Proxy URI is unset by default. Requests to kServer should be received by kServer.
+    GUniquePtr<char> serverPortAsString(g_strdup_printf("%u", soup_uri_get_port(kServer->baseURI())));
+    auto mainResourceData = test->loadURIAndGetMainResourceData(kServer->getURIForPath("/echoPort").data());
+    ASSERT_CMP_CSTRING(mainResourceData, ==, serverPortAsString.get());
+
+    // Set default proxy URI to point to proxyServer. Requests to kServer should be received by proxyServer instead.
+    GUniquePtr<char> proxyURI(soup_uri_to_string(test->m_proxyServer.baseURI(), FALSE));
+    WebKitNetworkProxySettings* settings = webkit_network_proxy_settings_new(proxyURI.get(), nullptr);
+    webkit_web_context_set_network_proxy_settings(test->m_webContext.get(), WEBKIT_NETWORK_PROXY_MODE_CUSTOM, settings);
+    GUniquePtr<char> proxyServerPortAsString = test->proxyServerPortAsString();
+    mainResourceData = test->loadURIAndGetMainResourceData(kServer->getURIForPath("/echoPort").data());
+    ASSERT_CMP_CSTRING(mainResourceData, ==, proxyServerPortAsString.get());
+    webkit_network_proxy_settings_free(settings);
+
+    // Remove the proxy. Requests to kServer should be received by kServer again.
+    webkit_web_context_set_network_proxy_settings(test->m_webContext.get(), WEBKIT_NETWORK_PROXY_MODE_NO_PROXY, nullptr);
+    mainResourceData = test->loadURIAndGetMainResourceData(kServer->getURIForPath("/echoPort").data());
+    ASSERT_CMP_CSTRING(mainResourceData, ==, serverPortAsString.get());
+
+    // Use a default proxy uri, but ignoring requests to localhost.
+    static const char* ignoreHosts[] = { "localhost", nullptr };
+    settings = webkit_network_proxy_settings_new(proxyURI.get(), ignoreHosts);
+    webkit_web_context_set_network_proxy_settings(test->m_webContext.get(), WEBKIT_NETWORK_PROXY_MODE_CUSTOM, settings);
+    mainResourceData = test->loadURIAndGetMainResourceData(kServer->getURIForPath("/echoPort").data());
+    ASSERT_CMP_CSTRING(mainResourceData, ==, proxyServerPortAsString.get());
+    GUniquePtr<char> localhostEchoPortURI(g_strdup_printf("http://localhost:%s/echoPort", serverPortAsString.get()));
+    mainResourceData = test->loadURIAndGetMainResourceData(localhostEchoPortURI.get());
+    ASSERT_CMP_CSTRING(mainResourceData, ==, serverPortAsString.get());
+    webkit_network_proxy_settings_free(settings);
+
+    // Remove the proxy again to ensure next test is not using any previous values.
+    webkit_web_context_set_network_proxy_settings(test->m_webContext.get(), WEBKIT_NETWORK_PROXY_MODE_NO_PROXY, nullptr);
+    mainResourceData = test->loadURIAndGetMainResourceData(kServer->getURIForPath("/echoPort").data());
+    ASSERT_CMP_CSTRING(mainResourceData, ==, serverPortAsString.get());
+
+    // Use scheme specific proxy instead of the default.
+    settings = webkit_network_proxy_settings_new(nullptr, nullptr);
+    webkit_network_proxy_settings_add_proxy_for_scheme(settings, "http", proxyURI.get());
+    webkit_web_context_set_network_proxy_settings(test->m_webContext.get(), WEBKIT_NETWORK_PROXY_MODE_CUSTOM, settings);
+    mainResourceData = test->loadURIAndGetMainResourceData(kServer->getURIForPath("/echoPort").data());
+    ASSERT_CMP_CSTRING(mainResourceData, ==, proxyServerPortAsString.get());
+    webkit_network_proxy_settings_free(settings);
+
+    // Reset to use the default resolver.
+    webkit_web_context_set_network_proxy_settings(test->m_webContext.get(), WEBKIT_NETWORK_PROXY_MODE_DEFAULT, nullptr);
+    mainResourceData = test->loadURIAndGetMainResourceData(kServer->getURIForPath("/echoPort").data());
+    ASSERT_CMP_CSTRING(mainResourceData, ==, serverPortAsString.get());
+}
+
 void beforeAll()
 {
     kServer = new WebKitTestServer();
@@ -713,6 +802,7 @@ void beforeAll()
     WebViewTest::add("WebKitWebContext", "languages", testWebContextLanguages);
     SecurityPolicyTest::add("WebKitSecurityManager", "security-policy", testWebContextSecurityPolicy);
     WebViewTest::add("WebKitSecurityManager", "file-xhr", testWebContextSecurityFileXHR);
+    ProxyTest::add("WebKitWebContext", "proxy", testWebContextProxySettings);
 }
 
 void afterAll()