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 AtomString& 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, ContentSecurityPolicy* previousPolicy);
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 AtomString& 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 dispatchDidFailProvisionalLoad(DocumentLoader& provisionalDocumentLoader, const ResourceError&);
365 void checkLoadCompleteForThisFrame();
366
367 void setDocumentLoader(DocumentLoader*);
368 void setPolicyDocumentLoader(DocumentLoader*);
369 void setProvisionalDocumentLoader(DocumentLoader*);
370
371 void setState(FrameState);
372
373 void closeOldDataSources();
374 void willRestoreFromCachedPage();
375
376 bool shouldReloadToHandleUnreachableURL(DocumentLoader&);
377
378 void dispatchDidCommitLoad(Optional<HasInsecureContent> initialHasInsecureContent);
379
380 void urlSelected(FrameLoadRequest&&, Event*, Optional<AdClickAttribution>&& = WTF::nullopt);
381
382 void loadWithDocumentLoader(DocumentLoader*, FrameLoadType, RefPtr<FormState>&&, AllowNavigationToInvalidURL, ShouldTreatAsContinuingLoad, CompletionHandler<void()>&& = [] { }); // Calls continueLoadAfterNavigationPolicy
383 void load(DocumentLoader&); // Calls loadWithDocumentLoader
384
385 void loadWithNavigationAction(const ResourceRequest&, NavigationAction&&, LockHistory, FrameLoadType, RefPtr<FormState>&&, AllowNavigationToInvalidURL, const String& downloadAttribute = { }, CompletionHandler<void()>&& = [] { }); // Calls loadWithDocumentLoader
386
387 void loadPostRequest(FrameLoadRequest&&, const String& referrer, FrameLoadType, Event*, RefPtr<FormState>&&, CompletionHandler<void()>&&);
388 void loadURL(FrameLoadRequest&&, const String& referrer, FrameLoadType, Event*, RefPtr<FormState>&&, Optional<AdClickAttribution>&&, CompletionHandler<void()>&&);
389
390 bool shouldReload(const URL& currentURL, const URL& destinationURL);
391
392 void requestFromDelegate(ResourceRequest&, unsigned long& identifier, ResourceError&);
393
394 WEBCORE_EXPORT void detachChildren();
395 void closeAndRemoveChild(Frame&);
396
397 void loadInSameDocument(const URL&, SerializedScriptValue* stateObject, bool isNewNavigation);
398
399 void prepareForLoadStart();
400 void provisionalLoadStarted();
401
402 void willTransitionToCommitted();
403 bool didOpenURL();
404
405 void scheduleCheckCompleted();
406 void scheduleCheckLoadComplete();
407 void startCheckCompleteTimer();
408
409 bool shouldTreatURLAsSameAsCurrent(const URL&) const;
410
411 void dispatchGlobalObjectAvailableInAllWorlds();
412
413 bool isNavigationAllowed() const;
414 bool isStopLoadingAllowed() const;
415
416 enum class LoadContinuingState : uint8_t { NotContinuing, ContinuingWithRequest, ContinuingWithHistoryItem };
417 bool shouldTreatCurrentLoadAsContinuingLoad() const { return m_currentLoadContinuingState != LoadContinuingState::NotContinuing; }
418
419 Frame& m_frame;
420 FrameLoaderClient& m_client;
421
422 const std::unique_ptr<PolicyChecker> m_policyChecker;
423 const std::unique_ptr<HistoryController> m_history;
424 mutable ResourceLoadNotifier m_notifier;
425 const std::unique_ptr<SubframeLoader> m_subframeLoader;
426 mutable FrameLoaderStateMachine m_stateMachine;
427 mutable MixedContentChecker m_mixedContentChecker;
428
429 class FrameProgressTracker;
430 std::unique_ptr<FrameProgressTracker> m_progressTracker;
431
432 FrameState m_state;
433 FrameLoadType m_loadType;
434
435 // Document loaders for the three phases of frame loading. Note that while
436 // a new request is being loaded, the old document loader may still be referenced.
437 // E.g. while a new request is in the "policy" state, the old document loader may
438 // be consulted in particular as it makes sense to imply certain settings on the new loader.
439 RefPtr<DocumentLoader> m_documentLoader;
440 RefPtr<DocumentLoader> m_provisionalDocumentLoader;
441 RefPtr<DocumentLoader> m_policyDocumentLoader;
442
443 URL m_provisionalLoadErrorBeingHandledURL;
444
445 bool m_quickRedirectComing;
446 bool m_sentRedirectNotification;
447 bool m_inStopAllLoaders;
448 bool m_inClearProvisionalLoadForPolicyCheck { false };
449 bool m_shouldReportResourceTimingToParentFrame { true };
450
451 String m_outgoingReferrer;
452
453 bool m_isExecutingJavaScriptFormAction;
454
455 bool m_didCallImplicitClose;
456 bool m_wasUnloadEventEmitted;
457
458 PageDismissalType m_pageDismissalEventBeingDispatched { PageDismissalType::None };
459 bool m_isComplete;
460
461 RefPtr<SerializedScriptValue> m_pendingStateObject;
462
463 bool m_needsClear;
464
465 URL m_submittedFormURL;
466
467 Timer m_checkTimer;
468 bool m_shouldCallCheckCompleted;
469 bool m_shouldCallCheckLoadComplete;
470
471 Frame* m_opener;
472 HashSet<Frame*> m_openedFrames;
473
474 bool m_loadingFromCachedPage;
475
476 bool m_currentNavigationHasShownBeforeUnloadConfirmPanel;
477
478 bool m_loadsSynchronously;
479
480 SandboxFlags m_forcedSandboxFlags;
481
482 RefPtr<FrameNetworkingContext> m_networkingContext;
483
484 Optional<ResourceRequestCachePolicy> m_overrideCachePolicyForTesting;
485 Optional<ResourceLoadPriority> m_overrideResourceLoadPriorityForTesting;
486 bool m_isStrictRawResourceValidationPolicyDisabledForTesting { false };
487
488 LoadContinuingState m_currentLoadContinuingState { LoadContinuingState::NotContinuing };
489
490 bool m_checkingLoadCompleteForDetachment { false };
491
492 URL m_previousURL;
493 RefPtr<HistoryItem> m_requestedHistoryItem;
494
495 bool m_alwaysAllowLocalWebarchive { false };
496};
497
498// This function is called by createWindow() in JSDOMWindowBase.cpp, for example, for
499// modal dialog creation. The lookupFrame is for looking up the frame name in case
500// the frame name references a frame different from the openerFrame, e.g. when it is
501// "_self" or "_parent".
502//
503// FIXME: Consider making this function part of an appropriate class (not FrameLoader)
504// and moving it to a more appropriate location.
505RefPtr<Frame> createWindow(Frame& openerFrame, Frame& lookupFrame, FrameLoadRequest&&, const WindowFeatures&, bool& created);
506
507} // namespace WebCore
508