541dfbe4de859fcdfee6fed24757c1e4512650e9
[WebKit-https.git] / Source / WebCore / loader / DocumentLoader.h
1 /*
2  * Copyright (C) 2006-2016 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 "DocumentWriter.h"
35 #include "IconDatabaseBase.h"
36 #include "LoadTiming.h"
37 #include "NavigationAction.h"
38 #include "ResourceError.h"
39 #include "ResourceLoaderOptions.h"
40 #include "ResourceRequest.h"
41 #include "ResourceResponse.h"
42 #include "StringWithDirection.h"
43 #include "StyleSheetContents.h"
44 #include "SubstituteData.h"
45 #include "Timer.h"
46 #include <wtf/HashSet.h>
47 #include <wtf/RefPtr.h>
48 #include <wtf/Vector.h>
49
50 #if HAVE(RUNLOOP_TIMER)
51 #include <wtf/RunLoopTimer.h>
52 #endif
53
54 #if USE(QUICK_LOOK)
55 #include "QuickLook.h"
56 #endif
57
58 #if PLATFORM(COCOA) && !USE(CFURLCONNECTION)
59 #include <wtf/SchedulePair.h>
60 #endif
61
62 namespace WebCore {
63
64 class ApplicationCacheHost;
65 class Archive;
66 class ArchiveResource;
67 class ArchiveResourceCollection;
68 class CachedRawResource;
69 class CachedResourceLoader;
70 class ContentFilter;
71 class FormState;
72 class Frame;
73 class FrameLoader;
74 class Page;
75 class ResourceLoader;
76 class SharedBuffer;
77 class SubresourceLoader;
78 class SubstituteResource;
79
80 typedef HashMap<unsigned long, RefPtr<ResourceLoader>> ResourceLoaderMap;
81 typedef Vector<ResourceResponse> ResponseVector;
82
83 class DocumentLoader : public RefCounted<DocumentLoader>, private CachedRawResourceClient {
84     WTF_MAKE_FAST_ALLOCATED;
85     friend class ContentFilter;
86 public:
87     static Ref<DocumentLoader> create(const ResourceRequest& request, const SubstituteData& data)
88     {
89         return adoptRef(*new DocumentLoader(request, data));
90     }
91     WEBCORE_EXPORT virtual ~DocumentLoader();
92
93     void attachToFrame(Frame&);
94     Frame* frame() const { return m_frame; }
95
96     WEBCORE_EXPORT virtual void detachFromFrame();
97
98     WEBCORE_EXPORT FrameLoader* frameLoader() const;
99     WEBCORE_EXPORT SubresourceLoader* mainResourceLoader() const;
100     WEBCORE_EXPORT RefPtr<SharedBuffer> mainResourceData() const;
101     
102     DocumentWriter& writer() const { return m_writer; }
103
104     WEBCORE_EXPORT const ResourceRequest& originalRequest() const;
105     WEBCORE_EXPORT const ResourceRequest& originalRequestCopy() const;
106
107     WEBCORE_EXPORT const ResourceRequest& request() const;
108     WEBCORE_EXPORT ResourceRequest& request();
109
110     CachedResourceLoader& cachedResourceLoader() { return m_cachedResourceLoader; }
111
112     const SubstituteData& substituteData() const { return m_substituteData; }
113
114     WEBCORE_EXPORT const URL& url() const;
115     WEBCORE_EXPORT const URL& unreachableURL() const;
116
117     const URL& originalURL() const;
118     WEBCORE_EXPORT const URL& responseURL() const;
119     WEBCORE_EXPORT const String& responseMIMEType() const;
120 #if PLATFORM(IOS)
121     // FIXME: This method seems to violate the encapsulation of this class.
122     WEBCORE_EXPORT void setResponseMIMEType(const String&);
123 #endif
124     const String& currentContentType() const;
125     void replaceRequestURLForSameDocumentNavigation(const URL&);
126     bool isStopping() const { return m_isStopping; }
127     void stopLoading();
128     void setCommitted(bool committed) { m_committed = committed; }
129     bool isCommitted() const { return m_committed; }
130     WEBCORE_EXPORT bool isLoading() const;
131
132     const ResourceError& mainDocumentError() const { return m_mainDocumentError; }
133
134     const ResourceResponse& response() const { return m_response; }
135 #if PLATFORM(IOS)
136     // FIXME: This method seems to violate the encapsulation of this class.
137     void setResponse(const ResourceResponse& response) { m_response = response; }
138 #endif
139
140     bool isClientRedirect() const { return m_isClientRedirect; }
141     void setIsClientRedirect(bool isClientRedirect) { m_isClientRedirect = isClientRedirect; }
142     void dispatchOnloadEvents();
143     bool wasOnloadDispatched() { return m_wasOnloadDispatched; }
144     WEBCORE_EXPORT bool isLoadingInAPISense() const;
145     WEBCORE_EXPORT void setTitle(const StringWithDirection&);
146     const String& overrideEncoding() const { return m_overrideEncoding; }
147
148 #if PLATFORM(COCOA) && !USE(CFURLCONNECTION)
149     void schedule(SchedulePair&);
150     void unschedule(SchedulePair&);
151 #endif
152
153 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
154     void setArchive(PassRefPtr<Archive>);
155     WEBCORE_EXPORT void addAllArchiveResources(Archive*);
156     WEBCORE_EXPORT void addArchiveResource(Ref<ArchiveResource>&&);
157     PassRefPtr<Archive> popArchiveForSubframe(const String& frameName, const URL&);
158     WEBCORE_EXPORT SharedBuffer* parsedArchiveData() const;
159
160     WEBCORE_EXPORT bool scheduleArchiveLoad(ResourceLoader&, const ResourceRequest&);
161 #endif
162     void scheduleSubstituteResourceLoad(ResourceLoader&, SubstituteResource&);
163
164     // Return the ArchiveResource for the URL only when loading an Archive
165     WEBCORE_EXPORT ArchiveResource* archiveResourceForURL(const URL&) const;
166
167     WEBCORE_EXPORT RefPtr<ArchiveResource> mainResource() const;
168
169     // Return an ArchiveResource for the URL, either creating from live data or
170     // pulling from the ArchiveResourceCollection
171     WEBCORE_EXPORT PassRefPtr<ArchiveResource> subresource(const URL&) const;
172     WEBCORE_EXPORT Vector<RefPtr<ArchiveResource>> subresources() const;
173
174 #ifndef NDEBUG
175     bool isSubstituteLoadPending(ResourceLoader*) const;
176 #endif
177     void cancelPendingSubstituteLoad(ResourceLoader*);   
178     
179     void addResponse(const ResourceResponse&);
180     const ResponseVector& responses() const { return m_responses; }
181
182     const NavigationAction& triggeringAction() const { return m_triggeringAction; }
183     void setTriggeringAction(const NavigationAction&);
184     void setOverrideEncoding(const String& encoding) { m_overrideEncoding = encoding; }
185     void setLastCheckedRequest(const ResourceRequest& request) { m_lastCheckedRequest = request; }
186     const ResourceRequest& lastCheckedRequest()  { return m_lastCheckedRequest; }
187
188     void stopRecordingResponses();
189     const StringWithDirection& title() const { return m_pageTitle; }
190
191     WEBCORE_EXPORT URL urlForHistory() const;
192     WEBCORE_EXPORT bool urlForHistoryReflectsFailure() const;
193
194     // These accessors accommodate WebCore's somewhat fickle custom of creating history
195     // items for redirects, but only sometimes. For "source" and "destination",
196     // these accessors return the URL that would have been used if a history
197     // item were created. This allows WebKit to link history items reflecting
198     // redirects into a chain from start to finish.
199     String clientRedirectSourceForHistory() const { return m_clientRedirectSourceForHistory; } // null if no client redirect occurred.
200     String clientRedirectDestinationForHistory() const { return urlForHistory(); }
201     void setClientRedirectSourceForHistory(const String& clientRedirectSourceForHistory) { m_clientRedirectSourceForHistory = clientRedirectSourceForHistory; }
202     
203     String serverRedirectSourceForHistory() const { return (urlForHistory() == url() || url() == blankURL()) ? String() : urlForHistory().string(); } // null if no server redirect occurred.
204     String serverRedirectDestinationForHistory() const { return url(); }
205
206     bool didCreateGlobalHistoryEntry() const { return m_didCreateGlobalHistoryEntry; }
207     void setDidCreateGlobalHistoryEntry(bool didCreateGlobalHistoryEntry) { m_didCreateGlobalHistoryEntry = didCreateGlobalHistoryEntry; }
208
209     bool subresourceLoadersArePageCacheAcceptable() const { return m_subresourceLoadersArePageCacheAcceptable; }
210
211     void setDefersLoading(bool);
212     void setMainResourceDataBufferingPolicy(DataBufferingPolicy);
213
214     void startLoadingMainResource();
215     WEBCORE_EXPORT void cancelMainResourceLoad(const ResourceError&);
216     void willContinueMainResourceLoadAfterRedirect(const ResourceRequest&);
217
218     // Support iconDatabase in synchronous mode.
219     void iconLoadDecisionAvailable();
220     
221     // Support iconDatabase in asynchronous mode.
222     void continueIconLoadWithDecision(IconLoadDecision);
223     void getIconLoadDecisionForIconURL(const String&);
224     void getIconDataForIconURL(const String&);
225
226     bool isLoadingMainResource() const { return m_loadingMainResource; }
227     bool isLoadingMultipartContent() const { return m_isLoadingMultipartContent; }
228
229     void stopLoadingPlugIns();
230     void stopLoadingSubresources();
231
232     bool userContentExtensionsEnabled() const { return m_userContentExtensionsEnabled; }
233     void setUserContentExtensionsEnabled(bool enabled) { m_userContentExtensionsEnabled = enabled; }
234
235     void addSubresourceLoader(ResourceLoader*);
236     void removeSubresourceLoader(ResourceLoader*);
237     void addPlugInStreamLoader(ResourceLoader&);
238     void removePlugInStreamLoader(ResourceLoader&);
239
240     void subresourceLoaderFinishedLoadingOnePart(ResourceLoader*);
241
242     void setDeferMainResourceDataLoad(bool defer) { m_deferMainResourceDataLoad = defer; }
243     
244     void didTellClientAboutLoad(const String& url)
245     { 
246 #if !PLATFORM(COCOA)
247         // Don't include data urls here, as if a lot of data is loaded
248         // that way, we hold on to the (large) url string for too long.
249         if (protocolIs(url, "data"))
250             return;
251 #endif
252         if (!url.isEmpty())
253             m_resourcesClientKnowsAbout.add(url);
254     }
255     bool haveToldClientAboutLoad(const String& url) { return m_resourcesClientKnowsAbout.contains(url); }
256     void recordMemoryCacheLoadForFutureClientNotification(const ResourceRequest&);
257     void takeMemoryCacheLoadsForClientNotification(Vector<ResourceRequest>& loads);
258
259     LoadTiming& timing() { return m_loadTiming; }
260     void resetTiming() { m_loadTiming = LoadTiming(); }
261
262     // The WebKit layer calls this function when it's ready for the data to
263     // actually be added to the document.
264     WEBCORE_EXPORT void commitData(const char* bytes, size_t length);
265
266     ApplicationCacheHost* applicationCacheHost() const { return m_applicationCacheHost.get(); }
267
268     void checkLoadComplete();
269
270     // The URL of the document resulting from this DocumentLoader.
271     URL documentURL() const;
272
273 #if USE(QUICK_LOOK)
274     void setQuickLookHandle(std::unique_ptr<QuickLookHandle> quickLookHandle) { m_quickLookHandle = WTFMove(quickLookHandle); }
275     QuickLookHandle* quickLookHandle() const { return m_quickLookHandle.get(); }
276 #endif
277
278 #if ENABLE(CONTENT_EXTENSIONS)
279     void addPendingContentExtensionSheet(const String& identifier, StyleSheetContents&);
280     void addPendingContentExtensionDisplayNoneSelector(const String& identifier, const String& selector, uint32_t selectorID);
281 #endif
282
283     void setShouldOpenExternalURLsPolicy(ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy) { m_shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicy; }
284     ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicyToPropagate() const;
285
286 #if ENABLE(CONTENT_FILTERING)
287     ContentFilter* contentFilter() const;
288 #endif
289
290     bool isAlwaysOnLoggingAllowed() const;
291
292 protected:
293     WEBCORE_EXPORT DocumentLoader(const ResourceRequest&, const SubstituteData&);
294
295     WEBCORE_EXPORT virtual void attachToFrame();
296
297     bool m_deferMainResourceDataLoad;
298
299 private:
300     Document* document() const;
301
302     void setRequest(const ResourceRequest&);
303
304     void commitIfReady();
305     void setMainDocumentError(const ResourceError&);
306     void commitLoad(const char*, int);
307     void clearMainResourceLoader();
308
309     void setupForReplace();
310     void maybeFinishLoadingMultipartContent();
311     
312     bool maybeCreateArchive();
313 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
314     void clearArchiveResources();
315 #endif
316
317     void willSendRequest(ResourceRequest&, const ResourceResponse&);
318     void finishedLoading(double finishTime);
319     void mainReceivedError(const ResourceError&);
320     WEBCORE_EXPORT void redirectReceived(CachedResource&, ResourceRequest&, const ResourceResponse&) override;
321     WEBCORE_EXPORT void responseReceived(CachedResource&, const ResourceResponse&) override;
322     WEBCORE_EXPORT void dataReceived(CachedResource&, const char* data, int length) override;
323     WEBCORE_EXPORT void notifyFinished(CachedResource&) override;
324
325     void responseReceived(const ResourceResponse&);
326     void dataReceived(const char* data, int length);
327
328     bool maybeLoadEmpty();
329
330     bool isMultipartReplacingLoad() const;
331     bool isPostOrRedirectAfterPost(const ResourceRequest&, const ResourceResponse&);
332
333     void continueAfterNavigationPolicy(const ResourceRequest&, bool shouldContinue);
334     void continueAfterContentPolicy(PolicyAction);
335
336     void stopLoadingForPolicyChange();
337     ResourceError interruptedForPolicyChangeError() const;
338
339     void stopLoadingAfterXFrameOptionsOrContentSecurityPolicyDenied(unsigned long identifier, const ResourceResponse&);
340
341 #if HAVE(RUNLOOP_TIMER)
342     typedef RunLoopTimer<DocumentLoader> DocumentLoaderTimer;
343 #else
344     typedef Timer DocumentLoaderTimer;
345 #endif
346     void handleSubstituteDataLoadSoon();
347     void handleSubstituteDataLoadNow();
348     void startDataLoadTimer();
349
350     void deliverSubstituteResourcesAfterDelay();
351     void substituteResourceDeliveryTimerFired();
352
353     void clearMainResource();
354
355     void cancelPolicyCheckIfNeeded();
356     void becomeMainResourceClient();
357
358     Frame* m_frame;
359     Ref<CachedResourceLoader> m_cachedResourceLoader;
360
361     CachedResourceHandle<CachedRawResource> m_mainResource;
362     ResourceLoaderMap m_subresourceLoaders;
363     ResourceLoaderMap m_multipartSubresourceLoaders;
364     ResourceLoaderMap m_plugInStreamLoaders;
365     
366     mutable DocumentWriter m_writer;
367
368     // A reference to actual request used to create the data source.
369     // This should only be used by the resourceLoadDelegate's
370     // identifierForInitialRequest:fromDatasource: method. It is
371     // not guaranteed to remain unchanged, as requests are mutable.
372     ResourceRequest m_originalRequest;   
373
374     SubstituteData m_substituteData;
375
376     // A copy of the original request used to create the data source.
377     // We have to copy the request because requests are mutable.
378     ResourceRequest m_originalRequestCopy;
379     
380     // The 'working' request. It may be mutated
381     // several times from the original request to include additional
382     // headers, cookie information, canonicalization and redirects.
383     ResourceRequest m_request;
384
385     ResourceResponse m_response;
386
387     ResourceError m_mainDocumentError;    
388
389     bool m_originalSubstituteDataWasValid;
390     bool m_committed;
391     bool m_isStopping;
392     bool m_gotFirstByte;
393     bool m_isClientRedirect;
394     bool m_isLoadingMultipartContent;
395
396     // FIXME: Document::m_processingLoadEvent and DocumentLoader::m_wasOnloadDispatched are roughly the same
397     // and should be merged.
398     bool m_wasOnloadDispatched;
399
400     StringWithDirection m_pageTitle;
401
402     String m_overrideEncoding;
403
404     // The action that triggered loading - we keep this around for the
405     // benefit of the various policy handlers.
406     NavigationAction m_triggeringAction;
407
408     // The last request that we checked click policy for - kept around
409     // so we can avoid asking again needlessly.
410     ResourceRequest m_lastCheckedRequest;
411
412     // We retain all the received responses so we can play back the
413     // WebResourceLoadDelegate messages if the item is loaded from the
414     // page cache.
415     ResponseVector m_responses;
416     bool m_stopRecordingResponses;
417     
418     typedef HashMap<RefPtr<ResourceLoader>, RefPtr<SubstituteResource>> SubstituteResourceMap;
419     SubstituteResourceMap m_pendingSubstituteResources;
420     Timer m_substituteResourceDeliveryTimer;
421
422     std::unique_ptr<ArchiveResourceCollection> m_archiveResourceCollection;
423 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
424     RefPtr<Archive> m_archive;
425     RefPtr<SharedBuffer> m_parsedArchiveData;
426 #endif
427
428     HashSet<String> m_resourcesClientKnowsAbout;
429     Vector<ResourceRequest> m_resourcesLoadedFromMemoryCacheForClientNotification;
430     
431     String m_clientRedirectSourceForHistory;
432     bool m_didCreateGlobalHistoryEntry;
433
434     bool m_loadingMainResource;
435     LoadTiming m_loadTiming;
436
437     double m_timeOfLastDataReceived;
438     unsigned long m_identifierForLoadWithoutResourceLoader;
439
440     DocumentLoaderTimer m_dataLoadTimer;
441     bool m_waitingForContentPolicy { false };
442     bool m_waitingForNavigationPolicy { false };
443
444     RefPtr<IconLoadDecisionCallback> m_iconLoadDecisionCallback;
445     RefPtr<IconDataCallback> m_iconDataCallback;
446
447     bool m_subresourceLoadersArePageCacheAcceptable;
448     ShouldOpenExternalURLsPolicy m_shouldOpenExternalURLsPolicy { ShouldOpenExternalURLsPolicy::ShouldNotAllow };
449
450     std::unique_ptr<ApplicationCacheHost> m_applicationCacheHost;
451
452 #if ENABLE(CONTENT_FILTERING)
453     std::unique_ptr<ContentFilter> m_contentFilter;
454 #endif
455
456 #if USE(QUICK_LOOK)
457     std::unique_ptr<QuickLookHandle> m_quickLookHandle;
458 #endif
459
460 #if ENABLE(CONTENT_EXTENSIONS)
461     HashMap<String, RefPtr<StyleSheetContents>> m_pendingNamedContentExtensionStyleSheets;
462     HashMap<String, Vector<std::pair<String, uint32_t>>> m_pendingContentExtensionDisplayNoneSelectors;
463 #endif
464     bool m_userContentExtensionsEnabled { true };
465
466 #ifndef NDEBUG
467     bool m_hasEverBeenAttached { false };
468 #endif
469 };
470
471 inline void DocumentLoader::recordMemoryCacheLoadForFutureClientNotification(const ResourceRequest& request)
472 {
473     m_resourcesLoadedFromMemoryCacheForClientNotification.append(request);
474 }
475
476 inline void DocumentLoader::takeMemoryCacheLoadsForClientNotification(Vector<ResourceRequest>& loadsSet)
477 {
478     loadsSet.swap(m_resourcesLoadedFromMemoryCacheForClientNotification);
479     m_resourcesLoadedFromMemoryCacheForClientNotification.clear();
480 }
481
482 }