Title: [155347] trunk/Source/WebKit2
Revision
155347
Author
[email protected]
Date
2013-09-09 06:49:33 -0700 (Mon, 09 Sep 2013)

Log Message

[GTK] Cancel the current active WebKitAuthenticationRequest on load failed
https://bugs.webkit.org/show_bug.cgi?id=120350

Patch by Anton Obzhirov <[email protected]> on 2013-09-09
Reviewed by Carlos Garcia Campos.

The default dialog does not get closed and the authentication is not cancelled
if loading fails or is stopped on a page which requires HTTP authentication.

This patch cancels the authentication request on load failed
and adds new authentication cancelled signal in WebKitAuthenticationRequest
to allow the application handling of authentication UI.

* UIProcess/API/gtk/WebKitAuthenticationDialog.cpp:
(authenticationCancelled):
(webkitAuthenticationDialogInitialize):
(webkitAuthenticationDialogDispose):
(webkitAuthenticationDialogNew):
* UIProcess/API/gtk/WebKitAuthenticationDialog.h:
* UIProcess/API/gtk/WebKitAuthenticationRequest.cpp:
(webkit_authentication_request_class_init):
(webkit_authentication_request_cancel):
* UIProcess/API/gtk/WebKitWebView.cpp:
(webkitWebViewAuthenticate):
(webkitWebViewLoadFailed):
(webkitWebViewHandleAuthenticationChallenge):
(webkitWebViewCancelAuthenticationRequest):
* UIProcess/API/gtk/tests/TestWebKitWebView.cpp:
(testWebViewAuthenticationLoadCancelled):
(beforeAll):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (155346 => 155347)


--- trunk/Source/WebKit2/ChangeLog	2013-09-09 13:47:24 UTC (rev 155346)
+++ trunk/Source/WebKit2/ChangeLog	2013-09-09 13:49:33 UTC (rev 155347)
@@ -1,3 +1,35 @@
+2013-09-09  Anton Obzhirov  <[email protected]>
+
+        [GTK] Cancel the current active WebKitAuthenticationRequest on load failed
+        https://bugs.webkit.org/show_bug.cgi?id=120350
+
+        Reviewed by Carlos Garcia Campos.
+
+        The default dialog does not get closed and the authentication is not cancelled
+        if loading fails or is stopped on a page which requires HTTP authentication.
+
+        This patch cancels the authentication request on load failed
+        and adds new authentication cancelled signal in WebKitAuthenticationRequest
+        to allow the application handling of authentication UI.
+
+        * UIProcess/API/gtk/WebKitAuthenticationDialog.cpp:
+        (authenticationCancelled):
+        (webkitAuthenticationDialogInitialize):
+        (webkitAuthenticationDialogDispose):
+        (webkitAuthenticationDialogNew):
+        * UIProcess/API/gtk/WebKitAuthenticationDialog.h:
+        * UIProcess/API/gtk/WebKitAuthenticationRequest.cpp:
+        (webkit_authentication_request_class_init):
+        (webkit_authentication_request_cancel):
+        * UIProcess/API/gtk/WebKitWebView.cpp:
+        (webkitWebViewAuthenticate):
+        (webkitWebViewLoadFailed):
+        (webkitWebViewHandleAuthenticationChallenge):
+        (webkitWebViewCancelAuthenticationRequest):
+        * UIProcess/API/gtk/tests/TestWebKitWebView.cpp:
+        (testWebViewAuthenticationLoadCancelled):
+        (beforeAll):
+
 2013-09-09  Brian Holt  <[email protected]>
 
         [GTK][WK2] Update ContextMenu Download API

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.cpp (155346 => 155347)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.cpp	2013-09-09 13:47:24 UTC (rev 155346)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.cpp	2013-09-09 13:49:33 UTC (rev 155347)
@@ -32,9 +32,8 @@
     GRefPtr<WebKitAuthenticationRequest> request;
     GtkWidget* authWidget;
     GtkWidget* defaultButton;
-    unsigned long loadFailedEventID;
+    unsigned long authenticationCancelledID;
     GRefPtr<GtkStyleContext> styleContext;
-    WebKitWebView* webView;
 };
 
 WEBKIT_DEFINE_TYPE(WebKitAuthenticationDialog, webkit_authentication_dialog, GTK_TYPE_EVENT_BOX)
@@ -54,13 +53,12 @@
     gtk_widget_destroy(GTK_WIDGET(authDialog));
 }
 
-static void pageLoadFailed(WebKitWebView*, WebKitLoadEvent, const char*, GError*, WebKitAuthenticationDialog* authDialog)
+static void authenticationCancelled(WebKitAuthenticationRequest*, WebKitAuthenticationDialog* authDialog)
 {
-    webkit_authentication_request_cancel(authDialog->priv->request.get());
     gtk_widget_destroy(GTK_WIDGET(authDialog));
 }
 
