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
48namespace WebCore {
49
50class Archive;
51class AuthenticationChallenge;
52class CachedFrameBase;
53class CachedPage;
54class CachedResource;
55class Chrome;
56class DOMWrapperWorld;
57class Document;
58class DocumentLoader;
59class Event;
60class FormData;
61class FormState;
62class FormSubmission;
63class Frame;
64class FrameLoaderClient;
65class FrameNetworkingContext;
66class HistoryItem;
67class HTMLFormElement;
68class IconLoader;
69class NavigationAction;
70class NetworkingContext;
71class Page;
72class ProtectionSpace;
73class ResourceError;
74class ResourceLoader;
75class ResourceRequest;
76class ResourceResponse;
77class ScriptSourceCode;
78class ScriptValue;
79class SecurityOrigin;
80class SerializedScriptValue;
81class SharedBuffer;
82class StringWithDirection;
83class SubstituteData;
84class TextResourceDecoder;
85
86struct FrameLoadRequest;
87struct WindowFeatures;
88
89bool isBackForwardLoadType(FrameLoadType);
90
91class FrameLoader {
92    WTF_MAKE_NONCOPYABLE(FrameLoader);
93public:
94    FrameLoader(Frame*, FrameLoaderClient*);
95    ~FrameLoader();
96
97    void init();
98
99    Frame* frame() const { return m_frame; }
100
101    PolicyChecker* policyChecker() const { return &m_policyChecker; }
102    HistoryController* history() const { return &m_history; }
103    ResourceLoadNotifier* notifier() const { return &m_notifer; }
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
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;
149    DocumentLoader* documentLoader() const { return m_documentLoader.get(); }
150    DocumentLoader* policyDocumentLoader() const { return m_policyDocumentLoader.get(); }
151    DocumentLoader* provisionalDocumentLoader() const { return m_provisionalDocumentLoader.get(); }
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
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
249    void ownerElementSandboxFlagsChanged() { updateSandboxFlags(); }
250
251    bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; }
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.
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();
291    bool isLoadingFromCachedPage() const { return m_loadingFromCachedPage; }
292
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
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
332    bool quickRedirectComing() const { return m_quickRedirectComing; }
333
334    bool shouldClose();
335
336    void started();
337
338    bool pageDismissalEventBeingDispatched() const { return m_pageDismissalEventBeingDispatched; }
339
340    NetworkingContext* networkingContext() const;
341
342private:
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.
505Frame* createWindow(Frame* openerFrame, Frame* lookupFrame, const FrameLoadRequest&, const WindowFeatures&, bool& created);
506
507} // namespace WebCore
508
509#endif // FrameLoader_h
510