Diff
Modified: trunk/Source/WebCore/ChangeLog (275951 => 275952)
--- trunk/Source/WebCore/ChangeLog 2021-04-14 17:39:33 UTC (rev 275951)
+++ trunk/Source/WebCore/ChangeLog 2021-04-14 17:54:05 UTC (rev 275952)
@@ -1,3 +1,30 @@
+2021-04-14 Kate Cheney <[email protected]>
+
+ Service worker soft-update loads not being marked app-bound
+ https://bugs.webkit.org/show_bug.cgi?id=223200
+ <rdar://problem/75438555>
+
+ Reviewed by Youenn Fablet.
+
+ We need to mark requests initiated by service worker soft updates as
+ app-bound based on the last navigation. We should get this value from the
+ NetworkResourceLoader and store it in SWServerRegistration so we can
+ use it to build a new request.
+
+ * workers/service/server/SWServer.cpp:
+ (WebCore::SWServer::startScriptFetch):
+ * workers/service/server/SWServer.h:
+ Pass the entire SWServerRegistration to SWServer::startScriptFetch
+ now that we need more than one value from it. Move shouldRefreshCache
+ logic here instead of SWServerJobQueue::runUpdateJob.
+
+ * workers/service/server/SWServerJobQueue.cpp:
+ (WebCore::SWServerJobQueue::runUpdateJob):
+ * workers/service/server/SWServerRegistration.cpp:
+ (WebCore::SWServerRegistration::scheduleSoftUpdate):
+ * workers/service/server/SWServerRegistration.h:
+ (WebCore::SWServerRegistration::isAppBound):
+
2021-04-14 Eric Carlson <[email protected]>
Allow text tracks to purge cues outside of the buffered range
Modified: trunk/Source/WebCore/workers/service/server/SWServer.cpp (275951 => 275952)
--- trunk/Source/WebCore/workers/service/server/SWServer.cpp 2021-04-14 17:39:33 UTC (rev 275951)
+++ trunk/Source/WebCore/workers/service/server/SWServer.cpp 2021-04-14 17:54:05 UTC (rev 275952)
@@ -441,9 +441,17 @@
return url;
}
-void SWServer::startScriptFetch(const ServiceWorkerJobData& jobData, bool shouldRefreshCache)
+void SWServer::startScriptFetch(const ServiceWorkerJobData& jobData, SWServerRegistration& registration)
{
LOG(ServiceWorker, "Server issuing startScriptFetch for current job %s in client", jobData.identifier().loggingString().utf8().data());
+
+ // Set request's cache mode to "no-cache" if any of the following are true:
+ // - registration's update via cache mode is not "all".
+ // - job's force bypass cache flag is set.
+ // - newestWorker is not null, and registration's last update check time is not null and the time difference in seconds calculated by the
+ // current time minus registration's last update check time is greater than 86400.
+ bool shouldRefreshCache = registration.updateViaCache() != ServiceWorkerUpdateViaCache::All || (registration.getNewestWorker() && registration.isStale());
+
auto* connection = m_connections.get(jobData.connectionIdentifier());
if (connection) {
connection->startScriptFetchInClient(jobData.identifier().jobIdentifier, jobData.registrationKey(), shouldRefreshCache ? FetchOptions::Cache::NoCache : FetchOptions::Cache::Default);
@@ -466,6 +474,7 @@
request.setHTTPReferrer(originURL(origin).string());
request.setHTTPUserAgent(serviceWorkerClientUserAgent(ClientOrigin { jobData.topOrigin, SecurityOrigin::create(jobData.scriptURL)->data() }));
request.setPriority(ResourceLoadPriority::Low);
+ request.setIsAppBound(registration.isAppBound());
m_softUpdateCallback(ServiceWorkerJobData { jobData }, shouldRefreshCache, WTFMove(request), [this, weakThis = makeWeakPtr(this)](auto& result) {
if (!weakThis)
Modified: trunk/Source/WebCore/workers/service/server/SWServer.h (275951 => 275952)
--- trunk/Source/WebCore/workers/service/server/SWServer.h 2021-04-14 17:39:33 UTC (rev 275951)
+++ trunk/Source/WebCore/workers/service/server/SWServer.h 2021-04-14 17:54:05 UTC (rev 275952)
@@ -150,7 +150,7 @@
void rejectJob(const ServiceWorkerJobData&, const ExceptionData&);
void resolveRegistrationJob(const ServiceWorkerJobData&, const ServiceWorkerRegistrationData&, ShouldNotifyWhenResolved);
void resolveUnregistrationJob(const ServiceWorkerJobData&, const ServiceWorkerRegistrationKey&, bool unregistrationResult);
- void startScriptFetch(const ServiceWorkerJobData&, bool shouldRefreshCache);
+ void startScriptFetch(const ServiceWorkerJobData&, SWServerRegistration&);
void updateWorker(const ServiceWorkerJobDataIdentifier&, SWServerRegistration&, const URL&, const ScriptBuffer&, const CertificateInfo&, const ContentSecurityPolicyResponseHeaders&, const String& referrerPolicy, WorkerType, HashMap<URL, ServiceWorkerContextData::ImportedScript>&&);
void fireInstallEvent(SWServerWorker&);
Modified: trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp (275951 => 275952)
--- trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp 2021-04-14 17:39:33 UTC (rev 275951)
+++ trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp 2021-04-14 17:54:05 UTC (rev 275952)
@@ -352,13 +352,7 @@
if (job.type == ServiceWorkerJobType::Update && newestWorker && !equalIgnoringFragmentIdentifier(job.scriptURL, newestWorker->scriptURL()))
return rejectCurrentJob(ExceptionData { TypeError, "Cannot update a service worker with a requested script URL whose newest worker has a different script URL"_s });
- // Set request's cache mode to "no-cache" if any of the following are true:
- // - registration's update via cache mode is not "all".
- // - job's force bypass cache flag is set.
- // - newestWorker is not null, and registration's last update check time is not null and the time difference in seconds calculated by the
- // current time minus registration's last update check time is greater than 86400.
- bool shouldRefreshCache = registration->updateViaCache() != ServiceWorkerUpdateViaCache::All || (newestWorker && registration->isStale());
- m_server.startScriptFetch(job, shouldRefreshCache);
+ m_server.startScriptFetch(job, *registration);
}
void SWServerJobQueue::rejectCurrentJob(const ExceptionData& exceptionData)
Modified: trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp (275951 => 275952)
--- trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp 2021-04-14 17:39:33 UTC (rev 275951)
+++ trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp 2021-04-14 17:54:05 UTC (rev 275952)
@@ -370,7 +370,7 @@
m_server.softUpdate(*this);
}
-void SWServerRegistration::scheduleSoftUpdate()
+void SWServerRegistration::scheduleSoftUpdate(IsAppBound isAppBound)
{
// To avoid scheduling many updates during a single page load, we do soft updates on a 1 second delay and keep delaying
// as long as soft update requests keep coming. This seems to match Chrome's behavior.
@@ -377,6 +377,8 @@
if (m_softUpdateTimer.isActive())
return;
+ m_isAppBound = isAppBound == IsAppBound::Yes;
+
RELEASE_LOG(ServiceWorker, "SWServerRegistration::softUpdateIfNeeded");
m_softUpdateTimer.startOneShot(softUpdateDelay);
}
Modified: trunk/Source/WebCore/workers/service/server/SWServerRegistration.h (275951 => 275952)
--- trunk/Source/WebCore/workers/service/server/SWServerRegistration.h 2021-04-14 17:39:33 UTC (rev 275951)
+++ trunk/Source/WebCore/workers/service/server/SWServerRegistration.h 2021-04-14 17:54:05 UTC (rev 275952)
@@ -47,6 +47,8 @@
struct ServiceWorkerContextData;
struct ServiceWorkerFetchResult;
+enum class IsAppBound : bool { No, Yes };
+
class SWServerRegistration : public CanMakeWeakPtr<SWServerRegistration> {
WTF_MAKE_FAST_ALLOCATED;
public:
@@ -99,12 +101,14 @@
void forEachConnection(const WTF::Function<void(SWServer::Connection&)>&);
WEBCORE_EXPORT bool shouldSoftUpdate(const FetchOptions&) const;
- WEBCORE_EXPORT void scheduleSoftUpdate();
+ WEBCORE_EXPORT void scheduleSoftUpdate(IsAppBound);
static constexpr Seconds softUpdateDelay { 1_s };
URL scopeURLWithoutFragment() const { return m_scopeURL; }
URL scriptURL() const { return m_scriptURL; }
+ bool isAppBound() { return m_isAppBound; }
+
private:
void activate();
void handleClientUnload();
@@ -130,6 +134,8 @@
HashMap<SWServerConnectionIdentifier, HashSet<DocumentIdentifier>> m_clientsUsingRegistration;
WebCore::Timer m_softUpdateTimer;
+
+ bool m_isAppBound { false };
};
} // namespace WebCore
Modified: trunk/Source/WebKit/ChangeLog (275951 => 275952)
--- trunk/Source/WebKit/ChangeLog 2021-04-14 17:39:33 UTC (rev 275951)
+++ trunk/Source/WebKit/ChangeLog 2021-04-14 17:54:05 UTC (rev 275952)
@@ -1,3 +1,36 @@
+2021-04-14 Kate Cheney <[email protected]>
+
+ Service worker soft-update loads not being marked app-bound
+ https://bugs.webkit.org/show_bug.cgi?id=223200
+ <rdar://problem/75438555>
+
+ Reviewed by Youenn Fablet.
+
+ We should pass the app-bound request value when doing a soft update.
+
+ * NetworkProcess/NetworkResourceLoader.cpp:
+ (WebKit::NetworkResourceLoader::isAppBound):
+ * NetworkProcess/NetworkResourceLoader.h:
+ Make a helper function to get the request's app-bound value.
+
+ * NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp:
+ (WebKit::ServiceWorkerFetchTask::softUpdateIfNeeded):
+ * NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.cpp:
+ (WebKit::ServiceWorkerSoftUpdateLoader::loadFromNetwork):
+ * NetworkProcess/ServiceWorker/WebSWServerConnection.cpp:
+ (WebKit::WebSWServerConnection::createFetchTask):
+ * Shared/NavigatingToAppBoundDomain.h:
+ (WebKit::AppBoundNavigationTestingData::setDidPerformSoftUpdate):
+ (WebKit::AppBoundNavigationTestingData::clearAppBoundNavigationDataTesting):
+ (WebKit::AppBoundNavigationTestingData::encode const):
+ (WebKit::AppBoundNavigationTestingData::decode):
+ * UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h:
+ * UIProcess/API/Cocoa/WKWebViewTesting.mm:
+ (-[WKWebView _appBoundNavigationData:]):
+ Update testing struct to make sure a soft-update occurred before
+ checking app-bound data. This accounts for the delay between the
+ page load and the soft update.
+
2021-04-14 Alex Christensen <[email protected]>
Reduce maximum HashTable entry size to 128 bytes
Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp (275951 => 275952)
--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp 2021-04-14 17:39:33 UTC (rev 275951)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp 2021-04-14 17:54:05 UTC (rev 275952)
@@ -1513,6 +1513,11 @@
}
#endif
+bool NetworkResourceLoader::isAppBound()
+{
+ return m_parameters.request.isAppBound();
+}
+
} // namespace WebKit
#undef RELEASE_LOG_IF_ALLOWED
Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.h (275951 => 275952)
--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.h 2021-04-14 17:39:33 UTC (rev 275951)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.h 2021-04-14 17:54:05 UTC (rev 275952)
@@ -143,6 +143,8 @@
void serviceWorkerDidNotHandle(ServiceWorkerFetchTask*);
#endif
+ bool isAppBound();
+
private:
NetworkResourceLoader(NetworkResourceLoadParameters&&, NetworkConnectionToWebProcess&, Messages::NetworkConnectionToWebProcess::PerformSynchronousLoadDelayedReply&&);
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp (275951 => 275952)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp 2021-04-14 17:39:33 UTC (rev 275951)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp 2021-04-14 17:54:05 UTC (rev 275952)
@@ -255,7 +255,7 @@
if (!m_shouldSoftUpdate)
return;
if (auto* registration = m_loader.connectionToWebProcess().swConnection().server().getRegistration(m_serviceWorkerRegistrationIdentifier))
- registration->scheduleSoftUpdate();
+ registration->scheduleSoftUpdate(m_loader.isAppBound() ? WebCore::IsAppBound::Yes : WebCore::IsAppBound::No);
}
} // namespace WebKit
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.cpp (275951 => 275952)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.cpp 2021-04-14 17:39:33 UTC (rev 275951)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.cpp 2021-04-14 17:54:05 UTC (rev 275952)
@@ -129,6 +129,10 @@
parameters.request = WTFMove(request);
m_networkLoad = makeUnique<NetworkLoad>(*this, nullptr, WTFMove(parameters), session);
m_networkLoad->start();
+
+#if PLATFORM(COCOA)
+ session.appBoundNavigationTestingData().setDidPerformSoftUpdate();
+#endif
}
void ServiceWorkerSoftUpdateLoader::willSendRedirectedRequest(ResourceRequest&&, ResourceRequest&&, ResourceResponse&&)
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp (275951 => 275952)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp 2021-04-14 17:39:33 UTC (rev 275951)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp 2021-04-14 17:54:05 UTC (rev 275952)
@@ -187,7 +187,8 @@
bool shouldSoftUpdate = registration && registration->shouldSoftUpdate(loader.parameters().options);
if (worker->shouldSkipFetchEvent()) {
if (shouldSoftUpdate)
- registration->scheduleSoftUpdate();
+ registration->scheduleSoftUpdate(loader.isAppBound() ? WebCore::IsAppBound::Yes : WebCore::IsAppBound::No);
+
return nullptr;
}
Modified: trunk/Source/WebKit/Shared/NavigatingToAppBoundDomain.h (275951 => 275952)
--- trunk/Source/WebKit/Shared/NavigatingToAppBoundDomain.h 2021-04-14 17:39:33 UTC (rev 275951)
+++ trunk/Source/WebKit/Shared/NavigatingToAppBoundDomain.h 2021-04-14 17:54:05 UTC (rev 275952)
@@ -43,10 +43,16 @@
#if PLATFORM(COCOA)
struct AppBoundNavigationTestingData {
+ void setDidPerformSoftUpdate()
+ {
+ didPerformSoftUpdate = true;
+ }
+
void clearAppBoundNavigationDataTesting()
{
hasLoadedAppBoundRequestTesting = false;
hasLoadedNonAppBoundRequestTesting = false;
+ didPerformSoftUpdate = false;
contextData.clear();
}
@@ -60,6 +66,7 @@
{
encoder << hasLoadedAppBoundRequestTesting;
encoder << hasLoadedNonAppBoundRequestTesting;
+ encoder << didPerformSoftUpdate;
encoder << contextData;
}
@@ -74,6 +81,11 @@
decoder >> hasLoadedNonAppBoundRequestTesting;
if (!hasLoadedNonAppBoundRequestTesting)
return WTF::nullopt;
+
+ Optional<bool> didPerformSoftUpdate;
+ decoder >> didPerformSoftUpdate;
+ if (!didPerformSoftUpdate)
+ return WTF::nullopt;
Optional<HashMap<RequestDomain, ContextDomain>> contextData;
decoder >> contextData;
@@ -80,11 +92,12 @@
if (!contextData)
return WTF::nullopt;
- return {{ *hasLoadedAppBoundRequestTesting, *hasLoadedNonAppBoundRequestTesting, WTFMove(*contextData) }};
+ return {{ *hasLoadedAppBoundRequestTesting, *hasLoadedNonAppBoundRequestTesting, *didPerformSoftUpdate, WTFMove(*contextData) }};
}
bool hasLoadedAppBoundRequestTesting { false };
bool hasLoadedNonAppBoundRequestTesting { false };
+ bool didPerformSoftUpdate { false };
HashMap<RequestDomain, ContextDomain> contextData;
};
#endif
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h (275951 => 275952)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h 2021-04-14 17:39:33 UTC (rev 275951)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h 2021-04-14 17:54:05 UTC (rev 275952)
@@ -37,6 +37,7 @@
struct WKAppBoundNavigationTestingData {
BOOL hasLoadedAppBoundRequestTesting;
BOOL hasLoadedNonAppBoundRequestTesting;
+ BOOL didPerformSoftUpdate;
};
@protocol _WKMediaSessionCoordinator;
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm (275951 => 275952)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm 2021-04-14 17:39:33 UTC (rev 275951)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm 2021-04-14 17:54:05 UTC (rev 275952)
@@ -374,7 +374,7 @@
- (void)_appBoundNavigationData:(void(^)(struct WKAppBoundNavigationTestingData data))completionHandler
{
_page->appBoundNavigationData([completionHandler = makeBlockPtr(completionHandler)] (auto&& appBoundData) {
- completionHandler({ appBoundData.hasLoadedAppBoundRequestTesting, appBoundData.hasLoadedNonAppBoundRequestTesting });
+ completionHandler({ appBoundData.hasLoadedAppBoundRequestTesting, appBoundData.hasLoadedNonAppBoundRequestTesting, appBoundData.didPerformSoftUpdate });
});
}
Modified: trunk/Tools/ChangeLog (275951 => 275952)
--- trunk/Tools/ChangeLog 2021-04-14 17:39:33 UTC (rev 275951)
+++ trunk/Tools/ChangeLog 2021-04-14 17:54:05 UTC (rev 275952)
@@ -1,3 +1,18 @@
+2021-04-14 Kate Cheney <[email protected]>
+
+ Service worker soft-update loads not being marked app-bound
+ https://bugs.webkit.org/show_bug.cgi?id=223200
+ <rdar://problem/75438555>
+
+ Reviewed by Youenn Fablet.
+
+ API test coverage. Refactor to avoid code duplication in other tests.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
+ A soft update might be delayed after the synthetic response comes
+ back. We should wait until we receive the test data indicating that
+ a soft update has occurred before checking the app-bound values.
+
2021-04-14 Aakash Jain <[email protected]>
Add support for using local-worker for build.webkit.org
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm (275951 => 275952)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm 2021-04-14 17:39:33 UTC (rev 275951)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm 2021-04-14 17:54:05 UTC (rev 275952)
@@ -1418,7 +1418,7 @@
TestWebKitAPI::Util::run(&isDone);
}
-#endif // PLATFORM(IOS_FAMILY)
+#endif // ENABLE(APP_BOUND_DOMAINS)
#if USE(APPLE_INTERNAL_SDK)
TEST(InAppBrowserPrivacy, AppBoundRequest)
@@ -1558,6 +1558,28 @@
TestWebKitAPI::Util::run(&isDone);
};
+static const char* mainSWBytes = R"SWRESOURCE(
+<script>
+try {
+ navigator.serviceWorker.register('/sw.js').then(function(reg) {
+ if (reg.active) {
+ alert('worker already active');
+ return;
+ }
+ worker = reg.installing;
+ worker.addEventListener('statechange', function() {
+ if (worker.state == 'activated')
+ alert('successfully registered');
+ });
+ }).catch(function(error) {
+ alert('Registration failed with: ' + error);
+ });
+} catch(e) {
+ alert('Exception: ' + e);
+}
+</script>
+)SWRESOURCE";
+
enum class ResponseType { Synthetic, Fetched };
enum class IsAppBound : bool { No, Yes };
static void runTest(ResponseType responseType, IsAppBound appBound)
@@ -1568,27 +1590,6 @@
}];
TestWebKitAPI::Util::run(&isDone);
- static const char* main =
- "<script>"
- "try {"
- " navigator.serviceWorker.register('/sw.js').then(function(reg) {"
- " if (reg.active) {"
- " alert('worker unexpectedly already active');"
- " return;"
- " }"
- " worker = reg.installing;"
- " worker.addEventListener('statechange', function() {"
- " if (worker.state == 'activated')"
- " alert('successfully registered');"
- " });"
- " }).catch(function(error) {"
- " alert('Registration failed with: ' + error);"
- " });"
- "} catch(e) {"
- " alert('Exception: ' + e);"
- "}"
- "</script>";
-
const char* js = nullptr;
const char* expectedAlert = nullptr;
@@ -1604,7 +1605,7 @@
}
TestWebKitAPI::HTTPServer server({
- { "/", { main } },
+ { "/", { mainSWBytes } },
{ "/sw.js", { {{ "Content-Type", "application/_javascript_" }}, js } },
{ "/fetched.html", { "<script>alert('fetched from server')</script>" } },
}, TestWebKitAPI::HTTPServer::Protocol::Https);
@@ -1676,32 +1677,9 @@
runTest(ResponseType::Fetched, IsAppBound::Yes);
}
-static const char* mainSWBytes = R"SWRESOURCE(
-<script>
-try {
- navigator.serviceWorker.register('/sw.js').then(function(reg) {
- if (reg.active) {
- alert('worker already active');
- return;
- }
- worker = reg.installing;
- worker.addEventListener('statechange', function() {
- if (worker.state == 'activated')
- alert('successfully registered');
- });
- }).catch(function(error) {
- alert('Registration failed with: ' + error);
- });
-} catch(e) {
- alert('Exception: ' + e);
-}
-</script>
-)SWRESOURCE";
-
TEST(InAppBrowserPrivacy, MultipleWebViewsWithSharedServiceWorker)
{
static bool isDone = false;
- isDone = false;
[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
isDone = true;
@@ -1767,4 +1745,97 @@
TestWebKitAPI::Util::run(&isDone);
isDone = false;
}
+
+static void softUpdateTest(IsAppBound isAppBound)
+{
+ __block bool isDone = false;
+ [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
+ isDone = true;
+ }];
+ TestWebKitAPI::Util::run(&isDone);
+
+ auto delegate = adoptNS([TestNavigationDelegate new]);
+ [delegate setDidReceiveAuthenticationChallenge:^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^callback)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
+ EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust);
+ callback(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
+ }];
+
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ auto webView1 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+ auto webView2 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+
+ webView1.get().navigationDelegate = delegate.get();
+ webView2.get().navigationDelegate = delegate.get();
+
+ uint16_t serverPort;
+ static const char* js = "self.addEventListener('fetch', (event) => { event.respondWith(new Response(new Blob(['<script>alert(\"synthetic response\")</script>'], {type: 'text/html'}))); })";
+
+ {
+ TestWebKitAPI::HTTPServer server1({
+ { "/", { mainSWBytes } },
+ { "/sw.js", { {{ "Content-Type", "application/_javascript_" }}, js } },
+ }, TestWebKitAPI::HTTPServer::Protocol::Https, nullptr, testIdentity());
+ serverPort = server1.port();
+
+ NSURLRequest *request = server1.request();
+ if (isAppBound == IsAppBound::No) {
+ NSMutableURLRequest *nonAppBoundRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://127.0.0.1:%d/", server1.port()]]];
+ APP_BOUND_REQUEST_ADDITIONS
+ request = nonAppBoundRequest;
+ }
+
+ [webView1 loadRequest:request];
+ EXPECT_WK_STREQ([webView1 _test_waitForAlert], "successfully registered");
+
+ server1.cancel();
+ }
+
+ {
+ TestWebKitAPI::HTTPServer server2({
+ { "/", { mainSWBytes } },
+ { "/sw.js", { {{ "Content-Type", "application/_javascript_" }}, js } }
+ }, TestWebKitAPI::HTTPServer::Protocol::Https, nullptr, testIdentity2(), serverPort);
+
+ NSURLRequest *request2 = server2.request();
+ if (isAppBound == IsAppBound::No) {
+ NSMutableURLRequest *nonAppBoundRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://127.0.0.1:%d/", server2.port()]]];
+ APP_BOUND_REQUEST_ADDITIONS
+ request2 = nonAppBoundRequest;
+ }
+
+ isDone = false;
+ [webView1 _clearAppBoundNavigationData:^{
+ isDone = true;
+ }];
+
+ TestWebKitAPI::Util::run(&isDone);
+
+ [webView2 loadRequest:request2];
+ EXPECT_WK_STREQ([webView2 _test_waitForAlert], "synthetic response");
+ }
+
+ isDone = false;
+ bool expectingAppBoundRequests = isAppBound == IsAppBound::Yes ? true : false;
+ while (!isDone) {
+ [webView2 _appBoundNavigationData: ^(struct WKAppBoundNavigationTestingData data) {
+ if (!data.didPerformSoftUpdate)
+ return;
+
+ EXPECT_EQ(data.hasLoadedAppBoundRequestTesting, expectingAppBoundRequests);
+ EXPECT_EQ(data.hasLoadedNonAppBoundRequestTesting, !expectingAppBoundRequests);
+ isDone = true;
+ }];
+ TestWebKitAPI::Util::spinRunLoop(1);
+ }
+}
+
+TEST(InAppBrowserPrivacy, AppBoundRequestWithServiceWorkerSoftUpdate)
+{
+ softUpdateTest(IsAppBound::Yes);
+}
+
+TEST(InAppBrowserPrivacy, NonAppBoundRequestWithServiceWorkerSoftUpdate)
+{
+ softUpdateTest(IsAppBound::No);
+}
#endif