-static void webkitAuthenticationDialogInitialize(WebKitAuthenticationDialog* authDialog, CredentialStorageMode credentialStorageMode, WebKitWebView* webView)
+static void webkitAuthenticationDialogInitialize(WebKitAuthenticationDialog* authDialog, CredentialStorageMode credentialStorageMode)
 {
     GtkWidget* frame = gtk_frame_new(0);
     gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
@@ -98,8 +96,7 @@
     gtk_container_add(GTK_CONTAINER(authDialog), frame);
     gtk_widget_show(frame);
 
-    authDialog->priv->webView = webView;
-    authDialog->priv->loadFailedEventID = g_signal_connect(webView, "load-failed", G_CALLBACK(pageLoadFailed), authDialog);
+    authDialog->priv->authenticationCancelledID = g_signal_connect(authDialog->priv->request.get(), "cancelled", G_CALLBACK(authenticationCancelled), authDialog);
 }
 
 static gboolean webkitAuthenticationDialogDraw(GtkWidget* widget, cairo_t* cr)
@@ -139,9 +136,9 @@
 static void webkitAuthenticationDialogDispose(GObject* object)
 {
     WebKitAuthenticationDialogPrivate* priv = WEBKIT_AUTHENTICATION_DIALOG(object)->priv;
-    if (priv->loadFailedEventID) {
-        g_signal_handler_disconnect(priv->webView, priv->loadFailedEventID);
-        priv->loadFailedEventID = 0;
+    if (priv->authenticationCancelledID) {
+        g_signal_handler_disconnect(priv->request.get(), priv->authenticationCancelledID);
+        priv->authenticationCancelledID = 0;
     }
 
     G_OBJECT_CLASS(webkit_authentication_dialog_parent_class)->dispose(object);
@@ -158,10 +155,10 @@
     widgetClass->map = webkitAuthenticationDialogMap;
 }
 
-GtkWidget* webkitAuthenticationDialogNew(WebKitAuthenticationRequest* request, CredentialStorageMode mode, WebKitWebView* webView)
+GtkWidget* webkitAuthenticationDialogNew(WebKitAuthenticationRequest* request, CredentialStorageMode mode)
 {
     WebKitAuthenticationDialog* authDialog = WEBKIT_AUTHENTICATION_DIALOG(g_object_new(WEBKIT_TYPE_AUTHENTICATION_DIALOG, NULL));
     authDialog->priv->request = request;
-    webkitAuthenticationDialogInitialize(authDialog, mode, webView);
+    webkitAuthenticationDialogInitialize(authDialog, mode);
     return GTK_WIDGET(authDialog);
 }

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.h (155346 => 155347)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.h	2013-09-09 13:47:24 UTC (rev 155346)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.h	2013-09-09 13:49:33 UTC (rev 155347)
@@ -49,7 +49,7 @@
 };
 
 GType webkit_authentication_dialog_get_type();
-GtkWidget* webkitAuthenticationDialogNew(WebKitAuthenticationRequest*, CredentialStorageMode, WebKitWebView*);
+GtkWidget* webkitAuthenticationDialogNew(WebKitAuthenticationRequest*, CredentialStorageMode);
 
 G_END_DECLS
 

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationRequest.cpp (155346 => 155347)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationRequest.cpp	2013-09-09 13:47:24 UTC (rev 155346)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationRequest.cpp	2013-09-09 13:49:33 UTC (rev 155347)
@@ -51,6 +51,12 @@
  * WebKitAuthenticationRequest object.
  */
 
+enum {
+    CANCELLED,
+
+    LAST_SIGNAL
+};
+
 struct _WebKitAuthenticationRequestPrivate {
     RefPtr<AuthenticationChallengeProxy> authenticationChallenge;
     bool privateBrowsingEnabled;
@@ -59,6 +65,8 @@
     CString realm;
 };
 
+static guint signals[LAST_SIGNAL] = { 0, };
+
 COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_DEFAULT, ProtectionSpaceAuthenticationSchemeDefault);
 COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_HTTP_BASIC, ProtectionSpaceAuthenticationSchemeHTTPBasic);
 COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_HTTP_DIGEST, ProtectionSpaceAuthenticationSchemeHTTPDigest);
