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