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: create(const ResourceRequest & request,const SubstituteData & data)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*); frame()67 Frame* frame() const { return m_frame; } 68 69 virtual void attachToFrame(); 70 virtual void detachFromFrame(); 71 72 FrameLoader* frameLoader() const; mainResourceLoader()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 substituteData()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&); isStopping()94 bool isStopping() const { return m_isStopping; } 95 void stopLoading(DatabasePolicy = DatabasePolicyStop); setCommitted(bool committed)96 void setCommitted(bool committed) { m_committed = committed; } isCommitted()97 bool isCommitted() const { return m_committed; } isLoading()98 bool isLoading() const { return m_loading; } setLoading(bool 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(); response()104 const ResourceResponse& response() const { return m_response; } mainDocumentError()105 const ResourceError& mainDocumentError() const { return m_mainDocumentError; } 106 void mainReceivedError(const ResourceError&, bool isComplete); setResponse(const ResourceResponse & response)107 void setResponse(const ResourceResponse& response) { m_response = response; } 108 void prepareForLoadStart(); isClientRedirect()109 bool isClientRedirect() const { return m_isClientRedirect; } setIsClientRedirect(bool isClientRedirect)110 void setIsClientRedirect(bool isClientRedirect) { m_isClientRedirect = isClientRedirect; } 111 bool isLoadingInAPISense() const; 112 void setPrimaryLoadComplete(bool); 113 void setTitle(const String&); overrideEncoding()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&); responses()147 const ResponseVector& responses() const { return m_responses; } 148 triggeringAction()149 const NavigationAction& triggeringAction() const { return m_triggeringAction; } setTriggeringAction(const NavigationAction & action)150 void setTriggeringAction(const NavigationAction& action) { m_triggeringAction = action; } setOverrideEncoding(const String & encoding)151 void setOverrideEncoding(const String& encoding) { m_overrideEncoding = encoding; } setLastCheckedRequest(const ResourceRequest & request)152 void setLastCheckedRequest(const ResourceRequest& request) { m_lastCheckedRequest = request; } lastCheckedRequest()153 const ResourceRequest& lastCheckedRequest() { return m_lastCheckedRequest; } 154 155 void stopRecordingResponses(); title()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. clientRedirectSourceForHistory()166 String clientRedirectSourceForHistory() const { return m_clientRedirectSourceForHistory; } // null if no client redirect occurred. clientRedirectDestinationForHistory()167 String clientRedirectDestinationForHistory() const { return urlForHistory(); } setClientRedirectSourceForHistory(const String & clientedirectSourceForHistory)168 void setClientRedirectSourceForHistory(const String& clientedirectSourceForHistory) { m_clientRedirectSourceForHistory = clientedirectSourceForHistory; } 169 serverRedirectSourceForHistory()170 String serverRedirectSourceForHistory() const { return urlForHistory() == url() ? String() : urlForHistory(); } // null if no server redirect occurred. serverRedirectDestinationForHistory()171 String serverRedirectDestinationForHistory() const { return url(); } 172 didCreateGlobalHistoryEntry()173 bool didCreateGlobalHistoryEntry() const { return m_didCreateGlobalHistoryEntry; } setDidCreateGlobalHistoryEntry(bool 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 setDeferMainResourceDataLoad(bool defer)198 void setDeferMainResourceDataLoad(bool defer) { m_deferMainResourceDataLoad = defer; } deferMainResourceDataLoad()199 bool deferMainResourceDataLoad() const { return m_deferMainResourceDataLoad; } 200 didTellClientAboutLoad(const String & url)201 void didTellClientAboutLoad(const String& url) { m_resourcesClientKnowsAbout.add(url); } haveToldClientAboutLoad(const String & 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) applicationCacheHost()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 recordMemoryCacheLoadForFutureClientNotification(const String & url)302 inline void DocumentLoader::recordMemoryCacheLoadForFutureClientNotification(const String& url) 303 { 304 m_resourcesLoadedFromMemoryCacheForClientNotification.append(url); 305 } 306 takeMemoryCacheLoadsForClientNotification(Vector<String> & loadsSet)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