@@ -86,6 +94,24 @@
 {
     GObjectClass* objectClass = G_OBJECT_CLASS(requestClass);
     objectClass->dispose = webkitAuthenticationRequestDispose;
+
+    /**
+     * WebKitAuthenticationRequest::cancelled:
+     * @request: the #WebKitAuthenticationRequest
+     *
+     * This signal is emitted when the user authentication request is
+     * cancelled. It allows the application to dismiss its authentication
+     * dialog in case of page load failure for example.
+     *
+     * Since: 2.2
+     */
+    signals[CANCELLED] =
+        g_signal_new("cancelled",
+            G_TYPE_FROM_CLASS(objectClass),
+            G_SIGNAL_RUN_LAST,
+            0, 0, 0,
+            g_cclosure_marshal_VOID__VOID,
+            G_TYPE_NONE, 0);
 }
 
 WebKitAuthenticationRequest* webkitAuthenticationRequestCreate(AuthenticationChallengeProxy* authenticationChallenge, bool privateBrowsingEnabled)
@@ -288,4 +314,6 @@
     g_return_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request));
 
     request->priv->authenticationChallenge->listener()->cancel();
+
+    g_signal_emit(request, signals[CANCELLED], 0);
 }

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp (155346 => 155347)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp	2013-09-09 13:47:24 UTC (rev 155346)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp	2013-09-09 13:49:33 UTC (rev 155347)
@@ -190,6 +190,7 @@
     unsigned long faviconChangedHandlerID;
 
     SnapshotResultsMap snapshotResultsMap;
+    GRefPtr<WebKitAuthenticationRequest> authenticationRequest;
 };
 
 static guint signals[LAST_SIGNAL] = { 0, };
@@ -437,7 +438,7 @@
 static gboolean webkitWebViewAuthenticate(WebKitWebView* webView, WebKitAuthenticationRequest* request)
 {
     CredentialStorageMode credentialStorageMode = webkit_authentication_request_can_save_credentials(request) ? AllowPersistentStorage : DisallowPersistentStorage;
-    webkitWebViewBaseAddAuthenticationDialog(WEBKIT_WEB_VIEW_BASE(webView), webkitAuthenticationDialogNew(request, credentialStorageMode, webView));
+    webkitWebViewBaseAddAuthenticationDialog(WEBKIT_WEB_VIEW_BASE(webView), webkitAuthenticationDialogNew(request, credentialStorageMode));
 
     return TRUE;
 }
@@ -1430,15 +1431,24 @@
     g_object_thaw_notify(G_OBJECT(webView));
 }
 
