⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 242788 in webkit


Ignore:
Timestamp:
Mar 12, 2019, 1:30:43 AM (7 years ago)
Author:
Carlos Garcia Campos
Message:

[WPE][GTK] Load events may occur in unexpected order when JS redirects page before subresource load finishes
https://bugs.webkit.org/show_bug.cgi?id=194131

Source/WebKit:

Reviewed by Michael Catanzaro.

Ensure we emit the load-failed and load-changed with finished event when there's still an ongoing load when a
new provisional load strarts. Previous load fails with cancelled error.

  • UIProcess/API/glib/WebKitWebView.cpp:

(webkitWebViewWillStartLoad): Call webkitWebViewLoadFailed() if current page load state is not finished.

  • UIProcess/API/glib/WebKitWebViewPrivate.h:
  • UIProcess/API/gtk/PageClientImpl.cpp:

(WebKit::PageClientImpl::didStartProvisionalLoadForMainFrame): Call webkitWebViewWillStartLoad().

  • UIProcess/API/wpe/APIViewClient.h:

(API::ViewClient::willStartLoad): Add willStartLoad() to API::ViewClient

  • UIProcess/API/wpe/PageClientImpl.cpp:

(WebKit::PageClientImpl::didStartProvisionalLoadForMainFrame): Call WPEView::willStartLoad().

  • UIProcess/API/wpe/PageClientImpl.h:
  • UIProcess/API/wpe/WPEView.cpp:

(WKWPE::View::willStartLoad): Call API::ViewClient::willStartLoad().

  • UIProcess/API/wpe/WPEView.h:
  • UIProcess/PageLoadState.h:

(WebKit::PageLoadState::isProvisional const):
(WebKit::PageLoadState::isCommitted const):
(WebKit::PageLoadState::isFinished const):

Tools:

Patch by Michael Catanzaro <Michael Catanzaro> on 2019-03-12
Reviewed by Michael Catanzaro.

  • TestWebKitAPI/Tests/WebKitGLib/TestLoaderClient.cpp:

(uriChanged):
(testUnfinishedSubresourceLoad):
(serverCallback):
(beforeAll):

