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 ApplicationCache; 42 class ApplicationCacheGroup; 43 class ApplicationCacheResource; 44 #if ENABLE(ARCHIVE) // ANDROID extension: disabled to reduce code size 45 class Archive; 46 class ArchiveResource; 47 class ArchiveResourceCollection; 48 #endif 49 class CachedPage; 50 class Frame; 51 class FrameLoader; 52 class MainResourceLoader; 53 class ResourceLoader; 54 class SchedulePair; 55 class SharedBuffer; 56 class SubstituteResource; 57 58 typedef HashSet<RefPtr<ResourceLoader> > ResourceLoaderSet; 59 typedef Vector<ResourceResponse> ResponseVector; 60 61 class DocumentLoader : public RefCounted<DocumentLoader> { 62 public: create(const ResourceRequest & request,const SubstituteData & data)63 static PassRefPtr<DocumentLoader> create(const ResourceRequest& request, const SubstituteData& data) 64 { 65 return adoptRef(new DocumentLoader(request, data)); 66 } 67 virtual ~DocumentLoader(); 68 69 void setFrame(Frame*); frame()70 Frame* frame() const { return m_frame; } 71 72 virtual void attachToFrame(); 73 virtual void detachFromFrame(); 74 75 FrameLoader* frameLoader() const; mainResourceLoader()76 MainResourceLoader* mainResourceLoader() const { return m_mainResourceLoader.get(); } 77 PassRefPtr<SharedBuffer> mainResourceData() const; 78 79 const ResourceRequest& originalRequest() const; 80 const ResourceRequest& originalRequestCopy() const; 81 82 const ResourceRequest& request() const; 83 ResourceRequest& request(); 84 void setRequest(const ResourceRequest&); 85 substituteData()86 const SubstituteData& substituteData() const { return m_substituteData; } 87 88 const KURL& url() const; 89 const KURL& unreachableURL() const; 90 91 const KURL& originalURL() const; 92 const KURL& requestURL() const; 93 const KURL& responseURL() const; 94 const String& responseMIMEType() const; 95 96 void replaceRequestURLForAnchorScroll(const KURL&); isStopping()97 bool isStopping() const { return m_isStopping; } 98 void stopLoading(); setCommitted(bool committed)99 void setCommitted(bool committed) { m_committed = committed; } isCommitted()100 bool isCommitted() const { return m_committed; } isLoading()101 bool isLoading() const { return m_loading; } setLoading(bool loading)102 void setLoading(bool loading) { m_loading = loading; } 103 void updateLoading(); 104 void receivedData(const char*, int); 105 void setupForReplaceByMIMEType(const String& newMIMEType); 106 void finishedLoading(); response()107 const ResourceResponse& response() const { return m_response; } mainDocumentError()108 const ResourceError& mainDocumentError() const { return m_mainDocumentError; } 109 void mainReceivedError(const ResourceError&, bool isComplete); setResponse(const ResourceResponse & response)110 void setResponse(const ResourceResponse& response) { m_response = response; } 111 void prepareForLoadStart(); isClientRedirect()112 bool isClientRedirect() const { return m_isClientRedirect; } setIsClientRedirect(bool isClientRedirect)113 void setIsClientRedirect(bool isClientRedirect) { m_isClientRedirect = isClientRedirect; } 114 bool isLoadingInAPISense() const; 115 void setPrimaryLoadComplete(bool); 116 void setTitle(const String&); overrideEncoding()117 const String& overrideEncoding() const { return m_overrideEncoding; } 118 119 #if PLATFORM(MAC) 120 void schedule(SchedulePair*); 121 void unschedule(SchedulePair*); 122 #endif 123 124 #if ENABLE(ARCHIVE) // ANDROID extension: disabled to reduce code size 125 void addAllArchiveResources(Archive*); 126 void addArchiveResource(PassRefPtr<ArchiveResource>); 127 128 // Return an ArchiveResource for the URL, either creating from live data or 129 // pulling from the ArchiveResourceCollection 130 PassRefPtr<ArchiveResource> subresource(const KURL&) const; 131 // Return the ArchiveResource for the URL only when loading an Archive 132 ArchiveResource* archiveResourceForURL(const KURL&) const; 133 134 PassRefPtr<Archive> popArchiveForSubframe(const String& frameName); 135 void clearArchiveResources(); 136 void setParsedArchiveData(PassRefPtr<SharedBuffer>); 137 SharedBuffer* parsedArchiveData() const; 138 139 PassRefPtr<ArchiveResource> mainResource() const; 140 void getSubresources(Vector<PassRefPtr<ArchiveResource> >&) const; 141 142 bool scheduleArchiveLoad(ResourceLoader*, const ResourceRequest&, const KURL&); 143 #endif 144 #ifndef NDEBUG 145 bool isSubstituteLoadPending(ResourceLoader*) const; 146 #endif 147 void cancelPendingSubstituteLoad(ResourceLoader*); 148 149 void addResponse(const ResourceResponse&); responses()150 const ResponseVector& responses() const { return m_responses; } 151 triggeringAction()152 const NavigationAction& triggeringAction() const { return m_triggeringAction; } setTriggeringAction(const NavigationAction & action)153 void setTriggeringAction(const NavigationAction& action) { m_triggeringAction = action; } setOverrideEncoding(const String & encoding)154 void setOverrideEncoding(const String& encoding) { m_overrideEncoding = encoding; } setLastCheckedRequest(const ResourceRequest & request)155 void setLastCheckedRequest(const ResourceRequest& request) { m_lastCheckedRequest = request; } lastCheckedRequest()156 const ResourceRequest& lastCheckedRequest() { return m_lastCheckedRequest; } 157 158 void stopRecordingResponses(); title()159 const String& title() const { return m_pageTitle; } 160 161 KURL urlForHistory() const; 162 bool urlForHistoryReflectsFailure() const; urlForHistoryReflectsServerRedirect()163 bool urlForHistoryReflectsServerRedirect() const { return urlForHistory() != url(); } urlForHistoryReflectsClientRedirect()164 bool urlForHistoryReflectsClientRedirect() const { return m_urlForHistoryReflectsClientRedirect; } setURLForHistoryReflectsClientRedirect(bool b)165 void setURLForHistoryReflectsClientRedirect(bool b) { m_urlForHistoryReflectsClientRedirect = b; } 166 167 void loadFromCachedPage(PassRefPtr<CachedPage>); setLoadingFromCachedPage(bool loading)168 void setLoadingFromCachedPage(bool loading) { m_loadingFromCachedPage = loading; } isLoadingFromCachedPage()169 bool isLoadingFromCachedPage() const { return m_loadingFromCachedPage; } 170 171 void setDefersLoading(bool); 172 173 bool startLoadingMainResource(unsigned long identifier); 174 void cancelMainResourceLoad(const ResourceError&); 175 176 void iconLoadDecisionAvailable(); 177 178 bool isLoadingMainResource() const; 179 bool isLoadingSubresources() const; 180 bool isLoadingPlugIns() const; 181 bool isLoadingMultipartContent() const; 182 183 void stopLoadingPlugIns(); 184 void stopLoadingSubresources(); 185 186 void addSubresourceLoader(ResourceLoader*); 187 void removeSubresourceLoader(ResourceLoader*); 188 void addPlugInStreamLoader(ResourceLoader*); 189 void removePlugInStreamLoader(ResourceLoader*); 190 191 void subresourceLoaderFinishedLoadingOnePart(ResourceLoader*); 192 setDeferMainResourceDataLoad(bool defer)193 void setDeferMainResourceDataLoad(bool defer) { m_deferMainResourceDataLoad = defer; } deferMainResourceDataLoad()194 bool deferMainResourceDataLoad() const { return m_deferMainResourceDataLoad; } 195 didTellClientAboutLoad(const String & url)196 void didTellClientAboutLoad(const String& url) { m_resourcesClientKnowsAbout.add(url); } haveToldClientAboutLoad(const String & url)197 bool haveToldClientAboutLoad(const String& url) { return m_resourcesClientKnowsAbout.contains(url); } 198 void recordMemoryCacheLoadForFutureClientNotification(const String& url); 199 void takeMemoryCacheLoadsForClientNotification(Vector<String>& loads); 200 201 #if ENABLE(OFFLINE_WEB_APPLICATIONS) 202 bool scheduleApplicationCacheLoad(ResourceLoader*, const ResourceRequest&, const KURL& originalURL); 203 bool scheduleLoadFallbackResourceFromApplicationCache(ResourceLoader*, const ResourceRequest&, ApplicationCache* = 0); 204 bool shouldLoadResourceFromApplicationCache(const ResourceRequest&, ApplicationCacheResource*&); 205 bool getApplicationCacheFallbackResource(const ResourceRequest&, ApplicationCacheResource*&, ApplicationCache* = 0); 206 207 void setCandidateApplicationCacheGroup(ApplicationCacheGroup* group); candidateApplicationCacheGroup()208 ApplicationCacheGroup* candidateApplicationCacheGroup() const { return m_candidateApplicationCacheGroup; } 209 210 void setApplicationCache(PassRefPtr<ApplicationCache> applicationCache); applicationCache()211 ApplicationCache* applicationCache() const { return m_applicationCache.get(); } 212 213 ApplicationCache* mainResourceApplicationCache() const; 214 #endif 215 216 protected: 217 DocumentLoader(const ResourceRequest&, const SubstituteData&); 218 219 bool m_deferMainResourceDataLoad; 220 221 private: 222 void setupForReplace(); 223 void commitIfReady(); 224 void clearErrors(); 225 void setMainDocumentError(const ResourceError&); 226 void commitLoad(const char*, int); 227 bool doesProgressiveLoad(const String& MIMEType) const; 228 229 void deliverSubstituteResourcesAfterDelay(); 230 void substituteResourceDeliveryTimerFired(Timer<DocumentLoader>*); 231 232 Frame* m_frame; 233 234 RefPtr<MainResourceLoader> m_mainResourceLoader; 235 ResourceLoaderSet m_subresourceLoaders; 236 ResourceLoaderSet m_multipartSubresourceLoaders; 237 ResourceLoaderSet m_plugInStreamLoaders; 238 239 RefPtr<SharedBuffer> m_mainResourceData; 240 241 // A reference to actual request used to create the data source. 242 // This should only be used by the resourceLoadDelegate's 243 // identifierForInitialRequest:fromDatasource: method. It is 244 // not guaranteed to remain unchanged, as requests are mutable. 245 ResourceRequest m_originalRequest; 246 247 SubstituteData m_substituteData; 248 249 // A copy of the original request used to create the data source. 250 // We have to copy the request because requests are mutable. 251 ResourceRequest m_originalRequestCopy; 252 253 // The 'working' request. It may be mutated 254 // several times from the original request to include additional 255 // headers, cookie information, canonicalization and redirects. 256 ResourceRequest m_request; 257 258 ResourceResponse m_response; 259 260 ResourceError m_mainDocumentError; 261 262 bool m_committed; 263 bool m_isStopping; 264 bool m_loading; 265 bool m_gotFirstByte; 266 bool m_primaryLoadComplete; 267 bool m_isClientRedirect; 268 bool m_loadingFromCachedPage; 269 270 String m_pageTitle; 271 272 String m_overrideEncoding; 273 274 // The action that triggered loading - we keep this around for the 275 // benefit of the various policy handlers. 276 NavigationAction m_triggeringAction; 277 278 // The last request that we checked click policy for - kept around 279 // so we can avoid asking again needlessly. 280 ResourceRequest m_lastCheckedRequest; 281 282 // We retain all the received responses so we can play back the 283 // WebResourceLoadDelegate messages if the item is loaded from the 284 // page cache. 285 ResponseVector m_responses; 286 bool m_stopRecordingResponses; 287 288 typedef HashMap<RefPtr<ResourceLoader>, RefPtr<SubstituteResource> > SubstituteResourceMap; 289 SubstituteResourceMap m_pendingSubstituteResources; 290 Timer<DocumentLoader> m_substituteResourceDeliveryTimer; 291 292 #if ENABLE(ARCHIVE) // ANDROID extension: disabled to reduce code size 293 OwnPtr<ArchiveResourceCollection> m_archiveResourceCollection; 294 RefPtr<SharedBuffer> m_parsedArchiveData; 295 #endif 296 297 HashSet<String> m_resourcesClientKnowsAbout; 298 Vector<String> m_resourcesLoadedFromMemoryCacheForClientNotification; 299 300 bool m_urlForHistoryReflectsClientRedirect; 301 302 #if ENABLE(OFFLINE_WEB_APPLICATIONS) 303 // The application cache that the document loader is associated with (if any). 304 RefPtr<ApplicationCache> m_applicationCache; 305 306 // Before an application cache has finished loading, this will be the candidate application 307 // group that the document loader is associated with. 308 ApplicationCacheGroup* m_candidateApplicationCacheGroup; 309 310 // Once the main resource has finished loading, this is the application cache it was loaded from (if any). 311 RefPtr<ApplicationCache> m_mainResourceApplicationCache; 312 #endif 313 }; 314 recordMemoryCacheLoadForFutureClientNotification(const String & url)315 inline void DocumentLoader::recordMemoryCacheLoadForFutureClientNotification(const String& url) 316 { 317 m_resourcesLoadedFromMemoryCacheForClientNotification.append(url); 318 } 319 takeMemoryCacheLoadsForClientNotification(Vector<String> & loadsSet)320 inline void DocumentLoader::takeMemoryCacheLoadsForClientNotification(Vector<String>& loadsSet) 321 { 322 loadsSet.swap(m_resourcesLoadedFromMemoryCacheForClientNotification); 323 m_resourcesLoadedFromMemoryCacheForClientNotification.clear(); 324 } 325 326 } 327 328 #endif // DocumentLoader_h 329