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