source: webkit/trunk/Source/WebCore/loader/ThreadableLoader.cpp

Last change on this file was 292861, checked in by [email protected], 3 years ago

Expose workers as service worker clients and implement registration matching for dedicated workers
https://bugs.webkit.org/show_bug.cgi?id=239066

Reviewed by Chris Dumez.

LayoutTests/imported/w3c:

  • web-platform-tests/service-workers/service-worker/local-url-inherit-controller.https-expected.txt:
  • web-platform-tests/service-workers/service-worker/worker-client-id.https-expected.txt:
  • web-platform-tests/service-workers/service-worker/worker-interception-redirect.https-expected.txt:
  • web-platform-tests/service-workers/service-worker/worker-interception.https-expected.txt:

Source/WebCore:

Add support for exposing workers (dedicated and shared) as service worker clients.
Add support for setting the controlling registration for dedicated workers
(a follow-up patch should handle shared workers).
To properly handle loads coming from a worker, we properly set clientIdentifier and registration identifier
from the worker context, instead of from the worker's document.

Small refactoring to pass additional data to worker through WorkerInitializationData.
This is used to set the context ID and context controlling service worker.

Adding a specific check in CachedResourceLoader to not reuse the cache in case the service worker modes are different.
A potential issue is that the service workers are the same (0) as one request is the main request
and the second request is the request triggered by service worker to answer the first request.

Properly support blob URL matching directly in WorkerScriptLoader for workers.

Test: http/wpt/service-workers/controlled-dedicatedworker.https.html

  • WebCore.xcodeproj/project.pbxproj:
  • dom/Document.h:
  • dom/ScriptExecutionContext.h:
  • loader/DocumentLoader.cpp:
  • loader/FetchOptions.h:
  • loader/ThreadableLoader.cpp:
  • loader/WorkerThreadableLoader.cpp:
  • loader/cache/CachedResourceLoader.cpp:
  • workers/DedicatedWorkerThread.cpp:
  • workers/Worker.cpp:
  • workers/Worker.h:
  • workers/WorkerGlobalScope.cpp:
  • workers/WorkerGlobalScope.h:
  • workers/WorkerGlobalScopeProxy.h:
  • workers/WorkerInitializationData.h: Added.
  • workers/WorkerMessagingProxy.cpp:
  • workers/WorkerMessagingProxy.h:
  • workers/WorkerOrWorkletGlobalScope.cpp:
  • workers/WorkerOrWorkletGlobalScope.h:
  • workers/WorkerScriptLoader.cpp:
  • workers/WorkerScriptLoader.h:
  • workers/WorkerThread.cpp:
  • workers/WorkerThread.h:
  • workers/service/SWClientConnection.cpp:
  • workers/service/ServiceWorker.h:
  • workers/service/ServiceWorkerClientData.cpp:
  • workers/service/ServiceWorkerClientType.h:
  • workers/service/ServiceWorkerContainer.cpp:
  • workers/service/context/ServiceWorkerThread.cpp:
  • workers/shared/SharedWorkerScriptLoader.h:
  • workers/shared/context/SharedWorkerThreadProxy.cpp:

Source/WebKit:

Reuse the same strategy for DedicatedWorkers as for Documents to match registrations and control then:

  • Do matching in network process
  • If matching, send a message to WebProcess to set the matching registration data.

Add specific handling for worker registration rematching in case of redirections:

  • If redirection comes from service worker (via respondWith), do rematching.
  • If redirection comes from network, do not do rematching.
  • NetworkProcess/NetworkResourceLoader.cpp:
  • NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp:
  • NetworkProcess/ServiceWorker/WebSWServerConnection.cpp:
  • WebProcess/Network/WebLoaderStrategy.cpp:
  • WebProcess/Storage/WebSWClientConnection.cpp:
  • WebProcess/Storage/WebSWClientConnection.h:
  • WebProcess/Storage/WebSWClientConnection.messages.in:

LayoutTests:

  • TestExpectations:
  • http/wpt/service-workers/controlled-dedicatedworker.https-expected.txt: Added.
  • http/wpt/service-workers/controlled-dedicatedworker.https.html: Added.
  • http/wpt/service-workers/resources/controlled-worker.js: Added.
  • Property svn:eol-style set to native
