Changeset 183698 in webkit


Ignore:
Timestamp:
May 1, 2015, 4:47:03 PM (10 years ago)
Author:
mitz@apple.com
Message:

Source/WebCore:
WebCore part of <rdar://problem/8636045> Back/forward navigation to an error page in Safari breaks the back-forward list
https://bugs.webkit.org/show_bug.cgi?id=144501

Reviewed by Darin Adler.

Test: TestWebKitAPI/Tests/WebKit2Cocoa/LoadAlternateHTMLString.mm

Normally, loading substitute data (such as an error page) creates a new back-forward list
item. FrameLoader has a mechanism that detects when a substitute data load occurs during
handling of a provisional load error and prevents the creation of a new back-forwards list
item in that case if the unreachable URL is the same as the failing provisional URL. This
mechanism was broken in WebKit2, where handling the provisional load error is asynchronous.

The fix is to capture some state (namely, the failing provisional URL) when dispatching the
load error and allow it to be restored when loading the substitute data.

  • loader/FrameLoader.cpp:

(WebCore::FrameLoader::FrameLoader): Removed initialization of
m_delegateIsHandlingProvisionalLoadError.
(WebCore::FrameLoader::shouldReloadToHandleUnreachableURL): Instead of checking
m_delegateIsHandlingProvisionalLoadError and if true using the provisional document loader’s
URL, check m_provisionalLoadErrorBeingHandledURL.
(WebCore::FrameLoader::checkLoadCompleteForThisFrame): Instead of checking and setting
m_delegateIsHandlingProvisionalLoadError, use m_provisionalLoadErrorBeingHandledURL.

  • loader/FrameLoader.h:

(WebCore::FrameLoader::provisionalLoadErrorBeingHandledURL): Added this getter. The client
can call this from its override of dispatchDidFailProvisionalLoad and store the result.
(WebCore::FrameLoader::setProvisionalLoadErrorBeingHandledURL): Added this setter. The
client can call this prior to loading substitute data if it’s done as part of handling a
previously-dispatched didFailProvisionalLoad.

Source/WebKit2:
WebKit2 part of <rdar://problem/8636045> Back/forward navigation to an error page in Safari breaks the back-forward list
https://bugs.webkit.org/show_bug.cgi?id=144501

Reviewed by Darin Adler.

  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::loadAlternateHTMLString): If this is called during
didFailProvisionalLoadForFrame, send back the provisional URL captured at the time of
failure.
(WebKit::WebPageProxy::didFailProvisionalLoadForFrame): Get the provisioinal URL and keep
it in new member variable m_failingProvisionalLoadURL for the duration of the client’s
handling of this message.

  • UIProcess/WebPageProxy.h:
  • UIProcess/WebPageProxy.messages.in: Added provisionalURL parameter to

DidFailProvisionalLoadForFrame.

  • WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:

(WebKit::WebFrameLoaderClient::dispatchDidFailProvisionalLoad): Send the URL for this error
to the UI process.

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::loadAlternateHTMLString): Temporarily restore the loader’s state to
reflect the provisional load error being handled.

  • WebProcess/WebPage/WebPage.h:
  • WebProcess/WebPage/WebPage.messages.in: Added provisionalLoadErrorURL parameter to

LoadAlternateHTMLString.