+static void webkitWebViewCancelAuthenticationRequest(WebKitWebView* webView)
+{
+    if (!webView->priv->authenticationRequest)
+        return;
+
+    webkit_authentication_request_cancel(webView->priv->authenticationRequest.get());
+    webView->priv->authenticationRequest.clear();
+}
+
 static void webkitWebViewEmitLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent)
 {
     if (loadEvent == WEBKIT_LOAD_STARTED) {
         webkitWebViewSetIsLoading(webView, true);
         webkitWebViewWatchForChangesInFavicon(webView);
-        webkitWebViewBaseCancelAuthenticationDialog(WEBKIT_WEB_VIEW_BASE(webView));
+        webkitWebViewCancelAuthenticationRequest(webView);
     } else if (loadEvent == WEBKIT_LOAD_FINISHED) {
         webkitWebViewSetIsLoading(webView, false);
-        webView->priv->waitingForMainResource = false;
+        webkitWebViewCancelAuthenticationRequest(webView);
         webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(webView);
     } else
         webkitWebViewUpdateURI(webView);
@@ -1492,6 +1502,8 @@
 void webkitWebViewLoadFailed(WebKitWebView* webView, WebKitLoadEvent loadEvent, const char* failingURI, GError *error)
 {
     webkitWebViewSetIsLoading(webView, false);
+    webkitWebViewCancelAuthenticationRequest(webView);
+
     gboolean returnValue;
     g_signal_emit(webView, signals[LOAD_FAILED], 0, loadEvent, failingURI, error, &returnValue);
     g_signal_emit(webView, signals[LOAD_CHANGED], 0, WEBKIT_LOAD_FINISHED);
@@ -1500,6 +1512,7 @@
 void webkitWebViewLoadFailedWithTLSErrors(WebKitWebView* webView, const char* failingURI, GError *error, GTlsCertificateFlags tlsErrors, GTlsCertificate* certificate)
 {
     webkitWebViewSetIsLoading(webView, false);
+    webkitWebViewCancelAuthenticationRequest(webView);
 
     WebKitTLSErrorsPolicy tlsErrorsPolicy = webkit_web_context_get_tls_errors_policy(webView->priv->context);
     if (tlsErrorsPolicy == WEBKIT_TLS_ERRORS_POLICY_FAIL) {
@@ -1786,9 +1799,9 @@
 void webkitWebViewHandleAuthenticationChallenge(WebKitWebView* webView, AuthenticationChallengeProxy* authenticationChallenge)
 {
     gboolean privateBrowsingEnabled = webkit_settings_get_enable_private_browsing(webkit_web_view_get_settings(webView));
-    GRefPtr<WebKitAuthenticationRequest> request = adoptGRef(webkitAuthenticationRequestCreate(authenticationChallenge, privateBrowsingEnabled));
+    webView->priv->authenticationRequest = adoptGRef(webkitAuthenticationRequestCreate(authenticationChallenge, privateBrowsingEnabled));
     gboolean returnValue;
-    g_signal_emit(webView, signals[AUTHENTICATE], 0, request.get(), &returnValue);
+    g_signal_emit(webView, signals[AUTHENTICATE], 0, webView->priv->authenticationRequest.get(), &returnValue);
 }
 
 void webkitWebViewInsecureContentDetected(WebKitWebView* webView, WebKitInsecureContentEvent type)

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp (155346 => 155347)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp	2013-09-09 13:47:24 UTC (rev 155346)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp	2013-09-09 13:49:33 UTC (rev 155347)
@@ -298,13 +298,6 @@
     gtk_widget_queue_draw(GTK_WIDGET(webViewBase));
 }
 
-void webkitWebViewBaseCancelAuthenticationDialog(WebKitWebViewBase* webViewBase)
-{
-    WebKitWebViewBasePrivate* priv = webViewBase->priv;
-    if (priv->authenticationDialog)
-        gtk_widget_destroy(priv->authenticationDialog);
-}
-
 void webkitWebViewBaseAddWebInspector(WebKitWebViewBase* webViewBase, GtkWidget* inspector)
 {
     webViewBase->priv->inspectorView = inspector;

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp (155346 => 155347)


--- trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp	2013-09-09 13:47:24 UTC (rev 155346)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp	2013-09-09 13:49:33 UTC (rev 155347)
@@ -1248,20 +1248,28 @@
     }
 
     static int authenticationRetries;
+    static bool authenticationCancelledReceived;
 
     void loadURI(const char* uri)
     {
         // Reset the retry count of the fake server when a page is loaded.
         authenticationRetries = 0;
+        authenticationCancelledReceived = false;
         LoadTrackingTest::loadURI(uri);
     }
 
     static gboolean runAuthenticationCallback(WebKitWebView*, WebKitAuthenticationRequest* request, AuthenticationTest* test)
     {
+        g_signal_connect(request, "cancelled", G_CALLBACK(authenticationCancelledCallback), test);
         test->runAuthentication(request);
         return TRUE;
     }
 
+    static void authenticationCancelledCallback(WebKitAuthenticationRequest*, AuthenticationTest*)
+    {
+        authenticationCancelledReceived = true;
+    }
+
     void runAuthentication(WebKitAuthenticationRequest* request)
     {
         assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request));
@@ -1280,6 +1288,7 @@
 };
 
 int AuthenticationTest::authenticationRetries = 0;
+bool AuthenticationTest::authenticationCancelledReceived = false;
 
 static const char authTestUsername[] = "username";
 static const char authTestPassword[] = "password";
@@ -1325,6 +1334,23 @@
     g_assert_error(test->m_error.get(), WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED);
 }
 
+static void testWebViewAuthenticationLoadCancelled(AuthenticationTest* test, gconstpointer)
+{
+    test->loadURI(kServer->getURIForPath("/auth-test.html").data());
+    test->waitForAuthenticationRequest();
+    webkit_web_view_stop_loading(test->m_webView);
+    // Expect empty page.
+    test->waitUntilLoadFinished();
+    g_assert(test->authenticationCancelledReceived);
+
+    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);
+}
+
 static void testWebViewAuthenticationFailure(AuthenticationTest* test, gconstpointer)
 {
     // Test authentication failures.
@@ -1474,6 +1500,7 @@
     WebViewTest::add("WebKitWebView", "page-visibility", testWebViewPageVisibility);
     AuthenticationTest::add("WebKitWebView", "authentication-request", testWebViewAuthenticationRequest);
     AuthenticationTest::add("WebKitWebView", "authentication-cancel", testWebViewAuthenticationCancel);
+    AuthenticationTest::add("WebKitWebView", "authentication-load-cancelled", testWebViewAuthenticationLoadCancelled);
     AuthenticationTest::add("WebKitWebView", "authentication-failure", testWebViewAuthenticationFailure);
     AuthenticationTest::add("WebKitWebView", "authentication-no-credential", testWebViewAuthenticationNoCredential);
     AuthenticationTest::add("WebKitWebView", "authentication-storage", testWebViewAuthenticationStorage);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to