1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009, 2011 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  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1.  Redistributions of source code must retain the above copyright
11  *     notice, this list of conditions and the following disclaimer.
12  * 2.  Redistributions in binary form must reproduce the above copyright
13  *     notice, this list of conditions and the following disclaimer in the
14  *     documentation and/or other materials provided with the distribution.
15  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16  *     its contributors may be used to endorse or promote products derived
17  *     from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #ifndef FrameLoader_h
32 #define FrameLoader_h
33 
34 #include "CachePolicy.h"
35 #include "FrameLoaderStateMachine.h"
36 #include "FrameLoaderTypes.h"
37 #include "HistoryController.h"
38 #include "IconDatabaseBase.h"
39 #include "IconURL.h"
40 #include "PolicyChecker.h"
41 #include "ResourceLoadNotifier.h"
42 #include "SubframeLoader.h"
43 #include "ThreadableLoader.h"
44 #include "Timer.h"
45 #include <wtf/Forward.h>
46 #include <wtf/HashSet.h>
47 
48 namespace WebCore {
49 
50 class Archive;
51 class AuthenticationChallenge;
52 class CachedFrameBase;
53 class CachedPage;
54 class CachedResource;
55 class Chrome;
56 class DOMWrapperWorld;
57 class Document;
58 class DocumentLoader;
59 class Event;
60 class FormData;
61 class FormState;
62 class FormSubmission;
63 class Frame;
64 class FrameLoaderClient;
65 class FrameNetworkingContext;
66 class HistoryItem;
67 class HTMLFormElement;
68 class IconLoader;
69 class NavigationAction;
70 class NetworkingContext;
71 class Page;
72 class ProtectionSpace;
73 class ResourceError;
74 class ResourceLoader;
75 class ResourceRequest;
76 class ResourceResponse;
77 class ScriptSourceCode;
78 class ScriptValue;
79 class SecurityOrigin;
80 class SerializedScriptValue;
81 class SharedBuffer;
82 class StringWithDirection;
83 class SubstituteData;
84 class TextResourceDecoder;
85 
86 struct FrameLoadRequest;
87 struct WindowFeatures;
88 
89 bool isBackForwardLoadType(FrameLoadType);
90 
91 class FrameLoader {
92     WTF_MAKE_NONCOPYABLE(FrameLoader);
93 public:
94     FrameLoader(Frame*, FrameLoaderClient*);
95     ~FrameLoader();
96 
97     void init();
98 
frame()99     Frame* frame() const { return m_frame; }
100 
policyChecker()101     PolicyChecker* policyChecker() const { return &m_policyChecker; }
history()102     HistoryController* history() const { return &m_history; }
notifier()103     ResourceLoadNotifier* notifier() const { return &m_notifer; }
subframeLoader()104     SubframeLoader* subframeLoader() const { return &m_subframeLoader; }
105 
106     // FIXME: This is not cool, people. There are too many different functions that all start loads.
107     // We should aim to consolidate these into a smaller set of functions, and try to reuse more of
108     // the logic by extracting common code paths.
109 
110     void prepareForLoadStart();
111     void setupForReplace();
112     void setupForReplaceByMIMEType(const String& newMIMEType);
113 
114     void loadURLIntoChildFrame(const KURL&, const String& referer, Frame*);
115 
116     void loadFrameRequest(const FrameLoadRequest&, bool lockHistory, bool lockBackForwardList,  // Called by submitForm, calls loadPostRequest and loadURL.
117         PassRefPtr<Event>, PassRefPtr<FormState>, ReferrerPolicy);
118 
119     void load(const ResourceRequest&, bool lockHistory);                                        // Called by WebFrame, calls load(ResourceRequest, SubstituteData).
120     void load(const ResourceRequest&, const SubstituteData&, bool lockHistory);                 // Called both by WebFrame and internally, calls load(DocumentLoader*).
121     void load(const ResourceRequest&, const String& frameName, bool lockHistory);               // Called by WebPluginController.
122 
123 #if ENABLE(WEB_ARCHIVE)
124     void loadArchive(PassRefPtr<Archive>);
125 #endif
126 
127     static void reportLocalLoadFailed(Frame*, const String& url);
128 
129     unsigned long loadResourceSynchronously(const ResourceRequest&, StoredCredentials, ResourceError&, ResourceResponse&, Vector<char>& data);
130 
131     bool canHandleRequest(const ResourceRequest&);
132 
133     // Also not cool.
134     void stopAllLoaders(ClearProvisionalItemPolicy = ShouldClearProvisionalItem);
135     void stopForUserCancel(bool deferCheckLoadComplete = false);
136 
isLoadingMainResource()137     bool isLoadingMainResource() const { return m_isLoadingMainResource; }
138     bool isLoading() const;
139     bool frameHasLoaded() const;
140     void transferLoadingResourcesFromPage(Page*);
141     void dispatchTransferLoadingResourceFromPage(unsigned long, DocumentLoader*, const ResourceRequest&, Page*);
142 
143     int numPendingOrLoadingRequests(bool recurse) const;
144     String referrer() const;
145     String outgoingReferrer() const;
146     String outgoingOrigin() const;
147 
148     DocumentLoader* activeDocumentLoader() const;
documentLoader()149     DocumentLoader* documentLoader() const { return m_documentLoader.get(); }
policyDocumentLoader()150     DocumentLoader* policyDocumentLoader() const { return m_policyDocumentLoader.get(); }
provisionalDocumentLoader()151     DocumentLoader* provisionalDocumentLoader() const { return m_provisionalDocumentLoader.get(); }
state()152     FrameState state() const { return m_state; }
153     static double timeOfLastCompletedLoad();
154 
155     bool shouldUseCredentialStorage(ResourceLoader*);
156 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
157     bool canAuthenticateAgainstProtectionSpace(ResourceLoader* loader, const ProtectionSpace& protectionSpace);
158 #endif
159     const ResourceRequest& originalRequest() const;
160     const ResourceRequest& initialRequest() const;
161     void receivedMainResourceError(const ResourceError&, bool isComplete);
162 
163     bool willLoadMediaElementURL(KURL&);
164 
165     void handleFallbackContent();
166     bool isStopping() const;
167 
168     void finishedLoading();
169 
170     ResourceError cancelledError(const ResourceRequest&) const;
171     ResourceError fileDoesNotExistError(const ResourceResponse&) const;
172     ResourceError blockedError(const ResourceRequest&) const;
173     ResourceError cannotShowURLError(const ResourceRequest&) const;
174     ResourceError interruptionForPolicyChangeError(const ResourceRequest&) const;
175 
176     bool isHostedByObjectElement() const;
177     bool isLoadingMainFrame() const;
178     bool canShowMIMEType(const String& MIMEType) const;
179     bool representationExistsForURLScheme(const String& URLScheme);
180     String generatedMIMETypeForURLScheme(const String& URLScheme);
181 
182     void reload(bool endToEndReload = false);
183     void reloadWithOverrideEncoding(const String& overrideEncoding);
184 
185     void didReceiveServerRedirectForProvisionalLoadForFrame();
186     void finishedLoadingDocument(DocumentLoader*);
187     bool isReplacing() const;
188     void setReplacing();
189     void revertToProvisional(DocumentLoader*);
190     void setMainDocumentError(DocumentLoader*, const ResourceError&);
191     void mainReceivedCompleteError(DocumentLoader*, const ResourceError&);
192     bool subframeIsLoading() const;
193     void willChangeTitle(DocumentLoader*);
194     void didChangeTitle(DocumentLoader*);
195     void didChangeIcons(DocumentLoader*, IconType);
196 
197     FrameLoadType loadType() const;
198 
199     CachePolicy subresourceCachePolicy() const;
200 
201     void didFirstLayout();
202 
203     void didFirstVisuallyNonEmptyLayout();
204 
205     void loadedResourceFromMemoryCache(const CachedResource*);
206     void tellClientAboutPastMemoryCacheLoads();
207 
208     void checkLoadComplete();
209     void detachFromParent();
210     void detachViewsAndDocumentLoader();
211 
212     void addExtraFieldsToSubresourceRequest(ResourceRequest&);
213     void addExtraFieldsToMainResourceRequest(ResourceRequest&);
214 
215     static void addHTTPOriginIfNeeded(ResourceRequest&, String origin);
216 
client()217     FrameLoaderClient* client() const { return m_client; }
218 
219     void setDefersLoading(bool);
220 
221     void changeLocation(PassRefPtr<SecurityOrigin>, const KURL&, const String& referrer, bool lockHistory = true, bool lockBackForwardList = true, bool refresh = false);
222     void urlSelected(const KURL&, const String& target, PassRefPtr<Event>, bool lockHistory, bool lockBackForwardList, ReferrerPolicy);
223 
224     void submitForm(PassRefPtr<FormSubmission>);
225 
226     void stop();
227     void stopLoading(UnloadEventPolicy);
228     bool closeURL();
229 
230     void didExplicitOpen();
231 
232     // Callbacks from DocumentWriter
233     void didBeginDocument(bool dispatchWindowObjectAvailable);
234     void didEndDocument();
235     void willSetEncoding();
236 
237     // Returns favicon.
238     KURL iconURL();
239 
240     // Returns the given iconTypes' IconURLs, iconTypes could be any combination of IconType.
241     IconURLs iconURLs(int iconTypes);
242     void commitIconURLToIconDatabase(const KURL&);
243 
244     KURL baseURL() const;
245 
246     void handledOnloadEvents();
247     String userAgent(const KURL&) const;
248 
249     void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*);
250     void dispatchDidClearWindowObjectsInAllWorlds();
251     void dispatchDocumentElementAvailable();
252 
ownerElementSandboxFlagsChanged()253     void ownerElementSandboxFlagsChanged() { updateSandboxFlags(); }
254 
isSandboxed(SandboxFlags mask)255     bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; }
sandboxFlags()256     SandboxFlags sandboxFlags() const { return m_sandboxFlags; }
257     // The following sandbox flags will be forced, regardless of changes to
258     // the sandbox attribute of any parent frames.
setForcedSandboxFlags(SandboxFlags flags)259     void setForcedSandboxFlags(SandboxFlags flags) { m_forcedSandboxFlags = flags; m_sandboxFlags |= flags; }
260 
261     // Mixed content related functions.
262     static bool isMixedContent(SecurityOrigin* context, const KURL&);
263     bool checkIfDisplayInsecureContent(SecurityOrigin* context, const KURL&);
264     bool checkIfRunInsecureContent(SecurityOrigin* context, const KURL&);
265 
266     Frame* opener();
267     void setOpener(Frame*);
268 
269     bool isProcessingUserGesture();
270 
271     void resetMultipleFormSubmissionProtection();
272 
273     void checkCallImplicitClose();
274 
275     void frameDetached();
276 
277     void setOutgoingReferrer(const KURL&);
278 
279     void loadDone();
280     void finishedParsing();
281     void checkCompleted();
282 
283     void checkDidPerformFirstNavigation();
284 
285     bool isComplete() const;
286 
287     KURL completeURL(const String& url);
288 
289     void cancelAndClear();
290 
291     void setTitle(const StringWithDirection&);
292     void setIconURL(const IconURL&);
293 
294     void commitProvisionalLoad();
isLoadingFromCachedPage()295     bool isLoadingFromCachedPage() const { return m_loadingFromCachedPage; }
296 
stateMachine()297     FrameLoaderStateMachine* stateMachine() const { return &m_stateMachine; }
298 
299     void startIconLoader();
300     void iconLoadDecisionReceived(IconLoadDecision);
301     void continueIconLoadWithDecision(IconLoadDecision);
302 
303     bool shouldAllowNavigation(Frame* targetFrame) const;
304     Frame* findFrameForNavigation(const AtomicString& name);
305 
306     void applyUserAgent(ResourceRequest& request);
307 
308     bool shouldInterruptLoadForXFrameOptions(const String&, const KURL&);
309 
310     void open(CachedFrameBase&);
311 
312 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
313     void hideMediaPlayerProxyPlugin(Widget*);
314     void showMediaPlayerProxyPlugin(Widget*);
315 #endif
316 
317     // FIXME: Should these really be public?
318     void completed();
319     bool allAncestorsAreComplete() const; // including this
320     bool allChildrenAreComplete() const; // immediate children, not all descendants
321     void clientRedirected(const KURL&, double delay, double fireDate, bool lockBackForwardList);
322     void clientRedirectCancelledOrFinished(bool cancelWithLoadInProgress);
323     void loadItem(HistoryItem*, FrameLoadType);
324 
325     // FIXME: This is public because this asynchronous callback from the FrameLoaderClient
326     // uses the policy machinery (and therefore is called via the PolicyChecker).  Once we
327     // introduce a proper callback type for this function, we should make it private again.
328     void continueLoadAfterWillSubmitForm();
329 
suppressOpenerInNewFrame()330     bool suppressOpenerInNewFrame() const { return m_suppressOpenerInNewFrame; }
331 
332     static ObjectContentType defaultObjectContentType(const KURL&, const String& mimeType, bool shouldPreferPlugInsForImages);
333 
334     void clear(bool clearWindowProperties = true, bool clearScriptObjects = true, bool clearFrameView = true);
335 
quickRedirectComing()336     bool quickRedirectComing() const { return m_quickRedirectComing; }
337 
338     bool shouldClose();
339 
340     void started();
341 
pageDismissalEventBeingDispatched()342     bool pageDismissalEventBeingDispatched() const { return m_pageDismissalEventBeingDispatched; }
343 
344     NetworkingContext* networkingContext() const;
345 
346 private:
347     void checkTimerFired(Timer<FrameLoader>*);
348 
349     void loadSameDocumentItem(HistoryItem*);
350     void loadDifferentDocumentItem(HistoryItem*, FrameLoadType);
351 
352     void loadProvisionalItemFromCachedPage();
353 
354     void receivedFirstData();
355 
356     void updateFirstPartyForCookies();
357     void setFirstPartyForCookies(const KURL&);
358 
359     void addExtraFieldsToRequest(ResourceRequest&, FrameLoadType, bool isMainResource);
360 
361     // Also not cool.
362     void stopLoadingSubframes(ClearProvisionalItemPolicy);
363 
364     void clearProvisionalLoad();
365     void markLoadComplete();
366     void transitionToCommitted(PassRefPtr<CachedPage>);
367     void frameLoadCompleted();
368 
369     void mainReceivedError(const ResourceError&, bool isComplete);
370 
371     static void callContinueLoadAfterNavigationPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue);
372     static void callContinueLoadAfterNewWindowPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, const String& frameName, const NavigationAction&, bool shouldContinue);
373     static void callContinueFragmentScrollAfterNavigationPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue);
374 
375     bool fireBeforeUnloadEvent(Chrome*);
376 
377     void continueLoadAfterNavigationPolicy(const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue);
378     void continueLoadAfterNewWindowPolicy(const ResourceRequest&, PassRefPtr<FormState>, const String& frameName, const NavigationAction&, bool shouldContinue);
379     void continueFragmentScrollAfterNavigationPolicy(const ResourceRequest&, bool shouldContinue);
380 
381     bool shouldScrollToAnchor(bool isFormSubmission, const String& httpMethod, FrameLoadType, const KURL&);
382 
383     void checkLoadCompleteForThisFrame();
384 
385     void setDocumentLoader(DocumentLoader*);
386     void setPolicyDocumentLoader(DocumentLoader*);
387     void setProvisionalDocumentLoader(DocumentLoader*);
388 
389     void setState(FrameState);
390 
391     void closeOldDataSources();
392     void prepareForCachedPageRestore();
393 
394     bool shouldReloadToHandleUnreachableURL(DocumentLoader*);
395 
396     void dispatchDidCommitLoad();
397 
398     void urlSelected(const FrameLoadRequest&, PassRefPtr<Event>, bool lockHistory, bool lockBackForwardList, ReferrerPolicy, ShouldReplaceDocumentIfJavaScriptURL);
399 
400     void loadWithDocumentLoader(DocumentLoader*, FrameLoadType, PassRefPtr<FormState>); // Calls continueLoadAfterNavigationPolicy
401     void load(DocumentLoader*);                                                         // Calls loadWithDocumentLoader
402 
403     void loadWithNavigationAction(const ResourceRequest&, const NavigationAction&,      // Calls loadWithDocumentLoader
404         bool lockHistory, FrameLoadType, PassRefPtr<FormState>);
405 
406     void loadPostRequest(const ResourceRequest&, const String& referrer,                // Called by loadFrameRequest, calls loadWithNavigationAction
407         const String& frameName, bool lockHistory, FrameLoadType, PassRefPtr<Event>, PassRefPtr<FormState>);
408     void loadURL(const KURL&, const String& referrer, const String& frameName,          // Called by loadFrameRequest, calls loadWithNavigationAction or dispatches to navigation policy delegate
409         bool lockHistory, FrameLoadType, PassRefPtr<Event>, PassRefPtr<FormState>);
410 
411     bool shouldReload(const KURL& currentURL, const KURL& destinationURL);
412 
413     void requestFromDelegate(ResourceRequest&, unsigned long& identifier, ResourceError&);
414 
415     void recursiveCheckLoadComplete();
416 
417     void detachChildren();
418     void closeAndRemoveChild(Frame*);
419 
420     void loadInSameDocument(const KURL&, SerializedScriptValue* stateObject, bool isNewNavigation);
421 
422     void provisionalLoadStarted();
423 
424     bool didOpenURL(const KURL&);
425 
426     void scheduleCheckCompleted();
427     void scheduleCheckLoadComplete();
428     void startCheckCompleteTimer();
429 
430     KURL originalRequestURL() const;
431 
432     bool shouldTreatURLAsSameAsCurrent(const KURL&) const;
433 
434     void updateSandboxFlags();
435 
436     bool fillIconURL(IconType, IconURLs*);
437     IconURL getDefaultIconURL(IconType);
438 
439     Frame* m_frame;
440     FrameLoaderClient* m_client;
441 
442     mutable PolicyChecker m_policyChecker;
443     mutable HistoryController m_history;
444     mutable ResourceLoadNotifier m_notifer;
445     mutable SubframeLoader m_subframeLoader;
446     mutable FrameLoaderStateMachine m_stateMachine;
447 
448     FrameState m_state;
449     FrameLoadType m_loadType;
450 
451     // Document loaders for the three phases of frame loading. Note that while
452     // a new request is being loaded, the old document loader may still be referenced.
453     // E.g. while a new request is in the "policy" state, the old document loader may
454     // be consulted in particular as it makes sense to imply certain settings on the new loader.
455     RefPtr<DocumentLoader> m_documentLoader;
456     RefPtr<DocumentLoader> m_provisionalDocumentLoader;
457     RefPtr<DocumentLoader> m_policyDocumentLoader;
458 
459     bool m_delegateIsHandlingProvisionalLoadError;
460 
461     bool m_quickRedirectComing;
462     bool m_sentRedirectNotification;
463     bool m_inStopAllLoaders;
464 
465     String m_outgoingReferrer;
466 
467     bool m_isExecutingJavaScriptFormAction;
468 
469     bool m_didCallImplicitClose;
470     bool m_wasUnloadEventEmitted;
471     bool m_pageDismissalEventBeingDispatched;
472     bool m_isComplete;
473     bool m_isLoadingMainResource;
474 
475     RefPtr<SerializedScriptValue> m_pendingStateObject;
476 
477     KURL m_workingURL;
478 
479     OwnPtr<IconLoader> m_iconLoader;
480     bool m_mayLoadIconLater;
481 
482     bool m_needsClear;
483 
484     KURL m_submittedFormURL;
485 
486     Timer<FrameLoader> m_checkTimer;
487     bool m_shouldCallCheckCompleted;
488     bool m_shouldCallCheckLoadComplete;
489 
490     Frame* m_opener;
491     HashSet<Frame*> m_openedFrames;
492 
493     bool m_didPerformFirstNavigation;
494     bool m_loadingFromCachedPage;
495     bool m_suppressOpenerInNewFrame;
496 
497     SandboxFlags m_sandboxFlags;
498     SandboxFlags m_forcedSandboxFlags;
499 
500     RefPtr<FrameNetworkingContext> m_networkingContext;
501 
502     KURL m_previousUrl;
503 };
504 
505 // This function is called by createWindow() in JSDOMWindowBase.cpp, for example, for
506 // modal dialog creation.  The lookupFrame is for looking up the frame name in case
507 // the frame name references a frame different from the openerFrame, e.g. when it is
508 // "_self" or "_parent".
509 //
510 // FIXME: Consider making this function part of an appropriate class (not FrameLoader)
511 // and moving it to a more appropriate location.
512 Frame* createWindow(Frame* openerFrame, Frame* lookupFrame, const FrameLoadRequest&, const WindowFeatures&, bool& created);
513 
514 } // namespace WebCore
515 
516 #endif // FrameLoader_h
517