fdcebe8ef550b1b013c79ae2e12eaece0f2e9cc3
[WebKit-https.git] / Source / WebCore / loader / DocumentLoader.cpp
1 /*
2  * Copyright (C) 2006, 2007, 2008 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 "ArchiveResourceCollection.h"
35 #include "CachedPage.h"
36 #include "CachedRawResource.h"
37 #include "CachedResourceLoader.h"
38 #include "DOMWindow.h"
39 #include "Document.h"
40 #include "DocumentParser.h"
41 #include "DocumentWriter.h"
42 #include "Event.h"
43 #include "FormState.h"
44 #include "FrameLoader.h"
45 #include "FrameLoaderClient.h"
46 #include "FrameTree.h"
47 #include "HTMLFormElement.h"
48 #include "HTMLFrameOwnerElement.h"
49 #include "HTTPHeaderNames.h"
50 #include "HistoryItem.h"
51 #include "IconController.h"
52 #include "InspectorInstrumentation.h"
53 #include "Logging.h"
54 #include "MainFrame.h"
55 #include "MemoryCache.h"
56 #include "Page.h"
57 #include "PolicyChecker.h"
58 #include "ProgressTracker.h"
59 #include "ResourceHandle.h"
60 #include "SchemeRegistry.h"
61 #include "ScriptController.h"
62 #include "SecurityPolicy.h"
63 #include "Settings.h"
64 #include "SubresourceLoader.h"
65 #include "TextResourceDecoder.h"
66 #include <wtf/Assertions.h>
67 #include <wtf/NeverDestroyed.h>
68 #include <wtf/Ref.h>
69 #include <wtf/text/CString.h>
70 #include <wtf/text/WTFString.h>
71
72 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
73 #include "ArchiveFactory.h"
74 #endif
75
76 #if ENABLE(CONTENT_FILTERING)
77 #include "ContentFilter.h"
78 #endif
79
80 namespace WebCore {
81
82 static void cancelAll(const ResourceLoaderMap& loaders)
83 {
84     Vector<RefPtr<ResourceLoader>> loadersCopy;
85     copyValuesToVector(loaders, loadersCopy);
86     for (auto& loader : loadersCopy)
87         loader->cancel();
88 }
89
90 static void setAllDefersLoading(const ResourceLoaderMap& loaders, bool defers)
91 {
92     Vector<RefPtr<ResourceLoader>> loadersCopy;
93     copyValuesToVector(loaders, loadersCopy);
94     for (auto& loader : loadersCopy)
95         loader->setDefersLoading(defers);
96 }
97
98 static bool areAllLoadersPageCacheAcceptable(const ResourceLoaderMap& loaders)
99 {
100     Vector<RefPtr<ResourceLoader>> loadersCopy;
101     copyValuesToVector(loaders, loadersCopy);
102     for (auto& loader : loadersCopy) {
103         if (!loader->frameLoader())
104             return false;
105
106         CachedResource* cachedResource = MemoryCache::singleton().resourceForRequest(loader->request(), loader->frameLoader()->frame().page()->sessionID());
107         if (!cachedResource)
108             return false;
109
110         // Only image and XHR loads do prevent the page from entering the PageCache.
111         // All non-image loads will prevent the page from entering the PageCache.
112         if (!cachedResource->isImage() && !cachedResource->areAllClientsXMLHttpRequests())
113             return false;
114     }
115     return true;
116 }
117
118 DocumentLoader::DocumentLoader(const ResourceRequest& req, const SubstituteData& substituteData)
119     : m_deferMainResourceDataLoad(true)
120     , m_frame(0)
121     , m_cachedResourceLoader(CachedResourceLoader::create(this))
122     , m_writer(m_frame)
123     , m_originalRequest(req)
124     , m_substituteData(substituteData)
125     , m_originalRequestCopy(req)
126     , m_request(req)
127     , m_originalSubstituteDataWasValid(substituteData.isValid())
128     , m_committed(false)
129     , m_isStopping(false)
130     , m_gotFirstByte(false)
131     , m_isClientRedirect(false)
132     , m_isLoadingMultipartContent(false)
133     , m_wasOnloadHandled(false)
134     , m_stopRecordingResponses(false)
135     , m_substituteResourceDeliveryTimer(*this, &DocumentLoader::substituteResourceDeliveryTimerFired)
136     , m_didCreateGlobalHistoryEntry(false)
137     , m_loadingMainResource(false)
138     , m_timeOfLastDataReceived(0.0)
139     , m_identifierForLoadWithoutResourceLoader(0)
140     , m_dataLoadTimer(*this, &DocumentLoader::handleSubstituteDataLoadNow)
141     , m_waitingForContentPolicy(false)
142     , m_subresourceLoadersArePageCacheAcceptable(false)
143     , m_applicationCacheHost(std::make_unique<ApplicationCacheHost>(*this))
144 #if ENABLE(CONTENT_FILTERING)
145     , m_contentFilter(!substituteData.isValid() ? ContentFilter::createIfNeeded(std::bind(&DocumentLoader::contentFilterDidDecide, this)) : nullptr)
146 #endif
147 {
148 }
149
150 FrameLoader* DocumentLoader::frameLoader() const
151 {
152     if (!m_frame)
153         return 0;
154     return &m_frame->loader();
155 }
156
157 ResourceLoader* DocumentLoader::mainResourceLoader() const
158 {
159     return m_mainResource ? m_mainResource->loader() : 0;
160 }
161
162 DocumentLoader::~DocumentLoader()
163 {
164     ASSERT(!m_frame || frameLoader()->activeDocumentLoader() != this || !isLoading());
165     ASSERT_WITH_MESSAGE(!m_waitingForContentPolicy, "The content policy callback should never outlive its DocumentLoader.");
166     if (m_iconLoadDecisionCallback)
167         m_iconLoadDecisionCallback->invalidate();
168     if (m_iconDataCallback)
169         m_iconDataCallback->invalidate();
170     m_cachedResourceLoader->clearDocumentLoader();
171     
172     clearMainResource();
173 }
174
175 PassRefPtr<SharedBuffer> DocumentLoader::mainResourceData() const
176 {
177     if (m_substituteData.isValid())
178         return m_substituteData.content()->copy();
179     if (m_mainResource)
180         return m_mainResource->resourceBuffer();
181     return nullptr;
182 }
183
184 Document* DocumentLoader::document() const
185 {
186     if (m_frame && m_frame->loader().documentLoader() == this)
187         return m_frame->document();
188     return nullptr;
189 }
190
191 const ResourceRequest& DocumentLoader::originalRequest() const
192 {
193     return m_originalRequest;
194 }
195
196 const ResourceRequest& DocumentLoader::originalRequestCopy() const
197 {
198     return m_originalRequestCopy;
199 }
200
201 const ResourceRequest& DocumentLoader::request() const
202 {
203     return m_request;
204 }
205
206 ResourceRequest& DocumentLoader::request()
207 {
208     return m_request;
209 }
210
211 const URL& DocumentLoader::url() const
212 {
213     return request().url();
214 }
215
216 void DocumentLoader::replaceRequestURLForSameDocumentNavigation(const URL& url)
217 {
218     m_originalRequestCopy.setURL(url);
219     m_request.setURL(url);
220 }
221
222 void DocumentLoader::setRequest(const ResourceRequest& req)
223 {
224     // Replacing an unreachable URL with alternate content looks like a server-side
225     // redirect at this point, but we can replace a committed dataSource.
226     bool handlingUnreachableURL = false;
227
228     handlingUnreachableURL = m_substituteData.isValid() && !m_substituteData.failingURL().isEmpty();
229
230     if (handlingUnreachableURL)
231         m_committed = false;
232
233     // We should never be getting a redirect callback after the data
234     // source is committed, except in the unreachable URL case. It 
235     // would be a WebFoundation bug if it sent a redirect callback after commit.
236     ASSERT(!m_committed);
237
238     m_request = req;
239 }
240
241 void DocumentLoader::setMainDocumentError(const ResourceError& error)
242 {
243     m_mainDocumentError = error;    
244     frameLoader()->client().setMainDocumentError(this, error);
245 }
246
247 void DocumentLoader::mainReceivedError(const ResourceError& error)
248 {
249     ASSERT(!error.isNull());
250
251     if (m_identifierForLoadWithoutResourceLoader) {
252         ASSERT(!mainResourceLoader());
253         frameLoader()->client().dispatchDidFailLoading(this, m_identifierForLoadWithoutResourceLoader, error);
254     }
255
256     // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
257     // See <rdar://problem/6304600> for more details.
258 #if !USE(CF)
259     ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading());
260 #endif
261
262     m_applicationCacheHost->failedLoadingMainResource();
263
264     if (!frameLoader())
265         return;
266     setMainDocumentError(error);
267     clearMainResourceLoader();
268     frameLoader()->receivedMainResourceError(error);
269 }
270
271 // Cancels the data source's pending loads.  Conceptually, a data source only loads
272 // one document at a time, but one document may have many related resources. 
273 // stopLoading will stop all loads initiated by the data source, 
274 // but not loads initiated by child frames' data sources -- that's the WebFrame's job.
275 void DocumentLoader::stopLoading()
276 {
277     RefPtr<Frame> protectFrame(m_frame);
278     Ref<DocumentLoader> protectLoader(*this);
279
280     // In some rare cases, calling FrameLoader::stopLoading could cause isLoading() to return false.
281     // (This can happen when there's a single XMLHttpRequest currently loading and stopLoading causes it
282     // to stop loading. Because of this, we need to save it so we don't return early.
283     bool loading = isLoading();
284
285     // We may want to audit the existing subresource loaders when we are on a page which has completed
286     // loading but there are subresource loads during cancellation. This must be done before the
287     // frame->stopLoading() call, which may evict the CachedResources, which we rely on to check
288     // the type of the resource loads.
289     if (loading && m_committed && !mainResourceLoader() && !m_subresourceLoaders.isEmpty())
290         m_subresourceLoadersArePageCacheAcceptable = areAllLoadersPageCacheAcceptable(m_subresourceLoaders);
291
292     if (m_committed) {
293         // Attempt to stop the frame if the document loader is loading, or if it is done loading but
294         // still  parsing. Failure to do so can cause a world leak.
295         Document* doc = m_frame->document();
296         
297         if (loading || doc->parsing())
298             m_frame->loader().stopLoading(UnloadEventPolicyNone);
299     }
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     FrameLoader* frameLoader = DocumentLoader::frameLoader();
327     
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())
332         // The main resource loader already finished loading. Set the cancelled error on the 
333         // document and let the subresourceLoaders 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     // We always need to explicitly cancel the Document's parser when stopping the load.
341     // Otherwise cancelling the parser while starting the next page load might result
342     // in unexpected side effects such as erroneous event dispatch. ( http://webkit.org/b/117112 )
343     if (Document* document = this->document())
344         document->cancelParsing();
345     
346     stopLoadingSubresources();
347     stopLoadingPlugIns();
348     
349     m_isStopping = false;
350 }
351
352 void DocumentLoader::commitIfReady()
353 {
354     if (!m_committed) {
355         m_committed = true;
356         frameLoader()->commitProvisionalLoad();
357     }
358 }
359
360 bool DocumentLoader::isLoading() const
361 {
362     // if (document() && document()->hasActiveParser())
363     //     return true;
364     // FIXME: The above code should be enabled, but it seems to cause
365     // http/tests/security/feed-urls-from-remote.html to timeout on Mac WK1
366     // see http://webkit.org/b/110554 and http://webkit.org/b/110401
367
368     return isLoadingMainResource() || !m_subresourceLoaders.isEmpty() || !m_plugInStreamLoaders.isEmpty();
369 }
370
371 void DocumentLoader::notifyFinished(CachedResource* resource)
372 {
373     ASSERT_UNUSED(resource, m_mainResource == resource);
374     ASSERT(m_mainResource);
375     if (!m_mainResource->errorOccurred() && !m_mainResource->wasCanceled()) {
376         finishedLoading(m_mainResource->loadFinishTime());
377         return;
378     }
379
380     if (m_request.cachePolicy() == ReturnCacheDataDontLoad && !m_mainResource->wasCanceled()) {
381         frameLoader()->retryAfterFailedCacheOnlyMainResourceLoad();
382         return;
383     }
384
385     mainReceivedError(m_mainResource->resourceError());
386 }
387
388 void DocumentLoader::finishedLoading(double finishTime)
389 {
390     // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
391     // See <rdar://problem/6304600> for more details.
392 #if !USE(CF)
393     ASSERT(!m_frame->page()->defersLoading() || InspectorInstrumentation::isDebuggerPaused(m_frame));
394 #endif
395
396     Ref<DocumentLoader> protect(*this);
397
398     if (m_identifierForLoadWithoutResourceLoader) {
399         // A didFinishLoading delegate might try to cancel the load (despite it
400         // being finished). Clear m_identifierForLoadWithoutResourceLoader
401         // before calling dispatchDidFinishLoading so that we don't later try to
402         // cancel the already-finished substitute load.
403         unsigned long identifier = m_identifierForLoadWithoutResourceLoader;
404         m_identifierForLoadWithoutResourceLoader = 0;
405         frameLoader()->notifier().dispatchDidFinishLoading(this, identifier, finishTime);
406     }
407
408     maybeFinishLoadingMultipartContent();
409
410     double responseEndTime = finishTime;
411     if (!responseEndTime)
412         responseEndTime = m_timeOfLastDataReceived;
413     if (!responseEndTime)
414         responseEndTime = monotonicallyIncreasingTime();
415     timing().setResponseEnd(responseEndTime);
416
417     commitIfReady();
418     if (!frameLoader())
419         return;
420
421     if (!maybeCreateArchive()) {
422         // If this is an empty document, it will not have actually been created yet. Commit dummy data so that
423         // DocumentWriter::begin() gets called and creates the Document.
424         if (!m_gotFirstByte)
425             commitData(0, 0);
426         frameLoader()->client().finishedLoading(this);
427     }
428
429     m_writer.end();
430     if (!m_mainDocumentError.isNull())
431         return;
432     clearMainResourceLoader();
433     if (!frameLoader()->stateMachine().creatingInitialEmptyDocument())
434         frameLoader()->checkLoadComplete();
435
436     // If the document specified an application cache manifest, it violates the author's intent if we store it in the memory cache
437     // and deny the appcache the chance to intercept it in the future, so remove from the memory cache.
438     if (m_frame) {
439         if (m_mainResource && m_frame->document()->hasManifest())
440             MemoryCache::singleton().remove(*m_mainResource);
441     }
442     m_applicationCacheHost->finishedLoadingMainResource();
443 }
444
445 bool DocumentLoader::isPostOrRedirectAfterPost(const ResourceRequest& newRequest, const ResourceResponse& redirectResponse)
446 {
447     if (newRequest.httpMethod() == "POST")
448         return true;
449
450     int status = redirectResponse.httpStatusCode();
451     if (((status >= 301 && status <= 303) || status == 307)
452         && m_originalRequest.httpMethod() == "POST")
453         return true;
454
455     return false;
456 }
457
458 void DocumentLoader::handleSubstituteDataLoadNow()
459 {
460     ResourceResponse response = m_substituteData.response();
461     if (response.url().isEmpty())
462         response = ResourceResponse(m_request.url(), m_substituteData.mimeType(), m_substituteData.content()->size(), m_substituteData.textEncoding());
463
464     responseReceived(0, response);
465 }
466
467 void DocumentLoader::startDataLoadTimer()
468 {
469     m_dataLoadTimer.startOneShot(0);
470
471 #if HAVE(RUNLOOP_TIMER)
472     if (SchedulePairHashSet* scheduledPairs = m_frame->page()->scheduledRunLoopPairs())
473         m_dataLoadTimer.schedule(*scheduledPairs);
474 #endif
475 }
476
477 void DocumentLoader::handleSubstituteDataLoadSoon()
478 {
479     if (!m_deferMainResourceDataLoad || frameLoader()->loadsSynchronously())
480         handleSubstituteDataLoadNow();
481     else
482         startDataLoadTimer();
483 }
484
485 void DocumentLoader::redirectReceived(CachedResource* resource, ResourceRequest& request, const ResourceResponse& redirectResponse)
486 {
487     ASSERT_UNUSED(resource, resource == m_mainResource);
488     willSendRequest(request, redirectResponse);
489 }
490
491 void DocumentLoader::willSendRequest(ResourceRequest& newRequest, const ResourceResponse& redirectResponse)
492 {
493     // Note that there are no asserts here as there are for the other callbacks. This is due to the
494     // fact that this "callback" is sent when starting every load, and the state of callback
495     // deferrals plays less of a part in this function in preventing the bad behavior deferring 
496     // callbacks is meant to prevent.
497     ASSERT(!newRequest.isNull());
498
499     if (!frameLoader()->checkIfFormActionAllowedByCSP(newRequest.url())) {
500         cancelMainResourceLoad(frameLoader()->cancelledError(newRequest));
501         return;
502     }
503
504     ASSERT(timing().fetchStart());
505     if (!redirectResponse.isNull()) {
506         // If the redirecting url is not allowed to display content from the target origin,
507         // then block the redirect.
508         Ref<SecurityOrigin> redirectingOrigin(SecurityOrigin::create(redirectResponse.url()));
509         if (!redirectingOrigin.get().canDisplay(newRequest.url())) {
510             FrameLoader::reportLocalLoadFailed(m_frame, newRequest.url().string());
511             cancelMainResourceLoad(frameLoader()->cancelledError(newRequest));
512             return;
513         }
514         timing().addRedirect(redirectResponse.url(), newRequest.url());
515     }
516
517     // Update cookie policy base URL as URL changes, except for subframes, which use the
518     // URL of the main frame which doesn't change when we redirect.
519     if (frameLoader()->frame().isMainFrame())
520         newRequest.setFirstPartyForCookies(newRequest.url());
521
522     // If we're fielding a redirect in response to a POST, force a load from origin, since
523     // this is a common site technique to return to a page viewing some data that the POST
524     // just modified.
525     // Also, POST requests always load from origin, but this does not affect subresources.
526     if (newRequest.cachePolicy() == UseProtocolCachePolicy && isPostOrRedirectAfterPost(newRequest, redirectResponse))
527         newRequest.setCachePolicy(ReloadIgnoringCacheData);
528
529     Frame& topFrame = m_frame->tree().top();
530     if (&topFrame != m_frame) {
531         if (!frameLoader()->mixedContentChecker().canDisplayInsecureContent(topFrame.document()->securityOrigin(), MixedContentChecker::ContentType::Active, newRequest.url())) {
532             cancelMainResourceLoad(frameLoader()->cancelledError(newRequest));
533             return;
534         }
535     }
536
537 #if ENABLE(CONTENT_FILTERING)
538     if (m_contentFilter) {
539         ASSERT(redirectResponse.isNull());
540         m_contentFilter->willSendRequest(newRequest, redirectResponse);
541         if (newRequest.isNull())
542             return;
543     }
544 #endif
545
546     setRequest(newRequest);
547
548     if (!redirectResponse.isNull()) {
549         // We checked application cache for initial URL, now we need to check it for redirected one.
550         ASSERT(!m_substituteData.isValid());
551         m_applicationCacheHost->maybeLoadMainResourceForRedirect(newRequest, m_substituteData);
552         if (m_substituteData.isValid())
553             m_identifierForLoadWithoutResourceLoader = mainResourceLoader()->identifier();
554     }
555
556     // FIXME: Ideally we'd stop the I/O until we hear back from the navigation policy delegate
557     // listener. But there's no way to do that in practice. So instead we cancel later if the
558     // listener tells us to. In practice that means the navigation policy needs to be decided
559     // synchronously for these redirect cases.
560     if (redirectResponse.isNull())
561         return;
562
563     frameLoader()->policyChecker().checkNavigationPolicy(newRequest, [this](const ResourceRequest& request, PassRefPtr<FormState>, bool shouldContinue) {
564         continueAfterNavigationPolicy(request, shouldContinue);
565     });
566 }
567
568 void DocumentLoader::continueAfterNavigationPolicy(const ResourceRequest&, bool shouldContinue)
569 {
570     if (!shouldContinue)
571         stopLoadingForPolicyChange();
572     else if (m_substituteData.isValid()) {
573         // A redirect resulted in loading substitute data.
574         ASSERT(timing().redirectCount());
575
576         // We need to remove our reference to the CachedResource in favor of a SubstituteData load.
577         // This will probably trigger the cancellation of the CachedResource's underlying ResourceLoader, though there is a
578         // small chance that the resource is being loaded by a different Frame, preventing the ResourceLoader from being cancelled.
579         // If the ResourceLoader is indeed cancelled, it would normally send resource load callbacks.
580         // However, from an API perspective, this isn't a cancellation. Therefore, sever our relationship with the network load,
581         // but prevent the ResourceLoader from sending ResourceLoadNotifier callbacks.
582         RefPtr<ResourceLoader> resourceLoader = mainResourceLoader();
583         ASSERT(resourceLoader->shouldSendResourceLoadCallbacks());
584         resourceLoader->setSendCallbackPolicy(DoNotSendCallbacks);
585         clearMainResource();
586         resourceLoader->setSendCallbackPolicy(SendCallbacks);
587         handleSubstituteDataLoadSoon();
588     }
589 }
590
591 void DocumentLoader::responseReceived(CachedResource* resource, const ResourceResponse& response)
592 {
593     ASSERT_UNUSED(resource, m_mainResource == resource);
594     Ref<DocumentLoader> protect(*this);
595     bool willLoadFallback = m_applicationCacheHost->maybeLoadFallbackForMainResponse(request(), response);
596
597     // The memory cache doesn't understand the application cache or its caching rules. So if a main resource is served
598     // from the application cache, ensure we don't save the result for future use.
599     if (willLoadFallback)
600         MemoryCache::singleton().remove(*m_mainResource);
601
602     if (willLoadFallback)
603         return;
604
605     const auto& commonHeaders = response.httpHeaderFields().commonHeaders();
606     auto it = commonHeaders.find(HTTPHeaderName::XFrameOptions);
607     if (it != commonHeaders.end()) {
608         String content = it->value;
609         ASSERT(m_identifierForLoadWithoutResourceLoader || m_mainResource);
610         unsigned long identifier = m_identifierForLoadWithoutResourceLoader ? m_identifierForLoadWithoutResourceLoader : m_mainResource->identifier();
611         ASSERT(identifier);
612         if (frameLoader()->shouldInterruptLoadForXFrameOptions(content, response.url(), identifier)) {
613             InspectorInstrumentation::continueAfterXFrameOptionsDenied(m_frame, *this, identifier, response);
614             String message = "Refused to display '" + response.url().stringCenterEllipsizedToLength() + "' in a frame because it set 'X-Frame-Options' to '" + content + "'.";
615             frame()->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message, identifier);
616             frame()->document()->enforceSandboxFlags(SandboxOrigin);
617             if (HTMLFrameOwnerElement* ownerElement = frame()->ownerElement())
618                 ownerElement->dispatchEvent(Event::create(eventNames().loadEvent, false, false));
619
620             // The load event might have detached this frame. In that case, the load will already have been cancelled during detach.
621             if (frameLoader())
622                 cancelMainResourceLoad(frameLoader()->cancelledError(m_request));
623             return;
624         }
625     }
626
627     // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
628     // See <rdar://problem/6304600> for more details.
629 #if !USE(CF)
630     ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading());
631 #endif
632
633     if (m_isLoadingMultipartContent) {
634         setupForReplace();
635         m_mainResource->clear();
636     } else if (response.isMultipart())
637         m_isLoadingMultipartContent = true;
638
639     m_response = response;
640
641     if (m_identifierForLoadWithoutResourceLoader) {
642         addResponse(m_response);
643         frameLoader()->notifier().dispatchDidReceiveResponse(this, m_identifierForLoadWithoutResourceLoader, m_response, 0);
644     }
645
646     ASSERT(!m_waitingForContentPolicy);
647     m_waitingForContentPolicy = true;
648
649     // Always show content with valid substitute data.
650     if (m_substituteData.isValid()) {
651         continueAfterContentPolicy(PolicyUse);
652         return;
653     }
654
655 #if ENABLE(FTPDIR)
656     // Respect the hidden FTP Directory Listing pref so it can be tested even if the policy delegate might otherwise disallow it
657     if (m_frame->settings().forceFTPDirectoryListings() && m_response.mimeType() == "application/x-ftp-directory") {
658         continueAfterContentPolicy(PolicyUse);
659         return;
660     }
661 #endif
662
663     frameLoader()->policyChecker().checkContentPolicy(m_response, [this](PolicyAction policy) {
664         continueAfterContentPolicy(policy);
665     });
666 }
667
668 void DocumentLoader::continueAfterContentPolicy(PolicyAction policy)
669 {
670     ASSERT(m_waitingForContentPolicy);
671     m_waitingForContentPolicy = false;
672     if (isStopping())
673         return;
674
675     URL url = m_request.url();
676     const String& mimeType = m_response.mimeType();
677     
678     switch (policy) {
679     case PolicyUse: {
680         // Prevent remote web archives from loading because they can claim to be from any domain and thus avoid cross-domain security checks (4120255).
681         bool isRemoteWebArchive = (equalIgnoringCase("application/x-webarchive", mimeType)
682             || equalIgnoringCase("application/x-mimearchive", mimeType)
683 #if PLATFORM(GTK)
684             || equalIgnoringCase("message/rfc822", mimeType)
685 #endif
686             || equalIgnoringCase("multipart/related", mimeType))
687             && !m_substituteData.isValid() && !SchemeRegistry::shouldTreatURLSchemeAsLocal(url.protocol());
688         if (!frameLoader()->client().canShowMIMEType(mimeType) || isRemoteWebArchive) {
689             frameLoader()->policyChecker().cannotShowMIMEType(m_response);
690             // Check reachedTerminalState since the load may have already been canceled inside of _handleUnimplementablePolicyWithErrorCode::.
691             stopLoadingForPolicyChange();
692             return;
693         }
694         break;
695     }
696
697     case PolicyDownload: {
698         // m_mainResource can be null, e.g. when loading a substitute resource from application cache.
699         if (!m_mainResource) {
700             mainReceivedError(frameLoader()->client().cannotShowURLError(m_request));
701             return;
702         }
703
704         if (ResourceLoader* mainResourceLoader = this->mainResourceLoader())
705             InspectorInstrumentation::continueWithPolicyDownload(m_frame, *this, mainResourceLoader->identifier(), m_response);
706
707         // 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.
708         // Download may use this knowledge for purposes unrelated to cookies, notably for setting file quarantine data.
709         frameLoader()->setOriginalURLForDownloadRequest(m_request);
710         frameLoader()->client().convertMainResourceLoadToDownload(this, m_request, m_response);
711
712         // It might have gone missing
713         if (mainResourceLoader())
714             mainResourceLoader()->didFail(interruptedForPolicyChangeError());
715         return;
716     }
717     case PolicyIgnore:
718         if (ResourceLoader* mainResourceLoader = this->mainResourceLoader())
719             InspectorInstrumentation::continueWithPolicyIgnore(m_frame, *this, mainResourceLoader->identifier(), m_response);
720         stopLoadingForPolicyChange();
721         return;
722     
723     default:
724         ASSERT_NOT_REACHED();
725     }
726
727     if (m_response.isHTTP()) {
728         int status = m_response.httpStatusCode(); // Status may be zero when loading substitute data, in particular from a WebArchive.
729         if (status && (status < 200 || status >= 300)) {
730             bool hostedByObject = frameLoader()->isHostedByObjectElement();
731
732             frameLoader()->handleFallbackContent();
733             // object elements are no longer rendered after we fallback, so don't
734             // keep trying to process data from their load
735
736             if (hostedByObject)
737                 cancelMainResourceLoad(frameLoader()->cancelledError(m_request));
738         }
739     }
740
741     if (!isStopping() && m_substituteData.isValid() && isLoadingMainResource()) {
742         if (m_substituteData.content()->size())
743             dataReceived(0, m_substituteData.content()->data(), m_substituteData.content()->size());
744         if (isLoadingMainResource())
745             finishedLoading(0);
746     }
747 }
748
749 void DocumentLoader::commitLoad(const char* data, int length)
750 {
751     // Both unloading the old page and parsing the new page may execute JavaScript which destroys the datasource
752     // by starting a new load, so retain temporarily.
753     RefPtr<Frame> protectFrame(m_frame);
754     Ref<DocumentLoader> protectLoader(*this);
755
756     commitIfReady();
757     FrameLoader* frameLoader = DocumentLoader::frameLoader();
758     if (!frameLoader)
759         return;
760 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
761     if (ArchiveFactory::isArchiveMimeType(response().mimeType()))
762         return;
763 #endif
764     frameLoader->client().committedLoad(this, data, length);
765
766     if (isMultipartReplacingLoad())
767         frameLoader->client().didReplaceMultipartContent();
768 }
769
770 ResourceError DocumentLoader::interruptedForPolicyChangeError() const
771 {
772     return frameLoader()->client().interruptedForPolicyChangeError(request());
773 }
774
775 void DocumentLoader::stopLoadingForPolicyChange()
776 {
777     ResourceError error = interruptedForPolicyChangeError();
778     error.setIsCancellation(true);
779     cancelMainResourceLoad(error);
780 }
781
782 void DocumentLoader::commitData(const char* bytes, size_t length)
783 {
784     if (!m_gotFirstByte) {
785         m_gotFirstByte = true;
786         m_writer.begin(documentURL(), false);
787         m_writer.setDocumentWasLoadedAsPartOfNavigation();
788
789         if (SecurityPolicy::allowSubstituteDataAccessToLocal() && m_originalSubstituteDataWasValid) {
790             // If this document was loaded with substituteData, then the document can
791             // load local resources. See https://bugs.webkit.org/show_bug.cgi?id=16756
792             // and https://bugs.webkit.org/show_bug.cgi?id=19760 for further
793             // discussion.
794             m_frame->document()->securityOrigin()->grantLoadLocalResources();
795         }
796
797         if (frameLoader()->stateMachine().creatingInitialEmptyDocument())
798             return;
799         
800 #if ENABLE(MHTML)
801         // The origin is the MHTML file, we need to set the base URL to the document encoded in the MHTML so
802         // relative URLs are resolved properly.
803         if (m_archive && m_archive->type() == Archive::MHTML)
804             m_frame->document()->setBaseURLOverride(m_archive->mainResource()->url());
805 #endif
806
807         // Call receivedFirstData() exactly once per load. We should only reach this point multiple times
808         // for multipart loads, and FrameLoader::isReplacing() will be true after the first time.
809         if (!isMultipartReplacingLoad())
810             frameLoader()->receivedFirstData();
811
812         // The load could be canceled under receivedFirstData(), which makes delegate calls and even sometimes dispatches DOM events.
813         if (!isLoading())
814             return;
815
816         bool userChosen;
817         String encoding;
818         if (overrideEncoding().isNull()) {
819             userChosen = false;
820             encoding = response().textEncodingName();
821 #if ENABLE(WEB_ARCHIVE)
822             if (m_archive && m_archive->type() == Archive::WebArchive)
823                 encoding = m_archive->mainResource()->textEncoding();
824 #endif
825         } else {
826             userChosen = true;
827             encoding = overrideEncoding();
828         }
829
830         m_writer.setEncoding(encoding, userChosen);
831     }
832
833 #if ENABLE(CONTENT_EXTENSIONS)
834     DocumentStyleSheetCollection& styleSheetCollection = m_frame->document()->styleSheetCollection();
835
836     for (auto& pendingStyleSheet : m_pendingNamedContentExtensionStyleSheets)
837         styleSheetCollection.maybeAddContentExtensionSheet(pendingStyleSheet.key, *pendingStyleSheet.value);
838     for (auto& pendingSelector : m_pendingContentExtensionDisplayNoneSelectors)
839         styleSheetCollection.addDisplayNoneSelector(pendingSelector.key, pendingSelector.value.first, pendingSelector.value.second);
840
841     m_pendingNamedContentExtensionStyleSheets.clear();
842     m_pendingContentExtensionDisplayNoneSelectors.clear();
843 #endif
844
845     ASSERT(m_frame->document()->parsing());
846     m_writer.addData(bytes, length);
847 }
848
849 void DocumentLoader::dataReceived(CachedResource* resource, const char* data, int length)
850 {
851     ASSERT(data);
852     ASSERT(length);
853     ASSERT_UNUSED(resource, resource == m_mainResource);
854     ASSERT(!m_response.isNull());
855
856     // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
857     // See <rdar://problem/6304600> for more details.
858 #if !USE(CF)
859     ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading());
860 #endif
861
862     if (m_identifierForLoadWithoutResourceLoader)
863         frameLoader()->notifier().dispatchDidReceiveData(this, m_identifierForLoadWithoutResourceLoader, data, length, -1);
864
865     m_applicationCacheHost->mainResourceDataReceived(data, length, -1, false);
866     m_timeOfLastDataReceived = monotonicallyIncreasingTime();
867
868     if (!isMultipartReplacingLoad())
869         commitLoad(data, length);
870 }
871
872 void DocumentLoader::setupForReplace()
873 {
874     if (!mainResourceData())
875         return;
876
877     frameLoader()->client().willReplaceMultipartContent();
878     
879     maybeFinishLoadingMultipartContent();
880     maybeCreateArchive();
881     m_writer.end();
882     frameLoader()->setReplacing();
883     m_gotFirstByte = false;
884     
885     stopLoadingSubresources();
886     stopLoadingPlugIns();
887 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
888     clearArchiveResources();
889 #endif
890 }
891
892 void DocumentLoader::checkLoadComplete()
893 {
894     if (!m_frame || isLoading())
895         return;
896
897     ASSERT(this == frameLoader()->activeDocumentLoader());
898     m_frame->document()->domWindow()->finishedLoading();
899 }
900
901 void DocumentLoader::setFrame(Frame* frame)
902 {
903     if (m_frame == frame)
904         return;
905     ASSERT(frame && !m_frame);
906     m_frame = frame;
907     m_writer.setFrame(frame);
908     attachToFrame();
909 }
910
911 void DocumentLoader::attachToFrame()
912 {
913     ASSERT(m_frame);
914 }
915
916 void DocumentLoader::detachFromFrame()
917 {
918     ASSERT(m_frame);
919     RefPtr<Frame> protectFrame(m_frame);
920     Ref<DocumentLoader> protectLoader(*this);
921
922     // It never makes sense to have a document loader that is detached from its
923     // frame have any loads active, so kill all the loads.
924     stopLoading();
925     if (m_mainResource && m_mainResource->hasClient(this))
926         m_mainResource->removeClient(this);
927 #if ENABLE(CONTENT_FILTERING)
928     m_contentFilter = nullptr;
929 #endif
930
931     m_applicationCacheHost->setDOMApplicationCache(nullptr);
932     InspectorInstrumentation::loaderDetachedFromFrame(*m_frame, *this);
933     m_frame = nullptr;
934     // The call to stopLoading() above should have canceled any pending content policy check.
935     ASSERT_WITH_MESSAGE(!m_waitingForContentPolicy, "The content policy callback needs a valid frame.");
936 }
937
938 void DocumentLoader::clearMainResourceLoader()
939 {
940     m_loadingMainResource = false;
941
942     if (this == frameLoader()->activeDocumentLoader())
943         checkLoadComplete();
944 }
945
946 bool DocumentLoader::isLoadingInAPISense() const
947 {
948     // Once a frame has loaded, we no longer need to consider subresources,
949     // but we still need to consider subframes.
950     if (frameLoader()->state() != FrameStateComplete) {
951         if (m_frame->settings().needsIsLoadingInAPISenseQuirk() && !m_subresourceLoaders.isEmpty())
952             return true;
953     
954         Document* doc = m_frame->document();
955         if ((isLoadingMainResource() || !m_frame->document()->loadEventFinished()) && isLoading())
956             return true;
957         if (m_cachedResourceLoader->requestCount())
958             return true;
959         if (doc->processingLoadEvent())
960             return true;
961         if (doc->hasActiveParser())
962             return true;
963     }
964     return frameLoader()->subframeIsLoading();
965 }
966
967 bool DocumentLoader::maybeCreateArchive()
968 {
969 #if !ENABLE(WEB_ARCHIVE) && !ENABLE(MHTML)
970     return false;
971 #else
972     
973     // Give the archive machinery a crack at this document. If the MIME type is not an archive type, it will return 0.
974     m_archive = ArchiveFactory::create(m_response.url(), mainResourceData().get(), m_response.mimeType());
975     if (!m_archive)
976         return false;
977     
978     addAllArchiveResources(m_archive.get());
979     ArchiveResource* mainResource = m_archive->mainResource();
980     m_parsedArchiveData = mainResource->data();
981     m_writer.setMIMEType(mainResource->mimeType());
982     
983     ASSERT(m_frame->document());
984     commitData(mainResource->data()->data(), mainResource->data()->size());
985     return true;
986 #endif // !ENABLE(WEB_ARCHIVE) && !ENABLE(MHTML)
987 }
988
989 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
990
991 void DocumentLoader::setArchive(PassRefPtr<Archive> archive)
992 {
993     m_archive = archive;
994     addAllArchiveResources(m_archive.get());
995 }
996
997 void DocumentLoader::addAllArchiveResources(Archive* archive)
998 {
999     if (!m_archiveResourceCollection)
1000         m_archiveResourceCollection = std::make_unique<ArchiveResourceCollection>();
1001         
1002     ASSERT(archive);
1003     if (!archive)
1004         return;
1005         
1006     m_archiveResourceCollection->addAllResources(archive);
1007 }
1008
1009 // FIXME: Adding a resource directly to a DocumentLoader/ArchiveResourceCollection seems like bad design, but is API some apps rely on.
1010 // Can we change the design in a manner that will let us deprecate that API without reducing functionality of those apps?
1011 void DocumentLoader::addArchiveResource(PassRefPtr<ArchiveResource> resource)
1012 {
1013     if (!m_archiveResourceCollection)
1014         m_archiveResourceCollection = std::make_unique<ArchiveResourceCollection>();
1015         
1016     ASSERT(resource);
1017     if (!resource)
1018         return;
1019         
1020     m_archiveResourceCollection->addResource(resource);
1021 }
1022
1023 PassRefPtr<Archive> DocumentLoader::popArchiveForSubframe(const String& frameName, const URL& url)
1024 {
1025     return m_archiveResourceCollection ? m_archiveResourceCollection->popSubframeArchive(frameName, url) : PassRefPtr<Archive>(0);
1026 }
1027
1028 void DocumentLoader::clearArchiveResources()
1029 {
1030     m_archiveResourceCollection = nullptr;
1031     m_substituteResourceDeliveryTimer.stop();
1032 }
1033
1034 SharedBuffer* DocumentLoader::parsedArchiveData() const
1035 {
1036     return m_parsedArchiveData.get();
1037 }
1038
1039 #endif // ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
1040
1041 ArchiveResource* DocumentLoader::archiveResourceForURL(const URL& url) const
1042 {
1043     if (!m_archiveResourceCollection)
1044         return nullptr;
1045     ArchiveResource* resource = m_archiveResourceCollection->archiveResourceForURL(url);
1046     if (!resource || resource->shouldIgnoreWhenUnarchiving())
1047         return nullptr;
1048     return resource;
1049 }
1050
1051 PassRefPtr<ArchiveResource> DocumentLoader::mainResource() const
1052 {
1053     RefPtr<SharedBuffer> data = mainResourceData();
1054     if (!data)
1055         data = SharedBuffer::create();
1056         
1057     auto& response = this->response();
1058     return ArchiveResource::create(data, response.url(), response.mimeType(), response.textEncodingName(), frame()->tree().uniqueName());
1059 }
1060
1061 PassRefPtr<ArchiveResource> DocumentLoader::subresource(const URL& url) const
1062 {
1063     if (!isCommitted())
1064         return nullptr;
1065     
1066     CachedResource* resource = m_cachedResourceLoader->cachedResource(url);
1067     if (!resource || !resource->isLoaded())
1068         return archiveResourceForURL(url);
1069
1070     if (resource->type() == CachedResource::MainResource)
1071         return nullptr;
1072
1073     auto* data = resource->resourceBuffer();
1074     if (!data)
1075         return nullptr;
1076
1077     return ArchiveResource::create(data, url, resource->response());
1078 }
1079
1080 Vector<RefPtr<ArchiveResource>> DocumentLoader::subresources() const
1081 {
1082     if (!isCommitted())
1083         return { };
1084
1085     Vector<RefPtr<ArchiveResource>> subresources;
1086
1087     for (auto& cachedResourceHandle : m_cachedResourceLoader->allCachedResources().values()) {
1088         if (RefPtr<ArchiveResource> subresource = this->subresource(URL(ParsedURLString, cachedResourceHandle->url())))
1089             subresources.append(WTF::move(subresource));
1090     }
1091
1092     return subresources;
1093 }
1094
1095 void DocumentLoader::deliverSubstituteResourcesAfterDelay()
1096 {
1097     if (m_pendingSubstituteResources.isEmpty())
1098         return;
1099     ASSERT(m_frame && m_frame->page());
1100     if (m_frame->page()->defersLoading())
1101         return;
1102     if (!m_substituteResourceDeliveryTimer.isActive())
1103         m_substituteResourceDeliveryTimer.startOneShot(0);
1104 }
1105
1106 void DocumentLoader::substituteResourceDeliveryTimerFired()
1107 {
1108     if (m_pendingSubstituteResources.isEmpty())
1109         return;
1110     ASSERT(m_frame && m_frame->page());
1111     if (m_frame->page()->defersLoading())
1112         return;
1113
1114     SubstituteResourceMap copy;
1115     copy.swap(m_pendingSubstituteResources);
1116
1117     SubstituteResourceMap::const_iterator end = copy.end();
1118     for (SubstituteResourceMap::const_iterator it = copy.begin(); it != end; ++it) {
1119         RefPtr<ResourceLoader> loader = it->key;
1120         SubstituteResource* resource = it->value.get();
1121         
1122         if (resource) {
1123             SharedBuffer* data = resource->data();
1124         
1125             loader->didReceiveResponse(resource->response());
1126
1127             // Calling ResourceLoader::didReceiveResponse can end up cancelling the load,
1128             // so we need to check if the loader has reached its terminal state.
1129             if (loader->reachedTerminalState())
1130                 return;
1131
1132             loader->didReceiveData(data->data(), data->size(), data->size(), DataPayloadWholeResource);
1133
1134             // Calling ResourceLoader::didReceiveData can end up cancelling the load,
1135             // so we need to check if the loader has reached its terminal state.
1136             if (loader->reachedTerminalState())
1137                 return;
1138
1139             loader->didFinishLoading(0);
1140         } else {
1141             // A null resource means that we should fail the load.
1142             // FIXME: Maybe we should use another error here - something like "not in cache".
1143             loader->didFail(loader->cannotShowURLError());
1144         }
1145     }
1146 }
1147
1148 #ifndef NDEBUG
1149 bool DocumentLoader::isSubstituteLoadPending(ResourceLoader* loader) const
1150 {
1151     return m_pendingSubstituteResources.contains(loader);
1152 }
1153 #endif
1154
1155 void DocumentLoader::cancelPendingSubstituteLoad(ResourceLoader* loader)
1156 {
1157     if (m_pendingSubstituteResources.isEmpty())
1158         return;
1159     m_pendingSubstituteResources.remove(loader);
1160     if (m_pendingSubstituteResources.isEmpty())
1161         m_substituteResourceDeliveryTimer.stop();
1162 }
1163
1164 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
1165 bool DocumentLoader::scheduleArchiveLoad(ResourceLoader* loader, const ResourceRequest& request)
1166 {
1167     if (ArchiveResource* resource = archiveResourceForURL(request.url())) {
1168         m_pendingSubstituteResources.set(loader, resource);
1169         deliverSubstituteResourcesAfterDelay();
1170         return true;
1171     }
1172
1173     if (!m_archive)
1174         return false;
1175
1176     switch (m_archive->type()) {
1177 #if ENABLE(WEB_ARCHIVE)
1178     case Archive::WebArchive:
1179         // WebArchiveDebugMode means we fail loads instead of trying to fetch them from the network if they're not in the archive.
1180         return m_frame->settings().webArchiveDebugModeEnabled() && ArchiveFactory::isArchiveMimeType(responseMIMEType());
1181 #endif
1182 #if ENABLE(MHTML)
1183     case Archive::MHTML:
1184         return true; // Always fail the load for resources not included in the MHTML.
1185 #endif
1186     default:
1187         return false;
1188     }
1189 }
1190 #endif // ENABLE(WEB_ARCHIVE)
1191
1192 void DocumentLoader::addResponse(const ResourceResponse& r)
1193 {
1194     if (!m_stopRecordingResponses)
1195         m_responses.append(r);
1196 }
1197
1198 void DocumentLoader::stopRecordingResponses()
1199 {
1200     m_stopRecordingResponses = true;
1201     m_responses.shrinkToFit();
1202 }
1203
1204 void DocumentLoader::setTitle(const StringWithDirection& title)
1205 {
1206     if (m_pageTitle == title)
1207         return;
1208
1209     frameLoader()->willChangeTitle(this);
1210     m_pageTitle = title;
1211     frameLoader()->didChangeTitle(this);
1212 }
1213
1214 URL DocumentLoader::urlForHistory() const
1215 {
1216     // Return the URL to be used for history and B/F list.
1217     // Returns nil for WebDataProtocol URLs that aren't alternates
1218     // for unreachable URLs, because these can't be stored in history.
1219     if (m_substituteData.isValid() && !m_substituteData.shouldRevealToSessionHistory())
1220         return unreachableURL();
1221
1222     return m_originalRequestCopy.url();
1223 }
1224
1225 bool DocumentLoader::urlForHistoryReflectsFailure() const
1226 {
1227     return m_substituteData.isValid() || m_response.httpStatusCode() >= 400;
1228 }
1229
1230 const URL& DocumentLoader::originalURL() const
1231 {
1232     return m_originalRequestCopy.url();
1233 }
1234
1235 const URL& DocumentLoader::responseURL() const
1236 {
1237     return m_response.url();
1238 }
1239
1240 URL DocumentLoader::documentURL() const
1241 {
1242     URL url = substituteData().response().url();
1243 #if ENABLE(WEB_ARCHIVE)
1244     if (url.isEmpty() && m_archive && m_archive->type() == Archive::WebArchive)
1245         url = m_archive->mainResource()->url();
1246 #endif
1247     if (url.isEmpty())
1248         url = m_request.url();
1249     if (url.isEmpty())
1250         url = m_response.url();
1251     return url;
1252 }
1253
1254 const String& DocumentLoader::responseMIMEType() const
1255 {
1256     return m_response.mimeType();
1257 }
1258
1259 const String& DocumentLoader::currentContentType() const
1260 {
1261     return m_writer.mimeType();
1262 }
1263
1264 #if PLATFORM(IOS)
1265 // FIXME: This method seems to violate the encapsulation of this class.
1266 void DocumentLoader::setResponseMIMEType(const String& responseMimeType)
1267 {
1268     m_response.setMimeType(responseMimeType);
1269 }
1270 #endif
1271
1272 const URL& DocumentLoader::unreachableURL() const
1273 {
1274     return m_substituteData.failingURL();
1275 }
1276
1277 void DocumentLoader::setDefersLoading(bool defers)
1278 {
1279     // Multiple frames may be loading the same main resource simultaneously. If deferral state changes,
1280     // each frame's DocumentLoader will try to send a setDefersLoading() to the same underlying ResourceLoader. Ensure only
1281     // the "owning" DocumentLoader does so, as setDefersLoading() is not resilient to setting the same value repeatedly.
1282     if (mainResourceLoader() && mainResourceLoader()->documentLoader() == this)
1283         mainResourceLoader()->setDefersLoading(defers);
1284
1285     setAllDefersLoading(m_subresourceLoaders, defers);
1286     setAllDefersLoading(m_plugInStreamLoaders, defers);
1287     if (!defers)
1288         deliverSubstituteResourcesAfterDelay();
1289 }
1290
1291 void DocumentLoader::setMainResourceDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy)
1292 {
1293     if (m_mainResource)
1294         m_mainResource->setDataBufferingPolicy(dataBufferingPolicy);
1295 }
1296
1297 void DocumentLoader::stopLoadingPlugIns()
1298 {
1299     cancelAll(m_plugInStreamLoaders);
1300 }
1301
1302 void DocumentLoader::stopLoadingSubresources()
1303 {
1304     cancelAll(m_subresourceLoaders);
1305     ASSERT(m_subresourceLoaders.isEmpty());
1306 }
1307
1308 void DocumentLoader::addSubresourceLoader(ResourceLoader* loader)
1309 {
1310     // The main resource's underlying ResourceLoader will ask to be added here.
1311     // It is much simpler to handle special casing of main resource loads if we don't
1312     // let it be added. In the main resource load case, mainResourceLoader()
1313     // will still be null at this point, but m_gotFirstByte should be false here if and only
1314     // if we are just starting the main resource load.
1315     if (!m_gotFirstByte)
1316         return;
1317     ASSERT(loader->identifier());
1318     ASSERT(!m_subresourceLoaders.contains(loader->identifier()));
1319     ASSERT(!mainResourceLoader() || mainResourceLoader() != loader);
1320
1321     // A page in the PageCache should not be able to start loads.
1322     ASSERT_WITH_SECURITY_IMPLICATION(!document() || !document()->inPageCache());
1323
1324     m_subresourceLoaders.add(loader->identifier(), loader);
1325 }
1326
1327 void DocumentLoader::removeSubresourceLoader(ResourceLoader* loader)
1328 {
1329     ASSERT(loader->identifier());
1330
1331     if (!m_subresourceLoaders.remove(loader->identifier()))
1332         return;
1333     checkLoadComplete();
1334     if (Frame* frame = m_frame)
1335         frame->loader().checkLoadComplete();
1336 }
1337
1338 void DocumentLoader::addPlugInStreamLoader(ResourceLoader* loader)
1339 {
1340     ASSERT(loader->identifier());
1341     ASSERT(!m_plugInStreamLoaders.contains(loader->identifier()));
1342
1343     m_plugInStreamLoaders.add(loader->identifier(), loader);
1344 }
1345
1346 void DocumentLoader::removePlugInStreamLoader(ResourceLoader* loader)
1347 {
1348     ASSERT(loader->identifier());
1349     ASSERT(loader == m_plugInStreamLoaders.get(loader->identifier()));
1350
1351     m_plugInStreamLoaders.remove(loader->identifier());
1352     checkLoadComplete();
1353 }
1354
1355 bool DocumentLoader::isMultipartReplacingLoad() const
1356 {
1357     return isLoadingMultipartContent() && frameLoader()->isReplacing();
1358 }
1359
1360 bool DocumentLoader::maybeLoadEmpty()
1361 {
1362     bool shouldLoadEmpty = !m_substituteData.isValid() && (m_request.url().isEmpty() || SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(m_request.url().protocol()));
1363     if (!shouldLoadEmpty && !frameLoader()->client().representationExistsForURLScheme(m_request.url().protocol()))
1364         return false;
1365
1366     if (m_request.url().isEmpty() && !frameLoader()->stateMachine().creatingInitialEmptyDocument()) {
1367         m_request.setURL(blankURL());
1368         if (isLoadingMainResource())
1369             frameLoader()->client().dispatchDidChangeProvisionalURL();
1370     }
1371
1372     String mimeType = shouldLoadEmpty ? "text/html" : frameLoader()->client().generatedMIMETypeForURLScheme(m_request.url().protocol());
1373     m_response = ResourceResponse(m_request.url(), mimeType, 0, String());
1374     finishedLoading(monotonicallyIncreasingTime());
1375     return true;
1376 }
1377
1378 void DocumentLoader::startLoadingMainResource()
1379 {
1380     m_mainDocumentError = ResourceError();
1381     timing().markNavigationStart();
1382     ASSERT(!m_mainResource);
1383     ASSERT(!m_loadingMainResource);
1384     m_loadingMainResource = true;
1385
1386     if (maybeLoadEmpty())
1387         return;
1388
1389     // FIXME: Is there any way the extra fields could have not been added by now?
1390     // If not, it would be great to remove this line of code.
1391     // Note that currently, some requests may have incorrect extra fields even if this function has been called,
1392     // because we pass a wrong loadType (see FIXME in addExtraFieldsToMainResourceRequest()).
1393     frameLoader()->addExtraFieldsToMainResourceRequest(m_request);
1394
1395     ASSERT(timing().navigationStart());
1396     ASSERT(!timing().fetchStart());
1397     timing().markFetchStart();
1398     willSendRequest(m_request, ResourceResponse());
1399
1400     // willSendRequest() may lead to our Frame being detached or cancelling the load via nulling the ResourceRequest.
1401     if (!m_frame || m_request.isNull())
1402         return;
1403
1404     m_applicationCacheHost->maybeLoadMainResource(m_request, m_substituteData);
1405
1406     if (m_substituteData.isValid()) {
1407         m_identifierForLoadWithoutResourceLoader = m_frame->page()->progress().createUniqueIdentifier();
1408         frameLoader()->notifier().assignIdentifierToInitialRequest(m_identifierForLoadWithoutResourceLoader, this, m_request);
1409         frameLoader()->notifier().dispatchWillSendRequest(this, m_identifierForLoadWithoutResourceLoader, m_request, ResourceResponse());
1410         handleSubstituteDataLoadSoon();
1411         return;
1412     }
1413
1414     ResourceRequest request(m_request);
1415     request.setRequester(ResourceRequest::Requester::Main);
1416     // If this is a reload the cache layer might have made the previous request conditional. DocumentLoader can't handle 304 responses itself.
1417     request.makeUnconditional();
1418
1419     static NeverDestroyed<ResourceLoaderOptions> mainResourceLoadOptions(SendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForAllCredentials, SkipSecurityCheck, UseDefaultOriginRestrictionsForType, IncludeCertificateInfo);
1420     CachedResourceRequest cachedResourceRequest(request, mainResourceLoadOptions);
1421     cachedResourceRequest.setInitiator(*this);
1422     m_mainResource = m_cachedResourceLoader->requestMainResource(cachedResourceRequest);
1423     if (!m_mainResource) {
1424         setRequest(ResourceRequest());
1425         // If the load was aborted by clearing m_request, it's possible the ApplicationCacheHost
1426         // is now in a state where starting an empty load will be inconsistent. Replace it with
1427         // a new ApplicationCacheHost.
1428         m_applicationCacheHost = std::make_unique<ApplicationCacheHost>(*this);
1429         maybeLoadEmpty();
1430         return;
1431     }
1432
1433     if (!mainResourceLoader()) {
1434         m_identifierForLoadWithoutResourceLoader = m_frame->page()->progress().createUniqueIdentifier();
1435         frameLoader()->notifier().assignIdentifierToInitialRequest(m_identifierForLoadWithoutResourceLoader, this, request);
1436         frameLoader()->notifier().dispatchWillSendRequest(this, m_identifierForLoadWithoutResourceLoader, request, ResourceResponse());
1437     }
1438
1439 #if ENABLE(CONTENT_FILTERING)
1440     becomeMainResourceClientIfFilterAllows();
1441 #else
1442     m_mainResource->addClient(this);
1443 #endif
1444
1445     // A bunch of headers are set when the underlying ResourceLoader is created, and m_request needs to include those.
1446     if (mainResourceLoader())
1447         request = mainResourceLoader()->originalRequest();
1448     // If there was a fragment identifier on m_request, the cache will have stripped it. m_request should include
1449     // the fragment identifier, so add that back in.
1450     if (equalIgnoringFragmentIdentifier(m_request.url(), request.url()))
1451         request.setURL(m_request.url());
1452     setRequest(request);
1453 }
1454
1455 void DocumentLoader::cancelMainResourceLoad(const ResourceError& resourceError)
1456 {
1457     Ref<DocumentLoader> protect(*this);
1458     ResourceError error = resourceError.isNull() ? frameLoader()->cancelledError(m_request) : resourceError;
1459
1460     m_dataLoadTimer.stop();
1461     if (m_waitingForContentPolicy) {
1462         frameLoader()->policyChecker().cancelCheck();
1463         ASSERT(m_waitingForContentPolicy);
1464         m_waitingForContentPolicy = false;
1465     }
1466
1467     if (mainResourceLoader())
1468         mainResourceLoader()->cancel(error);
1469
1470     clearMainResource();
1471
1472     mainReceivedError(error);
1473 }
1474
1475 void DocumentLoader::clearMainResource()
1476 {
1477     if (m_mainResource && m_mainResource->hasClient(this))
1478         m_mainResource->removeClient(this);
1479 #if ENABLE(CONTENT_FILTERING)
1480     m_contentFilter = nullptr;
1481 #endif
1482
1483     m_mainResource = 0;
1484 }
1485
1486 void DocumentLoader::subresourceLoaderFinishedLoadingOnePart(ResourceLoader* loader)
1487 {
1488     unsigned long identifier = loader->identifier();
1489     ASSERT(identifier);
1490
1491     if (!m_multipartSubresourceLoaders.add(identifier, loader).isNewEntry) {
1492         ASSERT(m_multipartSubresourceLoaders.get(identifier) == loader);
1493         ASSERT(!m_subresourceLoaders.contains(identifier));
1494     } else {
1495         ASSERT(m_subresourceLoaders.contains(identifier));
1496         m_subresourceLoaders.remove(identifier);
1497     }
1498
1499     checkLoadComplete();
1500     if (Frame* frame = m_frame)
1501         frame->loader().checkLoadComplete();    
1502 }
1503
1504 void DocumentLoader::maybeFinishLoadingMultipartContent()
1505 {
1506     if (!isMultipartReplacingLoad())
1507         return;
1508
1509     frameLoader()->setupForReplace();
1510     m_committed = false;
1511     RefPtr<SharedBuffer> resourceData = mainResourceData();
1512     commitLoad(resourceData->data(), resourceData->size());
1513 }
1514
1515 void DocumentLoader::iconLoadDecisionAvailable()
1516 {
1517     if (m_frame)
1518         m_frame->loader().icon().loadDecisionReceived(iconDatabase().synchronousLoadDecisionForIconURL(frameLoader()->icon().url(), this));
1519 }
1520
1521 static void iconLoadDecisionCallback(IconLoadDecision decision, void* context)
1522 {
1523     static_cast<DocumentLoader*>(context)->continueIconLoadWithDecision(decision);
1524 }
1525
1526 void DocumentLoader::getIconLoadDecisionForIconURL(const String& urlString)
1527 {
1528     if (m_iconLoadDecisionCallback)
1529         m_iconLoadDecisionCallback->invalidate();
1530     m_iconLoadDecisionCallback = IconLoadDecisionCallback::create(this, iconLoadDecisionCallback);
1531     iconDatabase().loadDecisionForIconURL(urlString, m_iconLoadDecisionCallback);
1532 }
1533
1534 void DocumentLoader::continueIconLoadWithDecision(IconLoadDecision decision)
1535 {
1536     ASSERT(m_iconLoadDecisionCallback);
1537     m_iconLoadDecisionCallback = 0;
1538     if (m_frame)
1539         m_frame->loader().icon().continueLoadWithDecision(decision);
1540 }
1541
1542 static void iconDataCallback(SharedBuffer*, void*)
1543 {
1544     // FIXME: Implement this once we know what parts of WebCore actually need the icon data returned.
1545 }
1546
1547 void DocumentLoader::getIconDataForIconURL(const String& urlString)
1548 {   
1549     if (m_iconDataCallback)
1550         m_iconDataCallback->invalidate();
1551     m_iconDataCallback = IconDataCallback::create(this, iconDataCallback);
1552     iconDatabase().iconDataForIconURL(urlString, m_iconDataCallback);
1553 }
1554
1555 void DocumentLoader::handledOnloadEvents()
1556 {
1557     m_wasOnloadHandled = true;
1558     applicationCacheHost()->stopDeferringEvents();
1559 }
1560
1561 void DocumentLoader::setTriggeringAction(const NavigationAction& action)
1562 {
1563     m_triggeringAction = action;
1564     if (!m_triggeringAction.isEmpty())
1565         m_triggeringAction.setShouldOpenExternalURLsPolicy(m_shouldOpenExternalURLsPolicy);
1566 }
1567
1568 #if ENABLE(CONTENT_EXTENSIONS)
1569 void DocumentLoader::addPendingContentExtensionSheet(const String& identifier, StyleSheetContents& sheet)
1570 {
1571     ASSERT(!m_gotFirstByte);
1572     m_pendingNamedContentExtensionStyleSheets.set(identifier, &sheet);
1573 }
1574
1575 void DocumentLoader::addPendingContentExtensionDisplayNoneSelector(const String& identifier, const String& selector, uint32_t selectorID)
1576 {
1577     ASSERT(!m_gotFirstByte);
1578     m_pendingContentExtensionDisplayNoneSelectors.set(identifier, std::make_pair(selector, selectorID));
1579 }
1580 #endif
1581
1582 #if ENABLE(CONTENT_FILTERING)
1583 void DocumentLoader::becomeMainResourceClientIfFilterAllows()
1584 {
1585     ASSERT(m_mainResource);
1586     if (m_contentFilter) {
1587         ASSERT(m_contentFilter->state() == ContentFilter::State::Initialized);
1588         m_contentFilter->startFilteringMainResource(*m_mainResource);
1589     } else
1590         m_mainResource->addClient(this);
1591 }
1592
1593 void DocumentLoader::installContentFilterUnblockHandler(ContentFilter& contentFilter)
1594 {
1595     ContentFilterUnblockHandler unblockHandler { contentFilter.unblockHandler() };
1596     unblockHandler.setUnreachableURL(documentURL());
1597     RefPtr<Frame> frame { this->frame() };
1598     String unblockRequestDeniedScript { contentFilter.unblockRequestDeniedScript() };
1599     if (!unblockRequestDeniedScript.isEmpty() && frame) {
1600         static_assert(std::is_base_of<ThreadSafeRefCounted<Frame>, Frame>::value, "Frame must be ThreadSafeRefCounted.");
1601         StringCapture capturedScript { unblockRequestDeniedScript };
1602         unblockHandler.wrapWithDecisionHandler([frame, capturedScript](bool unblocked) {
1603             if (!unblocked)
1604                 frame->script().executeScript(capturedScript.string());
1605         });
1606     }
1607     frameLoader()->client().contentFilterDidBlockLoad(WTF::move(unblockHandler));
1608 }
1609
1610 void DocumentLoader::contentFilterDidDecide()
1611 {
1612     using State = ContentFilter::State;
1613     ASSERT(m_contentFilter);
1614     ASSERT(m_contentFilter->state() == State::Blocked || m_contentFilter->state() == State::Allowed);
1615     std::unique_ptr<ContentFilter> contentFilter;
1616     std::swap(contentFilter, m_contentFilter);
1617     if (contentFilter->state() == State::Allowed) {
1618         if (m_mainResource)
1619             m_mainResource->addClient(this);
1620         return;
1621     }
1622
1623     installContentFilterUnblockHandler(*contentFilter);
1624
1625     URL blockedURL;
1626     blockedURL.setProtocol(ContentFilter::urlScheme());
1627     blockedURL.setHost(ASCIILiteral("blocked-page"));
1628     ResourceResponse response(URL(), ASCIILiteral("text/html"), contentFilter->replacementData()->size(), ASCIILiteral("UTF-8"));
1629     SubstituteData substituteData { contentFilter->replacementData(), documentURL(), response, SubstituteData::SessionHistoryVisibility::Hidden };
1630     frame()->navigationScheduler().scheduleSubstituteDataLoad(blockedURL, substituteData);
1631 }
1632 #endif
1633
1634
1635 } // namespace WebCore