Location:
trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r242777 r242788  
     12019-03-12  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [WPE][GTK] Load events may occur in unexpected order when JS redirects page before subresource load finishes
     4        https://bugs.webkit.org/show_bug.cgi?id=194131
     5
     6        Reviewed by Michael Catanzaro.
     7
     8        Ensure we emit the load-failed and load-changed with finished event when there's still an ongoing load when a
     9        new provisional load strarts. Previous load fails with cancelled error.
     10
     11        * UIProcess/API/glib/WebKitWebView.cpp:
     12        (webkitWebViewWillStartLoad): Call webkitWebViewLoadFailed() if current page load state is not finished.
     13        * UIProcess/API/glib/WebKitWebViewPrivate.h:
     14        * UIProcess/API/gtk/PageClientImpl.cpp:
     15        (WebKit::PageClientImpl::didStartProvisionalLoadForMainFrame): Call webkitWebViewWillStartLoad().
     16        * UIProcess/API/wpe/APIViewClient.h:
     17        (API::ViewClient::willStartLoad): Add willStartLoad() to API::ViewClient
     18        * UIProcess/API/wpe/PageClientImpl.cpp:
     19        (WebKit::PageClientImpl::didStartProvisionalLoadForMainFrame): Call WPEView::willStartLoad().
     20        * UIProcess/API/wpe/PageClientImpl.h:
     21        * UIProcess/API/wpe/WPEView.cpp:
     22        (WKWPE::View::willStartLoad): Call API::ViewClient::willStartLoad().
     23        * UIProcess/API/wpe/WPEView.h:
     24        * UIProcess/PageLoadState.h:
     25        (WebKit::PageLoadState::isProvisional const):
     26        (WebKit::PageLoadState::isCommitted const):
     27        (WebKit::PageLoadState::isFinished const):
     28
    1292019-03-11  Ryan Haddad  <ryanhaddad@apple.com>
    230
  • trunk/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp

    r242082 r242788  
    425425    }
    426426
     427    void willStartLoad(WKWPE::View&) override
     428    {
     429        webkitWebViewWillStartLoad(m_webView);
     430    }
     431
    427432    WebKitWebView* m_webView;
    428433};
     
    20692074{
    20702075    return getPage(webView);
     2076}
     2077
     2078void webkitWebViewWillStartLoad(WebKitWebView* webView)
     2079{
     2080    // This is called before NavigationClient::didStartProvisionalNavigation(), the page load state hasn't been committed yet.
     2081    auto& pageLoadState = getPage(webView).pageLoadState();
     2082    if (pageLoadState.isFinished())
     2083        return;
     2084
     2085    GUniquePtr<GError> error(g_error_new_literal(WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED, _("Load request cancelled")));
     2086    webkitWebViewLoadFailed(webView, pageLoadState.isProvisional() ? WEBKIT_LOAD_STARTED : WEBKIT_LOAD_COMMITTED,
     2087        webView->priv->activeURI.data(), error.get());
    20712088}
    20722089
  • trunk/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h

    r241000 r242788  
    4242void webkitWebViewCreatePage(WebKitWebView*, Ref<API::PageConfiguration>&&);
    4343WebKit::WebPageProxy& webkitWebViewGetPage(WebKitWebView*);
     44void webkitWebViewWillStartLoad(WebKitWebView*);
    4445void webkitWebViewLoadChanged(WebKitWebView*, WebKitLoadEvent);
    4546void webkitWebViewLoadFailed(WebKitWebView*, WebKitLoadEvent, const char* failingURI, GError*);
  • trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp

    r242346 r242788  
    473473void PageClientImpl::didStartProvisionalLoadForMainFrame()
    474474{
     475    if (WEBKIT_IS_WEB_VIEW(m_viewWidget))
     476        webkitWebViewWillStartLoad(WEBKIT_WEB_VIEW(m_viewWidget));
     477
    475478    webkitWebViewBaseDidStartProvisionalLoadForMainFrame(WEBKIT_WEB_VIEW_BASE(m_viewWidget));
    476479}
  • trunk/Source/WebKit/UIProcess/API/wpe/APIViewClient.h

    r229799 r242788  
    4444    virtual void frameDisplayed(WKWPE::View&) { }
    4545    virtual void handleDownloadRequest(WKWPE::View&, WebKit::DownloadProxy&) { }
     46    virtual void willStartLoad(WKWPE::View&) { }
    4647};
    4748
  • trunk/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp

    r242346 r242788  
    303303}
    304304
     305void PageClientImpl::didStartProvisionalLoadForMainFrame()
     306{
     307    m_view.willStartLoad();
     308}
     309
    305310void PageClientImpl::didFirstVisuallyNonEmptyLayoutForMainFrame()
    306311{
  • trunk/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h

    r242317 r242788  
    119119    void didRemoveNavigationGestureSnapshot() override;
    120120
     121    void didStartProvisionalLoadForMainFrame() override;
    121122    void didFirstVisuallyNonEmptyLayoutForMainFrame() override;
    122123    void didFinishLoadForMainFrame() override;
  • trunk/Source/WebKit/UIProcess/API/wpe/WPEView.cpp

    r242055 r242788  
    172172}
    173173
     174void View::willStartLoad()
     175{
     176    m_client->willStartLoad(*this);
     177}
     178
    174179void View::setSize(const WebCore::IntSize& size)
    175180{
  • trunk/Source/WebKit/UIProcess/API/wpe/WPEView.h

    r241260 r242788  
    6060    void frameDisplayed();
    6161    void handleDownloadRequest(WebKit::DownloadProxy&);
     62    void willStartLoad();
    6263
    6364    WebKit::WebPageProxy& page() { return *m_pageProxy; }
  • trunk/Source/WebKit/UIProcess/PageLoadState.h

    r238817 r242788  
    122122
    123123    bool isLoading() const;
     124    bool isProvisional() const { return m_committedState.state == State::Provisional; }
     125    bool isCommitted() const { return m_committedState.state == State::Committed; }
     126    bool isFinished() const { return m_committedState.state == State::Finished; }
    124127
    125128    const String& provisionalURL() const { return m_committedState.provisionalURL; }
  • trunk/Tools/ChangeLog

    r242778 r242788  
     12019-03-12  Michael Catanzaro  <mcatanzaro@igalia.com>
     2
     3        [WPE][GTK] Load events may occur in unexpected order when JS redirects page before subresource load finishes
     4        https://bugs.webkit.org/show_bug.cgi?id=194131
     5
     6        Reviewed by Michael Catanzaro.
     7
     8        * TestWebKitAPI/Tests/WebKitGLib/TestLoaderClient.cpp:
     9        (uriChanged):
     10        (testUnfinishedSubresourceLoad):
     11        (serverCallback):
     12        (beforeAll):
     13
    1142019-03-11  Alex Christensen  <achristensen@webkit.org>
    215
  • trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestLoaderClient.cpp

    r239772 r242788  
    241241}
    242242
     243static void uriChanged(WebKitWebView* webView, GParamSpec*, LoadTrackingTest* test)
     244{
     245    const char* uri = webkit_web_view_get_uri(webView);
     246    if (g_str_has_suffix(uri, "/normal"))
     247        test->m_activeURI = uri;
     248}
     249
     250static void testUnfinishedSubresourceLoad(LoadTrackingTest* test, gconstpointer)
     251{
     252    // Verify that LoadFinished occurs even if the next load starts before the
     253    // previous load actually finishes.
     254    test->loadURI(kServer->getURIForPath("/unfinished-subresource-load").data());
     255    auto signalID = g_signal_connect(test->m_webView, "notify::uri", G_CALLBACK(uriChanged), test);
     256    test->waitUntilLoadFinished();
     257    test->waitUntilLoadFinished();
     258    g_signal_handler_disconnect(test->m_webView, signalID);
     259
     260    Vector<LoadTrackingTest::LoadEvents>& events = test->m_loadEvents;
     261    g_assert_cmpint(events.size(), ==, 7);
     262    g_assert_cmpint(events[0], ==, LoadTrackingTest::ProvisionalLoadStarted);
     263    g_assert_cmpint(events[1], ==, LoadTrackingTest::LoadCommitted);
     264    g_assert_cmpint(events[2], ==, LoadTrackingTest::LoadFailed);
     265    g_assert_cmpint(events[3], ==, LoadTrackingTest::LoadFinished);
     266    g_assert_cmpint(events[4], ==, LoadTrackingTest::ProvisionalLoadStarted);
     267    g_assert_cmpint(events[5], ==, LoadTrackingTest::LoadCommitted);
     268    g_assert_cmpint(events[6], ==, LoadTrackingTest::LoadFinished);
     269}
     270
    243271class ViewURITrackingTest: public LoadTrackingTest {
    244272public:
     
    590618        "Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!"
    591619        "Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!</body></html>";
     620
     621    static const char* unfinishedSubresourceLoadResponseString = "<html><body>"
     622        "<img src=\"/stall\"/>"
     623        "<script>"
     624        "  function run() {"
     625        "      location = '/normal';"
     626        "  }"
     627        "  setInterval(run(), 50);"
     628        "</script>"
     629        "</body></html>";
    592630
    593631    if (message->method != SOUP_METHOD_GET) {
     
    626664        soup_message_set_status(message, SOUP_STATUS_MOVED_PERMANENTLY);
    627665        soup_message_headers_append(message->response_headers, "Location", "data:text/plain;charset=utf-8,data-uri");
     666    } else if (g_str_equal(path, "/unfinished-subresource-load")) {
     667        soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, unfinishedSubresourceLoadResponseString, strlen(unfinishedSubresourceLoadResponseString));
     668    } else if (g_str_equal(path, "/stall")) {
     669        // This request is never unpaused and stalls forever.
     670        soup_server_pause_message(server, message);
     671        return;
    628672    } else
    629673        soup_message_set_status(message, SOUP_STATUS_NOT_FOUND);
     
    656700    LoadTrackingTest::add("WebKitWebView", "history-load", testWebViewHistoryLoad);
    657701    LoadTwiceAndReloadTest::add("WebKitWebView", "load-twice-and-reload", testWebViewLoadTwiceAndReload);
     702    LoadTrackingTest::add("WebKitWebView", "unfinished-subresource-load", testUnfinishedSubresourceLoad);
    658703
    659704    // This test checks that web view notify::uri signal is correctly emitted
Note: See TracChangeset for help on using the changeset viewer.