File size: 7.2 KB
Line 
1/*
2 * Copyright (C) 2022 Apple Inc. All rights reserved.
3 * Copyright (C) 2009 Google Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "config.h"
33#include "ThreadableLoader.h"
34
35#include "CachedResourceRequestInitiators.h"
36#include "Document.h"
37#include "DocumentLoader.h"
38#include "DocumentThreadableLoader.h"
39#include "ResourceError.h"
40#include "ScriptExecutionContext.h"
41#include "WorkerGlobalScope.h"
42#include "WorkerRunLoop.h"
43#include "WorkerThreadableLoader.h"
44#include "WorkletGlobalScope.h"
45
46namespace WebCore {
47
48ThreadableLoaderOptions::ThreadableLoaderOptions()
49{
50 mode = FetchOptions::Mode::SameOrigin;
51}
52
53ThreadableLoaderOptions::~ThreadableLoaderOptions() = default;
54
55ThreadableLoaderOptions::ThreadableLoaderOptions(FetchOptions&& baseOptions)
56 : ResourceLoaderOptions { WTFMove(baseOptions) }
57{
58}
59
60ThreadableLoaderOptions::ThreadableLoaderOptions(const ResourceLoaderOptions& baseOptions, ContentSecurityPolicyEnforcement contentSecurityPolicyEnforcement, String&& initiator, ResponseFilteringPolicy filteringPolicy)
61 : ResourceLoaderOptions(baseOptions)
62 , contentSecurityPolicyEnforcement(contentSecurityPolicyEnforcement)
63 , initiator(WTFMove(initiator))
64 , filteringPolicy(filteringPolicy)
65{
66}
67
68ThreadableLoaderOptions ThreadableLoaderOptions::isolatedCopy() const
69{
70 ThreadableLoaderOptions copy;
71
72 // FetchOptions
73 copy.destination = this->destination;
74 copy.mode = this->mode;
75 copy.credentials = this->credentials;
76 copy.cache = this->cache;
77 copy.redirect = this->redirect;
78 copy.referrerPolicy = this->referrerPolicy;
79 copy.integrity = this->integrity.isolatedCopy();
80 copy.keepAlive = this->keepAlive;
81 copy.clientIdentifier = this->clientIdentifier;
82
83 // ResourceLoaderOptions
84 copy.sendLoadCallbacks = this->sendLoadCallbacks;
85 copy.sniffContent = this->sniffContent;
86 copy.dataBufferingPolicy = this->dataBufferingPolicy;
87 copy.storedCredentialsPolicy = this->storedCredentialsPolicy;
88 copy.securityCheck = this->securityCheck;
89 copy.certificateInfoPolicy = this->certificateInfoPolicy;
90 copy.contentSecurityPolicyImposition = this->contentSecurityPolicyImposition;
91 copy.defersLoadingPolicy = this->defersLoadingPolicy;
92 copy.cachingPolicy = this->cachingPolicy;
93 copy.sameOriginDataURLFlag = this->sameOriginDataURLFlag;
94 copy.initiatorContext = this->initiatorContext;
95 copy.clientCredentialPolicy = this->clientCredentialPolicy;
96 copy.maxRedirectCount = this->maxRedirectCount;
97 copy.preflightPolicy = this->preflightPolicy;
98 copy.navigationPreloadIdentifier = this->navigationPreloadIdentifier;
99
100 // ThreadableLoaderOptions
101 copy.contentSecurityPolicyEnforcement = this->contentSecurityPolicyEnforcement;
102 copy.initiator = this->initiator.isolatedCopy();
103 copy.filteringPolicy = this->filteringPolicy;
104
105 return copy;
106}
107
108
109RefPtr<ThreadableLoader> ThreadableLoader::create(ScriptExecutionContext& context, ThreadableLoaderClient& client, ResourceRequest&& request, const ThreadableLoaderOptions& options, String&& referrer, String&& taskMode)
110{
111 Document* document = nullptr;
112 if (is<WorkletGlobalScope>(context))
113 document = downcast<WorkletGlobalScope>(context).responsibleDocument();
114 else if (is<Document>(context))
115 document = &downcast<Document>(context);
116
117 if (auto* documentLoader = document ? document->loader() : nullptr)
118 request.setIsAppInitiated(documentLoader->lastNavigationWasAppInitiated());
119
120 if (is<WorkerGlobalScope>(context) || (is<WorkletGlobalScope>(context) && downcast<WorkletGlobalScope>(context).workerOrWorkletThread()))
121 return WorkerThreadableLoader::create(static_cast<WorkerOrWorkletGlobalScope&>(context), client, WTFMove(taskMode), WTFMove(request), options, WTFMove(referrer));
122
123 return DocumentThreadableLoader::create(*document, client, WTFMove(request), options, WTFMove(referrer));
124}
125
126void ThreadableLoader::loadResourceSynchronously(ScriptExecutionContext& context, ResourceRequest&& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options)
127{
128 auto resourceURL = request.url();
129 if (is<WorkerGlobalScope>(context))
130 WorkerThreadableLoader::loadResourceSynchronously(downcast<WorkerGlobalScope>(context), WTFMove(request), client, options);
131 else
132 DocumentThreadableLoader::loadResourceSynchronously(downcast<Document>(context), WTFMove(request), client, options);
133 context.didLoadResourceSynchronously(resourceURL);
134}
135
136void ThreadableLoader::logError(ScriptExecutionContext& context, const ResourceError& error, const String& initiator)
137{
138 if (error.isCancellation())
139 return;
140
141 // FIXME: Some errors are returned with null URLs. This leads to poor console messages. We should do better for these errors.
142 if (error.failingURL().isNull())
143 return;
144
145 // We further reduce logging to some errors.
146 // FIXME: Log more errors when making so do not make some layout tests flaky.
147 if (error.domain() != errorDomainWebKitInternal && error.domain() != errorDomainWebKitServiceWorker && !error.isAccessControl())
148 return;
149
150 const char* messageStart;
151 if (initiator == cachedResourceRequestInitiators().eventsource)
152 messageStart = "EventSource cannot load ";
153 else if (initiator == cachedResourceRequestInitiators().fetch)
154 messageStart = "Fetch API cannot load ";
155 else if (initiator == cachedResourceRequestInitiators().xmlhttprequest)
156 messageStart = "XMLHttpRequest cannot load ";
157 else
158 messageStart = "Cannot load ";
159
160 String messageEnd = error.isAccessControl() ? " due to access control checks."_s : "."_s;
161 context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, makeString(messageStart, error.failingURL().string(), messageEnd));
162}
163
164} // namespace WebCore
Note: See TracBrowser for help on using the repository browser.