Location:
trunk
Files:
1 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r183697 r183698  
     12015-05-01  Dan Bernstein  <mitz@apple.com>
     2
     3        WebCore part of <rdar://problem/8636045> Back/forward navigation to an error page in Safari breaks the back-forward list
     4        https://bugs.webkit.org/show_bug.cgi?id=144501
     5
     6        Reviewed by Darin Adler.
     7
     8        Test: TestWebKitAPI/Tests/WebKit2Cocoa/LoadAlternateHTMLString.mm
     9
     10        Normally, loading substitute data (such as an error page) creates a new back-forward list
     11        item. FrameLoader has a mechanism that detects when a substitute data load occurs during
     12        handling of a provisional load error and prevents the creation of a new back-forwards list
     13        item in that case if the unreachable URL is the same as the failing provisional URL. This
     14        mechanism was broken in WebKit2, where handling the provisional load error is asynchronous.
     15
     16        The fix is to capture some state (namely, the failing provisional URL) when dispatching the
     17        load error and allow it to be restored when loading the substitute data.
     18
     19        * loader/FrameLoader.cpp:
     20        (WebCore::FrameLoader::FrameLoader): Removed initialization of
     21        m_delegateIsHandlingProvisionalLoadError.
     22        (WebCore::FrameLoader::shouldReloadToHandleUnreachableURL): Instead of checking
     23        m_delegateIsHandlingProvisionalLoadError and if true using the provisional document loader’s
     24        URL, check m_provisionalLoadErrorBeingHandledURL.
     25        (WebCore::FrameLoader::checkLoadCompleteForThisFrame): Instead of checking and setting
     26        m_delegateIsHandlingProvisionalLoadError, use m_provisionalLoadErrorBeingHandledURL.
     27        * loader/FrameLoader.h:
     28        (WebCore::FrameLoader::provisionalLoadErrorBeingHandledURL): Added this getter. The client
     29        can call this from its override of dispatchDidFailProvisionalLoad and store the result.
     30        (WebCore::FrameLoader::setProvisionalLoadErrorBeingHandledURL): Added this setter. The
     31        client can call this prior to loading substitute data if it’s done as part of handling a
     32        previously-dispatched didFailProvisionalLoad.
     33
    1342015-05-01  Martin Robinson  <mrobinson@igalia.com>
    235
  • trunk/Source/WebCore/loader/FrameLoader.cpp

    r183537 r183698  
    221221    , m_state(FrameStateProvisional)
    222222    , m_loadType(FrameLoadType::Standard)
    223     , m_delegateIsHandlingProvisionalLoadError(false)
    224223    , m_quickRedirectComing(false)
    225224    , m_sentRedirectNotification(false)
     
    15111510    // case handles malformed URLs and unknown schemes. Loading alternate content
    15121511    // at other times behaves like a standard load.
    1513     DocumentLoader* compareDocumentLoader = 0;
    15141512    if (policyChecker().delegateIsDecidingNavigationPolicy() || policyChecker().delegateIsHandlingUnimplementablePolicy())
    1515         compareDocumentLoader = m_policyDocumentLoader.get();
    1516     else if (m_delegateIsHandlingProvisionalLoadError)
    1517         compareDocumentLoader = m_provisionalDocumentLoader.get();
    1518 
    1519     return compareDocumentLoader && unreachableURL == compareDocumentLoader->request().url();
     1513        return m_policyDocumentLoader && unreachableURL == m_policyDocumentLoader->request().url();
     1514
     1515    return unreachableURL == m_provisionalLoadErrorBeingHandledURL;
    15201516}
    15211517
     
    21712167    switch (m_state) {
    21722168        case FrameStateProvisional: {
    2173             if (m_delegateIsHandlingProvisionalLoadError)
     2169            if (!m_provisionalLoadErrorBeingHandledURL.isEmpty())
    21742170                return;
    21752171
     
    21932189            bool shouldReset = !history().provisionalItem();
    21942190            if (!pdl->isLoadingInAPISense() || pdl->isStopping()) {
    2195                 m_delegateIsHandlingProvisionalLoadError = true;
     2191                m_provisionalLoadErrorBeingHandledURL = m_provisionalDocumentLoader->url();
    21962192                m_client.dispatchDidFailProvisionalLoad(error);
    2197                 m_delegateIsHandlingProvisionalLoadError = false;
     2193                m_provisionalLoadErrorBeingHandledURL = { };
    21982194
    21992195                ASSERT(!pdl->isLoading());
  • trunk/Source/WebCore/loader/FrameLoader.h

    r183537 r183698  
    292292    WEBCORE_EXPORT void clearTestingOverrides();
    293293
     294    const URL& provisionalLoadErrorBeingHandledURL() const { return m_provisionalLoadErrorBeingHandledURL; }
     295    void setProvisionalLoadErrorBeingHandledURL(const URL& url) { m_provisionalLoadErrorBeingHandledURL = url; }
     296
    294297private:
    295298    enum FormSubmissionCacheLoadPolicy {
     
    403406    RefPtr<DocumentLoader> m_policyDocumentLoader;
    404407
    405     bool m_delegateIsHandlingProvisionalLoadError;
     408    URL m_provisionalLoadErrorBeingHandledURL;
    406409
    407410    bool m_quickRedirectComing;
  • trunk/Source/WebKit2/ChangeLog

    r183697 r183698  
     12015-05-01  Dan Bernstein  <mitz@apple.com>
     2
     3        WebKit2 part of <rdar://problem/8636045> Back/forward navigation to an error page in Safari breaks the back-forward list
     4        https://bugs.webkit.org/show_bug.cgi?id=144501
     5
     6        Reviewed by Darin Adler.
     7
     8        * UIProcess/WebPageProxy.cpp:
     9        (WebKit::WebPageProxy::loadAlternateHTMLString): If this is called during
     10        didFailProvisionalLoadForFrame, send back the provisional URL captured at the time of
     11        failure.
     12        (WebKit::WebPageProxy::didFailProvisionalLoadForFrame): Get the provisioinal URL and keep
     13        it in new member variable m_failingProvisionalLoadURL for the duration of the client’s
     14        handling of this message.
     15        * UIProcess/WebPageProxy.h:
     16
     17        * UIProcess/WebPageProxy.messages.in: Added provisionalURL parameter to
     18        DidFailProvisionalLoadForFrame.
     19
     20        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
     21        (WebKit::WebFrameLoaderClient::dispatchDidFailProvisionalLoad): Send the URL for this error
     22        to the UI process.
     23
     24        * WebProcess/WebPage/WebPage.cpp:
     25        (WebKit::WebPage::loadAlternateHTMLString): Temporarily restore the loader’s state to
     26        reflect the provisional load error being handled.
     27
     28        * WebProcess/WebPage/WebPage.h:
     29        * WebProcess/WebPage/WebPage.messages.in: Added provisionalLoadErrorURL parameter to
     30        LoadAlternateHTMLString.
     31
    1322015-05-01  Martin Robinson  <mrobinson@igalia.com>
    233
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp

    r183595 r183698  
    959959    m_process->assumeReadAccessToBaseURL(baseURL);
    960960    m_process->assumeReadAccessToBaseURL(unreachableURL);
    961     m_process->send(Messages::WebPage::LoadAlternateHTMLString(htmlString, baseURL, unreachableURL, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
     961    m_process->send(Messages::WebPage::LoadAlternateHTMLString(htmlString, baseURL, unreachableURL, m_failingProvisionalLoadURL, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
    962962    m_process->responsivenessTimer()->start();
    963963}
     
    28222822}
    28232823
    2824 void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const ResourceError& error, const UserData& userData)
     2824void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& provisionalURL, const ResourceError& error, const UserData& userData)
    28252825{
    28262826    WebFrameProxy* frame = m_process->webFrame(frameID);
     
    28402840
    28412841    m_pageLoadState.commitChanges();
     2842
     2843    ASSERT(!m_failingProvisionalLoadURL);
     2844    m_failingProvisionalLoadURL = provisionalURL;
     2845
    28422846    if (m_navigationClient) {
    28432847        if (frame->isMainFrame())
     
    28492853    } else
    28502854        m_loaderClient->didFailProvisionalLoadWithErrorForFrame(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
     2855
     2856    m_failingProvisionalLoadURL = { };
    28512857}
    28522858
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.h

    r183595 r183698  
    10791079    void didStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, const String& unreachableURL, const UserData&);
    10801080    void didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String&, const UserData&);
    1081     void didFailProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const WebCore::ResourceError&, const UserData&);
     1081    void didFailProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& provisionalURL, const WebCore::ResourceError&, const UserData&);
    10821082    void didCommitLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t frameLoadType, const WebCore::CertificateInfo&, const UserData&);
    10831083    void didFinishDocumentLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData&);
     
    14511451
    14521452    std::unique_ptr<WebNavigationState> m_navigationState;
     1453    String m_failingProvisionalLoadURL;
    14531454
    14541455    std::unique_ptr<DrawingAreaProxy> m_drawingArea;
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in

    r183517 r183698  
    130130    DidStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, String url, String unreachableURL, WebKit::UserData userData)
    131131    DidReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, String url, WebKit::UserData userData)
    132     DidFailProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, WebCore::ResourceError error, WebKit::UserData userData)
     132    DidFailProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, String provisionalURL, WebCore::ResourceError error, WebKit::UserData userData)
    133133    DidCommitLoadForFrame(uint64_t frameID, uint64_t navigationID, String mimeType, bool hasCustomContentProvider, uint32_t loadType, WebCore::CertificateInfo certificateInfo, WebKit::UserData userData)
    134134    DidFailLoadForFrame(uint64_t frameID, uint64_t navigationID, WebCore::ResourceError error, WebKit::UserData userData)
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp

    r183529 r183698  
    484484
    485485    // Notify the UIProcess.
    486     webPage->send(Messages::WebPageProxy::DidFailProvisionalLoadForFrame(m_frame->frameID(), navigationID, error, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
     486    webPage->send(Messages::WebPageProxy::DidFailProvisionalLoadForFrame(m_frame->frameID(), navigationID, m_frame->coreFrame()->loader().provisionalLoadErrorBeingHandledURL(), error, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
    487487
    488488    // If we have a load listener, notify it.
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp

    r183682 r183698  
    10691069}
    10701070
    1071 void WebPage::loadAlternateHTMLString(const String& htmlString, const String& baseURLString, const String& unreachableURLString, const UserData& userData)
     1071void WebPage::loadAlternateHTMLString(const String& htmlString, const String& baseURLString, const String& unreachableURLString, const String& provisionalLoadErrorURLString, const UserData& userData)
    10721072{
    10731073    URL baseURL = baseURLString.isEmpty() ? blankURL() : URL(URL(), baseURLString);
    10741074    URL unreachableURL = unreachableURLString.isEmpty() ? URL() : URL(URL(), unreachableURLString);
     1075    URL provisionalLoadErrorURL = provisionalLoadErrorURLString.isEmpty() ? URL() : URL(URL(), provisionalLoadErrorURLString);
     1076    m_mainFrame->coreFrame()->loader().setProvisionalLoadErrorBeingHandledURL(provisionalLoadErrorURL);
    10751077    loadString(0, htmlString, ASCIILiteral("text/html"), baseURL, unreachableURL, userData);
     1078    m_mainFrame->coreFrame()->loader().setProvisionalLoadErrorBeingHandledURL({ });
    10761079}
    10771080
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h

    r183595 r183698  
    933933    void loadData(const IPC::DataReference&, const String& MIMEType, const String& encodingName, const String& baseURL, const UserData&);
    934934    void loadHTMLString(uint64_t navigationID, const String& htmlString, const String& baseURL, const UserData&);
    935     void loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL, const UserData&);
     935    void loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL, const String& provisionalLoadErrorURL, const UserData&);
    936936    void loadPlainTextString(const String&, const UserData&);
    937937    void loadWebArchiveData(const IPC::DataReference&, const UserData&);
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in

    r183595 r183698  
    129129    LoadData(IPC::DataReference data, String MIMEType, String encoding, String baseURL, WebKit::UserData userData)
    130130    LoadHTMLString(uint64_t navigationID, String htmlString, String baseURL, WebKit::UserData userData)
    131     LoadAlternateHTMLString(String htmlString, String baseURL, String unreachableURL, WebKit::UserData userData)
     131    LoadAlternateHTMLString(String htmlString, String baseURL, String unreachableURL, String provisionalLoadErrorURL, WebKit::UserData userData)
    132132    LoadPlainTextString(String string, WebKit::UserData userData)
    133133    LoadWebArchiveData(IPC::DataReference webArchiveData, WebKit::UserData userData)
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r183136 r183698  
    4242                378E64791632707400B6C676 /* link-with-title.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 378E647816326FDF00B6C676 /* link-with-title.html */; };
    4343                379028B914FAC24C007E6B43 /* acceptsFirstMouse.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 379028B814FABE49007E6B43 /* acceptsFirstMouse.html */; };
     44                37D36ED71AF42ECD00BAF5D9 /* LoadAlternateHTMLString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37D36ED61AF42ECD00BAF5D9 /* LoadAlternateHTMLString.mm */; };
    4445                37DC6791140D7D7600ABCCDB /* DOMRangeOfString.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 37DC678F140D7D3A00ABCCDB /* DOMRangeOfString.html */; };
    4546                37E1064C1697681800B78BD0 /* DOMHTMLTableCellElementCellAbove.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 37E1064B169767F700B78BD0 /* DOMHTMLTableCellElementCellAbove.html */; };
     
    488489                37A6895D148A9B50005100FA /* SubresourceErrorCrash.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SubresourceErrorCrash.mm; sourceTree = "<group>"; };
    489490                37C784DE197C8F2E0010A496 /* RenderedImageFromDOMNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RenderedImageFromDOMNode.mm; sourceTree = "<group>"; };
     491                37D36ED61AF42ECD00BAF5D9 /* LoadAlternateHTMLString.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LoadAlternateHTMLString.mm; sourceTree = "<group>"; };
    490492                37DC678B140D7C5000ABCCDB /* DOMRangeOfString.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMRangeOfString.mm; sourceTree = "<group>"; };
    491493                37DC678F140D7D3A00ABCCDB /* DOMRangeOfString.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = DOMRangeOfString.html; sourceTree = "<group>"; };
     
    833835                                7CC3E1FA197E234100BE6252 /* UserContentController.mm */,
    834836                                0F3B94A51A77266C00DE3272 /* WKWebViewEvaluateJavaScript.mm */,
     837                                37D36ED61AF42ECD00BAF5D9 /* LoadAlternateHTMLString.mm */,
    835838                        );
    836839                        name = "WebKit2 Cocoa";
     
    15481551                                7CCE7ED31A411A7E00447C4C /* TypingStyleCrash.mm in Sources */,
    15491552                                7CCE7EDE1A411A9200447C4C /* URL.cpp in Sources */,
     1553                                37D36ED71AF42ECD00BAF5D9 /* LoadAlternateHTMLString.mm in Sources */,
    15501554                                7CCE7EB01A411A4400447C4C /* URLExtras.mm in Sources */,
    15511555                                7CCE7F271A411AF600447C4C /* UserContentController.mm in Sources */,
Note: See TracChangeset for help on using the changeset viewer.