initial import
[vuplus_webkit] / Source / WebKit / chromium / src / ResourceHandle.cpp
1 /*
2  * Copyright (C) 2009 Google 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 are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32 #include "ResourceHandle.h"
33
34 #include "PlatformSupport.h"
35 #include "ResourceHandleClient.h"
36 #include "ResourceHandleInternal.h"
37 #include "ResourceRequest.h"
38 #include "SharedBuffer.h"
39
40 #include "WebKit.h"
41 #include "WebKitPlatformSupport.h"
42 #include "WebURLError.h"
43 #include "WebURLLoader.h"
44 #include "WebURLLoaderClient.h"
45 #include "WebURLRequest.h"
46 #include "WebURLResponse.h"
47 #include "WrappedResourceRequest.h"
48 #include "WrappedResourceResponse.h"
49
50 using namespace WebKit;
51
52 namespace WebCore {
53
54 // ResourceHandleInternal -----------------------------------------------------
55 ResourceHandleInternal::ResourceHandleInternal(const ResourceRequest& request, ResourceHandleClient* client)
56     : m_request(request)
57     , m_owner(0)
58     , m_client(client)
59     , m_state(ConnectionStateNew)
60 { }
61
62 void ResourceHandleInternal::start()
63 {
64     if (m_state != ConnectionStateNew)
65         CRASH();
66     m_state = ConnectionStateStarted;
67
68     m_loader = adoptPtr(webKitPlatformSupport()->createURLLoader());
69     ASSERT(m_loader.get());
70
71     WrappedResourceRequest wrappedRequest(m_request);
72     wrappedRequest.setAllowStoredCredentials(allowStoredCredentials());
73     m_loader->loadAsynchronously(wrappedRequest, this);
74 }
75
76 void ResourceHandleInternal::cancel()
77 {
78     m_state = ConnectionStateCanceled;
79     m_loader->cancel();
80
81     // Do not make any further calls to the client.
82     m_client = 0;
83 }
84
85 void ResourceHandleInternal::setDefersLoading(bool value)
86 {
87     m_loader->setDefersLoading(value);
88 }
89
90 bool ResourceHandleInternal::allowStoredCredentials() const
91 {
92     return m_client && m_client->shouldUseCredentialStorage(m_owner);
93 }
94
95 void ResourceHandleInternal::willSendRequest(
96     WebURLLoader*, WebURLRequest& request, const WebURLResponse& response)
97 {
98     ASSERT(m_client);
99     ASSERT(!request.isNull());
100     ASSERT(!response.isNull());
101     m_client->willSendRequest(m_owner, request.toMutableResourceRequest(), response.toResourceResponse());
102 }
103
104 void ResourceHandleInternal::didSendData(
105     WebURLLoader*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
106 {
107     ASSERT(m_client);
108     m_client->didSendData(m_owner, bytesSent, totalBytesToBeSent);
109 }
110
111 void ResourceHandleInternal::didReceiveResponse(WebURLLoader*, const WebURLResponse& response)
112 {
113     ASSERT(m_client);
114     ASSERT(!response.isNull());
115     bool isMultipart = response.isMultipartPayload();
116     bool isValidStateTransition = (m_state == ConnectionStateStarted || m_state == ConnectionStateReceivedResponse);
117     // In the case of multipart loads, calls to didReceiveData & didReceiveResponse can be interleaved.
118     if (!isMultipart && !isValidStateTransition)
119         CRASH();
120     m_state = ConnectionStateReceivedResponse;
121     m_client->didReceiveResponse(m_owner, response.toResourceResponse());
122 }
123
124 void ResourceHandleInternal::didDownloadData(WebURLLoader*, int dataLength)
125 {
126     ASSERT(m_client);
127     if (m_state != ConnectionStateReceivedResponse)
128         CRASH();
129
130     m_client->didDownloadData(m_owner, dataLength);
131 }
132
133 void ResourceHandleInternal::didReceiveData(WebURLLoader*, const char* data, int dataLength, int encodedDataLength)
134 {
135     ASSERT(m_client);
136     if (m_state != ConnectionStateReceivedResponse && m_state != ConnectionStateReceivingData)
137         CRASH();
138     m_state = ConnectionStateReceivingData;
139
140     m_client->didReceiveData(m_owner, data, dataLength, encodedDataLength);
141 }
142
143 void ResourceHandleInternal::didReceiveCachedMetadata(WebURLLoader*, const char* data, int dataLength)
144 {
145     ASSERT(m_client);
146     if (m_state != ConnectionStateReceivedResponse && m_state != ConnectionStateReceivingData)
147         CRASH();
148
149     m_client->didReceiveCachedMetadata(m_owner, data, dataLength);
150 }
151
152 void ResourceHandleInternal::didFinishLoading(WebURLLoader*, double finishTime)
153 {
154     ASSERT(m_client);
155     if (m_state != ConnectionStateReceivedResponse && m_state != ConnectionStateReceivingData)
156         CRASH();
157     m_state = ConnectionStateFinishedLoading;
158     m_client->didFinishLoading(m_owner, finishTime);
159 }
160
161 void ResourceHandleInternal::didFail(WebURLLoader*, const WebURLError& error)
162 {
163     ASSERT(m_client);
164     m_state = ConnectionStateFailed;
165     m_client->didFail(m_owner, error);
166 }
167
168 ResourceHandleInternal* ResourceHandleInternal::FromResourceHandle(ResourceHandle* handle)
169 {
170     return handle->d.get();
171 }
172
173 // ResourceHandle -------------------------------------------------------------
174
175 ResourceHandle::ResourceHandle(const ResourceRequest& request,
176                                ResourceHandleClient* client,
177                                bool defersLoading,
178                                bool shouldContentSniff)
179     : d(adoptPtr(new ResourceHandleInternal(request, client)))
180 {
181     d->setOwner(this);
182
183     // FIXME: Figure out what to do with the bool params.
184 }
185
186 PassRefPtr<ResourceHandle> ResourceHandle::create(NetworkingContext* context,
187                                                   const ResourceRequest& request,
188                                                   ResourceHandleClient* client,
189                                                   bool defersLoading,
190                                                   bool shouldContentSniff)
191 {
192     RefPtr<ResourceHandle> newHandle = adoptRef(new ResourceHandle(
193         request, client, defersLoading, shouldContentSniff));
194
195     if (newHandle->start(context))
196         return newHandle.release();
197
198     return 0;
199 }
200
201 ResourceRequest& ResourceHandle::firstRequest()
202 {
203     return d->request();
204 }
205
206 ResourceHandleClient* ResourceHandle::client() const
207 {
208     return d->client();
209 }
210
211 void ResourceHandle::setClient(ResourceHandleClient* client)
212 {
213     d->setClient(client);
214 }
215
216 void ResourceHandle::setDefersLoading(bool value)
217 {
218     d->setDefersLoading(value);
219 }
220
221 bool ResourceHandle::start(NetworkingContext* context)
222 {
223     d->start();
224     return true;
225 }
226
227 bool ResourceHandle::hasAuthenticationChallenge() const
228 {
229     return false;
230 }
231
232 void ResourceHandle::clearAuthentication()
233 {
234 }
235
236 void ResourceHandle::cancel()
237 {
238     d->cancel();
239 }
240
241 ResourceHandle::~ResourceHandle()
242 {
243     d->setOwner(0);
244 }
245
246 bool ResourceHandle::loadsBlocked()
247 {
248     return false;  // This seems to be related to sync XMLHttpRequest...
249 }
250
251 // static
252 void ResourceHandle::loadResourceSynchronously(NetworkingContext* context,
253                                                const ResourceRequest& request,
254                                                StoredCredentials storedCredentials,
255                                                ResourceError& error,
256                                                ResourceResponse& response,
257                                                Vector<char>& data)
258 {
259     OwnPtr<WebURLLoader> loader = adoptPtr(webKitPlatformSupport()->createURLLoader());
260     ASSERT(loader.get());
261
262     WrappedResourceRequest requestIn(request);
263     requestIn.setAllowStoredCredentials(storedCredentials == AllowStoredCredentials);
264     WrappedResourceResponse responseOut(response);
265     WebURLError errorOut;
266     WebData dataOut;
267
268     loader->loadSynchronously(requestIn, responseOut, errorOut, dataOut);
269
270     error = errorOut;
271     data.clear();
272     data.append(dataOut.data(), dataOut.size());
273 }
274
275 // static
276 bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame*)
277 {
278     // This method is used to determine if a POST request can be repeated from
279     // cache, but you cannot really know until you actually try to read from the
280     // cache.  Even if we checked now, something else could come along and wipe
281     // out the cache entry by the time we fetch it.
282     //
283     // So, we always say yes here, to prevent the FrameLoader from initiating a
284     // reload.  Then in FrameLoaderClientImpl::dispatchWillSendRequest, we
285     // fix-up the cache policy of the request to force a load from the cache.
286     //
287     ASSERT(request.httpMethod() == "POST");
288     return true;
289 }
290
291 // static
292 void ResourceHandle::cacheMetadata(const ResourceResponse& response, const Vector<char>& data)
293 {
294     PlatformSupport::cacheMetadata(response.url(), response.responseTime(), data);
295 }
296
297 } // namespace WebCore