Move URL from WebCore to WTF
[WebKit-https.git] / Source / WebCore / loader / DocumentLoader.cpp
1 /*
2  * Copyright (C) 2006-2018 Apple Inc. All rights reserved.
3  * Copyright (C) 2011 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
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer. 
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution. 
14  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission. 
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "DocumentLoader.h"
32
33 #include "ApplicationCacheHost.h"
34 #include "Archive.h"
35 #include "ArchiveResourceCollection.h"
36 #include "CachedPage.h"
37 #include "CachedRawResource.h"
38 #include "CachedResourceLoader.h"
39 #include "ContentExtensionError.h"
40 #include "ContentSecurityPolicy.h"
41 #include "DOMWindow.h"
42 #include "Document.h"
43 #include "DocumentParser.h"
44 #include "DocumentWriter.h"
45 #include "ElementChildIterator.h"
46 #include "Event.h"
47 #include "EventNames.h"
48 #include "ExtensionStyleSheets.h"
49 #include "FormState.h"
50 #include "Frame.h"
51 #include "FrameLoader.h"
52 #include "FrameLoaderClient.h"
53 #include "FrameTree.h"
54 #include "HTMLFormElement.h"
55 #include "HTMLFrameOwnerElement.h"
56 #include "HTTPHeaderField.h"
57 #include "HTTPHeaderNames.h"
58 #include "HistoryItem.h"
59 #include "IconLoader.h"
60 #include "InspectorInstrumentation.h"
61 #include "LinkIconCollector.h"
62 #include "LinkIconType.h"
63 #include "LoaderStrategy.h"
64 #include "Logging.h"
65 #include "MemoryCache.h"
66 #include "NetworkLoadMetrics.h"
67 #include "Page.h"
68 #include "PingLoader.h"
69 #include "PlatformStrategies.h"
70 #include "PolicyChecker.h"
71 #include "ProgressTracker.h"
72 #include "ResourceHandle.h"
73 #include "ResourceLoadObserver.h"
74 #include "SWClientConnection.h"
75 #include "SchemeRegistry.h"
76 #include "ScriptableDocumentParser.h"
77 #include "SecurityPolicy.h"
78 #include "ServiceWorker.h"
79 #include "ServiceWorkerClientData.h"
80 #include "ServiceWorkerProvider.h"
81 #include "Settings.h"
82 #include "SubresourceLoader.h"
83 #include "TextResourceDecoder.h"
84 #include <wtf/Assertions.h>
85 #include <wtf/CompletionHandler.h>
86 #include <wtf/NeverDestroyed.h>
87 #include <wtf/Ref.h>
88 #include <wtf/text/CString.h>
89 #include <wtf/text/WTFString.h>
90
91 #if ENABLE(APPLICATION_MANIFEST)
92 #include "ApplicationManifestLoader.h"
93 #include "HTMLHeadElement.h"
94 #include "HTMLLinkElement.h"
95 #endif
96
97 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
98 #include "ArchiveFactory.h"
99 #endif
100
101 #if ENABLE(CONTENT_FILTERING)
102 #include "ContentFilter.h"
103 #endif
104
105 #if USE(QUICK_LOOK)
106 #include "PreviewConverter.h"
107 #include "QuickLook.h"
108 #endif
109
110 #define RELEASE_LOG_IF_ALLOWED(fmt, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), Network, "%p - DocumentLoader::" fmt, this, ##__VA_ARGS__)
111
112 namespace WebCore {
113
114 static void cancelAll(const ResourceLoaderMap& loaders)
115 {
116     for (auto& loader : copyToVector(loaders.values()))
117         loader->cancel();
118 }
119
120 static void setAllDefersLoading(const ResourceLoaderMap& loaders, bool defers)
121 {
122     for (auto& loader : copyToVector(loaders.values()))
123         loader->setDefersLoading(defers);
124 }
125
126 static bool areAllLoadersPageCacheAcceptable(const ResourceLoaderMap& loaders)
127 {
128     for (auto& loader : copyToVector(loaders.values())) {
129         if (!loader->frameLoader() || !loader->frameLoader()->frame().page())
130             return false;
131
132         CachedResource* cachedResource = MemoryCache::singleton().resourceForRequest(loader->request(), loader->frameLoader()->frame().page()->sessionID());
133         if (!cachedResource)
134             return false;
135
136         // Only image and XHR loads do prevent the page from entering the PageCache.
137         // All non-image loads will prevent the page from entering the PageCache.
138         if (!cachedResource->isImage() && !cachedResource->areAllClientsXMLHttpRequests())
139             return false;
140     }
141     return true;
142 }
143
144 DocumentLoader::DocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
145     : FrameDestructionObserver(nullptr)
146     , m_cachedResourceLoader(CachedResourceLoader::create(this))
147     , m_writer(m_frame)
148     , m_originalRequest(request)
149     , m_substituteData(substituteData)
150     , m_originalRequestCopy(request)
151     , m_request(request)
152     , m_originalSubstituteDataWasValid(substituteData.isValid())
153     , m_substituteResourceDeliveryTimer(*this, &DocumentLoader::substituteResourceDeliveryTimerFired)
154     , m_dataLoadTimer(*this, &DocumentLoader::handleSubstituteDataLoadNow)
155     , m_applicationCacheHost(std::make_unique<ApplicationCacheHost>(*this))
156 {
157 }
158
159 FrameLoader* DocumentLoader::frameLoader() const
160 {
161     if (!m_frame)
162         return nullptr;
163     return &m_frame->loader();
164 }
165
166 SubresourceLoader* DocumentLoader::mainResourceLoader() const
167 {
168     if (!m_mainResource)
169         return nullptr;
170     return m_mainResource->loader();
171 }
172
173 DocumentLoader::~DocumentLoader()
174 {
175     ASSERT(!m_frame || !isLoading() || frameLoader()->activeDocumentLoader() != this);
176     ASSERT_WITH_MESSAGE(!m_waitingForContentPolicy, "The content policy callback should never outlive its DocumentLoader.");
177     ASSERT_WITH_MESSAGE(!m_waitingForNavigationPolicy, "The navigation policy callback should never outlive its DocumentLoader.");
178
179     m_cachedResourceLoader->clearDocumentLoader();
180     clearMainResource();
181 }
182
183 RefPtr<SharedBuffer> DocumentLoader::mainResourceData() const
184 {
185     if (m_substituteData.isValid())
186         return m_substituteData.content()->copy();
187     if (m_mainResource)
188         return m_mainResource->resourceBuffer();
189     return nullptr;
190 }
191
192 Document* DocumentLoader::document() const
193 {
194     if (m_frame && m_frame->loader().documentLoader() == this)
195         return m_frame->document();
196     return nullptr;
197 }
198
199 void DocumentLoader::replaceRequestURLForSameDocumentNavigation(const URL& url)
200 {
201     m_originalRequestCopy.setURL(url);
202     m_request.setURL(url);
203 }
204
205 void DocumentLoader::setRequest(const ResourceRequest& req)
206 {
207     // Replacing an unreachable URL with alternate content looks like a server-side
208     // redirect at this point, but we can replace a committed dataSource.
209     bool handlingUnreachableURL = false;
210
211     handlingUnreachableURL = m_substituteData.isValid() && !m_substituteData.failingURL().isEmpty();
212
213     bool shouldNotifyAboutProvisionalURLChange = false;
214     if (handlingUnreachableURL)
215         m_committed = false;
216     else if (isLoadingMainResource() && req.url() != m_request.url())
217         shouldNotifyAboutProvisionalURLChange = true;
218
219     // We should never be getting a redirect callback after the data
220     // source is committed, except in the unreachable URL case. It 
221     // would be a WebFoundation bug if it sent a redirect callback after commit.
222     ASSERT(!m_committed);
223
224     m_request = req;
225     if (shouldNotifyAboutProvisionalURLChange)
226         frameLoader()->client().dispatchDidChangeProvisionalURL();
227 }
228
229 void DocumentLoader::setMainDocumentError(const ResourceError& error)
230 {
231     m_mainDocumentError = error;    
232     frameLoader()->client().setMainDocumentError(this, error);
233 }
234
235 void DocumentLoader::mainReceivedError(const ResourceError& error)
236 {
237     ASSERT(!error.isNull());
238
239     if (!frameLoader())
240         return;
241
242     if (m_identifierForLoadWithoutResourceLoader) {
243         ASSERT(!mainResourceLoader());
244         frameLoader()->client().dispatchDidFailLoading(this, m_identifierForLoadWithoutResourceLoader, error);
245     }
246
247     // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
248     // See <rdar://problem/6304600> for more details.
249 #if !USE(CF)
250     ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading());
251 #endif
252
253     m_applicationCacheHost->failedLoadingMainResource();
254
255     setMainDocumentError(error);
256     clearMainResourceLoader();
257     frameLoader()->receivedMainResourceError(error);
258 }
259
260 // Cancels the data source's pending loads.  Conceptually, a data source only loads
261 // one document at a time, but one document may have many related resources. 
262 // stopLoading will stop all loads initiated by the data source, 
263 // but not loads initiated by child frames' data sources -- that's the WebFrame's job.
264 void DocumentLoader::stopLoading()
265 {
266     RefPtr<Frame> protectedFrame(m_frame);
267     Ref<DocumentLoader> protectedThis(*this);
268
269     // In some rare cases, calling FrameLoader::stopLoading could cause isLoading() to return false.
270     // (This can happen when there's a single XMLHttpRequest currently loading and stopLoading causes it
271     // to stop loading. Because of this, we need to save it so we don't return early.
272     bool loading = isLoading();
273
274     // We may want to audit the existing subresource loaders when we are on a page which has completed
275     // loading but there are subresource loads during cancellation. This must be done before the
276     // frame->stopLoading() call, which may evict the CachedResources, which we rely on to check
277     // the type of the resource loads.
278     if (loading && m_committed && !mainResourceLoader() && !m_subresourceLoaders.isEmpty())
279         m_subresourceLoadersArePageCacheAcceptable = areAllLoadersPageCacheAcceptable(m_subresourceLoaders);
280
281     if (m_committed) {
282         // Attempt to stop the frame if the document loader is loading, or if it is done loading but
283         // still  parsing. Failure to do so can cause a world leak.
284         Document* doc = m_frame->document();
285         
286         if (loading || doc->parsing())
287             m_frame->loader().stopLoading(UnloadEventPolicyNone);
288     }
289
290     for (auto callbackIdentifier : m_iconLoaders.values())
291         notifyFinishedLoadingIcon(callbackIdentifier, nullptr);
292     m_iconLoaders.clear();
293     m_iconsPendingLoadDecision.clear();
294     
295 #if ENABLE(APPLICATION_MANIFEST)
296     for (auto callbackIdentifier : m_applicationManifestLoaders.values())
297         notifyFinishedLoadingApplicationManifest(callbackIdentifier, std::nullopt);
298     m_applicationManifestLoaders.clear();
299 #endif
300
301     // Always cancel multipart loaders
302     cancelAll(m_multipartSubresourceLoaders);
303
304     // Appcache uses ResourceHandle directly, DocumentLoader doesn't count these loads.
305     m_applicationCacheHost->stopLoadingInFrame(*m_frame);
306     
307 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
308     clearArchiveResources();
309 #endif
310
311     if (!loading) {
312         // If something above restarted loading we might run into mysterious crashes like 
313         // https://bugs.webkit.org/show_bug.cgi?id=62764 and <rdar://problem/9328684>
314         ASSERT(!isLoading());
315         return;
316     }
317
318     // We might run in to infinite recursion if we're stopping loading as the result of 
319     // detaching from the frame, so break out of that recursion here.
320     // See <rdar://problem/9673866> for more details.
321     if (m_isStopping)
322         return;
323
324     m_isStopping = true;
325
326     // The frame may have been detached from this document by the onunload handler
327     if (auto* frameLoader = DocumentLoader::frameLoader()) {
328         if (isLoadingMainResource()) {
329             // Stop the main resource loader and let it send the cancelled message.
330             cancelMainResourceLoad(frameLoader->cancelledError(m_request));
331         } else if (!m_subresourceLoaders.isEmpty() || !m_plugInStreamLoaders.isEmpty()) {
332             // The main resource loader already finished loading. Set the cancelled error on the
333             // document and let the subresourceLoaders and pluginLoaders send individual cancelled messages below.
334             setMainDocumentError(frameLoader->cancelledError(m_request));
335         } else {
336             // If there are no resource loaders, we need to manufacture a cancelled message.
337             // (A back/forward navigation has no resource loaders because its resources are cached.)
338             mainReceivedError(frameLoader->cancelledError(m_request));
339         }
340     }
341
342     // We always need to explicitly cancel the Document's parser when stopping the load.
343     // Otherwise cancelling the parser while starting the next page load might result
344     // in unexpected side effects such as erroneous event dispatch. ( http://webkit.org/b/117112 )
345     if (Document* document = this->document())
346         document->cancelParsing();
347     
348     stopLoadingSubresources();
349     stopLoadingPlugIns();
350     
351     m_isStopping = false;
352 }
353
354 void DocumentLoader::commitIfReady()
355 {
356     if (!m_committed) {
357         m_committed = true;
358         frameLoader()->commitProvisionalLoad();
359     }
360 }
361
362 bool DocumentLoader::isLoading() const
363 {
364     // if (document() && document()->hasActiveParser())
365     //     return true;
366     // FIXME: The above code should be enabled, but it seems to cause
367     // http/tests/security/feed-urls-from-remote.html to timeout on Mac WK1
368     // see http://webkit.org/b/110554 and http://webkit.org/b/110401
369
370     return isLoadingMainResource() || !m_subresourceLoaders.isEmpty() || !m_plugInStreamLoaders.isEmpty();
371 }
372
373 void DocumentLoader::notifyFinished(CachedResource& resource)
374 {
375     ASSERT(isMainThread());
376 #if ENABLE(CONTENT_FILTERING)
377     if (m_contentFilter && !m_contentFilter->continueAfterNotifyFinished(resource))
378         return;
379 #endif
380
381     ASSERT_UNUSED(resource, m_mainResource == &resource);
382     ASSERT(m_mainResource);
383     if (!m_mainResource->errorOccurred() && !m_mainResource->wasCanceled()) {
384         finishedLoading();
385         return;
386     }
387
388     if (m_request.cachePolicy() == ResourceRequestCachePolicy::ReturnCacheDataDontLoad && !m_mainResource->wasCanceled()) {
389         frameLoader()->retryAfterFailedCacheOnlyMainResourceLoad();
390         return;
391     }
392
393     mainReceivedError(m_mainResource->resourceError());
394 }
395
396 void DocumentLoader::finishedLoading()
397 {
398     // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
399     // See <rdar://problem/6304600> for more details.
400 #if !USE(CF)
401     ASSERT(!m_frame->page()->defersLoading() || frameLoader()->stateMachine().creatingInitialEmptyDocument() || InspectorInstrumentation::isDebuggerPaused(m_frame));
402 #endif
403
404     Ref<DocumentLoader> protectedThis(*this);
405
406     if (m_identifierForLoadWithoutResourceLoader) {
407         // A didFinishLoading delegate might try to cancel the load (despite it
408         // being finished). Clear m_identifierForLoadWithoutResourceLoader
409         // before calling dispatchDidFinishLoading so that we don't later try to
410         // cancel the already-finished substitute load.
411         NetworkLoadMetrics emptyMetrics;
412         unsigned long identifier = m_identifierForLoadWithoutResourceLoader;
413         m_identifierForLoadWithoutResourceLoader = 0;
414         frameLoader()->notifier().dispatchDidFinishLoading(this, identifier, emptyMetrics, nullptr);
415     }
416
417     maybeFinishLoadingMultipartContent();
418
419     MonotonicTime responseEndTime = m_timeOfLastDataReceived ? m_timeOfLastDataReceived : MonotonicTime::now();
420     timing().setResponseEnd(responseEndTime);
421
422     commitIfReady();
423     if (!frameLoader())
424         return;
425
426     if (!maybeCreateArchive()) {
427         // If this is an empty document, it will not have actually been created yet. Commit dummy data so that
428         // DocumentWriter::begin() gets called and creates the Document.
429         if (!m_gotFirstByte)
430             commitData(0, 0);
431         frameLoader()->client().finishedLoading(this);
432     }
433
434     m_writer.end();
435     if (!m_mainDocumentError.isNull())
436         return;
437     clearMainResourceLoader();
438     if (!frameLoader()->stateMachine().creatingInitialEmptyDocument())
439         frameLoader()->checkLoadComplete();
440
441     // If the document specified an application cache manifest, it violates the author's intent if we store it in the memory cache
442     // and deny the appcache the chance to intercept it in the future, so remove from the memory cache.
443     if (m_frame) {
444         if (m_mainResource && m_frame->document()->hasManifest())
445             MemoryCache::singleton().remove(*m_mainResource);
446     }
447     m_applicationCacheHost->finishedLoadingMainResource();
448 }
449
450 bool DocumentLoader::isPostOrRedirectAfterPost(const ResourceRequest& newRequest, const ResourceResponse& redirectResponse)
451 {
452     if (newRequest.httpMethod() == "POST")
453         return true;
454
455     int status = redirectResponse.httpStatusCode();
456     if (((status >= 301 && status <= 303) || status == 307)
457         && m_originalRequest.httpMethod() == "POST")
458         return true;
459
460     return false;
461 }
462
463 void DocumentLoader::handleSubstituteDataLoadNow()
464 {
465     ResourceResponse response = m_substituteData.response();
466     if (response.url().isEmpty())
467         response = ResourceResponse(m_request.url(), m_substituteData.mimeType(), m_substituteData.content()->size(), m_substituteData.textEncoding());
468
469     responseReceived(response, nullptr);
470 }
471
472 void DocumentLoader::startDataLoadTimer()
473 {
474     m_dataLoadTimer.startOneShot(0_s);
475
476 #if HAVE(RUNLOOP_TIMER)
477     if (SchedulePairHashSet* scheduledPairs = m_frame->page()->scheduledRunLoopPairs())
478         m_dataLoadTimer.schedule(*scheduledPairs);
479 #endif
480 }
481
482 #if ENABLE(SERVICE_WORKER)
483 void DocumentLoader::matchRegistration(const URL& url, SWClientConnection::RegistrationCallback&& callback)
484 {
485     auto shouldTryLoadingThroughServiceWorker = !frameLoader()->isReloadingFromOrigin() && m_frame->page() && RuntimeEnabledFeatures::sharedFeatures().serviceWorkerEnabled() && SchemeRegistry::canServiceWorkersHandleURLScheme(url.protocol().toStringWithoutCopying());
486     if (!shouldTryLoadingThroughServiceWorker) {
487         callback(std::nullopt);
488         return;
489     }
490
491     auto origin = (!m_frame->isMainFrame() && m_frame->document()) ? m_frame->document()->topOrigin().data() : SecurityOriginData::fromURL(url);
492     auto sessionID = m_frame->page()->sessionID();
493     auto& provider = ServiceWorkerProvider::singleton();
494     if (!provider.mayHaveServiceWorkerRegisteredForOrigin(sessionID, origin)) {
495         callback(std::nullopt);
496         return;
497     }
498
499     auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnectionForSession(sessionID);
500     connection.matchRegistration(WTFMove(origin), url, WTFMove(callback));
501 }
502
503 static inline bool areRegistrationsEqual(const std::optional<ServiceWorkerRegistrationData>& a, const std::optional<ServiceWorkerRegistrationData>& b)
504 {
505     if (!a)
506         return !b;
507     if (!b)
508         return false;
509     return a->identifier == b->identifier;
510 }
511 #endif
512
513 void DocumentLoader::redirectReceived(CachedResource& resource, ResourceRequest&& request, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
514 {
515     ASSERT_UNUSED(resource, &resource == m_mainResource);
516 #if ENABLE(SERVICE_WORKER)
517     bool isRedirectionFromServiceWorker = redirectResponse.source() == ResourceResponse::Source::ServiceWorker;
518     willSendRequest(WTFMove(request), redirectResponse, ShouldContinue::Yes, [isRedirectionFromServiceWorker, completionHandler = WTFMove(completionHandler), protectedThis = makeRef(*this), this] (auto&& request) mutable {
519         ASSERT(!m_substituteData.isValid());
520         if (request.isNull() || !m_mainDocumentError.isNull() || !m_frame) {
521             completionHandler({ });
522             return;
523         }
524
525         auto url = request.url();
526         this->matchRegistration(url, [request = WTFMove(request), isRedirectionFromServiceWorker, completionHandler = WTFMove(completionHandler), protectedThis = WTFMove(protectedThis), this] (auto&& registrationData) mutable {
527             if (!m_mainDocumentError.isNull() || !m_frame) {
528                 completionHandler({ });
529                 return;
530             }
531
532             if (!registrationData && this->tryLoadingRedirectRequestFromApplicationCache(request)) {
533                 completionHandler({ });
534                 return;
535             }
536
537             bool shouldContinueLoad = areRegistrationsEqual(m_serviceWorkerRegistrationData, registrationData)
538                 && isRedirectionFromServiceWorker == !!registrationData;
539
540             if (shouldContinueLoad) {
541                 completionHandler(WTFMove(request));
542                 return;
543             }
544
545             this->restartLoadingDueToServiceWorkerRegistrationChange(WTFMove(request), WTFMove(registrationData));
546             completionHandler({ });
547             return;
548         });
549     });
550 #else
551     willSendRequest(WTFMove(request), redirectResponse, ShouldContinue::Yes, WTFMove(completionHandler));
552 #endif
553 }
554
555 void DocumentLoader::willSendRequest(ResourceRequest&& newRequest, const ResourceResponse& redirectResponse, ShouldContinue shouldContinue, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
556 {
557     // Note that there are no asserts here as there are for the other callbacks. This is due to the
558     // fact that this "callback" is sent when starting every load, and the state of callback
559     // deferrals plays less of a part in this function in preventing the bad behavior deferring 
560     // callbacks is meant to prevent.
561     ASSERT(!newRequest.isNull());
562
563     ASSERT(shouldContinue != ShouldContinue::No);
564
565     bool didReceiveRedirectResponse = !redirectResponse.isNull();
566     if (!frameLoader()->checkIfFormActionAllowedByCSP(newRequest.url(), didReceiveRedirectResponse)) {
567         cancelMainResourceLoad(frameLoader()->cancelledError(newRequest));
568         return completionHandler(WTFMove(newRequest));
569     }
570
571     ASSERT(timing().fetchStart());
572     if (didReceiveRedirectResponse) {
573         // If the redirecting url is not allowed to display content from the target origin,
574         // then block the redirect.
575         Ref<SecurityOrigin> redirectingOrigin(SecurityOrigin::create(redirectResponse.url()));
576         if (!redirectingOrigin.get().canDisplay(newRequest.url())) {
577             FrameLoader::reportLocalLoadFailed(m_frame, newRequest.url().string());
578             cancelMainResourceLoad(frameLoader()->cancelledError(newRequest));
579             return completionHandler(WTFMove(newRequest));
580         }
581         if (!portAllowed(newRequest.url())) {
582             FrameLoader::reportBlockedPortFailed(m_frame, newRequest.url().string());
583             cancelMainResourceLoad(frameLoader()->blockedError(newRequest));
584             return completionHandler(WTFMove(newRequest));
585         }
586         timing().addRedirect(redirectResponse.url(), newRequest.url());
587     }
588
589     ASSERT(m_frame);
590
591     Frame& topFrame = m_frame->tree().top();
592
593     ASSERT(m_frame->document());
594     ASSERT(topFrame.document());
595     
596     // Update cookie policy base URL as URL changes, except for subframes, which use the
597     // URL of the main frame which doesn't change when we redirect.
598     if (m_frame->isMainFrame())
599         newRequest.setFirstPartyForCookies(newRequest.url());
600
601     FrameLoader::addSameSiteInfoToRequestIfNeeded(newRequest, m_frame->document());
602
603     if (!didReceiveRedirectResponse)
604         frameLoader()->client().dispatchWillChangeDocument(m_frame->document()->url(), newRequest.url());
605
606     // If we're fielding a redirect in response to a POST, force a load from origin, since
607     // this is a common site technique to return to a page viewing some data that the POST
608     // just modified.
609     // Also, POST requests always load from origin, but this does not affect subresources.
610     if (newRequest.cachePolicy() == ResourceRequestCachePolicy::UseProtocolCachePolicy && isPostOrRedirectAfterPost(newRequest, redirectResponse))
611         newRequest.setCachePolicy(ResourceRequestCachePolicy::ReloadIgnoringCacheData);
612
613     if (&topFrame != m_frame) {
614         if (!m_frame->loader().mixedContentChecker().canDisplayInsecureContent(m_frame->document()->securityOrigin(), MixedContentChecker::ContentType::Active, newRequest.url(), MixedContentChecker::AlwaysDisplayInNonStrictMode::Yes)) {
615             cancelMainResourceLoad(frameLoader()->cancelledError(newRequest));
616             return completionHandler(WTFMove(newRequest));
617         }
618         if (!frameLoader()->mixedContentChecker().canDisplayInsecureContent(topFrame.document()->securityOrigin(), MixedContentChecker::ContentType::Active, newRequest.url())) {
619             cancelMainResourceLoad(frameLoader()->cancelledError(newRequest));
620             return completionHandler(WTFMove(newRequest));
621         }
622     }
623
624 #if ENABLE(CONTENT_FILTERING)
625     if (m_contentFilter && !m_contentFilter->continueAfterWillSendRequest(newRequest, redirectResponse))
626         return completionHandler(WTFMove(newRequest));
627 #endif
628
629     setRequest(newRequest);
630
631     if (!didReceiveRedirectResponse && shouldContinue != ShouldContinue::ForSuspension)
632         return completionHandler(WTFMove(newRequest));
633
634     auto navigationPolicyCompletionHandler = [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)] (ResourceRequest&& request, WeakPtr<FormState>&&, ShouldContinue shouldContinue) mutable {
635         m_waitingForNavigationPolicy = false;
636         switch (shouldContinue) {
637         case ShouldContinue::ForSuspension:
638             // We handle suspension by navigating forward to about:blank, which leaves us setup to navigate back to resume.
639             request = { WTF::blankURL() };
640             break;
641         case ShouldContinue::No:
642             stopLoadingForPolicyChange();
643             break;
644         case ShouldContinue::Yes:
645             break;
646         }
647
648         completionHandler(WTFMove(request));
649     };
650
651     ASSERT(!m_waitingForNavigationPolicy);
652     m_waitingForNavigationPolicy = true;
653
654     if (shouldContinue == ShouldContinue::ForSuspension) {
655         navigationPolicyCompletionHandler(WTFMove(newRequest), nullptr, shouldContinue);
656         return;
657     }
658
659     frameLoader()->policyChecker().checkNavigationPolicy(WTFMove(newRequest), redirectResponse, WTFMove(navigationPolicyCompletionHandler));
660 }
661
662 bool DocumentLoader::tryLoadingRequestFromApplicationCache()
663 {
664     m_applicationCacheHost->maybeLoadMainResource(m_request, m_substituteData);
665     return tryLoadingSubstituteData();
666 }
667
668 bool DocumentLoader::tryLoadingSubstituteData()
669 {
670     if (!m_substituteData.isValid() || !m_frame->page())
671         return false;
672
673     RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Returning substitute data (frame = %p, main = %d)", m_frame, m_frame->isMainFrame());
674     m_identifierForLoadWithoutResourceLoader = m_frame->page()->progress().createUniqueIdentifier();
675     frameLoader()->notifier().assignIdentifierToInitialRequest(m_identifierForLoadWithoutResourceLoader, this, m_request);
676     frameLoader()->notifier().dispatchWillSendRequest(this, m_identifierForLoadWithoutResourceLoader, m_request, ResourceResponse());
677
678     if (!m_deferMainResourceDataLoad || frameLoader()->loadsSynchronously())
679         handleSubstituteDataLoadNow();
680     else
681         startDataLoadTimer();
682
683     return true;
684 }
685
686 bool DocumentLoader::tryLoadingRedirectRequestFromApplicationCache(const ResourceRequest& request)
687 {
688     m_applicationCacheHost->maybeLoadMainResourceForRedirect(request, m_substituteData);
689     if (!m_substituteData.isValid())
690         return false;
691
692     RELEASE_ASSERT(m_mainResource);
693     auto* loader = m_mainResource->loader();
694     m_identifierForLoadWithoutResourceLoader = loader ? loader->identifier() : m_mainResource->identifierForLoadWithoutResourceLoader();
695
696     // We need to remove our reference to the CachedResource in favor of a SubstituteData load, which can triger the cancellation of the underyling ResourceLoader.
697     // If the ResourceLoader is indeed cancelled, it would normally send resource load callbacks.
698     // Therefore, sever our relationship with the network load but prevent the ResourceLoader from sending ResourceLoadNotifier callbacks.
699
700     auto resourceLoader = makeRefPtr(mainResourceLoader());
701     if (resourceLoader) {
702         ASSERT(resourceLoader->shouldSendResourceLoadCallbacks());
703         resourceLoader->setSendCallbackPolicy(SendCallbackPolicy::DoNotSendCallbacks);
704     }
705
706     clearMainResource();
707
708     if (resourceLoader)
709         resourceLoader->setSendCallbackPolicy(SendCallbackPolicy::SendCallbacks);
710
711     handleSubstituteDataLoadNow();
712     return true;
713 }
714
715 #if ENABLE(SERVICE_WORKER)
716 void DocumentLoader::restartLoadingDueToServiceWorkerRegistrationChange(ResourceRequest&& request, std::optional<ServiceWorkerRegistrationData>&& registrationData)
717 {
718     clearMainResource();
719
720     ASSERT(!isCommitted());
721     m_serviceWorkerRegistrationData = WTFMove(registrationData);
722     loadMainResource(WTFMove(request));
723
724     if (m_mainResource)
725         frameLoader()->client().dispatchDidReceiveServerRedirectForProvisionalLoad();
726 }
727 #endif
728
729 void DocumentLoader::stopLoadingAfterXFrameOptionsOrContentSecurityPolicyDenied(unsigned long identifier, const ResourceResponse& response)
730 {
731     Ref<DocumentLoader> protectedThis { *this };
732     InspectorInstrumentation::continueAfterXFrameOptionsDenied(*m_frame, identifier, *this, response);
733     m_frame->document()->enforceSandboxFlags(SandboxOrigin);
734     if (HTMLFrameOwnerElement* ownerElement = m_frame->ownerElement())
735         ownerElement->dispatchEvent(Event::create(eventNames().loadEvent, Event::CanBubble::No, Event::IsCancelable::No));
736
737     // The load event might have detached this frame. In that case, the load will already have been cancelled during detach.
738     if (FrameLoader* frameLoader = this->frameLoader())
739         cancelMainResourceLoad(frameLoader->cancelledError(m_request));
740 }
741
742 void DocumentLoader::responseReceived(CachedResource& resource, const ResourceResponse& response, CompletionHandler<void()>&& completionHandler)
743 {
744     ASSERT_UNUSED(resource, m_mainResource == &resource);
745     responseReceived(response, WTFMove(completionHandler));
746 }
747
748 void DocumentLoader::responseReceived(const ResourceResponse& response, CompletionHandler<void()>&& completionHandler)
749 {
750     CompletionHandlerCallingScope completionHandlerCaller(WTFMove(completionHandler));
751
752 #if ENABLE(CONTENT_FILTERING)
753     if (m_contentFilter && !m_contentFilter->continueAfterResponseReceived(response))
754         return;
755 #endif
756
757     Ref<DocumentLoader> protectedThis(*this);
758     bool willLoadFallback = m_applicationCacheHost->maybeLoadFallbackForMainResponse(request(), response);
759
760     // The memory cache doesn't understand the application cache or its caching rules. So if a main resource is served
761     // from the application cache, ensure we don't save the result for future use.
762     if (willLoadFallback)
763         MemoryCache::singleton().remove(*m_mainResource);
764
765     if (willLoadFallback)
766         return;
767
768     ASSERT(m_identifierForLoadWithoutResourceLoader || m_mainResource);
769     unsigned long identifier = m_identifierForLoadWithoutResourceLoader ? m_identifierForLoadWithoutResourceLoader : m_mainResource->identifier();
770     ASSERT(identifier);
771
772     if (m_substituteData.isValid() || !platformStrategies()->loaderStrategy()->havePerformedSecurityChecks(response)) {
773         auto url = response.url();
774         ContentSecurityPolicy contentSecurityPolicy(URL { url }, this);
775         contentSecurityPolicy.didReceiveHeaders(ContentSecurityPolicyResponseHeaders { response }, m_request.httpReferrer());
776         if (!contentSecurityPolicy.allowFrameAncestors(*m_frame, url)) {
777             stopLoadingAfterXFrameOptionsOrContentSecurityPolicyDenied(identifier, response);
778             return;
779         }
780
781         String frameOptions = response.httpHeaderFields().get(HTTPHeaderName::XFrameOptions);
782         if (!frameOptions.isNull()) {
783             if (frameLoader()->shouldInterruptLoadForXFrameOptions(frameOptions, url, identifier)) {
784                 String message = "Refused to display '" + url.stringCenterEllipsizedToLength() + "' in a frame because it set 'X-Frame-Options' to '" + frameOptions + "'.";
785                 m_frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message, identifier);
786                 stopLoadingAfterXFrameOptionsOrContentSecurityPolicyDenied(identifier, response);
787                 return;
788             }
789         }
790     }
791
792     // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
793     // See <rdar://problem/6304600> for more details.
794 #if !USE(CF)
795     ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading());
796 #endif
797
798     if (m_isLoadingMultipartContent) {
799         setupForReplace();
800         m_mainResource->clear();
801     } else if (response.isMultipart())
802         m_isLoadingMultipartContent = true;
803
804     m_response = response;
805
806     if (m_identifierForLoadWithoutResourceLoader) {
807         if (m_mainResource && m_mainResource->wasRedirected()) {
808             ASSERT(m_mainResource->status() == CachedResource::Status::Cached);
809             frameLoader()->client().dispatchDidReceiveServerRedirectForProvisionalLoad();
810         }
811         addResponse(m_response);
812         frameLoader()->notifier().dispatchDidReceiveResponse(this, m_identifierForLoadWithoutResourceLoader, m_response, 0);
813     }
814
815     ASSERT(!m_waitingForContentPolicy);
816     ASSERT(frameLoader());
817     m_waitingForContentPolicy = true;
818
819     // Always show content with valid substitute data.
820     if (m_substituteData.isValid()) {
821         continueAfterContentPolicy(PolicyAction::Use);
822         return;
823     }
824
825 #if ENABLE(FTPDIR)
826     // Respect the hidden FTP Directory Listing pref so it can be tested even if the policy delegate might otherwise disallow it
827     if (m_frame->settings().forceFTPDirectoryListings() && m_response.mimeType() == "application/x-ftp-directory") {
828         continueAfterContentPolicy(PolicyAction::Use);
829         return;
830     }
831 #endif
832
833     RefPtr<SubresourceLoader> mainResourceLoader = this->mainResourceLoader();
834     if (mainResourceLoader)
835         mainResourceLoader->markInAsyncResponsePolicyCheck();
836     frameLoader()->checkContentPolicy(m_response, [this, protectedThis = makeRef(*this), mainResourceLoader = WTFMove(mainResourceLoader), completionHandler = completionHandlerCaller.release()] (PolicyAction policy) mutable {
837         continueAfterContentPolicy(policy);
838         if (mainResourceLoader)
839             mainResourceLoader->didReceiveResponsePolicy();
840         if (completionHandler)
841             completionHandler();
842     });
843 }
844
845 // Prevent web archives from loading if it is remote or it is not the main frame because they
846 // can claim to be from any domain and thus avoid cross-domain security checks (4120255, 45524528).
847 bool DocumentLoader::disallowWebArchive() const
848 {
849     using MIMETypeHashSet = HashSet<String, ASCIICaseInsensitiveHash>;
850     static NeverDestroyed<MIMETypeHashSet> webArchiveMIMETypes {
851         MIMETypeHashSet {
852             "application/x-webarchive"_s,
853             "application/x-mimearchive"_s,
854             "multipart/related"_s,
855 #if PLATFORM(GTK)
856             "message/rfc822"_s,
857 #endif
858         }
859     };
860
861     String mimeType = m_response.mimeType();
862     if (mimeType.isNull() || !webArchiveMIMETypes.get().contains(mimeType))
863         return false;
864
865 #if USE(QUICK_LOOK)
866     if (isQuickLookPreviewURL(m_response.url()))
867         return false;
868 #endif
869
870     if (m_substituteData.isValid())
871         return false;
872
873     if (!SchemeRegistry::shouldTreatURLSchemeAsLocal(m_request.url().protocol().toStringWithoutCopying()))
874         return true;
875
876     if (!frame() || frame()->isMainFrame())
877         return false;
878
879     // On purpose of maintaining existing tests.
880     if (!frame()->document() || frame()->document()->topDocument().alwaysAllowLocalWebarchive())
881         return false;
882     return true;
883 }
884
885 void DocumentLoader::continueAfterContentPolicy(PolicyAction policy)
886 {
887     ASSERT(m_waitingForContentPolicy);
888     m_waitingForContentPolicy = false;
889     if (isStopping())
890         return;
891
892     switch (policy) {
893     case PolicyAction::Use: {
894         if (!frameLoader()->client().canShowMIMEType(m_response.mimeType()) || disallowWebArchive()) {
895             frameLoader()->policyChecker().cannotShowMIMEType(m_response);
896             // Check reachedTerminalState since the load may have already been canceled inside of _handleUnimplementablePolicyWithErrorCode::.
897             stopLoadingForPolicyChange();
898             return;
899         }
900         break;
901     }
902
903     case PolicyAction::Download: {
904         // m_mainResource can be null, e.g. when loading a substitute resource from application cache.
905         if (!m_mainResource) {
906             mainReceivedError(frameLoader()->client().cannotShowURLError(m_request));
907             return;
908         }
909
910         if (ResourceLoader* mainResourceLoader = this->mainResourceLoader())
911             InspectorInstrumentation::continueWithPolicyDownload(*m_frame, mainResourceLoader->identifier(), *this, m_response);
912
913         // When starting the request, we didn't know that it would result in download and not navigation. Now we know that main document URL didn't change.
914         // Download may use this knowledge for purposes unrelated to cookies, notably for setting file quarantine data.
915         frameLoader()->setOriginalURLForDownloadRequest(m_request);
916
917         PAL::SessionID sessionID = PAL::SessionID::defaultSessionID();
918         if (frame() && frame()->page())
919             sessionID = frame()->page()->sessionID();
920
921         if (m_request.url().protocolIsData()) {
922             // We decode data URL internally, there is no resource load to convert.
923             frameLoader()->client().startDownload(m_request);
924         } else
925             frameLoader()->client().convertMainResourceLoadToDownload(this, sessionID, m_request, m_response);
926
927         // It might have gone missing
928         if (mainResourceLoader())
929             static_cast<ResourceLoader*>(mainResourceLoader())->didFail(interruptedForPolicyChangeError());
930         return;
931     }
932     case PolicyAction::Suspend:
933         // It is invalid to get a Suspend policy based on navigation response.
934         RELEASE_ASSERT_NOT_REACHED();
935     case PolicyAction::Ignore:
936         if (ResourceLoader* mainResourceLoader = this->mainResourceLoader())
937             InspectorInstrumentation::continueWithPolicyIgnore(*m_frame, mainResourceLoader->identifier(), *this, m_response);
938         stopLoadingForPolicyChange();
939         return;
940     }
941
942     if (m_response.isHTTP()) {
943         int status = m_response.httpStatusCode(); // Status may be zero when loading substitute data, in particular from a WebArchive.
944         if (status && (status < 200 || status >= 300)) {
945             bool hostedByObject = frameLoader()->isHostedByObjectElement();
946
947             frameLoader()->handleFallbackContent();
948             // object elements are no longer rendered after we fallback, so don't
949             // keep trying to process data from their load
950
951             if (hostedByObject)
952                 cancelMainResourceLoad(frameLoader()->cancelledError(m_request));
953         }
954     }
955
956     if (!isStopping() && m_substituteData.isValid() && isLoadingMainResource()) {
957         auto content = m_substituteData.content();
958         if (content && content->size())
959             dataReceived(content->data(), content->size());
960         if (isLoadingMainResource())
961             finishedLoading();
962
963         // Remove ourselves as a client of this CachedResource as we've decided to commit substitute data but the
964         // load may keep going and be useful to other clients of the CachedResource. If we did not do this, we
965         // may receive data later on even though this DocumentLoader has finished loading.
966         clearMainResource();
967     }
968 }
969
970 void DocumentLoader::commitLoad(const char* data, int length)
971 {
972     // Both unloading the old page and parsing the new page may execute JavaScript which destroys the datasource
973     // by starting a new load, so retain temporarily.
974     RefPtr<Frame> protectedFrame(m_frame);
975     Ref<DocumentLoader> protectedThis(*this);
976
977     commitIfReady();
978     FrameLoader* frameLoader = DocumentLoader::frameLoader();
979     if (!frameLoader)
980         return;
981 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
982     if (ArchiveFactory::isArchiveMIMEType(response().mimeType()))
983         return;
984 #endif
985     frameLoader->client().committedLoad(this, data, length);
986
987     if (isMultipartReplacingLoad())
988         frameLoader->client().didReplaceMultipartContent();
989 }
990
991 ResourceError DocumentLoader::interruptedForPolicyChangeError() const
992 {
993     return frameLoader()->client().interruptedForPolicyChangeError(request());
994 }
995
996 void DocumentLoader::stopLoadingForPolicyChange()
997 {
998     ResourceError error = interruptedForPolicyChangeError();
999     error.setType(ResourceError::Type::Cancellation);
1000     cancelMainResourceLoad(error);
1001 }
1002
1003 #if ENABLE(SERVICE_WORKER)
1004 static inline bool isLocalURL(const URL& url)
1005 {
1006     // https://fetch.spec.whatwg.org/#is-local
1007     auto protocol = url.protocol().toStringWithoutCopying();
1008     return equalLettersIgnoringASCIICase(protocol, "data") || equalLettersIgnoringASCIICase(protocol, "blob") || equalLettersIgnoringASCIICase(protocol, "about");
1009 }
1010 #endif
1011
1012 void DocumentLoader::commitData(const char* bytes, size_t length)
1013 {
1014     if (!m_gotFirstByte) {
1015         m_gotFirstByte = true;
1016         bool hasBegun = m_writer.begin(documentURL(), false);
1017         m_writer.setDocumentWasLoadedAsPartOfNavigation();
1018
1019         if (SecurityPolicy::allowSubstituteDataAccessToLocal() && m_originalSubstituteDataWasValid) {
1020             // If this document was loaded with substituteData, then the document can
1021             // load local resources. See https://bugs.webkit.org/show_bug.cgi?id=16756
1022             // and https://bugs.webkit.org/show_bug.cgi?id=19760 for further
1023             // discussion.
1024             m_frame->document()->securityOrigin().grantLoadLocalResources();
1025         }
1026
1027         if (frameLoader()->stateMachine().creatingInitialEmptyDocument())
1028             return;
1029
1030 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
1031         if (m_archive && m_archive->shouldOverrideBaseURL())
1032             m_frame->document()->setBaseURLOverride(m_archive->mainResource()->url());
1033 #endif
1034 #if ENABLE(SERVICE_WORKER)
1035         if (RuntimeEnabledFeatures::sharedFeatures().serviceWorkerEnabled()) {
1036             if (m_serviceWorkerRegistrationData && m_serviceWorkerRegistrationData->activeWorker) {
1037                 m_frame->document()->setActiveServiceWorker(ServiceWorker::getOrCreate(*m_frame->document(), WTFMove(m_serviceWorkerRegistrationData->activeWorker.value())));
1038                 m_serviceWorkerRegistrationData = { };
1039             } else if (isLocalURL(m_frame->document()->url())) {
1040                 if (auto* parent = m_frame->document()->parentDocument())
1041                     m_frame->document()->setActiveServiceWorker(parent->activeServiceWorker());
1042             }
1043
1044             if (m_frame->document()->activeServiceWorker() || SchemeRegistry::canServiceWorkersHandleURLScheme(m_frame->document()->url().protocol().toStringWithoutCopying()))
1045                 m_frame->document()->setServiceWorkerConnection(ServiceWorkerProvider::singleton().existingServiceWorkerConnectionForSession(m_frame->page()->sessionID()));
1046
1047             // We currently unregister the temporary service worker client since we now registered the real document.
1048             // FIXME: We should make the real document use the temporary client identifier.
1049             unregisterTemporaryServiceWorkerClient();
1050         }
1051 #endif
1052         // Call receivedFirstData() exactly once per load. We should only reach this point multiple times
1053         // for multipart loads, and FrameLoader::isReplacing() will be true after the first time.
1054         if (!isMultipartReplacingLoad())
1055             frameLoader()->receivedFirstData();
1056
1057         // The load could be canceled under receivedFirstData(), which makes delegate calls and even sometimes dispatches DOM events.
1058         if (!isLoading())
1059             return;
1060
1061         bool userChosen;
1062         String encoding;
1063         if (overrideEncoding().isNull()) {
1064             userChosen = false;
1065             encoding = response().textEncodingName();
1066 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
1067             if (m_archive && m_archive->shouldUseMainResourceEncoding())
1068                 encoding = m_archive->mainResource()->textEncoding();
1069 #endif
1070         } else {
1071             userChosen = true;
1072             encoding = overrideEncoding();
1073         }
1074
1075         m_writer.setEncoding(encoding, userChosen);
1076
1077         RELEASE_ASSERT(hasBegun);
1078     }
1079
1080 #if ENABLE(CONTENT_EXTENSIONS)
1081     auto& extensionStyleSheets = m_frame->document()->extensionStyleSheets();
1082
1083     for (auto& pendingStyleSheet : m_pendingNamedContentExtensionStyleSheets)
1084         extensionStyleSheets.maybeAddContentExtensionSheet(pendingStyleSheet.key, *pendingStyleSheet.value);
1085     for (auto& pendingSelectorEntry : m_pendingContentExtensionDisplayNoneSelectors) {
1086         for (const auto& pendingSelector : pendingSelectorEntry.value)
1087             extensionStyleSheets.addDisplayNoneSelector(pendingSelectorEntry.key, pendingSelector.first, pendingSelector.second);
1088     }
1089
1090     m_pendingNamedContentExtensionStyleSheets.clear();
1091     m_pendingContentExtensionDisplayNoneSelectors.clear();
1092 #endif
1093
1094     ASSERT(m_frame->document()->parsing());
1095     m_writer.addData(bytes, length);
1096 }
1097
1098 void DocumentLoader::dataReceived(CachedResource& resource, const char* data, int length)
1099 {
1100     ASSERT_UNUSED(resource, &resource == m_mainResource);
1101     dataReceived(data, length);
1102 }
1103
1104 void DocumentLoader::dataReceived(const char* data, int length)
1105 {
1106 #if ENABLE(CONTENT_FILTERING)
1107     if (m_contentFilter && !m_contentFilter->continueAfterDataReceived(data, length))
1108         return;
1109 #endif
1110
1111     ASSERT(data);
1112     ASSERT(length);
1113     ASSERT(!m_response.isNull());
1114
1115     // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
1116     // See <rdar://problem/6304600> for more details.
1117 #if !USE(CF)
1118     ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading());
1119 #endif
1120
1121     if (m_identifierForLoadWithoutResourceLoader)
1122         frameLoader()->notifier().dispatchDidReceiveData(this, m_identifierForLoadWithoutResourceLoader, data, length, -1);
1123
1124     m_applicationCacheHost->mainResourceDataReceived(data, length, -1, false);
1125     m_timeOfLastDataReceived = MonotonicTime::now();
1126
1127     if (!isMultipartReplacingLoad())
1128         commitLoad(data, length);
1129 }
1130
1131 void DocumentLoader::setupForReplace()
1132 {
1133     if (!mainResourceData())
1134         return;
1135
1136     frameLoader()->client().willReplaceMultipartContent();
1137     
1138     maybeFinishLoadingMultipartContent();
1139     maybeCreateArchive();
1140     m_writer.end();
1141     frameLoader()->setReplacing();
1142     m_gotFirstByte = false;
1143     
1144     stopLoadingSubresources();
1145     stopLoadingPlugIns();
1146 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
1147     clearArchiveResources();
1148 #endif
1149 }
1150
1151 void DocumentLoader::checkLoadComplete()
1152 {
1153     if (!m_frame || isLoading())
1154         return;
1155
1156     ASSERT(this == frameLoader()->activeDocumentLoader());
1157     m_frame->document()->domWindow()->finishedLoading();
1158 }
1159
1160 void DocumentLoader::attachToFrame(Frame& frame)
1161 {
1162     if (m_frame == &frame)
1163         return;
1164
1165     ASSERT(!m_frame);
1166     observeFrame(&frame);
1167     m_writer.setFrame(&frame);
1168     attachToFrame();
1169
1170 #ifndef NDEBUG
1171     m_hasEverBeenAttached = true;
1172 #endif
1173 }
1174
1175 void DocumentLoader::attachToFrame()
1176 {
1177     ASSERT(m_frame);
1178 }
1179
1180 void DocumentLoader::detachFromFrame()
1181 {
1182 #ifndef NDEBUG
1183     if (m_hasEverBeenAttached)
1184         ASSERT_WITH_MESSAGE(m_frame, "detachFromFrame() is being called on a DocumentLoader twice without an attachToFrame() inbetween");
1185     else
1186         ASSERT_WITH_MESSAGE(m_frame, "detachFromFrame() is being called on a DocumentLoader that has never attached to any Frame");
1187 #endif
1188     RefPtr<Frame> protectedFrame(m_frame);
1189     Ref<DocumentLoader> protectedThis(*this);
1190
1191     // It never makes sense to have a document loader that is detached from its
1192     // frame have any loads active, so kill all the loads.
1193     stopLoading();
1194     if (m_mainResource && m_mainResource->hasClient(*this))
1195         m_mainResource->removeClient(*this);
1196 #if ENABLE(CONTENT_FILTERING)
1197     if (m_contentFilter)
1198         m_contentFilter->stopFilteringMainResource();
1199 #endif
1200
1201     m_applicationCacheHost->setDOMApplicationCache(nullptr);
1202
1203     cancelPolicyCheckIfNeeded();
1204
1205     // cancelPolicyCheckIfNeeded can clear m_frame if the policy check
1206     // is stopped, resulting in a recursive call into this detachFromFrame.
1207     // If m_frame is nullptr after cancelPolicyCheckIfNeeded, our work is
1208     // already done so just return.
1209     if (!m_frame)
1210         return;
1211
1212     InspectorInstrumentation::loaderDetachedFromFrame(*m_frame, *this);
1213
1214     observeFrame(nullptr);
1215 }
1216
1217 void DocumentLoader::clearMainResourceLoader()
1218 {
1219     m_loadingMainResource = false;
1220
1221     if (this == frameLoader()->activeDocumentLoader())
1222         checkLoadComplete();
1223 }
1224
1225 #if ENABLE(APPLICATION_MANIFEST)
1226 uint64_t DocumentLoader::loadApplicationManifest()
1227 {
1228     static uint64_t nextCallbackID = 1;
1229
1230     auto* document = this->document();
1231     if (!document)
1232         return 0;
1233
1234     if (!m_frame->isMainFrame())
1235         return 0;
1236
1237     if (document->url().isEmpty() || document->url().protocolIsAbout())
1238         return 0;
1239
1240     auto head = document->head();
1241     if (!head)
1242         return 0;
1243
1244     URL manifestURL;
1245     bool useCredentials = false;
1246     for (const auto& link : childrenOfType<HTMLLinkElement>(*head)) {
1247         if (link.isApplicationManifest()) {
1248             manifestURL = link.href();
1249             useCredentials = equalIgnoringASCIICase(link.attributeWithoutSynchronization(HTMLNames::crossoriginAttr), "use-credentials");
1250             break;
1251         }
1252     }
1253
1254     if (manifestURL.isEmpty() || !manifestURL.isValid())
1255         return 0;
1256
1257     auto manifestLoader = std::make_unique<ApplicationManifestLoader>(*this, manifestURL, useCredentials);
1258     auto* rawManifestLoader = manifestLoader.get();
1259     auto callbackID = nextCallbackID++;
1260     m_applicationManifestLoaders.set(WTFMove(manifestLoader), callbackID);
1261
1262     if (!rawManifestLoader->startLoading()) {
1263         m_applicationManifestLoaders.remove(rawManifestLoader);
1264         return 0;
1265     }
1266
1267     return callbackID;
1268 }
1269
1270 void DocumentLoader::finishedLoadingApplicationManifest(ApplicationManifestLoader& loader)
1271 {
1272     // If the DocumentLoader has detached from its frame, all manifest loads should have already been canceled.
1273     ASSERT(m_frame);
1274
1275     auto callbackIdentifier = m_applicationManifestLoaders.get(&loader);
1276     notifyFinishedLoadingApplicationManifest(callbackIdentifier, loader.processManifest());
1277     m_applicationManifestLoaders.remove(&loader);
1278 }
1279
1280 void DocumentLoader::notifyFinishedLoadingApplicationManifest(uint64_t callbackIdentifier, std::optional<ApplicationManifest> manifest)
1281 {
1282     RELEASE_ASSERT(callbackIdentifier);
1283     RELEASE_ASSERT(m_frame);
1284     m_frame->loader().client().finishedLoadingApplicationManifest(callbackIdentifier, manifest);
1285 }
1286 #endif
1287
1288 void DocumentLoader::setCustomHeaderFields(Vector<HTTPHeaderField>&& fields)
1289 {
1290     m_customHeaderFields = WTFMove(fields);
1291 }
1292
1293 bool DocumentLoader::isLoadingInAPISense() const
1294 {
1295     // Once a frame has loaded, we no longer need to consider subresources,
1296     // but we still need to consider subframes.
1297     if (frameLoader()->state() != FrameStateComplete) {
1298         if (m_frame->settings().needsIsLoadingInAPISenseQuirk() && !m_subresourceLoaders.isEmpty())
1299             return true;
1300
1301         ASSERT(m_frame->document());
1302         auto& document = *m_frame->document();
1303         if ((isLoadingMainResource() || !document.loadEventFinished()) && isLoading())
1304             return true;
1305         if (m_cachedResourceLoader->requestCount())
1306             return true;
1307         if (document.isDelayingLoadEvent())
1308             return true;
1309         if (document.processingLoadEvent())
1310             return true;
1311         if (document.hasActiveParser())
1312             return true;
1313         auto* scriptableParser = document.scriptableDocumentParser();
1314         if (scriptableParser && scriptableParser->hasScriptsWaitingForStylesheets())
1315             return true;
1316     }
1317     return frameLoader()->subframeIsLoading();
1318 }
1319
1320 bool DocumentLoader::maybeCreateArchive()
1321 {
1322 #if !ENABLE(WEB_ARCHIVE) && !ENABLE(MHTML)
1323     return false;
1324 #else
1325     // Give the archive machinery a crack at this document. If the MIME type is not an archive type, it will return 0.
1326     m_archive = ArchiveFactory::create(m_response.url(), mainResourceData().get(), m_response.mimeType());
1327     if (!m_archive)
1328         return false;
1329     
1330     addAllArchiveResources(*m_archive);
1331     ASSERT(m_archive->mainResource());
1332     auto& mainResource = *m_archive->mainResource();
1333     m_parsedArchiveData = &mainResource.data();
1334     m_writer.setMIMEType(mainResource.mimeType());
1335
1336     ASSERT(m_frame->document());
1337     commitData(mainResource.data().data(), mainResource.data().size());
1338     return true;
1339 #endif
1340 }
1341
1342 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
1343
1344 void DocumentLoader::setArchive(Ref<Archive>&& archive)
1345 {
1346     m_archive = WTFMove(archive);
1347     addAllArchiveResources(*m_archive);
1348 }
1349
1350 void DocumentLoader::addAllArchiveResources(Archive& archive)
1351 {
1352     if (!m_archiveResourceCollection)
1353         m_archiveResourceCollection = std::make_unique<ArchiveResourceCollection>();
1354     m_archiveResourceCollection->addAllResources(archive);
1355 }
1356
1357 // FIXME: Adding a resource directly to a DocumentLoader/ArchiveResourceCollection seems like bad design, but is API some apps rely on.
1358 // Can we change the design in a manner that will let us deprecate that API without reducing functionality of those apps?
1359 void DocumentLoader::addArchiveResource(Ref<ArchiveResource>&& resource)
1360 {
1361     if (!m_archiveResourceCollection)
1362         m_archiveResourceCollection = std::make_unique<ArchiveResourceCollection>();
1363     m_archiveResourceCollection->addResource(WTFMove(resource));
1364 }
1365
1366 RefPtr<Archive> DocumentLoader::popArchiveForSubframe(const String& frameName, const URL& url)
1367 {
1368     return m_archiveResourceCollection ? m_archiveResourceCollection->popSubframeArchive(frameName, url) : nullptr;
1369 }
1370
1371 void DocumentLoader::clearArchiveResources()
1372 {
1373     m_archiveResourceCollection = nullptr;
1374     m_substituteResourceDeliveryTimer.stop();
1375 }
1376
1377 SharedBuffer* DocumentLoader::parsedArchiveData() const
1378 {
1379     return m_parsedArchiveData.get();
1380 }
1381
1382 #endif // ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
1383
1384 ArchiveResource* DocumentLoader::archiveResourceForURL(const URL& url) const
1385 {
1386     if (!m_archiveResourceCollection)
1387         return nullptr;
1388     auto* resource = m_archiveResourceCollection->archiveResourceForURL(url);
1389     if (!resource || resource->shouldIgnoreWhenUnarchiving())
1390         return nullptr;
1391     return resource;
1392 }
1393
1394 RefPtr<ArchiveResource> DocumentLoader::mainResource() const
1395 {
1396     RefPtr<SharedBuffer> data = mainResourceData();
1397     if (!data)
1398         data = SharedBuffer::create();
1399     auto& response = this->response();
1400     return ArchiveResource::create(WTFMove(data), response.url(), response.mimeType(), response.textEncodingName(), frame()->tree().uniqueName());
1401 }
1402
1403 RefPtr<ArchiveResource> DocumentLoader::subresource(const URL& url) const
1404 {
1405     if (!isCommitted())
1406         return nullptr;
1407     
1408     auto* resource = m_cachedResourceLoader->cachedResource(url);
1409     if (!resource || !resource->isLoaded())
1410         return archiveResourceForURL(url);
1411
1412     if (resource->type() == CachedResource::Type::MainResource)
1413         return nullptr;
1414
1415     auto* data = resource->resourceBuffer();
1416     if (!data)
1417         return nullptr;
1418
1419     return ArchiveResource::create(data, url, resource->response());
1420 }
1421
1422 Vector<Ref<ArchiveResource>> DocumentLoader::subresources() const
1423 {
1424     if (!isCommitted())
1425         return { };
1426
1427     Vector<Ref<ArchiveResource>> subresources;
1428     for (auto& handle : m_cachedResourceLoader->allCachedResources().values()) {
1429         if (auto subresource = this->subresource({ { }, handle->url() }))
1430             subresources.append(subresource.releaseNonNull());
1431     }
1432     return subresources;
1433 }
1434
1435 void DocumentLoader::deliverSubstituteResourcesAfterDelay()
1436 {
1437     if (m_pendingSubstituteResources.isEmpty())
1438         return;
1439     ASSERT(m_frame);
1440     ASSERT(m_frame->page());
1441     if (m_frame->page()->defersLoading())
1442         return;
1443
1444     if (!m_substituteResourceDeliveryTimer.isActive())
1445         m_substituteResourceDeliveryTimer.startOneShot(0_s);
1446 }
1447
1448 void DocumentLoader::substituteResourceDeliveryTimerFired()
1449 {
1450     if (m_pendingSubstituteResources.isEmpty())
1451         return;
1452     ASSERT(m_frame);
1453     ASSERT(m_frame->page());
1454     if (m_frame->page()->defersLoading())
1455         return;
1456
1457     auto pendingSubstituteResources = WTFMove(m_pendingSubstituteResources);
1458     for (auto& pendingSubstituteResource : pendingSubstituteResources) {
1459         auto& loader = pendingSubstituteResource.key;
1460         if (auto& resource = pendingSubstituteResource.value)
1461             resource->deliver(*loader);
1462         else {
1463             // A null resource means that we should fail the load.
1464             // FIXME: Maybe we should use another error here - something like "not in cache".
1465             loader->didFail(loader->cannotShowURLError());
1466         }
1467     }
1468 }
1469
1470 #ifndef NDEBUG
1471
1472 bool DocumentLoader::isSubstituteLoadPending(ResourceLoader* loader) const
1473 {
1474     return m_pendingSubstituteResources.contains(loader);
1475 }
1476
1477 #endif
1478
1479 void DocumentLoader::cancelPendingSubstituteLoad(ResourceLoader* loader)
1480 {
1481     if (m_pendingSubstituteResources.isEmpty())
1482         return;
1483     m_pendingSubstituteResources.remove(loader);
1484     if (m_pendingSubstituteResources.isEmpty())
1485         m_substituteResourceDeliveryTimer.stop();
1486 }
1487
1488 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
1489
1490 bool DocumentLoader::scheduleArchiveLoad(ResourceLoader& loader, const ResourceRequest& request)
1491 {
1492     if (auto* resource = archiveResourceForURL(request.url())) {
1493         scheduleSubstituteResourceLoad(loader, *resource);
1494         return true;
1495     }
1496
1497     if (!m_archive)
1498         return false;
1499
1500 #if ENABLE(WEB_ARCHIVE)
1501     // The idea of WebArchiveDebugMode is that we should fail instead of trying to fetch from the network.
1502     // Returning true ensures the caller will not try to fetch from the network.
1503     if (m_frame->settings().webArchiveDebugModeEnabled() && responseMIMEType() == "application/x-webarchive")
1504         return true;
1505 #endif
1506
1507     // If we want to load from the archive only, then we should always return true so that the caller
1508     // does not try to fetch form the network.
1509     return m_archive->shouldLoadFromArchiveOnly();
1510 }
1511
1512 #endif
1513
1514 void DocumentLoader::scheduleSubstituteResourceLoad(ResourceLoader& loader, SubstituteResource& resource)
1515 {
1516 #if ENABLE(SERVICE_WORKER)
1517     ASSERT(!loader.options().serviceWorkerRegistrationIdentifier);
1518 #endif
1519     m_pendingSubstituteResources.set(&loader, &resource);
1520     deliverSubstituteResourcesAfterDelay();
1521 }
1522
1523 void DocumentLoader::scheduleCannotShowURLError(ResourceLoader& loader)
1524 {
1525     m_pendingSubstituteResources.set(&loader, nullptr);
1526     deliverSubstituteResourcesAfterDelay();
1527 }
1528
1529 void DocumentLoader::addResponse(const ResourceResponse& response)
1530 {
1531     if (!m_stopRecordingResponses)
1532         m_responses.append(response);
1533 }
1534
1535 void DocumentLoader::stopRecordingResponses()
1536 {
1537     m_stopRecordingResponses = true;
1538     m_responses.shrinkToFit();
1539 }
1540
1541 void DocumentLoader::setTitle(const StringWithDirection& title)
1542 {
1543     if (m_pageTitle == title)
1544         return;
1545
1546     frameLoader()->willChangeTitle(this);
1547     m_pageTitle = title;
1548     frameLoader()->didChangeTitle(this);
1549 }
1550
1551 URL DocumentLoader::urlForHistory() const
1552 {
1553     // Return the URL to be used for history and B/F list.
1554     // Returns nil for WebDataProtocol URLs that aren't alternates
1555     // for unreachable URLs, because these can't be stored in history.
1556     if (m_substituteData.isValid() && !m_substituteData.shouldRevealToSessionHistory())
1557         return unreachableURL();
1558
1559     return m_originalRequestCopy.url();
1560 }
1561
1562 bool DocumentLoader::urlForHistoryReflectsFailure() const
1563 {
1564     return m_substituteData.isValid() || m_response.httpStatusCode() >= 400;
1565 }
1566
1567 URL DocumentLoader::documentURL() const
1568 {
1569     URL url = substituteData().response().url();
1570 #if ENABLE(WEB_ARCHIVE)
1571     if (url.isEmpty() && m_archive && m_archive->shouldUseMainResourceURL())
1572         url = m_archive->mainResource()->url();
1573 #endif
1574     if (url.isEmpty())
1575         url = m_request.url();
1576     if (url.isEmpty())
1577         url = m_response.url();
1578     return url;
1579 }
1580
1581 #if PLATFORM(IOS_FAMILY)
1582
1583 // FIXME: This method seems to violate the encapsulation of this class.
1584 void DocumentLoader::setResponseMIMEType(const String& responseMimeType)
1585 {
1586     m_response.setMimeType(responseMimeType);
1587 }
1588
1589 #endif
1590
1591 void DocumentLoader::setDefersLoading(bool defers)
1592 {
1593     // Multiple frames may be loading the same main resource simultaneously. If deferral state changes,
1594     // each frame's DocumentLoader will try to send a setDefersLoading() to the same underlying ResourceLoader. Ensure only
1595     // the "owning" DocumentLoader does so, as setDefersLoading() is not resilient to setting the same value repeatedly.
1596     if (mainResourceLoader() && mainResourceLoader()->documentLoader() == this)
1597         mainResourceLoader()->setDefersLoading(defers);
1598
1599     setAllDefersLoading(m_subresourceLoaders, defers);
1600     setAllDefersLoading(m_plugInStreamLoaders, defers);
1601     if (!defers)
1602         deliverSubstituteResourcesAfterDelay();
1603 }
1604
1605 void DocumentLoader::setMainResourceDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy)
1606 {
1607     if (m_mainResource)
1608         m_mainResource->setDataBufferingPolicy(dataBufferingPolicy);
1609 }
1610
1611 void DocumentLoader::stopLoadingPlugIns()
1612 {
1613     cancelAll(m_plugInStreamLoaders);
1614 }
1615
1616 void DocumentLoader::stopLoadingSubresources()
1617 {
1618     cancelAll(m_subresourceLoaders);
1619     ASSERT(m_subresourceLoaders.isEmpty());
1620 }
1621
1622 void DocumentLoader::addSubresourceLoader(ResourceLoader* loader)
1623 {
1624     // The main resource's underlying ResourceLoader will ask to be added here.
1625     // It is much simpler to handle special casing of main resource loads if we don't
1626     // let it be added. In the main resource load case, mainResourceLoader()
1627     // will still be null at this point, but m_gotFirstByte should be false here if and only
1628     // if we are just starting the main resource load.
1629     if (!m_gotFirstByte)
1630         return;
1631     ASSERT(loader->identifier());
1632     ASSERT(!m_subresourceLoaders.contains(loader->identifier()));
1633     ASSERT(!mainResourceLoader() || mainResourceLoader() != loader);
1634
1635     // Application Cache loaders are handled by their ApplicationCacheGroup directly.
1636     if (loader->options().applicationCacheMode == ApplicationCacheMode::Bypass)
1637         return;
1638
1639     // A page in the PageCache or about to enter PageCache should not be able to start loads.
1640     ASSERT_WITH_SECURITY_IMPLICATION(!document() || document()->pageCacheState() == Document::NotInPageCache);
1641
1642     m_subresourceLoaders.add(loader->identifier(), loader);
1643 }
1644
1645 void DocumentLoader::removeSubresourceLoader(LoadCompletionType type, ResourceLoader* loader)
1646 {
1647     ASSERT(loader->identifier());
1648
1649     if (!m_subresourceLoaders.remove(loader->identifier()))
1650         return;
1651     checkLoadComplete();
1652     if (Frame* frame = m_frame)
1653         frame->loader().subresourceLoadDone(type);
1654 }
1655
1656 void DocumentLoader::addPlugInStreamLoader(ResourceLoader& loader)
1657 {
1658     ASSERT(loader.identifier());
1659     ASSERT(!m_plugInStreamLoaders.contains(loader.identifier()));
1660
1661     m_plugInStreamLoaders.add(loader.identifier(), &loader);
1662 }
1663
1664 void DocumentLoader::removePlugInStreamLoader(ResourceLoader& loader)
1665 {
1666     ASSERT(loader.identifier());
1667     ASSERT(&loader == m_plugInStreamLoaders.get(loader.identifier()));
1668
1669     m_plugInStreamLoaders.remove(loader.identifier());
1670     checkLoadComplete();
1671 }
1672
1673 bool DocumentLoader::isMultipartReplacingLoad() const
1674 {
1675     return isLoadingMultipartContent() && frameLoader()->isReplacing();
1676 }
1677
1678 bool DocumentLoader::maybeLoadEmpty()
1679 {
1680     bool shouldLoadEmpty = !m_substituteData.isValid() && (m_request.url().isEmpty() || SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(m_request.url().protocol().toStringWithoutCopying()));
1681     if (!shouldLoadEmpty && !frameLoader()->client().representationExistsForURLScheme(m_request.url().protocol().toStringWithoutCopying()))
1682         return false;
1683
1684     if (m_request.url().isEmpty() && !frameLoader()->stateMachine().creatingInitialEmptyDocument()) {
1685         m_request.setURL(WTF::blankURL());
1686         if (isLoadingMainResource())
1687             frameLoader()->client().dispatchDidChangeProvisionalURL();
1688     }
1689
1690     String mimeType = shouldLoadEmpty ? "text/html" : frameLoader()->client().generatedMIMETypeForURLScheme(m_request.url().protocol().toStringWithoutCopying());
1691     m_response = ResourceResponse(m_request.url(), mimeType, 0, String());
1692     finishedLoading();
1693     return true;
1694 }
1695
1696 void DocumentLoader::startLoadingMainResource(ShouldContinue shouldContinue)
1697 {
1698     ASSERT(shouldContinue != ShouldContinue::No);
1699
1700     m_mainDocumentError = ResourceError();
1701     timing().markStartTimeAndFetchStart();
1702     ASSERT(!m_mainResource);
1703     ASSERT(!m_loadingMainResource);
1704     m_loadingMainResource = true;
1705
1706     Ref<DocumentLoader> protectedThis(*this);
1707
1708     if (maybeLoadEmpty()) {
1709         RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Returning empty document (frame = %p, main = %d)", m_frame, m_frame ? m_frame->isMainFrame() : false);
1710         return;
1711     }
1712
1713 #if ENABLE(CONTENT_FILTERING)
1714     m_contentFilter = !m_substituteData.isValid() ? ContentFilter::create(*this) : nullptr;
1715 #endif
1716
1717     // Make sure we re-apply the user agent to the Document's ResourceRequest upon reload in case the embedding
1718     // application has changed it.
1719     m_request.clearHTTPUserAgent();
1720     frameLoader()->addExtraFieldsToMainResourceRequest(m_request);
1721
1722     ASSERT(timing().startTime());
1723     ASSERT(timing().fetchStart());
1724
1725     willSendRequest(ResourceRequest(m_request), ResourceResponse(), shouldContinue, [this, protectedThis = WTFMove(protectedThis)] (ResourceRequest&& request) mutable {
1726         m_request = request;
1727
1728         // willSendRequest() may lead to our Frame being detached or cancelling the load via nulling the ResourceRequest.
1729         if (!m_frame || m_request.isNull()) {
1730             RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Load canceled after willSendRequest (frame = %p, main = %d)", m_frame, m_frame ? m_frame->isMainFrame() : false);
1731             return;
1732         }
1733
1734         request.setRequester(ResourceRequest::Requester::Main);
1735         // If this is a reload the cache layer might have made the previous request conditional. DocumentLoader can't handle 304 responses itself.
1736         request.makeUnconditional();
1737
1738         RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Starting load (frame = %p, main = %d)", m_frame, m_frame->isMainFrame());
1739
1740 #if ENABLE(SERVICE_WORKER)
1741         // FIXME: Implement local URL interception by getting the service worker of the parent.
1742         auto url = request.url();
1743         matchRegistration(url, [request = WTFMove(request), protectedThis = WTFMove(protectedThis), this] (auto&& registrationData) mutable {
1744             if (!m_mainDocumentError.isNull() || !m_frame)
1745                 return;
1746
1747             m_serviceWorkerRegistrationData = WTFMove(registrationData);
1748
1749             // Prefer existing substitute data (from WKWebView.loadData etc) over service worker fetch.
1750             if (this->tryLoadingSubstituteData())
1751                 return;
1752             // Try app cache only if there is no service worker.
1753             if (!m_serviceWorkerRegistrationData && this->tryLoadingRequestFromApplicationCache())
1754                 return;
1755             this->loadMainResource(WTFMove(request));
1756         });
1757 #else
1758         if (tryLoadingRequestFromApplicationCache())
1759             return;
1760         loadMainResource(WTFMove(request));
1761 #endif
1762     });
1763 }
1764
1765 void DocumentLoader::registerTemporaryServiceWorkerClient(const URL& url)
1766 {
1767 #if ENABLE(SERVICE_WORKER)
1768     ASSERT(!m_temporaryServiceWorkerClient);
1769
1770     if (!m_serviceWorkerRegistrationData)
1771         return;
1772
1773     m_temporaryServiceWorkerClient = TemporaryServiceWorkerClient {
1774         generateObjectIdentifier<DocumentIdentifierType>(),
1775         *ServiceWorkerProvider::singleton().existingServiceWorkerConnectionForSession(m_frame->page()->sessionID())
1776     };
1777
1778     // FIXME: Compute ServiceWorkerClientFrameType appropriately.
1779     ServiceWorkerClientData data { { m_temporaryServiceWorkerClient->serviceWorkerConnection->serverConnectionIdentifier(), m_temporaryServiceWorkerClient->documentIdentifier }, ServiceWorkerClientType::Window, ServiceWorkerClientFrameType::None, url };
1780
1781     RefPtr<SecurityOrigin> topOrigin;
1782     if (m_frame->isMainFrame())
1783         topOrigin = SecurityOrigin::create(url);
1784     else
1785         topOrigin = &m_frame->mainFrame().document()->topOrigin();
1786     m_temporaryServiceWorkerClient->serviceWorkerConnection->registerServiceWorkerClient(*topOrigin, WTFMove(data), m_serviceWorkerRegistrationData->identifier);
1787 #else
1788     UNUSED_PARAM(url);
1789 #endif
1790 }
1791
1792 void DocumentLoader::unregisterTemporaryServiceWorkerClient()
1793 {
1794 #if ENABLE(SERVICE_WORKER)
1795     if (!m_temporaryServiceWorkerClient)
1796         return;
1797
1798     m_temporaryServiceWorkerClient->serviceWorkerConnection->unregisterServiceWorkerClient(m_temporaryServiceWorkerClient->documentIdentifier);
1799     m_temporaryServiceWorkerClient = std::nullopt;
1800 #endif
1801 }
1802
1803 void DocumentLoader::loadMainResource(ResourceRequest&& request)
1804 {
1805     static NeverDestroyed<ResourceLoaderOptions> mainResourceLoadOptions(
1806         SendCallbackPolicy::SendCallbacks,
1807         ContentSniffingPolicy::SniffContent,
1808         DataBufferingPolicy::BufferData,
1809         StoredCredentialsPolicy::Use,
1810         ClientCredentialPolicy::MayAskClientForCredentials,
1811         FetchOptions::Credentials::Include,
1812         SecurityCheckPolicy::SkipSecurityCheck,
1813         FetchOptions::Mode::Navigate,
1814         CertificateInfoPolicy::IncludeCertificateInfo,
1815         ContentSecurityPolicyImposition::SkipPolicyCheck,
1816         DefersLoadingPolicy::AllowDefersLoading,
1817         CachingPolicy::AllowCaching);
1818     CachedResourceRequest mainResourceRequest(WTFMove(request), mainResourceLoadOptions);
1819     if (!m_frame->isMainFrame() && m_frame->document()) {
1820         // If we are loading the main resource of a subframe, use the cache partition of the main document.
1821         mainResourceRequest.setDomainForCachePartition(*m_frame->document());
1822     } else {
1823         auto origin = SecurityOrigin::create(mainResourceRequest.resourceRequest().url());
1824         origin->setStorageBlockingPolicy(frameLoader()->frame().settings().storageBlockingPolicy());
1825         mainResourceRequest.setDomainForCachePartition(origin->domainForCachePartition());
1826     }
1827
1828 #if ENABLE(SERVICE_WORKER)
1829     mainResourceRequest.setNavigationServiceWorkerRegistrationData(m_serviceWorkerRegistrationData);
1830     if (mainResourceRequest.options().serviceWorkersMode != ServiceWorkersMode::None) {
1831         // As per step 12 of https://w3c.github.io/ServiceWorker/#on-fetch-request-algorithm, the active service worker should be controlling the document.
1832         // Since we did not yet create the document, we register a temporary service worker client instead.
1833         registerTemporaryServiceWorkerClient(mainResourceRequest.resourceRequest().url());
1834     }
1835 #endif
1836
1837     m_mainResource = m_cachedResourceLoader->requestMainResource(WTFMove(mainResourceRequest)).value_or(nullptr);
1838
1839     if (!m_mainResource) {
1840         // The frame may have gone away if this load was cancelled synchronously and this was the last pending load.
1841         // This is because we may have fired the load event in a parent frame.
1842         if (!m_frame)
1843             return;
1844
1845         if (!m_request.url().isValid()) {
1846             RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Unable to load main resource, URL is invalid (frame = %p, main = %d)", m_frame, m_frame->isMainFrame());
1847             cancelMainResourceLoad(frameLoader()->client().cannotShowURLError(m_request));
1848             return;
1849         }
1850
1851         RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Unable to load main resource, returning empty document (frame = %p, main = %d)", m_frame, m_frame->isMainFrame());
1852
1853         setRequest(ResourceRequest());
1854         // If the load was aborted by clearing m_request, it's possible the ApplicationCacheHost
1855         // is now in a state where starting an empty load will be inconsistent. Replace it with
1856         // a new ApplicationCacheHost.
1857         m_applicationCacheHost = std::make_unique<ApplicationCacheHost>(*this);
1858         maybeLoadEmpty();
1859         return;
1860     }
1861
1862     ASSERT(m_frame);
1863
1864 #if ENABLE(CONTENT_EXTENSIONS)
1865     if (m_mainResource->errorOccurred() && m_frame->page() && m_mainResource->resourceError().domain() == ContentExtensions::WebKitContentBlockerDomain) {
1866         RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Blocked by content blocker error (frame = %p, main = %d)", m_frame, m_frame->isMainFrame());
1867         cancelMainResourceLoad(frameLoader()->blockedByContentBlockerError(m_request));
1868         return;
1869     }
1870 #endif
1871
1872     if (!mainResourceLoader()) {
1873         m_identifierForLoadWithoutResourceLoader = m_frame->page()->progress().createUniqueIdentifier();
1874         frameLoader()->notifier().assignIdentifierToInitialRequest(m_identifierForLoadWithoutResourceLoader, this, mainResourceRequest.resourceRequest());
1875         frameLoader()->notifier().dispatchWillSendRequest(this, m_identifierForLoadWithoutResourceLoader, mainResourceRequest.resourceRequest(), ResourceResponse());
1876     }
1877
1878     becomeMainResourceClient();
1879
1880     // A bunch of headers are set when the underlying ResourceLoader is created, and m_request needs to include those.
1881     ResourceRequest updatedRequest = mainResourceLoader() ? mainResourceLoader()->originalRequest() : mainResourceRequest.resourceRequest();
1882     // If there was a fragment identifier on m_request, the cache will have stripped it. m_request should include
1883     // the fragment identifier, so add that back in.
1884     if (equalIgnoringFragmentIdentifier(m_request.url(), updatedRequest.url()))
1885         updatedRequest.setURL(m_request.url());
1886     setRequest(updatedRequest);
1887 }
1888
1889 void DocumentLoader::cancelPolicyCheckIfNeeded()
1890 {
1891     if (m_waitingForContentPolicy || m_waitingForNavigationPolicy) {
1892         RELEASE_ASSERT(frameLoader());
1893         frameLoader()->policyChecker().stopCheck();
1894         m_waitingForContentPolicy = false;
1895         m_waitingForNavigationPolicy = false;
1896     }
1897 }
1898
1899 void DocumentLoader::cancelMainResourceLoad(const ResourceError& resourceError)
1900 {
1901     Ref<DocumentLoader> protectedThis(*this);
1902     ResourceError error = resourceError.isNull() ? frameLoader()->cancelledError(m_request) : resourceError;
1903
1904     m_dataLoadTimer.stop();
1905
1906     cancelPolicyCheckIfNeeded();
1907
1908     if (mainResourceLoader())
1909         mainResourceLoader()->cancel(error);
1910
1911     clearMainResource();
1912
1913     mainReceivedError(error);
1914 }
1915
1916 void DocumentLoader::willContinueMainResourceLoadAfterRedirect(const ResourceRequest& newRequest)
1917 {
1918     setRequest(newRequest);
1919 }
1920
1921 void DocumentLoader::clearMainResource()
1922 {
1923     ASSERT(isMainThread());
1924     if (m_mainResource && m_mainResource->hasClient(*this))
1925         m_mainResource->removeClient(*this);
1926 #if ENABLE(CONTENT_FILTERING)
1927     if (m_contentFilter)
1928         m_contentFilter->stopFilteringMainResource();
1929 #endif
1930
1931     m_mainResource = nullptr;
1932
1933     unregisterTemporaryServiceWorkerClient();
1934 }
1935
1936 void DocumentLoader::subresourceLoaderFinishedLoadingOnePart(ResourceLoader* loader)
1937 {
1938     unsigned long identifier = loader->identifier();
1939     ASSERT(identifier);
1940
1941     if (!m_multipartSubresourceLoaders.add(identifier, loader).isNewEntry) {
1942         ASSERT(m_multipartSubresourceLoaders.get(identifier) == loader);
1943         ASSERT(!m_subresourceLoaders.contains(identifier));
1944     } else {
1945         ASSERT(m_subresourceLoaders.contains(identifier));
1946         m_subresourceLoaders.remove(identifier);
1947     }
1948
1949     checkLoadComplete();
1950     if (Frame* frame = m_frame)
1951         frame->loader().checkLoadComplete();    
1952 }
1953
1954 void DocumentLoader::maybeFinishLoadingMultipartContent()
1955 {
1956     if (!isMultipartReplacingLoad())
1957         return;
1958
1959     frameLoader()->setupForReplace();
1960     m_committed = false;
1961     RefPtr<SharedBuffer> resourceData = mainResourceData();
1962     commitLoad(resourceData->data(), resourceData->size());
1963 }
1964
1965 void DocumentLoader::startIconLoading()
1966 {
1967     static uint64_t nextIconCallbackID = 1;
1968
1969     auto* document = this->document();
1970     if (!document)
1971         return;
1972
1973     if (!m_frame->isMainFrame())
1974         return;
1975
1976     if (document->url().isEmpty() || document->url().protocolIsAbout())
1977         return;
1978
1979     m_linkIcons = LinkIconCollector { *document }.iconsOfTypes({ LinkIconType::Favicon, LinkIconType::TouchIcon, LinkIconType::TouchPrecomposedIcon });
1980
1981     auto findResult = m_linkIcons.findMatching([](auto& icon) { return icon.type == LinkIconType::Favicon; });
1982     if (findResult == notFound)
1983         m_linkIcons.append({ document->completeURL("/favicon.ico"_s), LinkIconType::Favicon, String(), std::nullopt, { } });
1984
1985     if (!m_linkIcons.size())
1986         return;
1987
1988     Vector<std::pair<WebCore::LinkIcon&, uint64_t>> iconDecisions;
1989     iconDecisions.reserveInitialCapacity(m_linkIcons.size());
1990     for (auto& icon : m_linkIcons) {
1991         auto result = m_iconsPendingLoadDecision.add(nextIconCallbackID++, icon);
1992         iconDecisions.uncheckedAppend({ icon, result.iterator->key });
1993     }
1994
1995     m_frame->loader().client().getLoadDecisionForIcons(iconDecisions);
1996 }
1997
1998 void DocumentLoader::didGetLoadDecisionForIcon(bool decision, uint64_t loadIdentifier, uint64_t newCallbackID)
1999 {
2000     auto icon = m_iconsPendingLoadDecision.take(loadIdentifier);
2001
2002     // If the decision was not to load or this DocumentLoader is already detached, there is no load to perform.
2003     if (!decision || !m_frame)
2004         return;
2005
2006     // If the LinkIcon we just took is empty, then the DocumentLoader had all of its loaders stopped
2007     // while this icon load decision was pending.
2008     // In this case we need to notify the client that the icon finished loading with empty data.
2009     if (icon.url.isEmpty()) {
2010         notifyFinishedLoadingIcon(newCallbackID, nullptr);
2011         return;
2012     }
2013
2014     auto iconLoader = std::make_unique<IconLoader>(*this, icon.url);
2015     auto* rawIconLoader = iconLoader.get();
2016     m_iconLoaders.set(WTFMove(iconLoader), newCallbackID);
2017
2018     rawIconLoader->startLoading();
2019 }
2020
2021 void DocumentLoader::finishedLoadingIcon(IconLoader& loader, SharedBuffer* buffer)
2022 {
2023     // If the DocumentLoader has detached from its frame, all icon loads should have already been cancelled.
2024     ASSERT(m_frame);
2025
2026     auto callbackIdentifier = m_iconLoaders.take(&loader);
2027     notifyFinishedLoadingIcon(callbackIdentifier, buffer);
2028 }
2029
2030 void DocumentLoader::notifyFinishedLoadingIcon(uint64_t callbackIdentifier, SharedBuffer* buffer)
2031 {
2032     RELEASE_ASSERT(callbackIdentifier);
2033     RELEASE_ASSERT(m_frame);
2034     m_frame->loader().client().finishedLoadingIcon(callbackIdentifier, buffer);
2035 }
2036
2037 void DocumentLoader::dispatchOnloadEvents()
2038 {
2039     m_wasOnloadDispatched = true;
2040     m_applicationCacheHost->stopDeferringEvents();
2041 }
2042
2043 void DocumentLoader::setTriggeringAction(NavigationAction&& action)
2044 {
2045     m_triggeringAction = WTFMove(action);
2046     m_triggeringAction.setShouldOpenExternalURLsPolicy(m_frame ? shouldOpenExternalURLsPolicyToPropagate() : m_shouldOpenExternalURLsPolicy);
2047 }
2048
2049 ShouldOpenExternalURLsPolicy DocumentLoader::shouldOpenExternalURLsPolicyToPropagate() const
2050 {
2051     if (!m_frame || !m_frame->isMainFrame())
2052         return ShouldOpenExternalURLsPolicy::ShouldNotAllow;
2053
2054     return m_shouldOpenExternalURLsPolicy;
2055 }
2056
2057 void DocumentLoader::becomeMainResourceClient()
2058 {
2059 #if ENABLE(CONTENT_FILTERING)
2060     if (m_contentFilter)
2061         m_contentFilter->startFilteringMainResource(*m_mainResource);
2062 #endif
2063     m_mainResource->addClient(*this);
2064 }
2065
2066 #if ENABLE(CONTENT_EXTENSIONS)
2067 void DocumentLoader::addPendingContentExtensionSheet(const String& identifier, StyleSheetContents& sheet)
2068 {
2069     ASSERT(!m_gotFirstByte);
2070     m_pendingNamedContentExtensionStyleSheets.set(identifier, &sheet);
2071 }
2072
2073 void DocumentLoader::addPendingContentExtensionDisplayNoneSelector(const String& identifier, const String& selector, uint32_t selectorID)
2074 {
2075     ASSERT(!m_gotFirstByte);
2076     auto addResult = m_pendingContentExtensionDisplayNoneSelectors.add(identifier, Vector<std::pair<String, uint32_t>>());
2077     addResult.iterator->value.append(std::make_pair(selector, selectorID));
2078 }
2079 #endif
2080
2081 bool DocumentLoader::isAlwaysOnLoggingAllowed() const
2082 {
2083     return !m_frame || m_frame->isAlwaysOnLoggingAllowed();
2084 }
2085
2086 #if USE(QUICK_LOOK)
2087
2088 void DocumentLoader::setPreviewConverter(std::unique_ptr<PreviewConverter>&& previewConverter)
2089 {
2090     m_previewConverter = WTFMove(previewConverter);
2091 }
2092
2093 PreviewConverter* DocumentLoader::previewConverter() const
2094 {
2095     return m_previewConverter.get();
2096 }
2097
2098 #endif
2099
2100 void DocumentLoader::addConsoleMessage(MessageSource messageSource, MessageLevel messageLevel, const String& message, unsigned long requestIdentifier)
2101 {
2102     static_cast<ScriptExecutionContext*>(m_frame->document())->addConsoleMessage(messageSource, messageLevel, message, requestIdentifier);
2103 }
2104
2105 void DocumentLoader::sendCSPViolationReport(URL&& reportURL, Ref<FormData>&& report)
2106 {
2107     PingLoader::sendViolationReport(*m_frame, WTFMove(reportURL), WTFMove(report), ViolationReportType::ContentSecurityPolicy);
2108 }
2109
2110 void DocumentLoader::enqueueSecurityPolicyViolationEvent(SecurityPolicyViolationEvent::Init&& eventInit)
2111 {
2112     m_frame->document()->enqueueSecurityPolicyViolationEvent(WTFMove(eventInit));
2113 }
2114
2115 } // namespace WebCore