2 * Copyright (C) 2009 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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
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.
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.
32 #include "ResourceHandle.h"
34 #include "PlatformSupport.h"
35 #include "ResourceHandleClient.h"
36 #include "ResourceHandleInternal.h"
37 #include "ResourceRequest.h"
38 #include "SharedBuffer.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"
50 using namespace WebKit;
54 // ResourceHandleInternal -----------------------------------------------------
55 ResourceHandleInternal::ResourceHandleInternal(const ResourceRequest& request, ResourceHandleClient* client)
59 , m_state(ConnectionStateNew)
62 void ResourceHandleInternal::start()
64 if (m_state != ConnectionStateNew)
66 m_state = ConnectionStateStarted;
68 m_loader = adoptPtr(webKitPlatformSupport()->createURLLoader());
69 ASSERT(m_loader.get());
71 WrappedResourceRequest wrappedRequest(m_request);
72 wrappedRequest.setAllowStoredCredentials(allowStoredCredentials());
73 m_loader->loadAsynchronously(wrappedRequest, this);
76 void ResourceHandleInternal::cancel()
78 m_state = ConnectionStateCanceled;
81 // Do not make any further calls to the client.
85 void ResourceHandleInternal::setDefersLoading(bool value)
87 m_loader->setDefersLoading(value);
90 bool ResourceHandleInternal::allowStoredCredentials() const
92 return m_client && m_client->shouldUseCredentialStorage(m_owner);
95 void ResourceHandleInternal::willSendRequest(
96 WebURLLoader*, WebURLRequest& request, const WebURLResponse& response)
99 ASSERT(!request.isNull());
100 ASSERT(!response.isNull());
101 m_client->willSendRequest(m_owner, request.toMutableResourceRequest(), response.toResourceResponse());
104 void ResourceHandleInternal::didSendData(
105 WebURLLoader*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
108 m_client->didSendData(m_owner, bytesSent, totalBytesToBeSent);
111 void ResourceHandleInternal::didReceiveResponse(WebURLLoader*, const WebURLResponse& response)
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)
120 m_state = ConnectionStateReceivedResponse;
121 m_client->didReceiveResponse(m_owner, response.toResourceResponse());
124 void ResourceHandleInternal::didDownloadData(WebURLLoader*, int dataLength)
127 if (m_state != ConnectionStateReceivedResponse)
130 m_client->didDownloadData(m_owner, dataLength);
133 void ResourceHandleInternal::didReceiveData(WebURLLoader*, const char* data, int dataLength, int encodedDataLength)
136 if (m_state != ConnectionStateReceivedResponse && m_state != ConnectionStateReceivingData)
138 m_state = ConnectionStateReceivingData;
140 m_client->didReceiveData(m_owner, data, dataLength, encodedDataLength);
143 void ResourceHandleInternal::didReceiveCachedMetadata(WebURLLoader*, const char* data, int dataLength)
146 if (m_state != ConnectionStateReceivedResponse && m_state != ConnectionStateReceivingData)
149 m_client->didReceiveCachedMetadata(m_owner, data, dataLength);
152 void ResourceHandleInternal::didFinishLoading(WebURLLoader*, double finishTime)
155 if (m_state != ConnectionStateReceivedResponse && m_state != ConnectionStateReceivingData)
157 m_state = ConnectionStateFinishedLoading;
158 m_client->didFinishLoading(m_owner, finishTime);
161 void ResourceHandleInternal::didFail(WebURLLoader*, const WebURLError& error)
164 m_state = ConnectionStateFailed;
165 m_client->didFail(m_owner, error);
168 ResourceHandleInternal* ResourceHandleInternal::FromResourceHandle(ResourceHandle* handle)
170 return handle->d.get();
173 // ResourceHandle -------------------------------------------------------------
175 ResourceHandle::ResourceHandle(const ResourceRequest& request,
176 ResourceHandleClient* client,
178 bool shouldContentSniff)
179 : d(adoptPtr(new ResourceHandleInternal(request, client)))
183 // FIXME: Figure out what to do with the bool params.
186 PassRefPtr<ResourceHandle> ResourceHandle::create(NetworkingContext* context,
187 const ResourceRequest& request,
188 ResourceHandleClient* client,
190 bool shouldContentSniff)
192 RefPtr<ResourceHandle> newHandle = adoptRef(new ResourceHandle(
193 request, client, defersLoading, shouldContentSniff));
195 if (newHandle->start(context))
196 return newHandle.release();
201 ResourceRequest& ResourceHandle::firstRequest()
206 ResourceHandleClient* ResourceHandle::client() const
211 void ResourceHandle::setClient(ResourceHandleClient* client)
213 d->setClient(client);
216 void ResourceHandle::setDefersLoading(bool value)
218 d->setDefersLoading(value);
221 bool ResourceHandle::start(NetworkingContext* context)
227 bool ResourceHandle::hasAuthenticationChallenge() const
232 void ResourceHandle::clearAuthentication()
236 void ResourceHandle::cancel()
241 ResourceHandle::~ResourceHandle()
246 bool ResourceHandle::loadsBlocked()
248 return false; // This seems to be related to sync XMLHttpRequest...
252 void ResourceHandle::loadResourceSynchronously(NetworkingContext* context,
253 const ResourceRequest& request,
254 StoredCredentials storedCredentials,
255 ResourceError& error,
256 ResourceResponse& response,
259 OwnPtr<WebURLLoader> loader = adoptPtr(webKitPlatformSupport()->createURLLoader());
260 ASSERT(loader.get());
262 WrappedResourceRequest requestIn(request);
263 requestIn.setAllowStoredCredentials(storedCredentials == AllowStoredCredentials);
264 WrappedResourceResponse responseOut(response);
265 WebURLError errorOut;
268 loader->loadSynchronously(requestIn, responseOut, errorOut, dataOut);
272 data.append(dataOut.data(), dataOut.size());
276 bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame*)
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.
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.
287 ASSERT(request.httpMethod() == "POST");
292 void ResourceHandle::cacheMetadata(const ResourceResponse& response, const Vector<char>& data)
294 PlatformSupport::cacheMetadata(response.url(), response.responseTime(), data);
297 } // namespace WebCore