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