• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "PolicyChecker.h"
40 #include "ResourceLoadNotifier.h"
41 #include "ScriptValue.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*);
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     KURL iconURL();
238     void commitIconURLToIconDatabase(const KURL&);
239 
240     KURL baseURL() const;
241 
242     void handledOnloadEvents();
243     String userAgent(const KURL&) const;
244 
245     void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*);
246     void dispatchDidClearWindowObjectsInAllWorlds();
247     void dispatchDocumentElementAvailable();
248 
ownerElementSandboxFlagsChanged()249     void ownerElementSandboxFlagsChanged() { updateSandboxFlags(); }
250 
isSandboxed(SandboxFlags mask)251     bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; }
sandboxFlags()252     SandboxFlags sandboxFlags() const { return m_sandboxFlags; }
253     // The following sandbox flags will be forced, regardless of changes to
254     // the sandbox attribute of any parent frames.
setForcedSandboxFlags(SandboxFlags flags)255     void setForcedSandboxFlags(SandboxFlags flags) { m_forcedSandboxFlags = flags; m_sandboxFlags |= flags; }
256 
257     // Mixed content related functions.
258     static bool isMixedContent(SecurityOrigin* context, const KURL&);
259     void checkIfDisplayInsecureContent(SecurityOrigin* context, const KURL&);
260     void checkIfRunInsecureContent(SecurityOrigin* context, const KURL&);
261 
262     Frame* opener();
263     void setOpener(Frame*);
264 
265     bool isProcessingUserGesture();
266 
267     void resetMultipleFormSubmissionProtection();
268 
269     void checkCallImplicitClose();
270 
271     void frameDetached();
272 
273     void setOutgoingReferrer(const KURL&);
274 
275     void loadDone();
276     void finishedParsing();
277     void checkCompleted();
278 
279     void checkDidPerformFirstNavigation();
280 
281     bool isComplete() const;
282 
283     KURL completeURL(const String& url);
284 
285     void cancelAndClear();
286 
287     void setTitle(const StringWithDirection&);
288     void setIconURL(const String&);
289 
290     void commitProvisionalLoad();
isLoadingFromCachedPage()291     bool isLoadingFromCachedPage() const { return m_loadingFromCachedPage; }
292 
stateMachine()293     FrameLoaderStateMachine* stateMachine() const { return &m_stateMachine; }
294 
295     void startIconLoader();
296     void iconLoadDecisionReceived(IconLoadDecision);
297     void continueIconLoadWithDecision(IconLoadDecision);
298 
299     bool shouldAllowNavigation(Frame* targetFrame) const;
300     Frame* findFrameForNavigation(const AtomicString& name);
301 
302     void applyUserAgent(ResourceRequest& request);
303 
304     bool shouldInterruptLoadForXFrameOptions(const String&, const KURL&);
305 
306     void open(CachedFrameBase&);
307 
308 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
309     void hideMediaPlayerProxyPlugin(Widget*);
310     void showMediaPlayerProxyPlugin(Widget*);
311 #endif
312 
313     // FIXME: Should these really be public?
314     void completed();
315     bool allAncestorsAreComplete() const; // including this
316     bool allChildrenAreComplete() const; // immediate children, not all descendants
317     void clientRedirected(const KURL&, double delay, double fireDate, bool lockBackForwardList);
318     void clientRedirectCancelledOrFinished(bool cancelWithLoadInProgress);
319     void loadItem(HistoryItem*, FrameLoadType);
320 
321     // FIXME: This is public because this asynchronous callback from the FrameLoaderClient
322     // uses the policy machinery (and therefore is called via the PolicyChecker).  Once we
323     // introduce a proper callback type for this function, we should make it private again.
324     void continueLoadAfterWillSubmitForm();
325 
suppressOpenerInNewFrame()326     bool suppressOpenerInNewFrame() const { return m_suppressOpenerInNewFrame; }
327 
328     static ObjectContentType defaultObjectContentType(const KURL&, const String& mimeType, bool shouldPreferPlugInsForImages);
329 
330     void clear(bool clearWindowProperties = true, bool clearScriptObjects = true, bool clearFrameView = true);
331 
quickRedirectComing()332     bool quickRedirectComing() const { return m_quickRedirectComing; }
333 
334     bool shouldClose();
335 
336     void started();
337 
pageDismissalEventBeingDispatched()338     bool pageDismissalEventBeingDispatched() const { return m_pageDismissalEventBeingDispatched; }
339 
340     NetworkingContext* networkingContext() const;
341 
342 private:
343     void checkTimerFired(Timer<FrameLoader>*);
344 
345     void loadSameDocumentItem(HistoryItem*);
346     void loadDifferentDocumentItem(HistoryItem*, FrameLoadType);
347 
348     void loadProvisionalItemFromCachedPage();
349 
350     void receivedFirstData();
351 
352     void updateFirstPartyForCookies();
353     void setFirstPartyForCookies(const KURL&);
354 
355     void addExtraFieldsToRequest(ResourceRequest&, FrameLoadType loadType, bool isMainResource, bool cookiePolicyURLFromRequest);
356 
357     // Also not cool.
358     void stopLoadingSubframes(ClearProvisionalItemPolicy);
359 
360     void clearProvisionalLoad();
361     void markLoadComplete();
362     void transitionToCommitted(PassRefPtr<CachedPage>);
363     void frameLoadCompleted();
364 
365     void mainReceivedError(const ResourceError&, bool isComplete);
366 
367     static void callContinueLoadAfterNavigationPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue);
368     static void callContinueLoadAfterNewWindowPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, const String& frameName, const NavigationAction&, bool shouldContinue);
369     static void callContinueFragmentScrollAfterNavigationPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue);
370 
371     bool fireBeforeUnloadEvent(Chrome*);
372 
373     void continueLoadAfterNavigationPolicy(const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue);
374     void continueLoadAfterNewWindowPolicy(const ResourceRequest&, PassRefPtr<FormState>, const String& frameName, const NavigationAction&, bool shouldContinue);
375     void continueFragmentScrollAfterNavigationPolicy(const ResourceRequest&, bool shouldContinue);
376 
377     bool shouldScrollToAnchor(bool isFormSubmission, const String& httpMethod, FrameLoadType, const KURL&);
378 
379     void checkLoadCompleteForThisFrame();
380 
381     void setDocumentLoader(DocumentLoader*);
382     void setPolicyDocumentLoader(DocumentLoader*);
383     void setProvisionalDocumentLoader(DocumentLoader*);
384 
385     void setState(FrameState);
386 
387     void closeOldDataSources();
388     void prepareForCachedPageRestore();
389 
390     bool shouldReloadToHandleUnreachableURL(DocumentLoader*);
391 
392     void dispatchDidCommitLoad();
393 
394     void urlSelected(const FrameLoadRequest&, PassRefPtr<Event>, bool lockHistory, bool lockBackForwardList, ReferrerPolicy, ShouldReplaceDocumentIfJavaScriptURL);
395 
396     void loadWithDocumentLoader(DocumentLoader*, FrameLoadType, PassRefPtr<FormState>); // Calls continueLoadAfterNavigationPolicy
397     void load(DocumentLoader*);                                                         // Calls loadWithDocumentLoader
398 
399     void loadWithNavigationAction(const ResourceRequest&, const NavigationAction&,      // Calls loadWithDocumentLoader
400         bool lockHistory, FrameLoadType, PassRefPtr<FormState>);
401 
402     void loadPostRequest(const ResourceRequest&, const String& referrer,                // Called by loadFrameRequest, calls loadWithNavigationAction
403         const String& frameName, bool lockHistory, FrameLoadType, PassRefPtr<Event>, PassRefPtr<FormState>);
404     void loadURL(const KURL&, const String& referrer, const String& frameName,          // Called by loadFrameRequest, calls loadWithNavigationAction or dispatches to navigation policy delegate
405         bool lockHistory, FrameLoadType, PassRefPtr<Event>, PassRefPtr<FormState>);
406 
407     bool shouldReload(const KURL& currentURL, const KURL& destinationURL);
408 
409     void requestFromDelegate(ResourceRequest&, unsigned long& identifier, ResourceError&);
410 
411     void recursiveCheckLoadComplete();
412 
413     void detachChildren();
414     void closeAndRemoveChild(Frame*);
415 
416     void loadInSameDocument(const KURL&, SerializedScriptValue* stateObject, bool isNewNavigation);
417 
418     void provisionalLoadStarted();
419 
420     bool didOpenURL(const KURL&);
421 
422     void scheduleCheckCompleted();
423     void scheduleCheckLoadComplete();
424     void startCheckCompleteTimer();
425 
426     KURL originalRequestURL() const;
427 
428     bool shouldTreatURLAsSameAsCurrent(const KURL&) const;
429 
430     void updateSandboxFlags();
431 
432     Frame* m_frame;
433     FrameLoaderClient* m_client;
434 
435     mutable PolicyChecker m_policyChecker;
436     mutable HistoryController m_history;
437     mutable ResourceLoadNotifier m_notifer;
438     mutable SubframeLoader m_subframeLoader;
439     mutable FrameLoaderStateMachine m_stateMachine;
440 
441     FrameState m_state;
442     FrameLoadType m_loadType;
443 
444     // Document loaders for the three phases of frame loading. Note that while
445     // a new request is being loaded, the old document loader may still be referenced.
446     // E.g. while a new request is in the "policy" state, the old document loader may
447     // be consulted in particular as it makes sense to imply certain settings on the new loader.
448     RefPtr<DocumentLoader> m_documentLoader;
449     RefPtr<DocumentLoader> m_provisionalDocumentLoader;
450     RefPtr<DocumentLoader> m_policyDocumentLoader;
451 
452     bool m_delegateIsHandlingProvisionalLoadError;
453 
454     bool m_quickRedirectComing;
455     bool m_sentRedirectNotification;
456     bool m_inStopAllLoaders;
457 
458     String m_outgoingReferrer;
459 
460     bool m_isExecutingJavaScriptFormAction;
461 
462     bool m_didCallImplicitClose;
463     bool m_wasUnloadEventEmitted;
464     bool m_pageDismissalEventBeingDispatched;
465     bool m_isComplete;
466     bool m_isLoadingMainResource;
467 
468     RefPtr<SerializedScriptValue> m_pendingStateObject;
469 
470     KURL m_workingURL;
471 
472     OwnPtr<IconLoader> m_iconLoader;
473     bool m_mayLoadIconLater;
474 
475     bool m_needsClear;
476 
477     KURL m_submittedFormURL;
478 
479     Timer<FrameLoader> m_checkTimer;
480     bool m_shouldCallCheckCompleted;
481     bool m_shouldCallCheckLoadComplete;
482 
483     Frame* m_opener;
484     HashSet<Frame*> m_openedFrames;
485 
486     bool m_didPerformFirstNavigation;
487     bool m_loadingFromCachedPage;
488     bool m_suppressOpenerInNewFrame;
489 
490     SandboxFlags m_sandboxFlags;
491     SandboxFlags m_forcedSandboxFlags;
492 
493     RefPtr<FrameNetworkingContext> m_networkingContext;
494 
495     KURL m_previousUrl;
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.
505 Frame* createWindow(Frame* openerFrame, Frame* lookupFrame, const FrameLoadRequest&, const WindowFeatures&, bool& created);
506 
507 } // namespace WebCore
508 
509 #endif // FrameLoader_h
510