Home | History | Annotate | Download | only in loader
      1 /*
      2  * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     14  *     its contributors may be used to endorse or promote products derived
     15  *     from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #ifndef DocumentLoader_h
     30 #define DocumentLoader_h
     31 
     32 #include "NavigationAction.h"
     33 #include "ResourceError.h"
     34 #include "ResourceRequest.h"
     35 #include "ResourceResponse.h"
     36 #include "SubstituteData.h"
     37 #include "Timer.h"
     38 
     39 namespace WebCore {
     40 
     41     class ApplicationCacheHost;
     42 #if ENABLE(ARCHIVE) // ANDROID extension: disabled to reduce code size
     43     class Archive;
     44     class ArchiveResource;
     45     class ArchiveResourceCollection;
     46 #endif
     47     class Frame;
     48     class FrameLoader;
     49     class MainResourceLoader;
     50     class ResourceLoader;
     51     class SchedulePair;
     52     class SharedBuffer;
     53     class SubstituteResource;
     54 
     55     typedef HashSet<RefPtr<ResourceLoader> > ResourceLoaderSet;
     56     typedef Vector<ResourceResponse> ResponseVector;
     57 
     58     class DocumentLoader : public RefCounted<DocumentLoader> {
     59     public:
     60         static PassRefPtr<DocumentLoader> create(const ResourceRequest& request, const SubstituteData& data)
     61         {
     62             return adoptRef(new DocumentLoader(request, data));
     63         }
     64         virtual ~DocumentLoader();
     65 
     66         void setFrame(Frame*);
     67         Frame* frame() const { return m_frame; }
     68 
     69         virtual void attachToFrame();
     70         virtual void detachFromFrame();
     71 
     72         FrameLoader* frameLoader() const;
     73         MainResourceLoader* mainResourceLoader() const { return m_mainResourceLoader.get(); }
     74         PassRefPtr<SharedBuffer> mainResourceData() const;
     75 
     76         const ResourceRequest& originalRequest() const;
     77         const ResourceRequest& originalRequestCopy() const;
     78 
     79         const ResourceRequest& request() const;
     80         ResourceRequest& request();
     81         void setRequest(const ResourceRequest&);
     82 
     83         const SubstituteData& substituteData() const { return m_substituteData; }
     84 
     85         const KURL& url() const;
     86         const KURL& unreachableURL() const;
     87 
     88         const KURL& originalURL() const;
     89         const KURL& requestURL() const;
     90         const KURL& responseURL() const;
     91         const String& responseMIMEType() const;
     92 
     93         void replaceRequestURLForSameDocumentNavigation(const KURL&);
     94         bool isStopping() const { return m_isStopping; }
     95         void stopLoading(DatabasePolicy = DatabasePolicyStop);
     96         void setCommitted(bool committed) { m_committed = committed; }
     97         bool isCommitted() const { return m_committed; }
     98         bool isLoading() const { return m_loading; }
     99         void setLoading(bool loading) { m_loading = loading; }
    100         void updateLoading();
    101         void receivedData(const char*, int);
    102         void setupForReplaceByMIMEType(const String& newMIMEType);
    103         void finishedLoading();
    104         const ResourceResponse& response() const { return m_response; }
    105         const ResourceError& mainDocumentError() const { return m_mainDocumentError; }
    106         void mainReceivedError(const ResourceError&, bool isComplete);
    107         void setResponse(const ResourceResponse& response) { m_response = response; }
    108         void prepareForLoadStart();
    109         bool isClientRedirect() const { return m_isClientRedirect; }
    110         void setIsClientRedirect(bool isClientRedirect) { m_isClientRedirect = isClientRedirect; }
    111         bool isLoadingInAPISense() const;
    112         void setPrimaryLoadComplete(bool);
    113         void setTitle(const String&);
    114         const String& overrideEncoding() const { return m_overrideEncoding; }
    115 
    116 #if PLATFORM(MAC)
    117         void schedule(SchedulePair*);
    118         void unschedule(SchedulePair*);
    119 #endif
    120 
    121 #if ENABLE(ARCHIVE) // ANDROID extension: disabled to reduce code size
    122         void addAllArchiveResources(Archive*);
    123         void addArchiveResource(PassRefPtr<ArchiveResource>);
    124 
    125         // Return an ArchiveResource for the URL, either creating from live data or
    126         // pulling from the ArchiveResourceCollection
    127         PassRefPtr<ArchiveResource> subresource(const KURL&) const;
    128         // Return the ArchiveResource for the URL only when loading an Archive
    129         ArchiveResource* archiveResourceForURL(const KURL&) const;
    130 
    131         PassRefPtr<Archive> popArchiveForSubframe(const String& frameName);
    132         void clearArchiveResources();
    133         void setParsedArchiveData(PassRefPtr<SharedBuffer>);
    134         SharedBuffer* parsedArchiveData() const;
    135 
    136         PassRefPtr<ArchiveResource> mainResource() const;
    137         void getSubresources(Vector<PassRefPtr<ArchiveResource> >&) const;
    138 
    139         bool scheduleArchiveLoad(ResourceLoader*, const ResourceRequest&, const KURL&);
    140 #endif
    141 #ifndef NDEBUG
    142         bool isSubstituteLoadPending(ResourceLoader*) const;
    143 #endif
    144         void cancelPendingSubstituteLoad(ResourceLoader*);
    145 
    146         void addResponse(const ResourceResponse&);
    147         const ResponseVector& responses() const { return m_responses; }
    148 
    149         const NavigationAction& triggeringAction() const { return m_triggeringAction; }
    150         void setTriggeringAction(const NavigationAction& action) { m_triggeringAction = action; }
    151         void setOverrideEncoding(const String& encoding) { m_overrideEncoding = encoding; }
    152         void setLastCheckedRequest(const ResourceRequest& request) { m_lastCheckedRequest = request; }
    153         const ResourceRequest& lastCheckedRequest()  { return m_lastCheckedRequest; }
    154 
    155         void stopRecordingResponses();
    156         const String& title() const { return m_pageTitle; }
    157 
    158         KURL urlForHistory() const;
    159         bool urlForHistoryReflectsFailure() const;
    160 
    161         // These accessors accommodate WebCore's somewhat fickle custom of creating history
    162         // items for redirects, but only sometimes. For "source" and "destination",
    163         // these accessors return the URL that would have been used if a history
    164         // item were created. This allows WebKit to link history items reflecting
    165         // redirects into a chain from start to finish.
    166         String clientRedirectSourceForHistory() const { return m_clientRedirectSourceForHistory; } // null if no client redirect occurred.
    167         String clientRedirectDestinationForHistory() const { return urlForHistory(); }
    168         void setClientRedirectSourceForHistory(const String& clientedirectSourceForHistory) { m_clientRedirectSourceForHistory = clientedirectSourceForHistory; }
    169 
    170         String serverRedirectSourceForHistory() const { return urlForHistory() == url() ? String() : urlForHistory(); } // null if no server redirect occurred.
    171         String serverRedirectDestinationForHistory() const { return url(); }
    172 
    173         bool didCreateGlobalHistoryEntry() const { return m_didCreateGlobalHistoryEntry; }
    174         void setDidCreateGlobalHistoryEntry(bool didCreateGlobalHistoryEntry) { m_didCreateGlobalHistoryEntry = didCreateGlobalHistoryEntry; }
    175 
    176         void setDefersLoading(bool);
    177 
    178         bool startLoadingMainResource(unsigned long identifier);
    179         void cancelMainResourceLoad(const ResourceError&);
    180 
    181         void iconLoadDecisionAvailable();
    182 
    183         bool isLoadingMainResource() const;
    184         bool isLoadingSubresources() const;
    185         bool isLoadingPlugIns() const;
    186         bool isLoadingMultipartContent() const;
    187 
    188         void stopLoadingPlugIns();
    189         void stopLoadingSubresources();
    190 
    191         void addSubresourceLoader(ResourceLoader*);
    192         void removeSubresourceLoader(ResourceLoader*);
    193         void addPlugInStreamLoader(ResourceLoader*);
    194         void removePlugInStreamLoader(ResourceLoader*);
    195 
    196         void subresourceLoaderFinishedLoadingOnePart(ResourceLoader*);
    197 
    198         void setDeferMainResourceDataLoad(bool defer) { m_deferMainResourceDataLoad = defer; }
    199         bool deferMainResourceDataLoad() const { return m_deferMainResourceDataLoad; }
    200 
    201         void didTellClientAboutLoad(const String& url) { m_resourcesClientKnowsAbout.add(url); }
    202         bool haveToldClientAboutLoad(const String& url) { return m_resourcesClientKnowsAbout.contains(url); }
    203         void recordMemoryCacheLoadForFutureClientNotification(const String& url);
    204         void takeMemoryCacheLoadsForClientNotification(Vector<String>& loads);
    205 
    206 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
    207         ApplicationCacheHost* applicationCacheHost() const { return m_applicationCacheHost.get(); }
    208 #endif
    209 
    210     protected:
    211         DocumentLoader(const ResourceRequest&, const SubstituteData&);
    212 
    213         bool m_deferMainResourceDataLoad;
    214 
    215     private:
    216         void setupForReplace();
    217         void commitIfReady();
    218         void clearErrors();
    219         void setMainDocumentError(const ResourceError&);
    220         void commitLoad(const char*, int);
    221         bool doesProgressiveLoad(const String& MIMEType) const;
    222 
    223         void deliverSubstituteResourcesAfterDelay();
    224         void substituteResourceDeliveryTimerFired(Timer<DocumentLoader>*);
    225 
    226         Frame* m_frame;
    227 
    228         RefPtr<MainResourceLoader> m_mainResourceLoader;
    229         ResourceLoaderSet m_subresourceLoaders;
    230         ResourceLoaderSet m_multipartSubresourceLoaders;
    231         ResourceLoaderSet m_plugInStreamLoaders;
    232 
    233         RefPtr<SharedBuffer> m_mainResourceData;
    234 
    235         // A reference to actual request used to create the data source.
    236         // This should only be used by the resourceLoadDelegate's
    237         // identifierForInitialRequest:fromDatasource: method. It is
    238         // not guaranteed to remain unchanged, as requests are mutable.
    239         ResourceRequest m_originalRequest;
    240 
    241         SubstituteData m_substituteData;
    242 
    243         // A copy of the original request used to create the data source.
    244         // We have to copy the request because requests are mutable.
    245         ResourceRequest m_originalRequestCopy;
    246 
    247         // The 'working' request. It may be mutated
    248         // several times from the original request to include additional
    249         // headers, cookie information, canonicalization and redirects.
    250         ResourceRequest m_request;
    251 
    252         ResourceResponse m_response;
    253 
    254         ResourceError m_mainDocumentError;
    255 
    256         bool m_committed;
    257         bool m_isStopping;
    258         bool m_loading;
    259         bool m_gotFirstByte;
    260         bool m_primaryLoadComplete;
    261         bool m_isClientRedirect;
    262 
    263         String m_pageTitle;
    264 
    265         String m_overrideEncoding;
    266 
    267         // The action that triggered loading - we keep this around for the
    268         // benefit of the various policy handlers.
    269         NavigationAction m_triggeringAction;
    270 
    271         // The last request that we checked click policy for - kept around
    272         // so we can avoid asking again needlessly.
    273         ResourceRequest m_lastCheckedRequest;
    274 
    275         // We retain all the received responses so we can play back the
    276         // WebResourceLoadDelegate messages if the item is loaded from the
    277         // page cache.
    278         ResponseVector m_responses;
    279         bool m_stopRecordingResponses;
    280 
    281         typedef HashMap<RefPtr<ResourceLoader>, RefPtr<SubstituteResource> > SubstituteResourceMap;
    282         SubstituteResourceMap m_pendingSubstituteResources;
    283         Timer<DocumentLoader> m_substituteResourceDeliveryTimer;
    284 
    285 #if ENABLE(ARCHIVE) // ANDROID extension: disabled to reduce code size
    286         OwnPtr<ArchiveResourceCollection> m_archiveResourceCollection;
    287         RefPtr<SharedBuffer> m_parsedArchiveData;
    288 #endif
    289 
    290         HashSet<String> m_resourcesClientKnowsAbout;
    291         Vector<String> m_resourcesLoadedFromMemoryCacheForClientNotification;
    292 
    293         String m_clientRedirectSourceForHistory;
    294         bool m_didCreateGlobalHistoryEntry;
    295 
    296 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
    297         friend class ApplicationCacheHost;  // for substitute resource delivery
    298         OwnPtr<ApplicationCacheHost> m_applicationCacheHost;
    299 #endif
    300     };
    301 
    302     inline void DocumentLoader::recordMemoryCacheLoadForFutureClientNotification(const String& url)
    303     {
    304         m_resourcesLoadedFromMemoryCacheForClientNotification.append(url);
    305     }
    306 
    307     inline void DocumentLoader::takeMemoryCacheLoadsForClientNotification(Vector<String>& loadsSet)
    308     {
    309         loadsSet.swap(m_resourcesLoadedFromMemoryCacheForClientNotification);
    310         m_resourcesLoadedFromMemoryCacheForClientNotification.clear();
    311     }
    312 
    313 }
    314 
    315 #endif // DocumentLoader_h
    316