Diff
Modified: trunk/Source/WebCore/ChangeLog (237354 => 237355)
--- trunk/Source/WebCore/ChangeLog 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebCore/ChangeLog 2018-10-23 17:54:34 UTC (rev 237355)
@@ -1,3 +1,51 @@
+2018-10-23 Chris Dumez <[email protected]>
+
+ [PSON] Add support for cross-site client-side redirects
+ https://bugs.webkit.org/show_bug.cgi?id=190806
+ <rdar://problem/45047344>
+
+ Reviewed by Geoffrey Garen.
+
+ Add support for cross-site client-side redirects so that it swaps process and so that the back
+ forward list looks as expected. To support this, the following changes had to be done:
+ - The NavigationAction now provides additional information so that the WebProcess can communicate
+ things about the client-side redirect to the UIProcess: lockHistory / lockBackForwardList and
+ clientRedirectSourceForHistory.
+ - If the UIProcess decides to process-swap on a client-side redirect, we pass the client-side
+ redirect information to the new WebContent process via LoadRequest struct. WebCore then takes
+ care of setting things up using this information so that it recognizes that it is continuing
+ a load that is a client side redirect.
+ - We also need to pass the current BackForwardListItem / HistoryItem to the new WebContent
+ process so that the new process can truly lock history and keep updating the *current*
+ HistoryItem, instead of creating a new HistoryItem.
+ - After a process swap, when we re-construct the WebFrameProxy for the main frame in the new
+ process, we now set the frame's URL in the UIProcess to the URL it had before we swapped.
+ Clients such as Safari, rely on the main frame's URL being the expected value (the last
+ committed load URL) until the next load is committed when receiving didPerformRedirect
+ calls. Because we are destroying the main frame on process-swapping, we were losing the
+ last committed URL and Safari would hit assertions.
+
+ With this model, the willPerformClientRedirect IPC is still sent from the previous WebProcess
+ and the didPerformClientRedirect IPC is now sent by the new WebProcess. No change should be
+ observable from the client's point of view.
+
+ * loader/FrameLoadRequest.h:
+ (WebCore::FrameLoadRequest::setLockHistory):
+ (WebCore::FrameLoadRequest::setlockBackForwardList):
+ (WebCore::FrameLoadRequest::clientRedirectSourceForHistory const):
+ (WebCore::FrameLoadRequest::setClientRedirectSourceForHistory):
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::loadURL):
+ (WebCore::FrameLoader::load):
+ * loader/HistoryController.cpp:
+ (WebCore::HistoryController::updateForRedirectWithLockedBackForwardList):
+ * loader/HistoryController.h:
+ * loader/NavigationAction.h:
+ (WebCore::NavigationAction::lockHistory const):
+ (WebCore::NavigationAction::setLockHistory):
+ (WebCore::NavigationAction::lockBackForwardList const):
+ (WebCore::NavigationAction::setLockBackForwardList):
+
2018-10-23 Jer Noble <[email protected]>
Use WeakPtr and GenericTaskQueue within ObjC classes used by MediaPlayerPrivateAVFoundationObjC
Modified: trunk/Source/WebCore/loader/FrameLoadRequest.h (237354 => 237355)
--- trunk/Source/WebCore/loader/FrameLoadRequest.h 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebCore/loader/FrameLoadRequest.h 2018-10-23 17:54:34 UTC (rev 237355)
@@ -72,7 +72,14 @@
bool hasSubstituteData() { return m_substituteData.isValid(); }
LockHistory lockHistory() const { return m_lockHistory; }
+ void setLockHistory(LockHistory value) { m_lockHistory = value; }
+
LockBackForwardList lockBackForwardList() const { return m_lockBackForwardList; }
+ void setlockBackForwardList(LockBackForwardList value) { m_lockBackForwardList = value; }
+
+ const String& clientRedirectSourceForHistory() const { return m_clientRedirectSourceForHistory; }
+ void setClientRedirectSourceForHistory(const String& clientRedirectSourceForHistory) { m_clientRedirectSourceForHistory = clientRedirectSourceForHistory; }
+
ShouldSendReferrer shouldSendReferrer() const { return m_shouldSendReferrer; }
AllowNavigationToInvalidURL allowNavigationToInvalidURL() const { return m_allowNavigationToInvalidURL; }
NewFrameOpenerPolicy newFrameOpenerPolicy() const { return m_newFrameOpenerPolicy; }
@@ -97,6 +104,7 @@
ResourceRequest m_resourceRequest;
String m_frameName;
SubstituteData m_substituteData;
+ String m_clientRedirectSourceForHistory;
bool m_shouldCheckNewWindowPolicy { false };
bool m_shouldTreatAsContinuingLoad { false };
Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (237354 => 237355)
--- trunk/Source/WebCore/loader/FrameLoader.cpp 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp 2018-10-23 17:54:34 UTC (rev 237355)
@@ -1360,6 +1360,8 @@
if (m_frame.page() && m_frame.page()->openedViaWindowOpenWithOpener())
action.setOpenedViaWindowOpenWithOpener();
action.setHasOpenedFrames(!m_openedFrames.isEmpty());
+ action.setLockHistory(lockHistory);
+ action.setLockBackForwardList(frameLoadRequest.lockBackForwardList());
if (!targetFrame && !effectiveFrameName.isEmpty()) {
action = "" frameLoadRequest));
@@ -1458,6 +1460,13 @@
addSameSiteInfoToRequestIfNeeded(loader->request());
applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, request);
+ if (request.shouldTreatAsContinuingLoad() && request.lockHistory() == LockHistory::Yes) {
+ // The load we're continuing is a client-side redirect so set things up accordingly.
+ loader->setClientRedirectSourceForHistory(request.clientRedirectSourceForHistory());
+ loader->setIsClientRedirect(true);
+ m_loadType = FrameLoadType::RedirectWithLockedBackForwardList;
+ }
+
SetForScope<bool> currentLoadShouldBeTreatedAsContinuingLoadGuard(m_currentLoadShouldBeTreatedAsContinuingLoad, request.shouldTreatAsContinuingLoad());
load(loader.get(), request.shouldSkipSafeBrowsingCheck());
}
@@ -1495,7 +1504,7 @@
type = FrameLoadType::Same;
} else if (shouldTreatURLAsSameAsCurrent(newDocumentLoader.unreachableURL()) && isReload(m_loadType))
type = m_loadType;
- else if (m_loadType == FrameLoadType::RedirectWithLockedBackForwardList && !newDocumentLoader.unreachableURL().isEmpty() && newDocumentLoader.substituteData().isValid())
+ else if (m_loadType == FrameLoadType::RedirectWithLockedBackForwardList && ((!newDocumentLoader.unreachableURL().isEmpty() && newDocumentLoader.substituteData().isValid()) || m_currentLoadShouldBeTreatedAsContinuingLoad))
type = FrameLoadType::RedirectWithLockedBackForwardList;
else
type = FrameLoadType::Standard;
Modified: trunk/Source/WebCore/loader/HistoryController.cpp (237354 => 237355)
--- trunk/Source/WebCore/loader/HistoryController.cpp 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebCore/loader/HistoryController.cpp 2018-10-23 17:54:34 UTC (rev 237355)
@@ -440,7 +440,7 @@
if (Page* page = m_frame.page())
addVisitedLink(*page, historyURL);
- if (!m_frame.loader().documentLoader()->didCreateGlobalHistoryEntry() && m_frame.loader().documentLoader()->unreachableURL().isEmpty() && !m_frame.document()->url().isEmpty())
+ if (!m_frame.loader().documentLoader()->didCreateGlobalHistoryEntry() && m_frame.loader().documentLoader()->unreachableURL().isEmpty())
m_frame.loader().client().updateGlobalHistoryRedirectLinks();
}
}
Modified: trunk/Source/WebCore/loader/HistoryController.h (237354 => 237355)
--- trunk/Source/WebCore/loader/HistoryController.h 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebCore/loader/HistoryController.h 2018-10-23 17:54:34 UTC (rev 237355)
@@ -75,7 +75,7 @@
void updateForFrameLoadCompleted();
HistoryItem* currentItem() const { return m_currentItem.get(); }
- void setCurrentItem(HistoryItem&);
+ WEBCORE_EXPORT void setCurrentItem(HistoryItem&);
void setCurrentItemTitle(const StringWithDirection&);
bool currentItemShouldBeReplaced() const;
WEBCORE_EXPORT void replaceCurrentItem(HistoryItem*);
Modified: trunk/Source/WebCore/loader/NavigationAction.h (237354 => 237355)
--- trunk/Source/WebCore/loader/NavigationAction.h 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebCore/loader/NavigationAction.h 2018-10-23 17:54:34 UTC (rev 237355)
@@ -130,6 +130,12 @@
void setTargetBackForwardItem(HistoryItem&);
const std::optional<BackForwardItemIdentifier>& targetBackForwardItemIdentifier() const { return m_targetBackForwardItemIdentifier; }
+ LockHistory lockHistory() const { return m_lockHistory; }
+ void setLockHistory(LockHistory lockHistory) { m_lockHistory = lockHistory; }
+
+ LockBackForwardList lockBackForwardList() const { return m_lockBackForwardList; }
+ void setLockBackForwardList(LockBackForwardList lockBackForwardList) { m_lockBackForwardList = lockBackForwardList; }
+
private:
// Do not add a strong reference to the originating document or a subobject that holds the
// originating document. See comment above the class for more details.
@@ -147,6 +153,8 @@
bool m_openedViaWindowOpenWithOpener { false };
std::optional<PageIDAndFrameIDPair> m_opener;
std::optional<BackForwardItemIdentifier> m_targetBackForwardItemIdentifier;
+ LockHistory m_lockHistory { LockHistory::No };
+ LockBackForwardList m_lockBackForwardList { LockBackForwardList::No };
};
} // namespace WebCore
Modified: trunk/Source/WebKit/ChangeLog (237354 => 237355)
--- trunk/Source/WebKit/ChangeLog 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebKit/ChangeLog 2018-10-23 17:54:34 UTC (rev 237355)
@@ -1,3 +1,51 @@
+2018-10-23 Chris Dumez <[email protected]>
+
+ [PSON] Add support for cross-site client-side redirects
+ https://bugs.webkit.org/show_bug.cgi?id=190806
+ <rdar://problem/45047344>
+
+ Reviewed by Geoffrey Garen.
+
+ * Shared/LoadParameters.cpp:
+ (WebKit::LoadParameters::encode const):
+ (WebKit::LoadParameters::decode):
+ * Shared/LoadParameters.h:
+ * Shared/NavigationActionData.cpp:
+ (WebKit::NavigationActionData::encode const):
+ (WebKit::NavigationActionData::decode):
+ * Shared/NavigationActionData.h:
+ * Shared/WebBackForwardListItem.cpp:
+ (WebKit::WebBackForwardListItem::setSuspendedPage):
+ * UIProcess/API/APINavigation.h:
+ (API::Navigation::setLockHistory):
+ (API::Navigation::lockHistory const):
+ (API::Navigation::setLockBackForwardList):
+ (API::Navigation::lockBackForwardList const):
+ (API::Navigation::setClientRedirectSourceForHistory):
+ (API::Navigation::clientRedirectSourceForHistory const):
+ * UIProcess/API/APINavigationClient.h:
+ (API::NavigationClient::willPerformClientRedirect):
+ (API::NavigationClient::didPerformClientRedirect):
+ * UIProcess/API/Cocoa/WKNavigationDelegatePrivate.h:
+ * UIProcess/Cocoa/NavigationState.h:
+ * UIProcess/Cocoa/NavigationState.mm:
+ (WebKit::NavigationState::setNavigationDelegate):
+ (WebKit::NavigationState::NavigationClient::didPerformClientRedirect):
+ * UIProcess/FrameLoadState.h:
+ (WebKit::FrameLoadState::setURL):
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::loadRequestWithNavigation):
+ (WebKit::WebPageProxy::continueNavigationInNewProcess):
+ (WebKit::WebPageProxy::decidePolicyForNavigationAction):
+ (WebKit::WebPageProxy::didPerformClientRedirect):
+ * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+ (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::loadRequest):
+ (WebKit::WebPage::setCurrentHistoryItemForReattach):
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/WebPage.messages.in:
+
2018-10-23 Claudio Saavedra <[email protected]>
[WPE][GTK] Pass full certificate chain in CertificateInfo coder
Modified: trunk/Source/WebKit/Shared/LoadParameters.cpp (237354 => 237355)
--- trunk/Source/WebKit/Shared/LoadParameters.cpp 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebKit/Shared/LoadParameters.cpp 2018-10-23 17:54:34 UTC (rev 237355)
@@ -50,6 +50,9 @@
encoder << shouldTreatAsContinuingLoad;
encoder << userData;
encoder << forSafeBrowsing;
+ encoder.encodeEnum(lockHistory);
+ encoder.encodeEnum(lockBackForwardList);
+ encoder << clientRedirectSourceForHistory;
platformEncode(encoder);
}
@@ -108,7 +111,19 @@
if (!decoder.decode(data.forSafeBrowsing))
return false;
-
+
+ if (!decoder.decodeEnum(data.lockHistory))
+ return false;
+
+ if (!decoder.decodeEnum(data.lockBackForwardList))
+ return false;
+
+ std::optional<String> clientRedirectSourceForHistory;
+ decoder >> clientRedirectSourceForHistory;
+ if (!clientRedirectSourceForHistory)
+ return false;
+ data.clientRedirectSourceForHistory = WTFMove(*clientRedirectSourceForHistory);
+
if (!platformDecode(decoder, data))
return false;
Modified: trunk/Source/WebKit/Shared/LoadParameters.h (237354 => 237355)
--- trunk/Source/WebKit/Shared/LoadParameters.h 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebKit/Shared/LoadParameters.h 2018-10-23 17:54:34 UTC (rev 237355)
@@ -28,6 +28,7 @@
#include "DataReference.h"
#include "SandboxExtension.h"
#include "UserData.h"
+#include <WebCore/FrameLoaderTypes.h>
#include <WebCore/ResourceRequest.h>
OBJC_CLASS NSDictionary;
@@ -63,6 +64,9 @@
bool shouldTreatAsContinuingLoad { false };
UserData userData;
bool forSafeBrowsing { false };
+ WebCore::LockHistory lockHistory { WebCore::LockHistory::No };
+ WebCore::LockBackForwardList lockBackForwardList { WebCore::LockBackForwardList::No };
+ String clientRedirectSourceForHistory;
#if PLATFORM(COCOA)
RetainPtr<NSDictionary> dataDetectionContext;
Modified: trunk/Source/WebKit/Shared/NavigationActionData.cpp (237354 => 237355)
--- trunk/Source/WebKit/Shared/NavigationActionData.cpp 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebKit/Shared/NavigationActionData.cpp 2018-10-23 17:54:34 UTC (rev 237355)
@@ -51,6 +51,9 @@
encoder << opener;
encoder << requesterOrigin;
encoder << targetBackForwardItemIdentifier;
+ encoder.encodeEnum(lockHistory);
+ encoder.encodeEnum(lockBackForwardList);
+ encoder << clientRedirectSourceForHistory;
}
std::optional<NavigationActionData> NavigationActionData::decode(IPC::Decoder& decoder)
@@ -128,11 +131,24 @@
decoder >> targetBackForwardItemIdentifier;
if (!targetBackForwardItemIdentifier)
return std::nullopt;
-
+
+ WebCore::LockHistory lockHistory;
+ if (!decoder.decodeEnum(lockHistory))
+ return std::nullopt;
+
+ WebCore::LockBackForwardList lockBackForwardList;
+ if (!decoder.decodeEnum(lockBackForwardList))
+ return std::nullopt;
+
+ std::optional<String> clientRedirectSourceForHistory;
+ decoder >> clientRedirectSourceForHistory;
+ if (!clientRedirectSourceForHistory)
+ return std::nullopt;
+
return {{ WTFMove(navigationType), WTFMove(modifiers), WTFMove(mouseButton), WTFMove(syntheticClickType), WTFMove(*userGestureTokenIdentifier),
WTFMove(*canHandleRequest), WTFMove(shouldOpenExternalURLsPolicy), WTFMove(*downloadAttribute), WTFMove(clickLocationInRootViewCoordinates),
WTFMove(*isRedirect), *treatAsSameOriginNavigation, *hasOpenedFrames, *openedViaWindowOpenWithOpener, WTFMove(*opener), WTFMove(*requesterOrigin),
- WTFMove(*targetBackForwardItemIdentifier) }};
+ WTFMove(*targetBackForwardItemIdentifier), lockHistory, lockBackForwardList, WTFMove(*clientRedirectSourceForHistory) }};
}
} // namespace WebKit
Modified: trunk/Source/WebKit/Shared/NavigationActionData.h (237354 => 237355)
--- trunk/Source/WebKit/Shared/NavigationActionData.h 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebKit/Shared/NavigationActionData.h 2018-10-23 17:54:34 UTC (rev 237355)
@@ -58,6 +58,9 @@
std::optional<std::pair<uint64_t, uint64_t>> opener;
WebCore::SecurityOriginData requesterOrigin;
std::optional<WebCore::BackForwardItemIdentifier> targetBackForwardItemIdentifier;
+ WebCore::LockHistory lockHistory;
+ WebCore::LockBackForwardList lockBackForwardList;
+ WTF::String clientRedirectSourceForHistory;
};
}
Modified: trunk/Source/WebKit/Shared/WebBackForwardListItem.cpp (237354 => 237355)
--- trunk/Source/WebKit/Shared/WebBackForwardListItem.cpp 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebKit/Shared/WebBackForwardListItem.cpp 2018-10-23 17:54:34 UTC (rev 237355)
@@ -115,7 +115,6 @@
void WebBackForwardListItem::setSuspendedPage(SuspendedPageProxy& page)
{
- ASSERT(!m_suspendedPage);
m_suspendedPage = makeWeakPtr(page);
}
Modified: trunk/Source/WebKit/UIProcess/API/APINavigation.h (237354 => 237355)
--- trunk/Source/WebKit/UIProcess/API/APINavigation.h 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebKit/UIProcess/API/APINavigation.h 2018-10-23 17:54:34 UTC (rev 237355)
@@ -101,6 +101,15 @@
void setRequesterOrigin(const WebCore::SecurityOriginData& origin) { m_requesterOrigin = origin; }
const WebCore::SecurityOriginData& requesterOrigin() const { return m_requesterOrigin; }
+ void setLockHistory(WebCore::LockHistory lockHistory) { m_lockHistory = lockHistory; }
+ WebCore::LockHistory lockHistory() const { return m_lockHistory; }
+
+ void setLockBackForwardList(WebCore::LockBackForwardList lockBackForwardList) { m_lockBackForwardList = lockBackForwardList; }
+ WebCore::LockBackForwardList lockBackForwardList() const { return m_lockBackForwardList; }
+
+ void setClientRedirectSourceForHistory(const WTF::String& clientRedirectSourceForHistory) { m_clientRedirectSourceForHistory = clientRedirectSourceForHistory; }
+ WTF::String clientRedirectSourceForHistory() const { return m_clientRedirectSourceForHistory; }
+
#if !LOG_DISABLED
const char* loggingString() const;
#endif
@@ -127,6 +136,9 @@
bool m_openedViaWindowOpenWithOpener { false };
std::optional<std::pair<uint64_t, uint64_t>> m_opener;
WebCore::SecurityOriginData m_requesterOrigin;
+ WebCore::LockHistory m_lockHistory;
+ WebCore::LockBackForwardList m_lockBackForwardList;
+ WTF::String m_clientRedirectSourceForHistory;
};
} // namespace API
Modified: trunk/Source/WebKit/UIProcess/API/APINavigationClient.h (237354 => 237355)
--- trunk/Source/WebKit/UIProcess/API/APINavigationClient.h 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebKit/UIProcess/API/APINavigationClient.h 2018-10-23 17:54:34 UTC (rev 237355)
@@ -73,7 +73,8 @@
virtual void didStartProvisionalNavigation(WebKit::WebPageProxy&, Navigation*, Object*) { }
virtual void didReceiveServerRedirectForProvisionalNavigation(WebKit::WebPageProxy&, Navigation*, Object*) { }
- virtual void willPerformClientRedirect(WebKit::WebPageProxy&, const WTF::String&, double) { }
+ virtual void willPerformClientRedirect(WebKit::WebPageProxy&, const WTF::String& destinationURL, double) { }
+ virtual void didPerformClientRedirect(WebKit::WebPageProxy&, const WTF::String& sourceURL, const WTF::String& destinationURL) { }
virtual void didCancelClientRedirect(WebKit::WebPageProxy&) { }
virtual void didFailProvisionalNavigationWithError(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, Navigation*, const WebCore::ResourceError&, Object*) { }
virtual void didFailProvisionalLoadInSubframeWithError(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, const WebCore::SecurityOriginData&, Navigation*, const WebCore::ResourceError&, Object*) { }
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKNavigationDelegatePrivate.h (237354 => 237355)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKNavigationDelegatePrivate.h 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKNavigationDelegatePrivate.h 2018-10-23 17:54:34 UTC (rev 237355)
@@ -68,6 +68,7 @@
- (void)_webView:(WKWebView *)webView navigation:(WKNavigation *)navigation didFailProvisionalLoadInSubframe:(WKFrameInfo *)subframe withError:(NSError *)error;
- (void)_webView:(WKWebView *)webView willPerformClientRedirectToURL:(NSURL *)URL delay:(NSTimeInterval)delay;
+- (void)_webView:(WKWebView *)webView didPerformClientRedirectFromURL:(NSURL *)sourceURL toURL:(NSURL *)destinationURL;
- (void)_webViewDidCancelClientRedirect:(WKWebView *)webView;
- (void)_webView:(WKWebView *)webView navigationDidFinishDocumentLoad:(WKNavigation *)navigation;
Modified: trunk/Source/WebKit/UIProcess/Cocoa/NavigationState.h (237354 => 237355)
--- trunk/Source/WebKit/UIProcess/Cocoa/NavigationState.h 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebKit/UIProcess/Cocoa/NavigationState.h 2018-10-23 17:54:34 UTC (rev 237355)
@@ -98,6 +98,7 @@
void didStartProvisionalNavigation(WebPageProxy&, API::Navigation*, API::Object*) override;
void didReceiveServerRedirectForProvisionalNavigation(WebPageProxy&, API::Navigation*, API::Object*) override;
void willPerformClientRedirect(WebPageProxy&, const WTF::String&, double) override;
+ void didPerformClientRedirect(WebPageProxy&, const WTF::String&, const WTF::String&) override;
void didCancelClientRedirect(WebPageProxy&) override;
void didFailProvisionalNavigationWithError(WebPageProxy&, WebFrameProxy&, API::Navigation*, const WebCore::ResourceError&, API::Object*) override;
void didFailProvisionalLoadInSubframeWithError(WebPageProxy&, WebFrameProxy&, const WebCore::SecurityOriginData&, API::Navigation*, const WebCore::ResourceError&, API::Object*) override;
@@ -195,6 +196,7 @@
bool webViewDidFailProvisionalNavigationWithError : 1;
bool webViewNavigationDidFailProvisionalLoadInSubframeWithError : 1;
bool webViewWillPerformClientRedirect : 1;
+ bool webViewDidPerformClientRedirect : 1;
bool webViewDidCancelClientRedirect : 1;
bool webViewDidCommitNavigation : 1;
bool webViewNavigationDidFinishDocumentLoad : 1;
Modified: trunk/Source/WebKit/UIProcess/Cocoa/NavigationState.mm (237354 => 237355)
--- trunk/Source/WebKit/UIProcess/Cocoa/NavigationState.mm 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebKit/UIProcess/Cocoa/NavigationState.mm 2018-10-23 17:54:34 UTC (rev 237355)
@@ -157,6 +157,7 @@
m_navigationDelegateMethods.webViewNavigationDidFailProvisionalLoadInSubframeWithError = [delegate respondsToSelector:@selector(_webView:navigation:didFailProvisionalLoadInSubframe:withError:)];
m_navigationDelegateMethods.webViewWillPerformClientRedirect = [delegate respondsToSelector:@selector(_webView:willPerformClientRedirectToURL:delay:)];
+ m_navigationDelegateMethods.webViewDidPerformClientRedirect = [delegate respondsToSelector:@selector(_webView:didPerformClientRedirectFromURL:toURL:)];
m_navigationDelegateMethods.webViewDidCancelClientRedirect = [delegate respondsToSelector:@selector(_webViewDidCancelClientRedirect:)];
m_navigationDelegateMethods.webViewNavigationDidFinishDocumentLoad = [delegate respondsToSelector:@selector(_webView:navigationDidFinishDocumentLoad:)];
m_navigationDelegateMethods.webViewNavigationDidSameDocumentNavigation = [delegate respondsToSelector:@selector(_webView:navigation:didSameDocumentNavigation:)];
@@ -704,6 +705,21 @@
[static_cast<id <WKNavigationDelegatePrivate>>(navigationDelegate) _webView:m_navigationState.m_webView willPerformClientRedirectToURL:url delay:delay];
}
+void NavigationState::NavigationClient::didPerformClientRedirect(WebPageProxy& page, const WTF::String& sourceURLString, const WTF::String& destinationURLString)
+{
+ if (!m_navigationState.m_navigationDelegateMethods.webViewDidPerformClientRedirect)
+ return;
+
+ auto navigationDelegate = m_navigationState.m_navigationDelegate.get();
+ if (!navigationDelegate)
+ return;
+
+ WebCore::URL sourceURL(WebCore::URL(), sourceURLString);
+ WebCore::URL destinationURL(WebCore::URL(), destinationURLString);
+
+ [static_cast<id <WKNavigationDelegatePrivate>>(navigationDelegate) _webView:m_navigationState.m_webView didPerformClientRedirectFromURL:sourceURL toURL:destinationURL];
+}
+
void NavigationState::NavigationClient::didCancelClientRedirect(WebPageProxy& page)
{
if (!m_navigationState.m_navigationDelegateMethods.webViewDidCancelClientRedirect)
Modified: trunk/Source/WebKit/UIProcess/FrameLoadState.h (237354 => 237355)
--- trunk/Source/WebKit/UIProcess/FrameLoadState.h 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebKit/UIProcess/FrameLoadState.h 2018-10-23 17:54:34 UTC (rev 237355)
@@ -51,6 +51,7 @@
State state() const { return m_state; }
const WebCore::URL& url() const { return m_url; }
+ void setURL(const WebCore::URL& url) { m_url = url; }
const WebCore::URL& provisionalURL() const { return m_provisionalURL; }
void setUnreachableURL(const WebCore::URL&);
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (237354 => 237355)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2018-10-23 17:54:34 UTC (rev 237355)
@@ -103,6 +103,7 @@
#include "WebImage.h"
#include "WebInspectorProxy.h"
#include "WebInspectorUtilities.h"
+#include "WebNavigationDataStore.h"
#include "WebNavigationState.h"
#include "WebNotificationManagerProxy.h"
#include "WebOpenPanelResultListenerProxy.h"
@@ -1017,6 +1018,9 @@
loadParameters.shouldOpenExternalURLsPolicy = (uint64_t)shouldOpenExternalURLsPolicy;
loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get());
loadParameters.shouldTreatAsContinuingLoad = shouldTreatAsContinuingLoad == ShouldTreatAsContinuingLoad::Yes;
+ loadParameters.lockHistory = navigation.lockHistory();
+ loadParameters.lockBackForwardList = navigation.lockBackForwardList();
+ loadParameters.clientRedirectSourceForHistory = navigation.clientRedirectSourceForHistory();
bool createdExtension = maybeInitializeSandboxExtensionHandle(url, loadParameters.sandboxExtensionHandle);
if (createdExtension)
m_process->willAcquireUniversalFileReadSandboxExtension();
@@ -2548,6 +2552,7 @@
Ref<WebProcessProxy> previousProcess = m_process.copyRef();
std::optional<uint64_t> mainFrameIDInPreviousProcess = m_mainFrame ? std::make_optional(m_mainFrame->frameID()) : std::nullopt;
+ auto mainFrameURL = m_mainFrame ? m_mainFrame->url() : WebCore::URL();
ASSERT(m_process.ptr() != process.ptr());
@@ -2575,21 +2580,34 @@
return;
}
+ if (navigation.lockBackForwardList() == LockBackForwardList::Yes || navigation.lockHistory() == LockHistory::Yes) {
+ // If WebCore is supposed to lock the history for this load, then the new process needs to know about the current history item so it can update
+ // it instead of creating a new one.
+ auto itemStates = m_backForwardList->filteredItemStates([currentItem = m_backForwardList->currentItem()](WebBackForwardListItem& item) {
+ return &item == currentItem;
+ });
+ RELEASE_ASSERT(itemStates.size() == 1);
+ m_process->send(Messages::WebPage::SetCurrentHistoryItemForReattach(itemStates[0]), m_pageID);
+ }
+
// FIXME: Work out timing of responding with the last policy delegate, etc
ASSERT(!navigation.currentRequest().isEmpty());
loadRequestWithNavigation(navigation, ResourceRequest { navigation.currentRequest() }, WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes, nullptr, ShouldTreatAsContinuingLoad::Yes);
- // Normally, notification of a server redirect comes from the WebContent process.
- // If we are process swapping in response to a server redirect then that notification will not come from the new WebContent process.
- // In this case we have the UIProcess synthesize the redirect notification at the appropriate time.
- if (navigation.currentRequestIsRedirect()) {
- ASSERT(!m_mainFrame);
- m_mainFrameCreationHandler = [this, protectedThis = makeRef(*this), navigation = makeRef(navigation), request = navigation.currentRequest()]() mutable {
- ASSERT(m_mainFrame);
+ ASSERT(!m_mainFrame);
+ m_mainFrameCreationHandler = [this, protectedThis = makeRef(*this), navigation = makeRef(navigation), request = navigation.currentRequest(), mainFrameURL, isServerRedirect = navigation.currentRequestIsRedirect()]() mutable {
+ ASSERT(m_mainFrame);
+ // Restore the main frame's committed URL as some clients may rely on it until the next load is committed.
+ m_mainFrame->frameLoadState().setURL(mainFrameURL);
+
+ // Normally, notification of a server redirect comes from the WebContent process.
+ // If we are process swapping in response to a server redirect then that notification will not come from the new WebContent process.
+ // In this case we have the UIProcess synthesize the redirect notification at the appropriate time.
+ if (isServerRedirect) {
m_mainFrame->frameLoadState().didStartProvisionalLoad(request.url());
didReceiveServerRedirectForProvisionalLoadForFrame(m_mainFrame->frameID(), navigation->navigationID(), WTFMove(request), { });
- };
- }
+ }
+ };
bool isInitialNavigationInNewWindow = openedByDOM() && !hasCommittedAnyProvisionalLoads();
if (!isInitialNavigationInNewWindow || !mainFrameIDInPreviousProcess)
@@ -4115,6 +4133,9 @@
navigation->setOpenedViaWindowOpenWithOpener();
navigation->setOpener(navigationActionData.opener);
navigation->setRequesterOrigin(navigationActionData.requesterOrigin);
+ navigation->setLockHistory(navigationActionData.lockHistory);
+ navigation->setLockBackForwardList(navigationActionData.lockBackForwardList);
+ navigation->setClientRedirectSourceForHistory(navigationActionData.clientRedirectSourceForHistory);
#if ENABLE(CONTENT_FILTERING)
if (frame.didHandleContentFilterUnblockNavigation(request))
@@ -4302,8 +4323,10 @@
MESSAGE_CHECK_URL(sourceURLString);
MESSAGE_CHECK_URL(destinationURLString);
- if (frame->isMainFrame())
+ if (frame->isMainFrame()) {
m_historyClient->didPerformClientRedirect(*this, sourceURLString, destinationURLString);
+ m_navigationClient->didPerformClientRedirect(*this, sourceURLString, destinationURLString);
+ }
process().processPool().historyClient().didPerformClientRedirect(process().processPool(), *this, sourceURLString, destinationURLString, *frame);
}
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp (237354 => 237355)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2018-10-23 17:54:34 UTC (rev 237355)
@@ -871,6 +871,8 @@
if (auto& requester = navigationAction.requester())
navigationActionData.requesterOrigin = requester->securityOrigin().data();
navigationActionData.targetBackForwardItemIdentifier = navigationAction.targetBackForwardItemIdentifier();
+ navigationActionData.lockHistory = navigationAction.lockHistory();
+ navigationActionData.lockBackForwardList = navigationAction.lockBackForwardList();
WebCore::Frame* coreFrame = m_frame->coreFrame();
if (!coreFrame)
@@ -884,6 +886,8 @@
if (!documentLoader)
documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().documentLoader());
+ navigationActionData.clientRedirectSourceForHistory = documentLoader->clientRedirectSourceForHistory();
+
// Notify the UIProcess.
Ref<WebFrame> protect(*m_frame);
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (237354 => 237355)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2018-10-23 17:54:34 UTC (rev 237355)
@@ -1307,6 +1307,9 @@
ShouldOpenExternalURLsPolicy externalURLsPolicy = static_cast<ShouldOpenExternalURLsPolicy>(loadParameters.shouldOpenExternalURLsPolicy);
frameLoadRequest.setShouldOpenExternalURLsPolicy(externalURLsPolicy);
frameLoadRequest.setShouldTreatAsContinuingLoad(loadParameters.shouldTreatAsContinuingLoad);
+ frameLoadRequest.setLockHistory(loadParameters.lockHistory);
+ frameLoadRequest.setlockBackForwardList(loadParameters.lockBackForwardList);
+ frameLoadRequest.setClientRedirectSourceForHistory(loadParameters.clientRedirectSourceForHistory);
corePage()->userInputBridge().loadRequest(WTFMove(frameLoadRequest));
@@ -2606,6 +2609,14 @@
restoreSessionInternal(itemStates, WasRestoredByAPIRequest::No, WebBackForwardListProxy::OverwriteExistingItem::Yes);
}
+void WebPage::setCurrentHistoryItemForReattach(WebKit::BackForwardListItemState&& itemState)
+{
+ auto historyItem = toHistoryItem(itemState);
+ auto& historyItemRef = historyItem.get();
+ static_cast<WebBackForwardListProxy&>(corePage()->backForward().client()).addItemFromUIProcess(itemState.identifier, WTFMove(historyItem), m_pageID, WebBackForwardListProxy::OverwriteExistingItem::Yes);
+ corePage()->mainFrame().loader().history().setCurrentItem(historyItemRef);
+}
+
void WebPage::requestFontAttributesAtSelectionStart(CallbackID callbackID)
{
auto attributes = m_page->focusController().focusedOrMainFrame().editor().fontAttributesAtSelectionStart();
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (237354 => 237355)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2018-10-23 17:54:34 UTC (rev 237355)
@@ -1209,6 +1209,7 @@
void restoreSession(const Vector<BackForwardListItemState>&);
void didRemoveBackForwardItem(const WebCore::BackForwardItemIdentifier&);
void updateBackForwardListForReattach(const Vector<WebKit::BackForwardListItemState>&);
+ void setCurrentHistoryItemForReattach(WebKit::BackForwardListItemState&&);
void requestFontAttributesAtSelectionStart(CallbackID);
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (237354 => 237355)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2018-10-23 17:54:34 UTC (rev 237355)
@@ -157,6 +157,7 @@
RestoreSession(Vector<WebKit::BackForwardListItemState> itemStates)
UpdateBackForwardListForReattach(Vector<WebKit::BackForwardListItemState> itemStates)
+ SetCurrentHistoryItemForReattach(struct WebKit::BackForwardListItemState itemState)
DidRemoveBackForwardItem(struct WebCore::BackForwardItemIdentifier backForwardItemID)
Modified: trunk/Tools/ChangeLog (237354 => 237355)
--- trunk/Tools/ChangeLog 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Tools/ChangeLog 2018-10-23 17:54:34 UTC (rev 237355)
@@ -1,3 +1,17 @@
+2018-10-23 Chris Dumez <[email protected]>
+
+ [PSON] Add support for cross-site client-side redirects
+ https://bugs.webkit.org/show_bug.cgi?id=190806
+ <rdar://problem/45047344>
+
+ Reviewed by Geoffrey Garen.
+
+ Add API test coverage.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
+ (-[PSONNavigationDelegate _webView:willPerformClientRedirectToURL:delay:]):
+ (-[PSONNavigationDelegate _webView:didPerformClientRedirectFromURL:toURL:]):
+
2018-10-23 Claudio Saavedra <[email protected]>
[WPE][GTK] Pass full certificate chain in CertificateInfo coder
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm (237354 => 237355)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm 2018-10-23 17:26:55 UTC (rev 237354)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm 2018-10-23 17:54:34 UTC (rev 237355)
@@ -68,6 +68,11 @@
static bool receivedMessage;
static bool serverRedirected;
static HashSet<pid_t> seenPIDs;
+static bool willPerformClientRedirect;
+static bool didPerformClientRedirect;
+static RetainPtr<NSURL> clientRedirectSourceURL;
+static RetainPtr<NSURL> clientRedirectDestinationURL;
+
@interface PSONMessageHandler : NSObject <WKScriptMessageHandler>
@end
@@ -124,6 +129,20 @@
serverRedirected = true;
}
+- (void)_webView:(WKWebView *)webView willPerformClientRedirectToURL:(NSURL *)URL delay:(NSTimeInterval)delay
+{
+ clientRedirectDestinationURL = URL;
+ willPerformClientRedirect = true;
+}
+
+- (void)_webView:(WKWebView *)webView didPerformClientRedirectFromURL:(NSURL *)sourceURL toURL:(NSURL *)destinationURL
+{
+ EXPECT_TRUE(willPerformClientRedirect);
+ EXPECT_WK_STREQ([clientRedirectDestinationURL absoluteString], [destinationURL absoluteString]);
+ clientRedirectSourceURL = sourceURL;
+ didPerformClientRedirect = true;
+}
+
@end
static RetainPtr<WKWebView> createdWebView;
@@ -245,6 +264,22 @@
</head>
)PSONRESOURCE";
+static const char* linkToCrossSiteClientSideRedirectBytes = R"PSONRESOURCE(
+<body>
+ <a id="testLink" href="" to cross-site client-side redirect</a>
+</body>
+)PSONRESOURCE";
+
+static const char* crossSiteClientSideRedirectBytes = R"PSONRESOURCE(
+<body>
+<script>
+_onload_ = () => {
+ location = "pson://www.apple.com/main.html";
+};
+</script>
+</body>
+)PSONRESOURCE";
+
#if PLATFORM(MAC)
static const char* windowOpenCrossSiteNoOpenerTestBytes = R"PSONRESOURCE(
@@ -1097,6 +1132,143 @@
EXPECT_EQ(2u, seenPIDs.size());
}
+enum class ShouldEnablePSON { No, Yes };
+static void runClientSideRedirectTest(ShouldEnablePSON shouldEnablePSON)
+{
+ auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
+ processPoolConfiguration.get().processSwapsOnNavigation = shouldEnablePSON == ShouldEnablePSON::Yes ? YES : NO;
+ auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
+
+ auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ [webViewConfiguration setProcessPool:processPool.get()];
+ auto handler = adoptNS([[PSONScheme alloc] init]);
+ [handler addMappingFromURLString:@"pson://www.webkit.org/main.html" toData:linkToCrossSiteClientSideRedirectBytes];
+ [handler addMappingFromURLString:@"pson://www.google.com/clientSideRedirect.html" toData:crossSiteClientSideRedirectBytes];
+ [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"pson"];
+
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+ auto delegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+ [webView setNavigationDelegate:delegate.get()];
+
+ NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main.html"]];
+ [webView loadRequest:request];
+
+ TestWebKitAPI::Util::run(&done);
+ done = false;
+
+ auto webkitPID = [webView _webProcessIdentifier];
+
+ // Navigate to the page doing a client-side redirect to apple.com.
+ [webView evaluateJavaScript:@"testLink.click()" completionHandler:nil];
+
+ TestWebKitAPI::Util::run(&done);
+ done = false;
+
+ EXPECT_WK_STREQ(@"pson://www.google.com/clientSideRedirect.html", [[webView URL] absoluteString]);
+ auto googlePID = [webView _webProcessIdentifier];
+ if (shouldEnablePSON == ShouldEnablePSON::Yes)
+ EXPECT_NE(webkitPID, googlePID);
+ else
+ EXPECT_EQ(webkitPID, googlePID);
+
+ TestWebKitAPI::Util::run(&done);
+ done = false;
+
+ EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [[webView URL] absoluteString]);
+
+ auto applePID = [webView _webProcessIdentifier];
+ if (shouldEnablePSON == ShouldEnablePSON::Yes) {
+ EXPECT_NE(webkitPID, applePID);
+ EXPECT_NE(webkitPID, googlePID);
+ } else {
+ EXPECT_EQ(webkitPID, applePID);
+ EXPECT_EQ(webkitPID, googlePID);
+ }
+
+ EXPECT_TRUE(willPerformClientRedirect);
+ EXPECT_TRUE(didPerformClientRedirect);
+ EXPECT_WK_STREQ(@"pson://www.google.com/clientSideRedirect.html", [clientRedirectSourceURL absoluteString]);
+ EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [clientRedirectDestinationURL absoluteString]);
+
+ willPerformClientRedirect = false;
+ didPerformClientRedirect = false;
+ clientRedirectSourceURL = nullptr;
+ clientRedirectDestinationURL = nullptr;
+
+ // Validate Back/Forward list.
+ auto* backForwardList = [webView backForwardList];
+ auto* currentItem = backForwardList.currentItem;
+ EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [currentItem.URL absoluteString]);
+ EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [currentItem.initialURL absoluteString]);
+ EXPECT_TRUE(!backForwardList.forwardItem);
+
+ EXPECT_EQ(1U, backForwardList.backList.count);
+
+ auto* backItem = backForwardList.backItem;
+ EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html", [backItem.URL absoluteString]);
+ EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html", [backItem.initialURL absoluteString]);
+
+ // Navigate back.
+ [webView goBack];
+ TestWebKitAPI::Util::run(&done);
+ done = false;
+
+ EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html", [[webView URL] absoluteString]);
+ EXPECT_FALSE(willPerformClientRedirect);
+ EXPECT_FALSE(didPerformClientRedirect);
+
+ auto pidAfterBackNavigation = [webView _webProcessIdentifier];
+ EXPECT_EQ(webkitPID, pidAfterBackNavigation);
+
+ // Validate Back/Forward list.
+ currentItem = backForwardList.currentItem;
+ EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html", [currentItem.URL absoluteString]);
+ EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html", [currentItem.initialURL absoluteString]);
+
+ EXPECT_TRUE(!backForwardList.backItem);
+ EXPECT_EQ(1U, backForwardList.forwardList.count);
+
+ auto* forwardItem = backForwardList.forwardItem;
+ EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [forwardItem.URL absoluteString]);
+ EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [forwardItem.initialURL absoluteString]);
+
+ // Navigate forward.
+ [webView goForward];
+ TestWebKitAPI::Util::run(&done);
+ done = false;
+
+ EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [[webView URL] absoluteString]);
+ EXPECT_FALSE(willPerformClientRedirect);
+ EXPECT_FALSE(didPerformClientRedirect);
+
+ auto pidAfterForwardNavigation = [webView _webProcessIdentifier];
+ EXPECT_EQ(applePID, pidAfterForwardNavigation);
+
+ // Validate Back/Forward list.
+ currentItem = backForwardList.currentItem;
+ EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [currentItem.URL absoluteString]);
+ EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [currentItem.initialURL absoluteString]);
+ EXPECT_TRUE(!backForwardList.forwardItem);
+
+ EXPECT_EQ(1U, backForwardList.backList.count);
+
+ // FIXME: uncomment the following once <rdar://problem/45058938> has been fixed. When enabling PSON
+ // the backItem's URL currently becomes about:blank.
+ // backItem = backForwardList.backItem;
+ // EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html", [backItem.URL absoluteString]);
+ // EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html", [backItem.initialURL absoluteString]);
+}
+
+TEST(ProcessSwap, CrossSiteClientSideRedirectWithoutPSON)
+{
+ runClientSideRedirectTest(ShouldEnablePSON::No);
+}
+
+TEST(ProcessSwap, CrossSiteClientSideRedirectWithPSON)
+{
+ runClientSideRedirectTest(ShouldEnablePSON::Yes);
+}
+
static const char* sessionStorageTestBytes = R"PSONRESOURCE(
<head>
<script>