Need a mechanism to override navigator.userAgent
[WebKit-https.git] / Source / WebCore / loader / FrameLoader.h
1 /*
2  * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
3  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
4  * Copyright (C) Research In Motion Limited 2009. All rights reserved.
5  * Copyright (C) 2011 Google Inc. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1.  Redistributions of source code must retain the above copyright
12  *     notice, this list of conditions and the following disclaimer. 
13  * 2.  Redistributions in binary form must reproduce the above copyright
14  *     notice, this list of conditions and the following disclaimer in the
15  *     documentation and/or other materials provided with the distribution. 
16  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
17  *     its contributors may be used to endorse or promote products derived
18  *     from this software without specific prior written permission. 
19  *
20  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
21  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
24  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #pragma once
33
34 #include "CachePolicy.h"
35 #include "FrameLoaderStateMachine.h"
36 #include "FrameLoaderTypes.h"
37 #include "LayoutMilestone.h"
38 #include "MixedContentChecker.h"
39 #include "ReferrerPolicy.h"
40 #include "ResourceLoadNotifier.h"
41 #include "ResourceLoaderOptions.h"
42 #include "ResourceRequestBase.h"
43 #include "SecurityContext.h"
44 #include "StoredCredentialsPolicy.h"
45 #include "Timer.h"
46 #include <wtf/CompletionHandler.h>
47 #include <wtf/Forward.h>
48 #include <wtf/HashSet.h>
49 #include <wtf/OptionSet.h>
50 #include <wtf/Optional.h>
51 #include <wtf/WallTime.h>
52
53 namespace WebCore {
54
55 class Archive;
56 class CachedFrame;
57 class CachedFrameBase;
58 class CachedPage;
59 class CachedResource;
60 class Chrome;
61 class DOMWrapperWorld;
62 class Document;
63 class DocumentLoader;
64 class Event;
65 class FormState;
66 class FormSubmission;
67 class FrameLoadRequest;
68 class FrameLoaderClient;
69 class FrameNetworkingContext;
70 class HistoryController;
71 class HistoryItem;
72 class NavigationAction;
73 class NetworkingContext;
74 class Node;
75 class Page;
76 class PolicyChecker;
77 class ResourceError;
78 class ResourceRequest;
79 class ResourceResponse;
80 class SerializedScriptValue;
81 class SharedBuffer;
82 class SubframeLoader;
83 class SubstituteData;
84
85 enum class NewLoadInProgress : bool;
86 enum class ShouldContinue;
87 enum class ShouldTreatAsContinuingLoad : bool;
88
89 struct WindowFeatures;
90
91 WEBCORE_EXPORT bool isBackForwardLoadType(FrameLoadType);
92 WEBCORE_EXPORT bool isReload(FrameLoadType);
93
94 using ContentPolicyDecisionFunction = WTF::Function<void(PolicyAction)>;
95
96 class FrameLoader {
97     WTF_MAKE_NONCOPYABLE(FrameLoader);
98 public:
99     FrameLoader(Frame&, FrameLoaderClient&);
100     ~FrameLoader();
101
102     WEBCORE_EXPORT void init();
103     void initForSynthesizedDocument(const URL&);
104
105     Frame& frame() const { return m_frame; }
106
107     PolicyChecker& policyChecker() const { return *m_policyChecker; }
108     HistoryController& history() const { return *m_history; }
109     ResourceLoadNotifier& notifier() const { return m_notifier; }
110     SubframeLoader& subframeLoader() const { return *m_subframeLoader; }
111     MixedContentChecker& mixedContentChecker() const { return m_mixedContentChecker; }
112
113     void setupForReplace();
114
115     // FIXME: These are all functions which start loads. We have too many.
116     WEBCORE_EXPORT void loadURLIntoChildFrame(const URL&, const String& referer, Frame*);
117     WEBCORE_EXPORT void loadFrameRequest(FrameLoadRequest&&, Event*, RefPtr<FormState>&&); // Called by submitForm, calls loadPostRequest and loadURL.
118
119     WEBCORE_EXPORT void load(FrameLoadRequest&&);
120
121 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
122     WEBCORE_EXPORT void loadArchive(Ref<Archive>&&);
123 #endif
124     unsigned long loadResourceSynchronously(const ResourceRequest&, ClientCredentialPolicy, const FetchOptions&, const HTTPHeaderMap&, ResourceError&, ResourceResponse&, RefPtr<SharedBuffer>& data);
125
126     void changeLocation(FrameLoadRequest&&);
127     WEBCORE_EXPORT void urlSelected(const URL&, const String& target, Event*, LockHistory, LockBackForwardList, ShouldSendReferrer, ShouldOpenExternalURLsPolicy, Optional<NewFrameOpenerPolicy> = WTF::nullopt, const AtomicString& downloadAttribute = nullAtom(), const SystemPreviewInfo& = { });
128     void submitForm(Ref<FormSubmission>&&);
129
130     WEBCORE_EXPORT void reload(OptionSet<ReloadOption> = { });
131     WEBCORE_EXPORT void reloadWithOverrideEncoding(const String& overrideEncoding);
132
133     void open(CachedFrameBase&);
134     void loadItem(HistoryItem&, FrameLoadType, ShouldTreatAsContinuingLoad);
135     HistoryItem* requestedHistoryItem() const { return m_requestedHistoryItem.get(); }
136
137     void retryAfterFailedCacheOnlyMainResourceLoad();
138
139     static void reportLocalLoadFailed(Frame*, const String& url);
140     static void reportBlockedPortFailed(Frame*, const String& url);
141     static void reportAuthenticationChallengeBlocked(Frame*, const URL&, const String& reason);
142
143     // FIXME: These are all functions which stop loads. We have too many.
144     void stopAllLoadersAndCheckCompleteness();
145     WEBCORE_EXPORT void stopAllLoaders(ClearProvisionalItemPolicy = ShouldClearProvisionalItem);
146     WEBCORE_EXPORT void stopForUserCancel(bool deferCheckLoadComplete = false);
147     void stop();
148     void stopLoading(UnloadEventPolicy);
149     bool closeURL();
150     void cancelAndClear();
151     void clearProvisionalLoadForPolicyCheck();
152     // FIXME: clear() is trying to do too many things. We should break it down into smaller functions (ideally with fewer raw Boolean parameters).
153     void clear(Document* newDocument, bool clearWindowProperties = true, bool clearScriptObjects = true, bool clearFrameView = true);
154
155     bool isLoading() const;
156     WEBCORE_EXPORT bool frameHasLoaded() const;
157
158     WEBCORE_EXPORT int numPendingOrLoadingRequests(bool recurse) const;
159
160     ReferrerPolicy effectiveReferrerPolicy() const;
161     String referrer() const;
162     WEBCORE_EXPORT String outgoingReferrer() const;
163     String outgoingOrigin() const;
164
165     WEBCORE_EXPORT DocumentLoader* activeDocumentLoader() const;
166     DocumentLoader* documentLoader() const { return m_documentLoader.get(); }
167     DocumentLoader* policyDocumentLoader() const { return m_policyDocumentLoader.get(); }
168     DocumentLoader* provisionalDocumentLoader() const { return m_provisionalDocumentLoader.get(); }
169     FrameState state() const { return m_state; }
170
171     bool shouldReportResourceTimingToParentFrame() const { return m_shouldReportResourceTimingToParentFrame; };
172     
173 #if PLATFORM(IOS_FAMILY)
174     RetainPtr<CFDictionaryRef> connectionProperties(ResourceLoader*);
175 #endif
176     const ResourceRequest& originalRequest() const;
177     const ResourceRequest& initialRequest() const;
178     void receivedMainResourceError(const ResourceError&);
179
180     bool willLoadMediaElementURL(URL&, Node&);
181
182     void handleFallbackContent();
183
184     WEBCORE_EXPORT ResourceError cancelledError(const ResourceRequest&) const;
185     WEBCORE_EXPORT ResourceError blockedByContentBlockerError(const ResourceRequest&) const;
186     ResourceError blockedError(const ResourceRequest&) const;
187 #if ENABLE(CONTENT_FILTERING)
188     ResourceError blockedByContentFilterError(const ResourceRequest&) const;
189 #endif
190
191     bool isHostedByObjectElement() const;
192
193     bool isReplacing() const;
194     void setReplacing();
195     bool subframeIsLoading() const;
196     void willChangeTitle(DocumentLoader*);
197     void didChangeTitle(DocumentLoader*);
198
199     bool shouldTreatURLAsSrcdocDocument(const URL&) const;
200
201     WEBCORE_EXPORT FrameLoadType loadType() const;
202
203     CachePolicy subresourceCachePolicy(const URL&) const;
204
205     void didReachLayoutMilestone(OptionSet<LayoutMilestone>);
206     void didFirstLayout();
207
208     void loadedResourceFromMemoryCache(CachedResource&, ResourceRequest& newRequest, ResourceError&);
209     void tellClientAboutPastMemoryCacheLoads();
210
211     void checkLoadComplete();
212     WEBCORE_EXPORT void detachFromParent();
213     void detachViewsAndDocumentLoader();
214
215     void addExtraFieldsToSubresourceRequest(ResourceRequest&);
216     void addExtraFieldsToMainResourceRequest(ResourceRequest&);
217     
218     static void addHTTPOriginIfNeeded(ResourceRequest&, const String& origin);
219     static void addHTTPUpgradeInsecureRequestsIfNeeded(ResourceRequest&);
220     static void addSameSiteInfoToRequestIfNeeded(ResourceRequest&, const Document* initiator = nullptr);
221
222     FrameLoaderClient& client() const { return m_client; }
223
224     void setDefersLoading(bool);
225
226     void checkContentPolicy(const ResourceResponse&, ContentPolicyDecisionFunction&&);
227
228     void didExplicitOpen();
229
230     // Callbacks from DocumentWriter
231     void didBeginDocument(bool dispatchWindowObjectAvailable);
232
233     void receivedFirstData();
234
235     void dispatchOnloadEvents();
236     String userAgent(const URL&) const;
237     String userAgentForJavaScript(const URL&) const;
238     String navigatorPlatform() const;
239
240     void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld&);
241     void dispatchDidClearWindowObjectsInAllWorlds();
242
243     // The following sandbox flags will be forced, regardless of changes to
244     // the sandbox attribute of any parent frames.
245     void forceSandboxFlags(SandboxFlags flags) { m_forcedSandboxFlags |= flags; }
246     SandboxFlags effectiveSandboxFlags() const;
247
248     bool checkIfFormActionAllowedByCSP(const URL&, bool didReceiveRedirectResponse) const;
249
250     WEBCORE_EXPORT Frame* opener();
251     WEBCORE_EXPORT void setOpener(Frame*);
252     bool hasOpenedFrames() const { return !m_openedFrames.isEmpty(); }
253
254     void resetMultipleFormSubmissionProtection();
255
256     void checkCallImplicitClose();
257
258     void frameDetached();
259
260     void setOutgoingReferrer(const URL&);
261
262     void loadDone(LoadCompletionType);
263     void subresourceLoadDone(LoadCompletionType);
264     void finishedParsing();
265     void checkCompleted();
266
267     WEBCORE_EXPORT bool isComplete() const;
268
269     void commitProvisionalLoad();
270
271     void setLoadsSynchronously(bool loadsSynchronously) { m_loadsSynchronously = loadsSynchronously; }
272     bool loadsSynchronously() const { return m_loadsSynchronously; }
273
274     FrameLoaderStateMachine& stateMachine() { return m_stateMachine; }
275
276     WEBCORE_EXPORT Frame* findFrameForNavigation(const AtomicString& name, Document* activeDocument = nullptr);
277
278     void applyUserAgentIfNeeded(ResourceRequest&);
279
280     bool shouldInterruptLoadForXFrameOptions(const String&, const URL&, unsigned long requestIdentifier);
281
282     void completed();
283     bool allAncestorsAreComplete() const; // including this
284     void clientRedirected(const URL&, double delay, WallTime fireDate, LockBackForwardList);
285     void clientRedirectCancelledOrFinished(NewLoadInProgress);
286
287     WEBCORE_EXPORT void setOriginalURLForDownloadRequest(ResourceRequest&);
288
289     bool quickRedirectComing() const { return m_quickRedirectComing; }
290
291     WEBCORE_EXPORT bool shouldClose();
292     
293     void started();
294
295     enum class PageDismissalType { None, BeforeUnload, PageHide, Unload };
296     PageDismissalType pageDismissalEventBeingDispatched() const { return m_pageDismissalEventBeingDispatched; }
297
298     WEBCORE_EXPORT NetworkingContext* networkingContext() const;
299
300     void loadProgressingStatusChanged();
301
302     const URL& previousURL() const { return m_previousURL; }
303
304     void forcePageTransitionIfNeeded();
305
306     void setOverrideCachePolicyForTesting(ResourceRequestCachePolicy policy) { m_overrideCachePolicyForTesting = policy; }
307     void setOverrideResourceLoadPriorityForTesting(ResourceLoadPriority priority) { m_overrideResourceLoadPriorityForTesting = priority; }
308     void setStrictRawResourceValidationPolicyDisabledForTesting(bool disabled) { m_isStrictRawResourceValidationPolicyDisabledForTesting = disabled; }
309     bool isStrictRawResourceValidationPolicyDisabledForTesting() { return m_isStrictRawResourceValidationPolicyDisabledForTesting; }
310
311     WEBCORE_EXPORT void clearTestingOverrides();
312
313     const URL& provisionalLoadErrorBeingHandledURL() const { return m_provisionalLoadErrorBeingHandledURL; }
314     void setProvisionalLoadErrorBeingHandledURL(const URL& url) { m_provisionalLoadErrorBeingHandledURL = url; }
315
316     bool isAlwaysOnLoggingAllowed() const;
317     bool shouldSuppressTextInputFromEditing() const;
318     bool isReloadingFromOrigin() const { return m_loadType == FrameLoadType::ReloadFromOrigin; }
319
320 private:
321     enum FormSubmissionCacheLoadPolicy {
322         MayAttemptCacheOnlyLoadForFormSubmissionItem,
323         MayNotAttemptCacheOnlyLoadForFormSubmissionItem
324     };
325
326     bool allChildrenAreComplete() const; // immediate children, not all descendants
327
328     void checkTimerFired();
329     void checkCompletenessNow();
330
331     void loadSameDocumentItem(HistoryItem&);
332     void loadDifferentDocumentItem(HistoryItem&, FrameLoadType, FormSubmissionCacheLoadPolicy, ShouldTreatAsContinuingLoad);
333
334     void loadProvisionalItemFromCachedPage();
335
336     void updateFirstPartyForCookies();
337     void setFirstPartyForCookies(const URL&);
338
339     void addExtraFieldsToRequest(ResourceRequest&, FrameLoadType, bool isMainResource);
340     ResourceRequestCachePolicy defaultRequestCachingPolicy(const ResourceRequest&, FrameLoadType, bool isMainResource);
341
342     void clearProvisionalLoad();
343     void transitionToCommitted(CachedPage*);
344     void frameLoadCompleted();
345
346     SubstituteData defaultSubstituteDataForURL(const URL&);
347
348     bool dispatchBeforeUnloadEvent(Chrome&, FrameLoader* frameLoaderBeingNavigated);
349     void dispatchUnloadEvents(UnloadEventPolicy);
350
351     void continueLoadAfterNavigationPolicy(const ResourceRequest&, FormState*, ShouldContinue, AllowNavigationToInvalidURL);
352     void continueLoadAfterNewWindowPolicy(const ResourceRequest&, FormState*, const String& frameName, const NavigationAction&, ShouldContinue, AllowNavigationToInvalidURL, NewFrameOpenerPolicy);
353     void continueFragmentScrollAfterNavigationPolicy(const ResourceRequest&, bool shouldContinue);
354
355     bool shouldPerformFragmentNavigation(bool isFormSubmission, const String& httpMethod, FrameLoadType, const URL&);
356     void scrollToFragmentWithParentBoundary(const URL&, bool isNewNavigation = true);
357
358     void checkLoadCompleteForThisFrame();
359
360     void setDocumentLoader(DocumentLoader*);
361     void setPolicyDocumentLoader(DocumentLoader*);
362     void setProvisionalDocumentLoader(DocumentLoader*);
363
364     void setState(FrameState);
365
366     void closeOldDataSources();
367     void willRestoreFromCachedPage();
368
369     bool shouldReloadToHandleUnreachableURL(DocumentLoader&);
370
371     void dispatchDidCommitLoad(Optional<HasInsecureContent> initialHasInsecureContent);
372
373     void urlSelected(FrameLoadRequest&&, Event*);
374
375     void loadWithDocumentLoader(DocumentLoader*, FrameLoadType, RefPtr<FormState>&&, AllowNavigationToInvalidURL, ShouldTreatAsContinuingLoad, CompletionHandler<void()>&& = [] { }); // Calls continueLoadAfterNavigationPolicy
376     void load(DocumentLoader&); // Calls loadWithDocumentLoader
377
378     void loadWithNavigationAction(const ResourceRequest&, NavigationAction&&, LockHistory, FrameLoadType, RefPtr<FormState>&&, AllowNavigationToInvalidURL, CompletionHandler<void()>&& = [] { }); // Calls loadWithDocumentLoader
379
380     void loadPostRequest(FrameLoadRequest&&, const String& referrer, FrameLoadType, Event*, RefPtr<FormState>&&, CompletionHandler<void()>&&);
381     void loadURL(FrameLoadRequest&&, const String& referrer, FrameLoadType, Event*, RefPtr<FormState>&&, CompletionHandler<void()>&&);
382
383     bool shouldReload(const URL& currentURL, const URL& destinationURL);
384
385     void requestFromDelegate(ResourceRequest&, unsigned long& identifier, ResourceError&);
386
387     WEBCORE_EXPORT void detachChildren();
388     void closeAndRemoveChild(Frame&);
389
390     void loadInSameDocument(const URL&, SerializedScriptValue* stateObject, bool isNewNavigation);
391
392     void prepareForLoadStart(CompletionHandler<void()>&&);
393     void provisionalLoadStarted();
394
395     void willTransitionToCommitted();
396     bool didOpenURL();
397
398     void scheduleCheckCompleted();
399     void scheduleCheckLoadComplete();
400     void startCheckCompleteTimer();
401
402     bool shouldTreatURLAsSameAsCurrent(const URL&) const;
403
404     void dispatchGlobalObjectAvailableInAllWorlds();
405
406     bool isNavigationAllowed() const;
407     bool isStopLoadingAllowed() const;
408
409     Frame& m_frame;
410     FrameLoaderClient& m_client;
411
412     const std::unique_ptr<PolicyChecker> m_policyChecker;
413     const std::unique_ptr<HistoryController> m_history;
414     mutable ResourceLoadNotifier m_notifier;
415     const std::unique_ptr<SubframeLoader> m_subframeLoader;
416     mutable FrameLoaderStateMachine m_stateMachine;
417     mutable MixedContentChecker m_mixedContentChecker;
418
419     class FrameProgressTracker;
420     std::unique_ptr<FrameProgressTracker> m_progressTracker;
421
422     FrameState m_state;
423     FrameLoadType m_loadType;
424
425     // Document loaders for the three phases of frame loading. Note that while 
426     // a new request is being loaded, the old document loader may still be referenced.
427     // E.g. while a new request is in the "policy" state, the old document loader may
428     // be consulted in particular as it makes sense to imply certain settings on the new loader.
429     RefPtr<DocumentLoader> m_documentLoader;
430     RefPtr<DocumentLoader> m_provisionalDocumentLoader;
431     RefPtr<DocumentLoader> m_policyDocumentLoader;
432
433     URL m_provisionalLoadErrorBeingHandledURL;
434
435     bool m_quickRedirectComing;
436     bool m_sentRedirectNotification;
437     bool m_inStopAllLoaders;
438     bool m_inClearProvisionalLoadForPolicyCheck { false };
439     bool m_shouldReportResourceTimingToParentFrame { true };
440
441     String m_outgoingReferrer;
442
443     bool m_isExecutingJavaScriptFormAction;
444
445     bool m_didCallImplicitClose;
446     bool m_wasUnloadEventEmitted;
447
448     PageDismissalType m_pageDismissalEventBeingDispatched { PageDismissalType::None };
449     bool m_isComplete;
450
451     RefPtr<SerializedScriptValue> m_pendingStateObject;
452
453     bool m_needsClear;
454
455     URL m_submittedFormURL;
456
457     Timer m_checkTimer;
458     bool m_shouldCallCheckCompleted;
459     bool m_shouldCallCheckLoadComplete;
460
461     Frame* m_opener;
462     HashSet<Frame*> m_openedFrames;
463
464     bool m_loadingFromCachedPage;
465
466     bool m_currentNavigationHasShownBeforeUnloadConfirmPanel;
467
468     bool m_loadsSynchronously;
469
470     SandboxFlags m_forcedSandboxFlags;
471
472     RefPtr<FrameNetworkingContext> m_networkingContext;
473
474     Optional<ResourceRequestCachePolicy> m_overrideCachePolicyForTesting;
475     Optional<ResourceLoadPriority> m_overrideResourceLoadPriorityForTesting;
476     bool m_isStrictRawResourceValidationPolicyDisabledForTesting { false };
477     bool m_currentLoadShouldBeTreatedAsContinuingLoad { false };
478
479     bool m_checkingLoadCompleteForDetachment { false };
480
481     URL m_previousURL;
482     RefPtr<HistoryItem> m_requestedHistoryItem;
483 };
484
485 // This function is called by createWindow() in JSDOMWindowBase.cpp, for example, for
486 // modal dialog creation.  The lookupFrame is for looking up the frame name in case
487 // the frame name references a frame different from the openerFrame, e.g. when it is
488 // "_self" or "_parent".
489 //
490 // FIXME: Consider making this function part of an appropriate class (not FrameLoader)
491 // and moving it to a more appropriate location.
492 RefPtr<Frame> createWindow(Frame& openerFrame, Frame& lookupFrame, FrameLoadRequest&&, const WindowFeatures&, bool& created);
493
494 } // namespace WebCore