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