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 "DocumentLoadTiming.h"
     33 #include "DocumentWriter.h"
     34 #include "IconDatabaseBase.h"
     35 #include "NavigationAction.h"
     36 #include "ResourceError.h"
     37 #include "ResourceRequest.h"
     38 #include "ResourceResponse.h"
     39 #include "StringWithDirection.h"
     40 #include "SubstituteData.h"
     41 #include "Timer.h"
     42 #include <wtf/HashSet.h>
     43 #include <wtf/RefPtr.h>
     44 #include <wtf/Vector.h>
     45 
     46 namespace WebCore {
     47 
     48     class ApplicationCacheHost;
     49 #if ENABLE(WEB_ARCHIVE)
     50     class Archive;
     51 #endif
     52     class ArchiveResource;
     53     class ArchiveResourceCollection;
     54     class Frame;
     55     class FrameLoader;
     56     class MainResourceLoader;
     57     class Page;
     58     class ResourceLoader;
     59     class SchedulePair;
     60     class SharedBuffer;
     61     class SubstituteResource;
     62 
     63     typedef HashSet<RefPtr<ResourceLoader> > ResourceLoaderSet;
     64     typedef Vector<ResourceResponse> ResponseVector;
     65 
     66     class DocumentLoader : public RefCounted<DocumentLoader> {
     67     public:
     68         static PassRefPtr<DocumentLoader> create(const ResourceRequest& request, const SubstituteData& data)
     69         {
     70             return adoptRef(new DocumentLoader(request, data));
     71         }
     72         virtual ~DocumentLoader();
     73 
     74         void setFrame(Frame*);
     75         Frame* frame() const { return m_frame; }
     76 
     77         virtual void attachToFrame();
     78         virtual void detachFromFrame();
     79 
     80         FrameLoader* frameLoader() const;
     81         MainResourceLoader* mainResourceLoader() const { return m_mainResourceLoader.get(); }
     82         PassRefPtr<SharedBuffer> mainResourceData() const;
     83 
     84         DocumentWriter* writer() const { return &m_writer; }
     85 
     86         const ResourceRequest& originalRequest() const;
     87         const ResourceRequest& originalRequestCopy() const;
     88 
     89         const ResourceRequest& request() const;
     90         ResourceRequest& request();
     91         void setRequest(const ResourceRequest&);
     92 
     93         const SubstituteData& substituteData() const { return m_substituteData; }
     94 
     95         const KURL& url() const;
     96         const KURL& unreachableURL() const;
     97 
     98         const KURL& originalURL() const;
     99         const KURL& requestURL() const;
    100         const KURL& responseURL() const;
    101         const String& responseMIMEType() const;
    102 
    103         void replaceRequestURLForSameDocumentNavigation(const KURL&);
    104         bool isStopping() const { return m_isStopping; }
    105         void stopLoading();
    106         void setCommitted(bool committed) { m_committed = committed; }
    107         bool isCommitted() const { return m_committed; }
    108         bool isLoading() const { return m_loading; }
    109         void setLoading(bool loading) { m_loading = loading; }
    110         void updateLoading();
    111         void receivedData(const char*, int);
    112         void setupForReplaceByMIMEType(const String& newMIMEType);
    113         void finishedLoading();
    114         const ResourceResponse& response() const { return m_response; }
    115         const ResourceError& mainDocumentError() const { return m_mainDocumentError; }
    116         void mainReceivedError(const ResourceError&, bool isComplete);
    117         void setResponse(const ResourceResponse& response) { m_response = response; }
    118         void prepareForLoadStart();
    119         bool isClientRedirect() const { return m_isClientRedirect; }
    120         void setIsClientRedirect(bool isClientRedirect) { m_isClientRedirect = isClientRedirect; }
    121         void handledOnloadEvents() { m_wasOnloadHandled = true; }
    122         bool wasOnloadHandled() { return m_wasOnloadHandled; }
    123         bool isLoadingInAPISense() const;
    124         void setPrimaryLoadComplete(bool);
    125         void setTitle(const StringWithDirection&);
    126         void setIconURL(const String&);
    127         const String& overrideEncoding() const { return m_overrideEncoding; }
    128 
    129 #if PLATFORM(MAC)
    130         void schedule(SchedulePair*);
    131         void unschedule(SchedulePair*);
    132 #endif
    133 
    134 #if ENABLE(WEB_ARCHIVE)
    135         void addAllArchiveResources(Archive*);
    136         void addArchiveResource(PassRefPtr<ArchiveResource>);
    137 
    138         PassRefPtr<Archive> popArchiveForSubframe(const String& frameName);
    139         void clearArchiveResources();
    140         void setParsedArchiveData(PassRefPtr<SharedBuffer>);
    141         SharedBuffer* parsedArchiveData() const;
    142 
    143         bool scheduleArchiveLoad(ResourceLoader*, const ResourceRequest&, const KURL&);
    144 #endif // ENABLE(WEB_ARCHIVE)
    145 
    146         // Return the ArchiveResource for the URL only when loading an Archive
    147         ArchiveResource* archiveResourceForURL(const KURL&) const;
    148 
    149         PassRefPtr<ArchiveResource> mainResource() const;
    150 
    151         // Return an ArchiveResource for the URL, either creating from live data or
    152         // pulling from the ArchiveResourceCollection
    153         PassRefPtr<ArchiveResource> subresource(const KURL&) const;
    154         void getSubresources(Vector<PassRefPtr<ArchiveResource> >&) const;
    155 
    156 
    157 #ifndef NDEBUG
    158         bool isSubstituteLoadPending(ResourceLoader*) const;
    159 #endif
    160         void cancelPendingSubstituteLoad(ResourceLoader*);
    161 
    162         void addResponse(const ResourceResponse&);
    163         const ResponseVector& responses() const { return m_responses; }
    164 
    165         const NavigationAction& triggeringAction() const { return m_triggeringAction; }
    166         void setTriggeringAction(const NavigationAction& action) { m_triggeringAction = action; }
    167         void setOverrideEncoding(const String& encoding) { m_overrideEncoding = encoding; }
    168         void setLastCheckedRequest(const ResourceRequest& request) { m_lastCheckedRequest = request; }
    169         const ResourceRequest& lastCheckedRequest()  { return m_lastCheckedRequest; }
    170 
    171         void stopRecordingResponses();
    172         const StringWithDirection& title() const { return m_pageTitle; }
    173         const String& iconURL() const { return m_pageIconURL; }
    174 
    175         KURL urlForHistory() const;
    176         bool urlForHistoryReflectsFailure() const;
    177 
    178         // These accessors accommodate WebCore's somewhat fickle custom of creating history
    179         // items for redirects, but only sometimes. For "source" and "destination",
    180         // these accessors return the URL that would have been used if a history
    181         // item were created. This allows WebKit to link history items reflecting
    182         // redirects into a chain from start to finish.
    183         String clientRedirectSourceForHistory() const { return m_clientRedirectSourceForHistory; } // null if no client redirect occurred.
    184         String clientRedirectDestinationForHistory() const { return urlForHistory(); }
    185         void setClientRedirectSourceForHistory(const String& clientedirectSourceForHistory) { m_clientRedirectSourceForHistory = clientedirectSourceForHistory; }
    186 
    187         String serverRedirectSourceForHistory() const { return urlForHistory() == url() ? String() : urlForHistory().string(); } // null if no server redirect occurred.
    188         String serverRedirectDestinationForHistory() const { return url(); }
    189 
    190         bool didCreateGlobalHistoryEntry() const { return m_didCreateGlobalHistoryEntry; }
    191         void setDidCreateGlobalHistoryEntry(bool didCreateGlobalHistoryEntry) { m_didCreateGlobalHistoryEntry = didCreateGlobalHistoryEntry; }
    192 
    193         void setDefersLoading(bool);
    194 
    195         bool startLoadingMainResource(unsigned long identifier);
    196         void cancelMainResourceLoad(const ResourceError&);
    197 
    198         // Support iconDatabase in synchronous mode.
    199         void iconLoadDecisionAvailable();
    200 
    201         // Support iconDatabase in asynchronous mode.
    202         void continueIconLoadWithDecision(IconLoadDecision);
    203         void getIconLoadDecisionForIconURL(const String&);
    204         void getIconDataForIconURL(const String&);
    205 
    206         bool isLoadingMainResource() const;
    207         bool isLoadingSubresources() const;
    208         bool isLoadingPlugIns() const;
    209         bool isLoadingMultipartContent() const;
    210 
    211         void stopLoadingPlugIns();
    212         void stopLoadingSubresources();
    213 
    214         void addSubresourceLoader(ResourceLoader*);
    215         void removeSubresourceLoader(ResourceLoader*);
    216         void addPlugInStreamLoader(ResourceLoader*);
    217         void removePlugInStreamLoader(ResourceLoader*);
    218 
    219         void subresourceLoaderFinishedLoadingOnePart(ResourceLoader*);
    220 
    221         void transferLoadingResourcesFromPage(Page*);
    222 
    223         void setDeferMainResourceDataLoad(bool defer) { m_deferMainResourceDataLoad = defer; }
    224         bool deferMainResourceDataLoad() const { return m_deferMainResourceDataLoad; }
    225 
    226         void didTellClientAboutLoad(const String& url)
    227         {
    228             if (!url.isEmpty())
    229                 m_resourcesClientKnowsAbout.add(url);
    230         }
    231         bool haveToldClientAboutLoad(const String& url) { return m_resourcesClientKnowsAbout.contains(url); }
    232         void recordMemoryCacheLoadForFutureClientNotification(const String& url);
    233         void takeMemoryCacheLoadsForClientNotification(Vector<String>& loads);
    234 
    235         DocumentLoadTiming* timing() { return &m_documentLoadTiming; }
    236         void resetTiming() { m_documentLoadTiming = DocumentLoadTiming(); }
    237 
    238         // The WebKit layer calls this function when it's ready for the data to
    239         // actually be added to the document.
    240         void commitData(const char* bytes, int length);
    241 
    242 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
    243         ApplicationCacheHost* applicationCacheHost() const { return m_applicationCacheHost.get(); }
    244 #endif
    245 
    246     protected:
    247         DocumentLoader(const ResourceRequest&, const SubstituteData&);
    248 
    249         bool m_deferMainResourceDataLoad;
    250 
    251     private:
    252         void setupForReplace();
    253         void commitIfReady();
    254         void clearErrors();
    255         void setMainDocumentError(const ResourceError&);
    256         void commitLoad(const char*, int);
    257         bool doesProgressiveLoad(const String& MIMEType) const;
    258 
    259         void deliverSubstituteResourcesAfterDelay();
    260         void substituteResourceDeliveryTimerFired(Timer<DocumentLoader>*);
    261 
    262         Frame* m_frame;
    263 
    264         RefPtr<MainResourceLoader> m_mainResourceLoader;
    265         ResourceLoaderSet m_subresourceLoaders;
    266         ResourceLoaderSet m_multipartSubresourceLoaders;
    267         ResourceLoaderSet m_plugInStreamLoaders;
    268 
    269         RefPtr<SharedBuffer> m_mainResourceData;
    270 
    271         mutable DocumentWriter m_writer;
    272 
    273         // A reference to actual request used to create the data source.
    274         // This should only be used by the resourceLoadDelegate's
    275         // identifierForInitialRequest:fromDatasource: method. It is
    276         // not guaranteed to remain unchanged, as requests are mutable.
    277         ResourceRequest m_originalRequest;
    278 
    279         SubstituteData m_substituteData;
    280 
    281         // A copy of the original request used to create the data source.
    282         // We have to copy the request because requests are mutable.
    283         ResourceRequest m_originalRequestCopy;
    284 
    285         // The 'working' request. It may be mutated
    286         // several times from the original request to include additional
    287         // headers, cookie information, canonicalization and redirects.
    288         ResourceRequest m_request;
    289 
    290         ResourceResponse m_response;
    291 
    292         ResourceError m_mainDocumentError;
    293 
    294         bool m_committed;
    295         bool m_isStopping;
    296         bool m_loading;
    297         bool m_gotFirstByte;
    298         bool m_primaryLoadComplete;
    299         bool m_isClientRedirect;
    300         bool m_wasOnloadHandled;
    301 
    302         StringWithDirection m_pageTitle;
    303         String m_pageIconURL;
    304 
    305         String m_overrideEncoding;
    306 
    307         // The action that triggered loading - we keep this around for the
    308         // benefit of the various policy handlers.
    309         NavigationAction m_triggeringAction;
    310 
    311         // The last request that we checked click policy for - kept around
    312         // so we can avoid asking again needlessly.
    313         ResourceRequest m_lastCheckedRequest;
    314 
    315         // We retain all the received responses so we can play back the
    316         // WebResourceLoadDelegate messages if the item is loaded from the
    317         // page cache.
    318         ResponseVector m_responses;
    319         bool m_stopRecordingResponses;
    320 
    321         typedef HashMap<RefPtr<ResourceLoader>, RefPtr<SubstituteResource> > SubstituteResourceMap;
    322         SubstituteResourceMap m_pendingSubstituteResources;
    323         Timer<DocumentLoader> m_substituteResourceDeliveryTimer;
    324 
    325         OwnPtr<ArchiveResourceCollection> m_archiveResourceCollection;
    326 #if ENABLE(WEB_ARCHIVE)
    327         RefPtr<SharedBuffer> m_parsedArchiveData;
    328 #endif
    329 
    330         HashSet<String> m_resourcesClientKnowsAbout;
    331         Vector<String> m_resourcesLoadedFromMemoryCacheForClientNotification;
    332 
    333         String m_clientRedirectSourceForHistory;
    334         bool m_didCreateGlobalHistoryEntry;
    335 
    336         DocumentLoadTiming m_documentLoadTiming;
    337 
    338         RefPtr<IconLoadDecisionCallback> m_iconLoadDecisionCallback;
    339         RefPtr<IconDataCallback> m_iconDataCallback;
    340 
    341 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
    342         friend class ApplicationCacheHost;  // for substitute resource delivery
    343         OwnPtr<ApplicationCacheHost> m_applicationCacheHost;
    344 #endif
    345     };
    346 
    347     inline void DocumentLoader::recordMemoryCacheLoadForFutureClientNotification(const String& url)
    348     {
    349         m_resourcesLoadedFromMemoryCacheForClientNotification.append(url);
    350     }
    351 
    352     inline void DocumentLoader::takeMemoryCacheLoadsForClientNotification(Vector<String>& loadsSet)
    353     {
    354         loadsSet.swap(m_resourcesLoadedFromMemoryCacheForClientNotification);
    355         m_resourcesLoadedFromMemoryCacheForClientNotification.clear();
    356     }
    357 
    358 }
    359 
    360 #endif // DocumentLoader_h
    361