Home | History | Annotate | Download | only in loader
      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  * 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 Computer, 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 #ifndef FrameLoader_h
     33 #define FrameLoader_h
     34 
     35 #include "core/dom/IconURL.h"
     36 #include "core/dom/SandboxFlags.h"
     37 #include "core/dom/SecurityContext.h"
     38 #include "core/fetch/ResourceLoaderOptions.h"
     39 #include "core/history/HistoryItem.h"
     40 #include "core/loader/FrameLoaderStateMachine.h"
     41 #include "core/loader/FrameLoaderTypes.h"
     42 #include "core/loader/MixedContentChecker.h"
     43 #include "platform/Timer.h"
     44 #include "wtf/Forward.h"
     45 #include "wtf/HashSet.h"
     46 #include "wtf/OwnPtr.h"
     47 
     48 namespace WebCore {
     49 
     50 class Resource;
     51 class Chrome;
     52 class DOMWrapperWorld;
     53 class DocumentLoader;
     54 class Event;
     55 class FetchContext;
     56 class FormState;
     57 class FormSubmission;
     58 class FrameLoaderClient;
     59 class IconController;
     60 class NavigationAction;
     61 class Page;
     62 class ResourceError;
     63 class ResourceRequest;
     64 class ResourceResponse;
     65 class SecurityOrigin;
     66 class SerializedScriptValue;
     67 class SubstituteData;
     68 
     69 struct FrameLoadRequest;
     70 struct WindowFeatures;
     71 
     72 bool isBackForwardLoadType(FrameLoadType);
     73 
     74 class FrameLoader {
     75     WTF_MAKE_NONCOPYABLE(FrameLoader);
     76 public:
     77     FrameLoader(Frame*, FrameLoaderClient*);
     78     ~FrameLoader();
     79 
     80     void init();
     81 
     82     Frame* frame() const { return m_frame; }
     83 
     84     MixedContentChecker* mixedContentChecker() const { return &m_mixedContentChecker; }
     85 
     86     // These functions start a load. All eventually call into loadWithNavigationAction() or loadInSameDocument().
     87     void load(const FrameLoadRequest&); // The entry point for non-reload, non-history loads.
     88     void reload(ReloadPolicy = NormalReload, const KURL& overrideURL = KURL(), const AtomicString& overrideEncoding = nullAtom);
     89     void loadHistoryItem(HistoryItem*, HistoryLoadType = HistoryDifferentDocumentLoad); // The entry point for all back/forward loads
     90 
     91     static void reportLocalLoadFailed(Frame*, const String& url);
     92 
     93     // FIXME: These are all functions which stop loads. We have too many.
     94     // Warning: stopAllLoaders can and will detach the Frame out from under you. All callers need to either protect the Frame
     95     // or guarantee they won't in any way access the Frame after stopAllLoaders returns.
     96     void stopAllLoaders();
     97     void stopLoading();
     98     bool closeURL();
     99     // FIXME: clear() is trying to do too many things. We should break it down into smaller functions.
    100     void clear(ClearOptions);
    101 
    102     // Sets a timer to notify the client that the initial empty document has
    103     // been accessed, and thus it is no longer safe to show a provisional URL
    104     // above the document without risking a URL spoof.
    105     void didAccessInitialDocument();
    106 
    107     // If the initial empty document is showing and has been accessed, this
    108     // cancels the timer and immediately notifies the client in cases that
    109     // waiting to notify would allow a URL spoof.
    110     void notifyIfInitialDocumentAccessed();
    111 
    112     bool isLoading() const;
    113 
    114     int numPendingOrLoadingRequests(bool recurse) const;
    115 
    116     DocumentLoader* activeDocumentLoader() const;
    117     DocumentLoader* documentLoader() const { return m_documentLoader.get(); }
    118     DocumentLoader* policyDocumentLoader() const { return m_policyDocumentLoader.get(); }
    119     DocumentLoader* provisionalDocumentLoader() const { return m_provisionalDocumentLoader.get(); }
    120     FrameState state() const { return m_state; }
    121     FetchContext& fetchContext() const { return *m_fetchContext; }
    122 
    123     const ResourceRequest& originalRequest() const;
    124     void receivedMainResourceError(const ResourceError&);
    125 
    126     bool isLoadingMainFrame() const;
    127 
    128     bool subframeIsLoading() const;
    129 
    130     bool shouldTreatURLAsSameAsCurrent(const KURL&) const;
    131     bool shouldTreatURLAsSrcdocDocument(const KURL&) const;
    132 
    133     FrameLoadType loadType() const;
    134     void setLoadType(FrameLoadType loadType) { m_loadType = loadType; }
    135 
    136     void didFirstLayout();
    137 
    138     void checkLoadComplete(DocumentLoader*);
    139     void checkLoadComplete();
    140     void detachFromParent();
    141 
    142     void addExtraFieldsToRequest(ResourceRequest&);
    143 
    144     static void addHTTPOriginIfNeeded(ResourceRequest&, const AtomicString& origin);
    145 
    146     FrameLoaderClient* client() const { return m_client; }
    147 
    148     void setDefersLoading(bool);
    149 
    150     void didExplicitOpen();
    151 
    152     // Callbacks from DocumentWriter
    153     void didBeginDocument(bool dispatchWindowObjectAvailable);
    154 
    155     void receivedFirstData();
    156 
    157     String userAgent(const KURL&) const;
    158 
    159     void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*);
    160     void dispatchDidClearWindowObjectsInAllWorlds();
    161     void dispatchDocumentElementAvailable();
    162 
    163     // The following sandbox flags will be forced, regardless of changes to
    164     // the sandbox attribute of any parent frames.
    165     void forceSandboxFlags(SandboxFlags flags) { m_forcedSandboxFlags |= flags; }
    166     SandboxFlags effectiveSandboxFlags() const;
    167 
    168     Frame* opener();
    169     void setOpener(Frame*);
    170 
    171     void frameDetached();
    172 
    173     void loadDone();
    174     void finishedParsing();
    175     void checkCompleted();
    176 
    177     void commitProvisionalLoad();
    178 
    179     FrameLoaderStateMachine* stateMachine() const { return &m_stateMachine; }
    180 
    181     Frame* findFrameForNavigation(const AtomicString& name, Document* activeDocument);
    182 
    183     void applyUserAgent(ResourceRequest&);
    184 
    185     bool shouldInterruptLoadForXFrameOptions(const String&, const KURL&, unsigned long requestIdentifier);
    186 
    187     bool allAncestorsAreComplete() const; // including this
    188 
    189     bool shouldClose();
    190 
    191     void started();
    192 
    193     bool allowPlugins(ReasonForCallingAllowPlugins);
    194 
    195     enum UpdateBackForwardListPolicy {
    196         UpdateBackForwardList,
    197         DoNotUpdateBackForwardList
    198     };
    199     void updateForSameDocumentNavigation(const KURL&, SameDocumentNavigationSource, PassRefPtr<SerializedScriptValue>, UpdateBackForwardListPolicy);
    200 
    201     HistoryItem* currentItem() const { return m_currentItem.get(); }
    202     void saveDocumentAndScrollState();
    203     void clearScrollPositionAndViewState();
    204 
    205     enum RestorePolicy {
    206         StandardRestore,
    207         ForcedRestoreForSameDocumentHistoryNavigation
    208     };
    209     void restoreScrollPositionAndViewState(RestorePolicy = StandardRestore);
    210 
    211 private:
    212     bool allChildrenAreComplete() const; // immediate children, not all descendants
    213 
    214     void completed();
    215 
    216     void checkTimerFired(Timer<FrameLoader>*);
    217     void didAccessInitialDocumentTimerFired(Timer<FrameLoader>*);
    218 
    219     bool prepareRequestForThisFrame(FrameLoadRequest&);
    220     void setReferrerForFrameRequest(ResourceRequest&, ShouldSendReferrer, Document*);
    221     FrameLoadType determineFrameLoadType(const FrameLoadRequest&);
    222     bool isScriptTriggeredFormSubmissionInChildFrame(const FrameLoadRequest&) const;
    223 
    224     SubstituteData defaultSubstituteDataForURL(const KURL&);
    225 
    226     void checkNavigationPolicyAndContinueFragmentScroll(const NavigationAction&, bool isNewNavigation, ClientRedirectPolicy);
    227 
    228     bool shouldPerformFragmentNavigation(bool isFormSubmission, const String& httpMethod, FrameLoadType, const KURL&);
    229     void scrollToFragmentWithParentBoundary(const KURL&);
    230 
    231     void checkLoadCompleteForThisFrame();
    232 
    233     void closeOldDataSources();
    234 
    235     // Calls continueLoadAfterNavigationPolicy
    236     void loadWithNavigationAction(const NavigationAction&, FrameLoadType, PassRefPtr<FormState>,
    237         const SubstituteData&, ClientRedirectPolicy = NotClientRedirect, const AtomicString& overrideEncoding = nullAtom);
    238 
    239     void detachChildren();
    240     void closeAndRemoveChild(Frame*);
    241 
    242     enum HistoryItemPolicy {
    243         CreateNewHistoryItem,
    244         DoNotCreateNewHistoryItem
    245     };
    246     void setHistoryItemStateForCommit(HistoryItemPolicy);
    247 
    248     void loadInSameDocument(const KURL&, PassRefPtr<SerializedScriptValue> stateObject, bool isNewNavigation, ClientRedirectPolicy);
    249 
    250     void scheduleCheckCompleted();
    251     void startCheckCompleteTimer();
    252 
    253     Frame* m_frame;
    254     FrameLoaderClient* m_client;
    255 
    256     // FIXME: These should be OwnPtr<T> to reduce build times and simplify
    257     // header dependencies unless performance testing proves otherwise.
    258     // Some of these could be lazily created for memory savings on devices.
    259     mutable FrameLoaderStateMachine m_stateMachine;
    260     mutable MixedContentChecker m_mixedContentChecker;
    261 
    262     class FrameProgressTracker;
    263     OwnPtr<FrameProgressTracker> m_progressTracker;
    264 
    265     FrameState m_state;
    266     FrameLoadType m_loadType;
    267 
    268     // Document loaders for the three phases of frame loading. Note that while
    269     // a new request is being loaded, the old document loader may still be referenced.
    270     // E.g. while a new request is in the "policy" state, the old document loader may
    271     // be consulted in particular as it makes sense to imply certain settings on the new loader.
    272     RefPtr<DocumentLoader> m_documentLoader;
    273     RefPtr<DocumentLoader> m_provisionalDocumentLoader;
    274     RefPtr<DocumentLoader> m_policyDocumentLoader;
    275     OwnPtr<FetchContext> m_fetchContext;
    276 
    277     RefPtr<HistoryItem> m_currentItem;
    278 
    279     bool m_inStopAllLoaders;
    280 
    281     // FIXME: This is only used in checkCompleted(). Figure out a way to disentangle it.
    282     bool m_isComplete;
    283 
    284     Timer<FrameLoader> m_checkTimer;
    285     bool m_shouldCallCheckCompleted;
    286 
    287     Frame* m_opener;
    288     HashSet<Frame*> m_openedFrames;
    289 
    290     bool m_didAccessInitialDocument;
    291     Timer<FrameLoader> m_didAccessInitialDocumentTimer;
    292 
    293     SandboxFlags m_forcedSandboxFlags;
    294 };
    295 
    296 } // namespace WebCore
    297 
    298 #endif // FrameLoader_h
    299