/*
 * Copyright (C) 2012 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 "LoadTrackingTest.h"
#include "WebKitTestServer.h"
#include <WebCore/SoupVersioning.h>

static WebKitTestServer* kHttpsServer;
static WebKitTestServer* kHttpServer;

static const char* indexHTML = "<html><body>Testing WebKit2GTK+ SSL</body></htmll>";
static const char* insecureContentHTML = "<html><script src=\"%s\"></script><body><p>Text + image <img src=\"%s\" align=\"right\"/></p></body></html>";
static const char TLSExpectedSuccessTitle[] = "WebKit2Gtk+ TLS permission test";
static const char TLSSuccessHTMLString[] = "<html><head><title>WebKit2Gtk+ TLS permission test</title></head><body></body></html>";

class SSLTest: public LoadTrackingTest {
public:
    MAKE_GLIB_TEST_FIXTURE(SSLTest);

    SSLTest()
        : m_tlsErrors(static_cast<GTlsCertificateFlags>(0))
    {
    }

    virtual void provisionalLoadFailed(const gchar* failingURI, GError* error)
    {
        g_assert_error(error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
        LoadTrackingTest::provisionalLoadFailed(failingURI, error);
    }

    virtual void loadCommitted()
    {
        GTlsCertificate* certificate = 0;
        webkit_web_view_get_tls_info(m_webView, &certificate, &m_tlsErrors);
        m_certificate = certificate;
        LoadTrackingTest::loadCommitted();
    }

    void waitUntilLoadFinished()
    {
        m_certificate = 0;
        m_tlsErrors = static_cast<GTlsCertificateFlags>(0);
        LoadTrackingTest::waitUntilLoadFinished();
    }

    GRefPtr<GTlsCertificate> m_certificate;
    GTlsCertificateFlags m_tlsErrors;
};

static void testSSL(SSLTest* test, gconstpointer)
{
    auto* websiteDataManager = webkit_web_context_get_website_data_manager(test->m_webContext.get());
    WebKitTLSErrorsPolicy originalPolicy = webkit_website_data_manager_get_tls_errors_policy(websiteDataManager);
    webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, WEBKIT_TLS_ERRORS_POLICY_IGNORE);

    test->loadURI(kHttpsServer->getURIForPath("/").data());
    test->waitUntilLoadFinished();
    g_assert_nonnull(test->m_certificate);
    // Self-signed certificate has a nullptr issuer.
    g_assert_null(g_tls_certificate_get_issuer(test->m_certificate.get()));
    // We always expect errors because we are using a self-signed certificate,
    // but only G_TLS_CERTIFICATE_UNKNOWN_CA flags should be present.
    g_assert_cmpuint(test->m_tlsErrors, ==, G_TLS_CERTIFICATE_UNKNOWN_CA);

    // Non HTTPS loads shouldn't have a certificate nor errors.
    test->loadHtml(indexHTML, 0);
    test->waitUntilLoadFinished();
    g_assert_null(test->m_certificate);
    g_assert_cmpuint(test->m_tlsErrors, ==, 0);

    webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, originalPolicy);
}

class InsecureContentTest: public WebViewTest {
public:
    MAKE_GLIB_TEST_FIXTURE(InsecureContentTest);

    InsecureContentTest()
        : m_insecureContentRun(false)
        , m_insecureContentDisplayed(false)
    {
        g_signal_connect(m_webView, "insecure-content-detected", G_CALLBACK(insecureContentDetectedCallback), this);
    }

    static void insecureContentDetectedCallback(WebKitWebView* webView, WebKitInsecureContentEvent event, InsecureContentTest* test)
    {
        g_assert_true(webView == test->m_webView);

        if (event == WEBKIT_INSECURE_CONTENT_RUN)
            test->m_insecureContentRun = true;

        if (event == WEBKIT_INSECURE_CONTENT_DISPLAYED)
            test->m_insecureContentDisplayed = true;
    }

    bool m_insecureContentRun;
    bool m_insecureContentDisplayed;
};

static void testInsecureContent(InsecureContentTest* test, gconstpointer)
{
    auto* websiteDataManager = webkit_web_context_get_website_data_manager(test->m_webContext.get());
    WebKitTLSErrorsPolicy originalPolicy = webkit_website_data_manager_get_tls_errors_policy(websiteDataManager);
    webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, WEBKIT_TLS_ERRORS_POLICY_IGNORE);

    test->loadURI(kHttpsServer->getURIForPath("/insecure-content/").data());
    test->waitUntilLoadFinished();

    g_assert_false(test->m_insecureContentRun);
    // Images are currently always displayed, even bypassing mixed content settings. Check
    // https://bugs.webkit.org/show_bug.cgi?id=142469
    g_assert_true(test->m_insecureContentDisplayed);

    webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, originalPolicy);
}

static bool assertIfSSLRequestProcessed = false;

static void testTLSErrorsPolicy(SSLTest* test, gconstpointer)
{
    auto* websiteDataManager = webkit_web_context_get_website_data_manager(test->m_webContext.get());
    // TLS errors are treated as transport failures by default.
    g_assert_cmpint(webkit_website_data_manager_get_tls_errors_policy(websiteDataManager), ==, WEBKIT_TLS_ERRORS_POLICY_FAIL);

    assertIfSSLRequestProcessed = true;
    test->loadURI(kHttpsServer->getURIForPath("/").data());
    test->waitUntilLoadFinished();
    g_assert_true(test->m_loadFailed);
    g_assert_true(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed));
    g_assert_false(test->m_loadEvents.contains(LoadTrackingTest::LoadCommitted));
    assertIfSSLRequestProcessed = false;

    webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, WEBKIT_TLS_ERRORS_POLICY_IGNORE);
    g_assert_cmpint(webkit_website_data_manager_get_tls_errors_policy(websiteDataManager), ==, WEBKIT_TLS_ERRORS_POLICY_IGNORE);

    test->m_loadFailed = false;
    test->loadURI(kHttpsServer->getURIForPath("/").data());
    test->waitUntilLoadFinished();
    g_assert_false(test->m_loadFailed);

    // An ephemeral web view should keep the same network settings by default.
    auto webView = Test::adoptView(g_object_new(WEBKIT_TYPE_WEB_VIEW,
#if PLATFORM(WPE)
        "backend", Test::createWebViewBackend(),
#endif
        "web-context", test->m_webContext.get(),
        "is-ephemeral", TRUE,
        nullptr));
    g_assert_true(webkit_web_view_is_ephemeral(webView.get()));
    g_assert_false(webkit_web_context_is_ephemeral(test->m_webContext.get()));
    auto* webViewDataManager = webkit_web_view_get_website_data_manager(webView.get());
    g_assert_false(websiteDataManager == webViewDataManager);
    g_assert_cmpint(webkit_website_data_manager_get_tls_errors_policy(websiteDataManager), ==, webkit_website_data_manager_get_tls_errors_policy(webViewDataManager));

    webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, WEBKIT_TLS_ERRORS_POLICY_FAIL);
    g_assert_cmpint(webkit_website_data_manager_get_tls_errors_policy(websiteDataManager), ==, WEBKIT_TLS_ERRORS_POLICY_FAIL);
}

static void testTLSErrorsRedirect(SSLTest* test, gconstpointer)
{
    auto* websiteDataManager = webkit_web_context_get_website_data_manager(test->m_webContext.get());
    WebKitTLSErrorsPolicy originalPolicy = webkit_website_data_manager_get_tls_errors_policy(websiteDataManager);
    webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, WEBKIT_TLS_ERRORS_POLICY_FAIL);

    assertIfSSLRequestProcessed = true;
    test->loadURI(kHttpsServer->getURIForPath("/redirect").data());
    test->waitUntilLoadFinished();
    g_assert_true(test->m_loadFailed);
    g_assert_true(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed));
    g_assert_false(test->m_loadEvents.contains(LoadTrackingTest::LoadCommitted));
    assertIfSSLRequestProcessed = false;

    webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, originalPolicy);
}

static gboolean webViewAuthenticationCallback(WebKitWebView*, WebKitAuthenticationRequest* request)
{
    g_assert_not_reached();
    return TRUE;
}


static void testTLSErrorsHTTPAuth(SSLTest* test, gconstpointer)
{
    auto* websiteDataManager = webkit_web_context_get_website_data_manager(test->m_webContext.get());
    WebKitTLSErrorsPolicy originalPolicy = webkit_website_data_manager_get_tls_errors_policy(websiteDataManager);
    webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, WEBKIT_TLS_ERRORS_POLICY_FAIL);

    assertIfSSLRequestProcessed = true;
    g_signal_connect(test->m_webView, "authenticate", G_CALLBACK(webViewAuthenticationCallback), NULL);
    test->loadURI(kHttpsServer->getURIForPath("/auth").data());
    test->waitUntilLoadFinished();
    g_assert_true(test->m_loadFailed);
    g_assert_true(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed));
    g_assert_false(test->m_loadEvents.contains(LoadTrackingTest::LoadCommitted));
    assertIfSSLRequestProcessed = false;

    webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, originalPolicy);
}

class TLSErrorsTest: public SSLTest {
public:
    MAKE_GLIB_TEST_FIXTURE(TLSErrorsTest);

    TLSErrorsTest()
        : m_tlsErrors(static_cast<GTlsCertificateFlags>(0))
    {
    }

    bool loadFailedWithTLSErrors(const char* failingURI, GTlsCertificate* certificate, GTlsCertificateFlags tlsErrors) override
    {
        LoadTrackingTest::loadFailedWithTLSErrors(failingURI, certificate, tlsErrors);

        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(certificate));
        m_certificate = certificate;
        m_tlsErrors = tlsErrors;
        m_failingURL = URL({ }, failingURI);
        return true;
    }

    GTlsCertificate* certificate() const { return m_certificate.get(); }
    GTlsCertificateFlags tlsErrors() const { return m_tlsErrors; }
    CString host() const { return m_failingURL.host().toString().utf8(); }

private:
    GRefPtr<GTlsCertificate> m_certificate;
    GTlsCertificateFlags m_tlsErrors;
    URL m_failingURL;
};

static void testLoadFailedWithTLSErrors(TLSErrorsTest* test, gconstpointer)
{
    auto* websiteDataManager = webkit_web_context_get_website_data_manager(test->m_webContext.get());
    WebKitTLSErrorsPolicy originalPolicy = webkit_website_data_manager_get_tls_errors_policy(websiteDataManager);
    webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, WEBKIT_TLS_ERRORS_POLICY_FAIL);

    assertIfSSLRequestProcessed = true;
    // The load-failed-with-tls-errors signal should be emitted when there is a TLS failure.
    test->loadURI(kHttpsServer->getURIForPath("/test-tls/").data());
    test->waitUntilLoadFinished();
    g_assert_true(G_IS_TLS_CERTIFICATE(test->certificate()));
    g_assert_cmpuint(test->tlsErrors(), ==, G_TLS_CERTIFICATE_UNKNOWN_CA);
    ASSERT_CMP_CSTRING(test->host(), ==, kHttpsServer->baseURL().host().toString().utf8());
    g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted);
    g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::LoadFailedWithTLSErrors);
    g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished);
    assertIfSSLRequestProcessed = false;

    // Test allowing an exception for this certificate on this host.
    webkit_web_context_allow_tls_certificate_for_host(test->m_webContext.get(), test->certificate(), test->host().data());
    // The page should now load without errors.
    test->loadURI(kHttpsServer->getURIForPath("/test-tls/").data());
    test->waitUntilTitleChanged();

    g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted);
    g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::LoadCommitted);
    g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished);
    g_assert_cmpstr(webkit_web_view_get_title(test->m_webView), ==, TLSExpectedSuccessTitle);

    webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, originalPolicy);
}

class TLSSubresourceTest : public WebViewTest {
public:
    MAKE_GLIB_TEST_FIXTURE(TLSSubresourceTest);

    static void resourceLoadStartedCallback(WebKitWebView* webView, WebKitWebResource* resource, WebKitURIRequest* request, TLSSubresourceTest* test)
    {
        if (webkit_web_view_get_main_resource(test->m_webView) == resource)
            return;

        // Ignore favicons.
        if (g_str_has_suffix(webkit_uri_request_get_uri(request), "favicon.ico"))
            return;

        test->subresourceLoadStarted(resource);
    }

    TLSSubresourceTest()
        : m_tlsErrors(static_cast<GTlsCertificateFlags>(0))
    {
        g_signal_connect(m_webView, "resource-load-started", G_CALLBACK(resourceLoadStartedCallback), this);
    }

    static void subresourceFailedCallback(WebKitWebResource*, GError*)
    {
        g_assert_not_reached();
    }

    static void subresourceFailedWithTLSErrorsCallback(WebKitWebResource* resource, GTlsCertificate* certificate, GTlsCertificateFlags tlsErrors, TLSSubresourceTest* test)
    {
        test->subresourceFailedWithTLSErrors(resource, certificate, tlsErrors);
    }

    void subresourceLoadStarted(WebKitWebResource* resource)
    {
        g_signal_connect(resource, "failed", G_CALLBACK(subresourceFailedCallback), nullptr);
        g_signal_connect(resource, "failed-with-tls-errors", G_CALLBACK(subresourceFailedWithTLSErrorsCallback), this);
    }

    void subresourceFailedWithTLSErrors(WebKitWebResource* resource, GTlsCertificate* certificate, GTlsCertificateFlags tlsErrors)
    {
        m_certificate = certificate;
        m_tlsErrors = tlsErrors;
        g_main_loop_quit(m_mainLoop);
    }

    void waitUntilSubresourceLoadFail()
    {
        g_main_loop_run(m_mainLoop);
    }

    GRefPtr<GTlsCertificate> m_certificate;
    GTlsCertificateFlags m_tlsErrors;
};

static void testSubresourceLoadFailedWithTLSErrors(TLSSubresourceTest* test, gconstpointer)
{
    auto* websiteDataManager = webkit_web_context_get_website_data_manager(test->m_webContext.get());
    webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, WEBKIT_TLS_ERRORS_POLICY_FAIL);

    assertIfSSLRequestProcessed = true;
    test->loadURI(kHttpServer->getURIForPath("/").data());
    test->waitUntilSubresourceLoadFail();
    g_assert_true(G_IS_TLS_CERTIFICATE(test->m_certificate.get()));
    g_assert_cmpuint(test->m_tlsErrors, ==, G_TLS_CERTIFICATE_UNKNOWN_CA);
    assertIfSSLRequestProcessed = false;
}

class WebSocketTest : public WebViewTest {
public:
    MAKE_GLIB_TEST_FIXTURE(WebSocketTest);

    enum EventFlags {
        None = 0,
        DidServerCompleteHandshake = 1 << 0,
        DidOpen = 1 << 1,
        DidClose = 1 << 2
    };

    WebSocketTest()
    {
        webkit_user_content_manager_register_script_message_handler(m_userContentManager.get(), "event");
        g_signal_connect(m_userContentManager.get(), "script-message-received::event", G_CALLBACK(webSocketTestResultCallback), this);
    }

    virtual ~WebSocketTest()
    {
        webkit_user_content_manager_unregister_script_message_handler(m_userContentManager.get(), "event");
        g_signal_handlers_disconnect_by_data(m_userContentManager.get(), this);
    }

    static constexpr const char* webSocketTestJSFormat =
        "var socket = new WebSocket('%s');"
        "socket.addEventListener('open', onOpen);"
        "socket.addEventListener('close', onClose);"
        "function onOpen() {"
        "    window.webkit.messageHandlers.event.postMessage('open');"
        "    socket.removeEventListener('close', onClose);"
        "}"
        "function onClose() {"
        "    window.webkit.messageHandlers.event.postMessage('close');"
        "    socket.removeEventListener('open', onOpen);"
        "}";

#if USE(SOUP2)
    static void serverWebSocketCallback(SoupServer*, SoupWebsocketConnection*, const char*, SoupClientContext*, gpointer userData)
#else
    static void serverWebSocketCallback(SoupServer*, SoupServerMessage*, const char*, SoupWebsocketConnection*, gpointer userData)
#endif
    {
        static_cast<WebSocketTest*>(userData)->m_events |= WebSocketTest::EventFlags::DidServerCompleteHandshake;
    }

    static void webSocketTestResultCallback(WebKitUserContentManager*, WebKitJavascriptResult* javascriptResult, WebSocketTest* test)
    {
        GUniquePtr<char> event(WebViewTest::javascriptResultToCString(javascriptResult));
        if (!g_strcmp0(event.get(), "open"))
            test->m_events |= WebSocketTest::EventFlags::DidOpen;
        else if (!g_strcmp0(event.get(), "close"))
            test->m_events |= WebSocketTest::EventFlags::DidClose;
        else
            g_assert_not_reached();
        test->quitMainLoop();
    }

    unsigned connectToServerAndWaitForEvents(WebKitTestServer* server)
    {
        m_events = 0;

        server->addWebSocketHandler(serverWebSocketCallback, this);
        GUniquePtr<char> createWebSocketJS(g_strdup_printf(webSocketTestJSFormat, server->getWebSocketURIForPath("/foo").data()));
        webkit_web_view_run_javascript(m_webView, createWebSocketJS.get(), nullptr, nullptr, nullptr);
        g_main_loop_run(m_mainLoop);
        server->removeWebSocketHandler();

        return m_events;
    }

    unsigned m_events { 0 };
};

static void testWebSocketTLSErrors(WebSocketTest* test, gconstpointer)
{
    auto* websiteDataManager = webkit_web_context_get_website_data_manager(test->m_webContext.get());
    WebKitTLSErrorsPolicy originalPolicy = webkit_website_data_manager_get_tls_errors_policy(websiteDataManager);
    webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, WEBKIT_TLS_ERRORS_POLICY_FAIL);

    // First, check that insecure ws:// web sockets work fine.
    unsigned events = test->connectToServerAndWaitForEvents(kHttpServer);
    g_assert_true(events);
    g_assert_true(events & WebSocketTest::EventFlags::DidServerCompleteHandshake);
    g_assert_true(events & WebSocketTest::EventFlags::DidOpen);
    g_assert_false(events & WebSocketTest::EventFlags::DidClose);

    // Try again using wss:// this time. It should be blocked because the
    // server certificate is self-signed.
    events = test->connectToServerAndWaitForEvents(kHttpsServer);
    g_assert_true(events);
    g_assert_false(events & WebSocketTest::EventFlags::DidServerCompleteHandshake);
    g_assert_false(events & WebSocketTest::EventFlags::DidOpen);
    g_assert_true(events & WebSocketTest::EventFlags::DidClose);

    // Now try wss:// again, this time ignoring TLS errors.
    webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, WEBKIT_TLS_ERRORS_POLICY_IGNORE);
    events = test->connectToServerAndWaitForEvents(kHttpsServer);
    g_assert_true(events & WebSocketTest::EventFlags::DidServerCompleteHandshake);
    g_assert_true(events & WebSocketTest::EventFlags::DidOpen);
    g_assert_false(events & WebSocketTest::EventFlags::DidClose);

    webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, originalPolicy);
}

class EphemeralSSLTest : public SSLTest {
public:
    MAKE_GLIB_TEST_FIXTURE_WITH_SETUP_TEARDOWN(EphemeralSSLTest, setup, teardown);

    static void setup()
    {
        WebViewTest::shouldCreateEphemeralWebView = true;
    }

    static void teardown()
    {
        WebViewTest::shouldCreateEphemeralWebView = false;
    }
};

static void testTLSErrorsEphemeral(EphemeralSSLTest* test, gconstpointer)
{
    auto* websiteDataManager = webkit_web_view_get_website_data_manager(test->m_webView);
    g_assert_true(webkit_website_data_manager_is_ephemeral(websiteDataManager));
    g_assert_cmpint(webkit_website_data_manager_get_tls_errors_policy(websiteDataManager), ==, WEBKIT_TLS_ERRORS_POLICY_FAIL);

    test->loadURI(kHttpsServer->getURIForPath("/").data());
    test->waitUntilLoadFinished();
    g_assert_true(test->m_loadFailed);
    g_assert_true(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed));
    g_assert_false(test->m_loadEvents.contains(LoadTrackingTest::LoadCommitted));
}

#if !USE(SOUP2)
class ClientSideCertificateTest : public LoadTrackingTest {
public:
    MAKE_GLIB_TEST_FIXTURE(ClientSideCertificateTest);

    static gboolean acceptCertificateCallback(SoupServerMessage* message, GTlsCertificate* certificate, GTlsCertificateFlags errors, ClientSideCertificateTest* test)
    {
        bool acceptedCertificate = test->acceptCertificate(errors);
        g_object_set_data_full(G_OBJECT(message), acceptedCertificate ? "accepted-certificate" : "rejected-certificate", g_object_ref(certificate), g_object_unref);
        return acceptedCertificate;
    }

    static void requestStartedCallback(SoupServer*, SoupServerMessage* message, ClientSideCertificateTest* test)
    {
        g_signal_connect(message, "accept-certificate", G_CALLBACK(acceptCertificateCallback), test);
    }

    static gboolean authenticateCallback(WebKitWebView*, WebKitAuthenticationRequest* request, ClientSideCertificateTest* test)
    {
        test->authenticate(request);
        return TRUE;
    }

    ClientSideCertificateTest()
    {
        CString resourcesDir = Test::getResourcesDir();
        GUniquePtr<char> sslCertificateFile(g_build_filename(resourcesDir.data(), "test-cert.pem", nullptr));
        GUniquePtr<char> sslKeyFile(g_build_filename(resourcesDir.data(), "test-key.pem", nullptr));
        GUniqueOutPtr<GError> error;
        m_clientCertificate = adoptGRef(g_tls_certificate_new_from_files(sslCertificateFile.get(), sslKeyFile.get(), &error.outPtr()));
        g_assert_no_error(error.get());

        soup_server_set_tls_auth_mode(kHttpsServer->soupServer(), G_TLS_AUTHENTICATION_REQUIRED);
        g_signal_connect(kHttpsServer->soupServer(), "request-started", G_CALLBACK(requestStartedCallback), this);
        g_signal_connect(m_webView, "authenticate", G_CALLBACK(authenticateCallback), this);
    }

    ~ClientSideCertificateTest()
    {
        soup_server_set_tls_auth_mode(kHttpsServer->soupServer(), G_TLS_AUTHENTICATION_NONE);
        g_signal_handlers_disconnect_by_data(kHttpsServer->soupServer(), this);
    }

    void authenticate(WebKitAuthenticationRequest* request)
    {
        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request));
        m_authenticationRequest = request;
        g_main_loop_quit(m_mainLoop);
    }

    bool acceptCertificate(GTlsCertificateFlags errors)
    {
        if (m_rejectClientCertificates)
            return false;

        // We always expect errors because we are using a self-signed certificate,
        // but only G_TLS_CERTIFICATE_UNKNOWN_CA flags should be present.
        return !errors || errors == G_TLS_CERTIFICATE_UNKNOWN_CA;
    }

    WebKitAuthenticationRequest* waitForAuthenticationRequest()
    {
        m_authenticationRequest = nullptr;
        g_main_loop_run(m_mainLoop);
        return m_authenticationRequest.get();
    }

    GRefPtr<WebKitAuthenticationRequest> m_authenticationRequest;
    GRefPtr<GTlsCertificate> m_clientCertificate;
    bool m_rejectClientCertificates { false };
};

static void testClientSideCertificate(ClientSideCertificateTest* test, gconstpointer)
{
    // Ignore server certificate errors.
    auto* websiteDataManager = webkit_web_context_get_website_data_manager(test->m_webContext.get());
    WebKitTLSErrorsPolicy originalPolicy = webkit_website_data_manager_get_tls_errors_policy(websiteDataManager);
    webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, WEBKIT_TLS_ERRORS_POLICY_IGNORE);

    // Cancel the authentiation request.
    test->loadURI(kHttpsServer->getURIForPath("/").data());
    auto* request = test->waitForAuthenticationRequest();
    g_assert_cmpstr(webkit_authentication_request_get_realm(request), ==, "");
    g_assert_cmpint(webkit_authentication_request_get_scheme(request), ==, WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_REQUESTED);
    g_assert_false(webkit_authentication_request_is_for_proxy(request));
    g_assert_false(webkit_authentication_request_is_retry(request));
    auto* origin = webkit_authentication_request_get_security_origin(request);
    g_assert_nonnull(origin);
    ASSERT_CMP_CSTRING(webkit_security_origin_get_protocol(origin), ==, kHttpsServer->baseURL().protocol().toString().utf8());
    ASSERT_CMP_CSTRING(webkit_security_origin_get_host(origin), ==, kHttpsServer->baseURL().host().toString().utf8());
    g_assert_cmpuint(webkit_security_origin_get_port(origin), ==, kHttpsServer->port());
    webkit_security_origin_unref(origin);
    webkit_authentication_request_cancel(request);
    test->waitUntilLoadFinished();
    g_assert_cmpint(test->m_loadEvents.size(), ==, 3);
    g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted);
    g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::ProvisionalLoadFailed);
    g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished);
    g_assert_error(test->m_error.get(), WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED);
    test->m_loadEvents.clear();

    // Complete the request with no credential.
    test->loadURI(kHttpsServer->getURIForPath("/").data());
    request = test->waitForAuthenticationRequest();
    webkit_authentication_request_authenticate(request, nullptr);
    test->waitUntilLoadFinished();
    g_assert_cmpint(test->m_loadEvents.size(), ==, 3);
    g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted);
    g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::ProvisionalLoadFailed);
    g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished);
    // Sometimes glib-networking fails to report the error as certificate required and we end up
    // with connection reset by peer because the server closes the connection.
    if (!g_error_matches(test->m_error.get(), G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED))
        g_assert_error(test->m_error.get(), G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED);
    test->m_loadEvents.clear();

    // Complete the request with a credential with no certificate.
    test->loadURI(kHttpsServer->getURIForPath("/").data());
    request = test->waitForAuthenticationRequest();
    WebKitCredential* credential = webkit_credential_new_for_certificate(nullptr, WEBKIT_CREDENTIAL_PERSISTENCE_NONE);
    webkit_authentication_request_authenticate(request, credential);
    webkit_credential_free(credential);
    test->waitUntilLoadFinished();
    g_assert_cmpint(test->m_loadEvents.size(), ==, 3);
    g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted);
    g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::ProvisionalLoadFailed);
    g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished);
    if (!g_error_matches(test->m_error.get(), G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED))
        g_assert_error(test->m_error.get(), G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED);
    test->m_loadEvents.clear();

    // Complete the request with a credential with an invalid certificate.
    test->m_rejectClientCertificates = true;
    test->loadURI(kHttpsServer->getURIForPath("/").data());
    request = test->waitForAuthenticationRequest();
    credential = webkit_credential_new_for_certificate(test->m_clientCertificate.get(), WEBKIT_CREDENTIAL_PERSISTENCE_NONE);
    webkit_authentication_request_authenticate(request, credential);
    webkit_credential_free(credential);
    test->waitUntilLoadFinished();
    g_assert_cmpint(test->m_loadEvents.size(), ==, 3);
    g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted);
    g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::ProvisionalLoadFailed);
    g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished);
    if (!g_error_matches(test->m_error.get(), G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED))
        g_assert_error(test->m_error.get(), G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED);
    test->m_loadEvents.clear();
    test->m_rejectClientCertificates = false;

    // Complete the request with a credential with a valid certificate.
    test->loadURI(kHttpsServer->getURIForPath("/").data());
    request = test->waitForAuthenticationRequest();
    credential = webkit_credential_new_for_certificate(test->m_clientCertificate.get(), WEBKIT_CREDENTIAL_PERSISTENCE_NONE);
    webkit_authentication_request_authenticate(request, credential);
    webkit_credential_free(credential);
    test->waitUntilLoadFinished();
    g_assert_cmpint(test->m_loadEvents.size(), ==, 3);
    g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted);
    g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::LoadCommitted);
    g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished);
    test->m_loadEvents.clear();

    webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, originalPolicy);
}
#endif

#if USE(SOUP2)
static void httpsServerCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
#else
static void httpsServerCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer)
#endif
{
    if (soup_server_message_get_method(message) != SOUP_METHOD_GET) {
        soup_server_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED, nullptr);
        return;
    }

    g_assert_false(assertIfSSLRequestProcessed);

    auto* responseBody = soup_server_message_get_response_body(message);

    if (g_str_equal(path, "/")) {
        soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr);
        soup_message_body_append(responseBody, SOUP_MEMORY_STATIC, indexHTML, strlen(indexHTML));
        soup_message_body_complete(responseBody);
    } else if (g_str_equal(path, "/insecure-content/")) {
        GUniquePtr<char> responseHTML(g_strdup_printf(insecureContentHTML, kHttpServer->getURIForPath("/test-script").data(), kHttpServer->getURIForPath("/test-image").data()));
        soup_message_body_append(responseBody, SOUP_MEMORY_COPY, responseHTML.get(), strlen(responseHTML.get()));
        soup_message_body_complete(responseBody);
        soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr);
    } else if (g_str_equal(path, "/test-tls/")) {
        soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr);
        soup_message_body_append(responseBody, SOUP_MEMORY_STATIC, TLSSuccessHTMLString, strlen(TLSSuccessHTMLString));
        soup_message_body_complete(responseBody);
    } else if (g_str_equal(path, "/redirect")) {
        soup_server_message_set_status(message, SOUP_STATUS_MOVED_PERMANENTLY, nullptr);
        soup_message_headers_append(soup_server_message_get_response_headers(message), "Location", kHttpServer->getURIForPath("/test-image").data());
    } else if (g_str_equal(path, "/auth")) {
        soup_server_message_set_status(message, SOUP_STATUS_UNAUTHORIZED, nullptr);
        soup_message_headers_append(soup_server_message_get_response_headers(message), "WWW-Authenticate", "Basic realm=\"HTTPS auth\"");
    } else if (g_str_equal(path, "/style.css")) {
        soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr);
        static const char* styleCSS = "body { color: black; }";
        soup_message_body_append(responseBody, SOUP_MEMORY_STATIC, styleCSS, strlen(styleCSS));
    } else
        soup_server_message_set_status(message, SOUP_STATUS_NOT_FOUND, nullptr);
}

#if USE(SOUP2)
static void httpServerCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
#else
static void httpServerCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer)
#endif
{
    if (soup_server_message_get_method(message) != SOUP_METHOD_GET) {
        soup_server_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED, nullptr);
        return;
    }

    auto* responseBody = soup_server_message_get_response_body(message);

    if (g_str_equal(path, "/test-script")) {
        GUniquePtr<char> pathToFile(g_build_filename(Test::getResourcesDir().data(), "link-title.js", nullptr));
        char* contents;
        gsize length;
        g_file_get_contents(pathToFile.get(), &contents, &length, 0);

        soup_message_body_append(responseBody, SOUP_MEMORY_TAKE, contents, length);
        soup_message_body_complete(responseBody);
        soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr);
    } else if (g_str_equal(path, "/test-image")) {
        GUniquePtr<char> pathToFile(g_build_filename(Test::getResourcesDir().data(), "blank.ico", nullptr));
        char* contents;
        gsize length;
        g_file_get_contents(pathToFile.get(), &contents, &length, 0);

        soup_message_body_append(responseBody, SOUP_MEMORY_TAKE, contents, length);
        soup_message_body_complete(responseBody);
        soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr);
    } else if (g_str_equal(path, "/")) {
        soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr);
        char* responseHTML = g_strdup_printf("<html><head><link rel='stylesheet' href='%s' type='text/css'></head><body>SSL subresource test</body></html>",
            kHttpsServer->getURIForPath("/style.css").data());
        soup_message_body_append(responseBody, SOUP_MEMORY_TAKE, responseHTML, strlen(responseHTML));
        soup_message_body_complete(responseBody);
    } else
        soup_server_message_set_status(message, SOUP_STATUS_NOT_FOUND, nullptr);
}

void beforeAll()
{
    kHttpsServer = new WebKitTestServer(WebKitTestServer::ServerHTTPS);
    kHttpsServer->run(httpsServerCallback);

    kHttpServer = new WebKitTestServer();
    kHttpServer->run(httpServerCallback);

    SSLTest::add("WebKitWebView", "ssl", testSSL);
    InsecureContentTest::add("WebKitWebView", "insecure-content", testInsecureContent);
    SSLTest::add("WebKitWebView", "tls-errors-policy", testTLSErrorsPolicy);
    SSLTest::add("WebKitWebView", "tls-errors-redirect-to-http", testTLSErrorsRedirect);
    SSLTest::add("WebKitWebView", "tls-http-auth", testTLSErrorsHTTPAuth);
    TLSSubresourceTest::add("WebKitWebView", "tls-subresource", testSubresourceLoadFailedWithTLSErrors);
    TLSErrorsTest::add("WebKitWebView", "load-failed-with-tls-errors", testLoadFailedWithTLSErrors);
    WebSocketTest::add("WebKitWebView", "web-socket-tls-errors", testWebSocketTLSErrors);
    EphemeralSSLTest::add("WebKitWebView", "ephemeral-tls-errors", testTLSErrorsEphemeral);
#if !USE(SOUP2)
    ClientSideCertificateTest::add("WebKitWebView", "client-side-certificate", testClientSideCertificate);
#endif
}

void afterAll()
{
    delete kHttpsServer;
    delete kHttpServer;
}
