From: Carlos Garcia Campos <carlosgc@webkit.org>
Subject: Check TLS errors as soon as they are set in the SoupMessage
Bug: https://bugs.webkit.org/show_bug.cgi?id=142244
Origin: http://trac.webkit.org/changeset/181074
Index: webkitgtk/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp
===================================================================
--- webkitgtk.orig/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp
+++ webkitgtk/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp
@@ -331,16 +331,21 @@ static bool handleUnignoredTLSErrors(Res
     return true;
 }
 
-static void gotHeadersCallback(SoupMessage* message, gpointer data)
+static void tlsErrorsChangedCallback(SoupMessage* message, GParamSpec*, gpointer data)
 {
     ResourceHandle* handle = static_cast<ResourceHandle*>(data);
     if (!handle || handle->cancelledOrClientless())
         return;
 
-    if (handleUnignoredTLSErrors(handle, message)) {
+    if (handleUnignoredTLSErrors(handle, message))
         handle->cancel();
+}
+
+static void gotHeadersCallback(SoupMessage* message, gpointer data)
+{
+    ResourceHandle* handle = static_cast<ResourceHandle*>(data);
+    if (!handle || handle->cancelledOrClientless())
         return;
-    }
 
     ResourceHandleInternal* d = handle->getInternal();
 
@@ -931,6 +936,7 @@ static bool createSoupMessageForHandleAn
         && (!request.httpBody() || request.httpBody()->isEmpty()))
         soup_message_headers_set_content_length(soupMessage->request_headers, 0);
 
+    g_signal_connect(d->m_soupMessage.get(), "notify::tls-errors", G_CALLBACK(tlsErrorsChangedCallback), handle);
     g_signal_connect(d->m_soupMessage.get(), "got-headers", G_CALLBACK(gotHeadersCallback), handle);
     g_signal_connect(d->m_soupMessage.get(), "wrote-body-data", G_CALLBACK(wroteBodyDataCallback), handle);
 
Index: webkitgtk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestSSL.cpp
===================================================================
--- webkitgtk.orig/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestSSL.cpp
+++ webkitgtk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestSSL.cpp
@@ -129,16 +129,21 @@ static void testInsecureContent(Insecure
     webkit_web_context_set_tls_errors_policy(context, originalPolicy);
 }
 
+static bool assertIfSSLRequestProcessed = false;
+
 static void testTLSErrorsPolicy(SSLTest* test, gconstpointer)
 {
     WebKitWebContext* context = webkit_web_view_get_context(test->m_webView);
     // TLS errors are treated as transport failures by default.
     g_assert(webkit_web_context_get_tls_errors_policy(context) == WEBKIT_TLS_ERRORS_POLICY_FAIL);
+
+    assertIfSSLRequestProcessed = true;
     test->loadURI(kHttpsServer->getURIForPath("/").data());
     test->waitUntilLoadFinished();
     g_assert(test->m_loadFailed);
     g_assert(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed));
     g_assert(!test->m_loadEvents.contains(LoadTrackingTest::LoadCommitted));
+    assertIfSSLRequestProcessed = false;
 
     webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_IGNORE);
     g_assert(webkit_web_context_get_tls_errors_policy(context) == WEBKIT_TLS_ERRORS_POLICY_IGNORE);
@@ -158,11 +163,13 @@ static void testTLSErrorsRedirect(SSLTes
     WebKitTLSErrorsPolicy originalPolicy = webkit_web_context_get_tls_errors_policy(context);
     webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_FAIL);
 
+    assertIfSSLRequestProcessed = true;
     test->loadURI(kHttpsServer->getURIForPath("/redirect").data());
     test->waitUntilLoadFinished();
     g_assert(test->m_loadFailed);
     g_assert(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed));
     g_assert(!test->m_loadEvents.contains(LoadTrackingTest::LoadCommitted));
+    assertIfSSLRequestProcessed = false;
 
     webkit_web_context_set_tls_errors_policy(context, originalPolicy);
 }
@@ -180,12 +187,14 @@ static void testTLSErrorsHTTPAuth(SSLTes
     WebKitTLSErrorsPolicy originalPolicy = webkit_web_context_get_tls_errors_policy(context);
     webkit_web_context_set_tls_errors_policy(context, 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(test->m_loadFailed);
     g_assert(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed));
     g_assert(!test->m_loadEvents.contains(LoadTrackingTest::LoadCommitted));
+    assertIfSSLRequestProcessed = false;
 
     webkit_web_context_set_tls_errors_policy(context, originalPolicy);
 }
@@ -235,6 +244,7 @@ static void testLoadFailedWithTLSErrors(
     WebKitTLSErrorsPolicy originalPolicy = webkit_web_context_get_tls_errors_policy(context);
     webkit_web_context_set_tls_errors_policy(context, 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();
@@ -244,6 +254,7 @@ static void testLoadFailedWithTLSErrors(
     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(context, test->certificate(), test->host());
@@ -267,6 +278,8 @@ static void httpsServerCallback(SoupServ
         return;
     }
 
+    g_assert(!assertIfSSLRequestProcessed);
+
     if (g_str_equal(path, "/")) {
         soup_message_set_status(message, SOUP_STATUS_OK);
         soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, indexHTML, strlen(indexHTML));
