User agent string override for navigator.userAgent should be site specific quirks
[WebKit-https.git] / Source / WebCore / loader / DocumentLoader.h
1 /*
2  * Copyright (C) 2006-2017 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 #pragma once
31
32 #include "CachedRawResourceClient.h"
33 #include "CachedResourceHandle.h"
34 #include "ContentSecurityPolicyClient.h"
35 #include "DocumentIdentifier.h"
36 #include "DocumentWriter.h"
37 #include "FrameDestructionObserver.h"
38 #include "LinkIcon.h"
39 #include "LoadTiming.h"
40 #include "NavigationAction.h"
41 #include "ResourceError.h"
42 #include "ResourceLoaderOptions.h"
43 #include "ResourceRequest.h"
44 #include "ResourceResponse.h"
45 #include "SecurityPolicyViolationEvent.h"
46 #include "ServiceWorkerRegistrationData.h"
47 #include "StringWithDirection.h"
48 #include "StyleSheetContents.h"
49 #include "SubstituteData.h"
50 #include "Timer.h"
51 #include <wtf/HashSet.h>
52 #include <wtf/OptionSet.h>
53 #include <wtf/RefPtr.h>
54 #include <wtf/Vector.h>
55
56 #if ENABLE(APPLICATION_MANIFEST)
57 #include "ApplicationManifest.h"
58 #endif
59
60 #if HAVE(RUNLOOP_TIMER)
61 #include <wtf/RunLoopTimer.h>
62 #endif
63
64 #if PLATFORM(COCOA)
65 #include <wtf/SchedulePair.h>
66 #endif
67
68 namespace WebCore {
69
70 class ApplicationCacheHost;
71 class ApplicationManifestLoader;
72 class Archive;
73 class ArchiveResource;
74 class ArchiveResourceCollection;
75 class CachedRawResource;
76 class CachedResourceLoader;
77 class ContentFilter;
78 class FormState;
79 class Frame;
80 class FrameLoader;
81 class HTTPHeaderField;
82 class IconLoader;
83 class Page;
84 class PreviewConverter;
85 class ResourceLoader;
86 class SharedBuffer;
87 class SWClientConnection;
88 class SubresourceLoader;
89 class SubstituteResource;
90
91 enum class ShouldContinue;
92
93 using ResourceLoaderMap = HashMap<unsigned long, RefPtr<ResourceLoader>>;
94
95 enum class AutoplayPolicy {
96     Default, // Uses policies specified in document settings.
97     Allow,
98     AllowWithoutSound,
99     Deny,
100 };
101
102 enum class AutoplayQuirk {
103     SynthesizedPauseEvents = 1 << 0,
104     InheritedUserGestures = 1 << 1,
105     ArbitraryUserGestures = 1 << 2,
106     PerDocumentAutoplayBehavior = 1 << 3,
107 };
108
109 enum class PopUpPolicy {
110     Default, // Uses policies specified in frame settings.
111     Allow,
112     Block,
113 };
114
115 class DocumentLoader
116     : public RefCounted<DocumentLoader>
117     , public FrameDestructionObserver
118     , public ContentSecurityPolicyClient
119     , private CachedRawResourceClient {
120     WTF_MAKE_FAST_ALLOCATED;
121     friend class ContentFilter;
122 public:
123     static Ref<DocumentLoader> create(const ResourceRequest& request, const SubstituteData& data)
124     {
125         return adoptRef(*new DocumentLoader(request, data));
126     }
127     WEBCORE_EXPORT virtual ~DocumentLoader();
128
129     void attachToFrame(Frame&);
130
131     WEBCORE_EXPORT virtual void detachFromFrame();
132
133     WEBCORE_EXPORT FrameLoader* frameLoader() const;
134     WEBCORE_EXPORT SubresourceLoader* mainResourceLoader() const;
135     WEBCORE_EXPORT RefPtr<SharedBuffer> mainResourceData() const;
136     
137     DocumentWriter& writer() const { return m_writer; }
138
139     const ResourceRequest& originalRequest() const;
140     const ResourceRequest& originalRequestCopy() const;
141
142     const ResourceRequest& request() const;
143     ResourceRequest& request();
144
145     CachedResourceLoader& cachedResourceLoader() { return m_cachedResourceLoader; }
146
147     const SubstituteData& substituteData() const { return m_substituteData; }
148
149     const URL& url() const;
150     const URL& unreachableURL() const;
151
152     const URL& originalURL() const;
153     const URL& responseURL() const;
154     const String& responseMIMEType() const;
155 #if PLATFORM(IOS_FAMILY)
156     // FIXME: This method seems to violate the encapsulation of this class.
157     WEBCORE_EXPORT void setResponseMIMEType(const String&);
158 #endif
159     const String& currentContentType() const;
160     void replaceRequestURLForSameDocumentNavigation(const URL&);
161     bool isStopping() const { return m_isStopping; }
162     void stopLoading();
163     void setCommitted(bool committed) { m_committed = committed; }
164     bool isCommitted() const { return m_committed; }
165     WEBCORE_EXPORT bool isLoading() const;
166
167     const ResourceError& mainDocumentError() const { return m_mainDocumentError; }
168
169     const ResourceResponse& response() const { return m_response; }
170
171     // FIXME: This method seems to violate the encapsulation of this class.
172     void setResponse(const ResourceResponse& response) { m_response = response; }
173
174     bool isClientRedirect() const { return m_isClientRedirect; }
175     void setIsClientRedirect(bool isClientRedirect) { m_isClientRedirect = isClientRedirect; }
176     void dispatchOnloadEvents();
177     bool wasOnloadDispatched() { return m_wasOnloadDispatched; }
178     WEBCORE_EXPORT bool isLoadingInAPISense() const;
179     WEBCORE_EXPORT void setTitle(const StringWithDirection&);
180     const String& overrideEncoding() const { return m_overrideEncoding; }
181
182 #if PLATFORM(COCOA)
183     void schedule(SchedulePair&);
184     void unschedule(SchedulePair&);
185 #endif
186
187 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
188     void setArchive(Ref<Archive>&&);
189     WEBCORE_EXPORT void addAllArchiveResources(Archive&);
190     WEBCORE_EXPORT void addArchiveResource(Ref<ArchiveResource>&&);
191     RefPtr<Archive> popArchiveForSubframe(const String& frameName, const URL&);
192     WEBCORE_EXPORT SharedBuffer* parsedArchiveData() const;
193
194     WEBCORE_EXPORT bool scheduleArchiveLoad(ResourceLoader&, const ResourceRequest&);
195 #endif
196
197     void scheduleSubstituteResourceLoad(ResourceLoader&, SubstituteResource&);
198     void scheduleCannotShowURLError(ResourceLoader&);
199
200     // Return the ArchiveResource for the URL only when loading an Archive
201     WEBCORE_EXPORT ArchiveResource* archiveResourceForURL(const URL&) const;
202
203     WEBCORE_EXPORT RefPtr<ArchiveResource> mainResource() const;
204
205     // Return an ArchiveResource for the URL, either creating from live data or
206     // pulling from the ArchiveResourceCollection.
207     WEBCORE_EXPORT RefPtr<ArchiveResource> subresource(const URL&) const;
208
209     WEBCORE_EXPORT Vector<Ref<ArchiveResource>> subresources() const;
210
211 #ifndef NDEBUG
212     bool isSubstituteLoadPending(ResourceLoader*) const;
213 #endif
214     void cancelPendingSubstituteLoad(ResourceLoader*);   
215     
216     void addResponse(const ResourceResponse&);
217     const Vector<ResourceResponse>& responses() const { return m_responses; }
218
219     const NavigationAction& triggeringAction() const { return m_triggeringAction; }
220     void setTriggeringAction(NavigationAction&&);
221     void setOverrideEncoding(const String& encoding) { m_overrideEncoding = encoding; }
222     void setLastCheckedRequest(ResourceRequest&& request) { m_lastCheckedRequest = WTFMove(request); }
223     const ResourceRequest& lastCheckedRequest()  { return m_lastCheckedRequest; }
224
225     void stopRecordingResponses();
226     const StringWithDirection& title() const { return m_pageTitle; }
227
228     WEBCORE_EXPORT URL urlForHistory() const;
229     WEBCORE_EXPORT bool urlForHistoryReflectsFailure() const;
230
231     // These accessors accommodate WebCore's somewhat fickle custom of creating history
232     // items for redirects, but only sometimes. For "source" and "destination",
233     // these accessors return the URL that would have been used if a history
234     // item were created. This allows WebKit to link history items reflecting
235     // redirects into a chain from start to finish.
236     String clientRedirectSourceForHistory() const { return m_clientRedirectSourceForHistory; } // null if no client redirect occurred.
237     String clientRedirectDestinationForHistory() const { return urlForHistory(); }
238     void setClientRedirectSourceForHistory(const String& clientRedirectSourceForHistory) { m_clientRedirectSourceForHistory = clientRedirectSourceForHistory; }
239     
240     String serverRedirectSourceForHistory() const { return (urlForHistory() == url() || url() == WTF::blankURL()) ? String() : urlForHistory().string(); } // null if no server redirect occurred.
241     String serverRedirectDestinationForHistory() const { return url(); }
242
243     bool didCreateGlobalHistoryEntry() const { return m_didCreateGlobalHistoryEntry; }
244     void setDidCreateGlobalHistoryEntry(bool didCreateGlobalHistoryEntry) { m_didCreateGlobalHistoryEntry = didCreateGlobalHistoryEntry; }
245
246     bool subresourceLoadersArePageCacheAcceptable() const { return m_subresourceLoadersArePageCacheAcceptable; }
247
248     void setDefersLoading(bool);
249     void setMainResourceDataBufferingPolicy(DataBufferingPolicy);
250
251     void startLoadingMainResource();
252     WEBCORE_EXPORT void cancelMainResourceLoad(const ResourceError&);
253     void willContinueMainResourceLoadAfterRedirect(const ResourceRequest&);
254
255     bool isLoadingMainResource() const { return m_loadingMainResource; }
256     bool isLoadingMultipartContent() const { return m_isLoadingMultipartContent; }
257
258     void stopLoadingPlugIns();
259     void stopLoadingSubresources();
260     WEBCORE_EXPORT void stopLoadingAfterXFrameOptionsOrContentSecurityPolicyDenied(unsigned long identifier, const ResourceResponse&);
261
262     bool userContentExtensionsEnabled() const { return m_userContentExtensionsEnabled; }
263     void setUserContentExtensionsEnabled(bool enabled) { m_userContentExtensionsEnabled = enabled; }
264
265     bool deviceOrientationEventEnabled() const { return m_deviceOrientationEventEnabled; }
266     void setDeviceOrientationEventEnabled(bool enabled) { m_deviceOrientationEventEnabled = enabled; }
267
268     AutoplayPolicy autoplayPolicy() const { return m_autoplayPolicy; }
269     void setAutoplayPolicy(AutoplayPolicy policy) { m_autoplayPolicy = policy; }
270
271     void setCustomUserAgent(const String& customUserAgent) { m_customUserAgent = customUserAgent; }
272     const String& customUserAgent() const { return m_customUserAgent; }
273
274     void setCustomJavaScriptUserAgentAsSiteSpecificQuirks(const String& customUserAgent) { m_customJavaScriptUserAgentAsSiteSpecificQuirks = customUserAgent; }
275     const String& customJavaScriptUserAgentAsSiteSpecificQuirks() const { return m_customJavaScriptUserAgentAsSiteSpecificQuirks; }
276
277     void setCustomNavigatorPlatform(const String& customNavigatorPlatform) { m_customNavigatorPlatform = customNavigatorPlatform; }
278     const String& customNavigatorPlatform() const { return m_customNavigatorPlatform; }
279
280     OptionSet<AutoplayQuirk> allowedAutoplayQuirks() const { return m_allowedAutoplayQuirks; }
281     void setAllowedAutoplayQuirks(OptionSet<AutoplayQuirk> allowedQuirks) { m_allowedAutoplayQuirks = allowedQuirks; }
282
283     PopUpPolicy popUpPolicy() const { return m_popUpPolicy; }
284     void setPopUpPolicy(PopUpPolicy popUpPolicy) { m_popUpPolicy = popUpPolicy; }
285
286     void addSubresourceLoader(ResourceLoader*);
287     void removeSubresourceLoader(LoadCompletionType, ResourceLoader*);
288     void addPlugInStreamLoader(ResourceLoader&);
289     void removePlugInStreamLoader(ResourceLoader&);
290
291     void subresourceLoaderFinishedLoadingOnePart(ResourceLoader*);
292
293     void setDeferMainResourceDataLoad(bool defer) { m_deferMainResourceDataLoad = defer; }
294     
295     void didTellClientAboutLoad(const String& url);
296     bool haveToldClientAboutLoad(const String& url) { return m_resourcesClientKnowsAbout.contains(url); }
297     void recordMemoryCacheLoadForFutureClientNotification(const ResourceRequest&);
298     void takeMemoryCacheLoadsForClientNotification(Vector<ResourceRequest>& loads);
299
300     LoadTiming& timing() { return m_loadTiming; }
301     void resetTiming() { m_loadTiming = LoadTiming(); }
302
303     // The WebKit layer calls this function when it's ready for the data to actually be added to the document.
304     WEBCORE_EXPORT void commitData(const char* bytes, size_t length);
305
306     ApplicationCacheHost& applicationCacheHost() const;
307     ApplicationCacheHost* applicationCacheHostUnlessBeingDestroyed() const;
308
309     void checkLoadComplete();
310
311     // The URL of the document resulting from this DocumentLoader.
312     URL documentURL() const;
313
314 #if USE(QUICK_LOOK)
315     void setPreviewConverter(std::unique_ptr<PreviewConverter>&&);
316     PreviewConverter* previewConverter() const;
317 #endif
318
319 #if ENABLE(CONTENT_EXTENSIONS)
320     void addPendingContentExtensionSheet(const String& identifier, StyleSheetContents&);
321     void addPendingContentExtensionDisplayNoneSelector(const String& identifier, const String& selector, uint32_t selectorID);
322 #endif
323
324     void setShouldOpenExternalURLsPolicy(ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy) { m_shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicy; }
325     ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicyToPropagate() const;
326
327 #if ENABLE(CONTENT_FILTERING)
328     ContentFilter* contentFilter() const;
329 #endif
330
331     bool isAlwaysOnLoggingAllowed() const;
332
333     void startIconLoading();
334     WEBCORE_EXPORT void didGetLoadDecisionForIcon(bool decision, uint64_t loadIdentifier, uint64_t newCallbackID);
335     void finishedLoadingIcon(IconLoader&, SharedBuffer*);
336
337     const Vector<LinkIcon>& linkIcons() const { return m_linkIcons; }
338
339 #if ENABLE(APPLICATION_MANIFEST)
340     WEBCORE_EXPORT uint64_t loadApplicationManifest();
341     void finishedLoadingApplicationManifest(ApplicationManifestLoader&);
342 #endif
343
344     WEBCORE_EXPORT void setCustomHeaderFields(Vector<HTTPHeaderField>&& fields);
345     const Vector<HTTPHeaderField>& customHeaderFields() { return m_customHeaderFields; }
346     
347 protected:
348     WEBCORE_EXPORT DocumentLoader(const ResourceRequest&, const SubstituteData&);
349
350     WEBCORE_EXPORT virtual void attachToFrame();
351
352     bool m_deferMainResourceDataLoad { true };
353
354 private:
355     Document* document() const;
356
357 #if ENABLE(SERVICE_WORKER)
358     void matchRegistration(const URL&, CompletionHandler<void(Optional<ServiceWorkerRegistrationData>&&)>&&);
359 #endif
360     void registerTemporaryServiceWorkerClient(const URL&);
361     void unregisterTemporaryServiceWorkerClient();
362
363     void loadMainResource(ResourceRequest&&);
364
365     void setRequest(const ResourceRequest&);
366
367     void commitIfReady();
368     void setMainDocumentError(const ResourceError&);
369     void commitLoad(const char*, int);
370     void clearMainResourceLoader();
371
372     void setupForReplace();
373     void maybeFinishLoadingMultipartContent();
374     
375     bool maybeCreateArchive();
376 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
377     void clearArchiveResources();
378 #endif
379
380     void willSendRequest(ResourceRequest&&, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&&);
381     void finishedLoading();
382     void mainReceivedError(const ResourceError&);
383     WEBCORE_EXPORT void redirectReceived(CachedResource&, ResourceRequest&&, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&&) override;
384     WEBCORE_EXPORT void responseReceived(CachedResource&, const ResourceResponse&, CompletionHandler<void()>&&) override;
385     WEBCORE_EXPORT void dataReceived(CachedResource&, const char* data, int length) override;
386     WEBCORE_EXPORT void notifyFinished(CachedResource&) override;
387
388     void responseReceived(const ResourceResponse&, CompletionHandler<void()>&&);
389     void dataReceived(const char* data, int length);
390
391     bool maybeLoadEmpty();
392
393     bool isMultipartReplacingLoad() const;
394     bool isPostOrRedirectAfterPost(const ResourceRequest&, const ResourceResponse&);
395
396     bool tryLoadingRequestFromApplicationCache();
397     bool tryLoadingSubstituteData();
398     bool tryLoadingRedirectRequestFromApplicationCache(const ResourceRequest&);
399 #if ENABLE(SERVICE_WORKER)
400     void restartLoadingDueToServiceWorkerRegistrationChange(ResourceRequest&&, Optional<ServiceWorkerRegistrationData>&&);
401 #endif
402     void continueAfterContentPolicy(PolicyAction);
403
404     void stopLoadingForPolicyChange();
405     ResourceError interruptedForPolicyChangeError() const;
406
407 #if HAVE(RUNLOOP_TIMER)
408     typedef RunLoopTimer<DocumentLoader> DocumentLoaderTimer;
409 #else
410     typedef Timer DocumentLoaderTimer;
411 #endif
412     void handleSubstituteDataLoadNow();
413     void startDataLoadTimer();
414
415     void deliverSubstituteResourcesAfterDelay();
416     void substituteResourceDeliveryTimerFired();
417
418     void clearMainResource();
419
420     void cancelPolicyCheckIfNeeded();
421     void becomeMainResourceClient();
422
423     void notifyFinishedLoadingIcon(uint64_t callbackIdentifier, SharedBuffer*);
424
425 #if ENABLE(APPLICATION_MANIFEST)
426     void notifyFinishedLoadingApplicationManifest(uint64_t callbackIdentifier, Optional<ApplicationManifest>);
427 #endif
428
429     // ContentSecurityPolicyClient
430     WEBCORE_EXPORT void addConsoleMessage(MessageSource, MessageLevel, const String&, unsigned long requestIdentifier) final;
431     WEBCORE_EXPORT void sendCSPViolationReport(URL&&, Ref<FormData>&&) final;
432     WEBCORE_EXPORT void enqueueSecurityPolicyViolationEvent(SecurityPolicyViolationEvent::Init&&) final;
433
434     bool disallowWebArchive() const;
435
436     Ref<CachedResourceLoader> m_cachedResourceLoader;
437
438     CachedResourceHandle<CachedRawResource> m_mainResource;
439     ResourceLoaderMap m_subresourceLoaders;
440     ResourceLoaderMap m_multipartSubresourceLoaders;
441     ResourceLoaderMap m_plugInStreamLoaders;
442     
443     mutable DocumentWriter m_writer;
444
445     // A reference to actual request used to create the data source.
446     // This should only be used by the resourceLoadDelegate's
447     // identifierForInitialRequest:fromDatasource: method. It is
448     // not guaranteed to remain unchanged, as requests are mutable.
449     ResourceRequest m_originalRequest;   
450
451     SubstituteData m_substituteData;
452
453     // A copy of the original request used to create the data source.
454     // We have to copy the request because requests are mutable.
455     ResourceRequest m_originalRequestCopy;
456     
457     // The 'working' request. It may be mutated
458     // several times from the original request to include additional
459     // headers, cookie information, canonicalization and redirects.
460     ResourceRequest m_request;
461
462     ResourceResponse m_response;
463
464     ResourceError m_mainDocumentError;    
465
466     bool m_originalSubstituteDataWasValid;
467     bool m_committed { false };
468     bool m_isStopping { false };
469     bool m_gotFirstByte { false };
470     bool m_isClientRedirect { false };
471     bool m_isLoadingMultipartContent { false };
472
473     // FIXME: Document::m_processingLoadEvent and DocumentLoader::m_wasOnloadDispatched are roughly the same
474     // and should be merged.
475     bool m_wasOnloadDispatched { false };
476
477     StringWithDirection m_pageTitle;
478
479     String m_overrideEncoding;
480
481     // The action that triggered loading - we keep this around for the
482     // benefit of the various policy handlers.
483     NavigationAction m_triggeringAction;
484
485     // The last request that we checked click policy for - kept around
486     // so we can avoid asking again needlessly.
487     ResourceRequest m_lastCheckedRequest;
488
489     // We retain all the received responses so we can play back the
490     // WebResourceLoadDelegate messages if the item is loaded from the
491     // page cache.
492     Vector<ResourceResponse> m_responses;
493     bool m_stopRecordingResponses { false };
494     
495     typedef HashMap<RefPtr<ResourceLoader>, RefPtr<SubstituteResource>> SubstituteResourceMap;
496     SubstituteResourceMap m_pendingSubstituteResources;
497     Timer m_substituteResourceDeliveryTimer;
498
499     std::unique_ptr<ArchiveResourceCollection> m_archiveResourceCollection;
500 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
501     RefPtr<Archive> m_archive;
502     RefPtr<SharedBuffer> m_parsedArchiveData;
503 #endif
504
505     HashSet<String> m_resourcesClientKnowsAbout;
506     Vector<ResourceRequest> m_resourcesLoadedFromMemoryCacheForClientNotification;
507     
508     String m_clientRedirectSourceForHistory;
509     bool m_didCreateGlobalHistoryEntry { false };
510
511     bool m_loadingMainResource { false };
512     LoadTiming m_loadTiming;
513
514     MonotonicTime m_timeOfLastDataReceived;
515     unsigned long m_identifierForLoadWithoutResourceLoader { 0 };
516
517     DocumentLoaderTimer m_dataLoadTimer;
518     bool m_waitingForContentPolicy { false };
519     bool m_waitingForNavigationPolicy { false };
520
521     HashMap<uint64_t, LinkIcon> m_iconsPendingLoadDecision;
522     HashMap<std::unique_ptr<IconLoader>, uint64_t> m_iconLoaders;
523     Vector<LinkIcon> m_linkIcons;
524
525 #if ENABLE(APPLICATION_MANIFEST)
526     HashMap<std::unique_ptr<ApplicationManifestLoader>, uint64_t> m_applicationManifestLoaders;
527 #endif
528
529     Vector<HTTPHeaderField> m_customHeaderFields;
530     
531     bool m_subresourceLoadersArePageCacheAcceptable { false };
532     ShouldOpenExternalURLsPolicy m_shouldOpenExternalURLsPolicy { ShouldOpenExternalURLsPolicy::ShouldNotAllow };
533
534     std::unique_ptr<ApplicationCacheHost> m_applicationCacheHost;
535
536 #if ENABLE(CONTENT_FILTERING)
537     std::unique_ptr<ContentFilter> m_contentFilter;
538 #endif
539
540 #if USE(QUICK_LOOK)
541     std::unique_ptr<PreviewConverter> m_previewConverter;
542 #endif
543
544 #if ENABLE(CONTENT_EXTENSIONS)
545     HashMap<String, RefPtr<StyleSheetContents>> m_pendingNamedContentExtensionStyleSheets;
546     HashMap<String, Vector<std::pair<String, uint32_t>>> m_pendingContentExtensionDisplayNoneSelectors;
547 #endif
548     String m_customUserAgent;
549     String m_customJavaScriptUserAgentAsSiteSpecificQuirks;
550     String m_customNavigatorPlatform;
551     bool m_userContentExtensionsEnabled { true };
552     bool m_deviceOrientationEventEnabled { true };
553     AutoplayPolicy m_autoplayPolicy { AutoplayPolicy::Default };
554     OptionSet<AutoplayQuirk> m_allowedAutoplayQuirks;
555     PopUpPolicy m_popUpPolicy { PopUpPolicy::Default };
556
557 #if ENABLE(SERVICE_WORKER)
558     Optional<ServiceWorkerRegistrationData> m_serviceWorkerRegistrationData;
559     struct TemporaryServiceWorkerClient {
560         DocumentIdentifier documentIdentifier;
561         Ref<SWClientConnection> serviceWorkerConnection;
562     };
563     Optional<TemporaryServiceWorkerClient> m_temporaryServiceWorkerClient;
564 #endif
565
566 #ifndef NDEBUG
567     bool m_hasEverBeenAttached { false };
568 #endif
569 };
570
571 inline void DocumentLoader::recordMemoryCacheLoadForFutureClientNotification(const ResourceRequest& request)
572 {
573     m_resourcesLoadedFromMemoryCacheForClientNotification.append(request);
574 }
575
576 inline void DocumentLoader::takeMemoryCacheLoadsForClientNotification(Vector<ResourceRequest>& loadsSet)
577 {
578     loadsSet.swap(m_resourcesLoadedFromMemoryCacheForClientNotification);
579     m_resourcesLoadedFromMemoryCacheForClientNotification.clear();
580 }
581
582 inline const ResourceRequest& DocumentLoader::originalRequest() const
583 {
584     return m_originalRequest;
585 }
586
587 inline const ResourceRequest& DocumentLoader::originalRequestCopy() const
588 {
589     return m_originalRequestCopy;
590 }
591
592 inline const ResourceRequest& DocumentLoader::request() const
593 {
594     return m_request;
595 }
596
597 inline ResourceRequest& DocumentLoader::request()
598 {
599     return m_request;
600 }
601
602 inline const URL& DocumentLoader::url() const
603 {
604     return m_request.url();
605 }
606
607 inline const URL& DocumentLoader::originalURL() const
608 {
609     return m_originalRequestCopy.url();
610 }
611
612 inline const URL& DocumentLoader::responseURL() const
613 {
614     return m_response.url();
615 }
616
617 inline const String& DocumentLoader::responseMIMEType() const
618 {
619     return m_response.mimeType();
620 }
621
622 inline const String& DocumentLoader::currentContentType() const
623 {
624     return m_writer.mimeType();
625 }
626
627 inline const URL& DocumentLoader::unreachableURL() const
628 {
629     return m_substituteData.failingURL();
630 }
631
632 inline ApplicationCacheHost& DocumentLoader::applicationCacheHost() const
633 {
634     // For a short time while the document loader is being destroyed, m_applicationCacheHost is null.
635     // It's not acceptable to call this function during that time.
636     ASSERT(m_applicationCacheHost);
637     return *m_applicationCacheHost;
638 }
639
640 inline ApplicationCacheHost* DocumentLoader::applicationCacheHostUnlessBeingDestroyed() const
641 {
642     return m_applicationCacheHost.get();
643 }
644
645 #if ENABLE(CONTENT_FILTERING)
646
647 inline ContentFilter* DocumentLoader::contentFilter() const
648 {
649     return m_contentFilter.get();
650 }
651
652 #endif
653
654 inline void DocumentLoader::didTellClientAboutLoad(const String& url)
655 {
656 #if !PLATFORM(COCOA)
657     // Don't include data URLs here, as if a lot of data is loaded that way, we hold on to the (large) URL string for too long.
658     if (protocolIs(url, "data"))
659         return;
660 #endif
661     if (!url.isEmpty())
662         m_resourcesClientKnowsAbout.add(url);
663 }
664
665 }