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