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