Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(318)

Side by Side Diff: sky/engine/core/fetch/ResourceLoader.cpp

Issue 1223793006: Delete sky/engine/core/fetch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sky/engine/core/fetch/ResourceLoader.h ('k') | sky/engine/core/fetch/ResourceLoaderHost.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2006, 2007, 2010, 2011 Apple Inc. All rights reserved.
3 * (C) 2007 Graham Dennis (graham.dennis@gmail.com)
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "sky/engine/core/fetch/ResourceLoader.h"
31
32 #include "sky/engine/core/fetch/Resource.h"
33 #include "sky/engine/core/fetch/ResourceLoaderHost.h"
34 #include "sky/engine/core/fetch/ResourcePtr.h"
35 #include "sky/engine/platform/Logging.h"
36 #include "sky/engine/platform/SharedBuffer.h"
37 #include "sky/engine/platform/exported/WrappedResourceRequest.h"
38 #include "sky/engine/platform/exported/WrappedResourceResponse.h"
39 #include "sky/engine/platform/network/ResourceError.h"
40 #include "sky/engine/public/platform/Platform.h"
41 #include "sky/engine/public/platform/WebData.h"
42 #include "sky/engine/public/platform/WebURLError.h"
43 #include "sky/engine/public/platform/WebURLRequest.h"
44 #include "sky/engine/public/platform/WebURLResponse.h"
45 #include "sky/engine/wtf/Assertions.h"
46 #include "sky/engine/wtf/CurrentTime.h"
47
48 namespace blink {
49
50 ResourceLoader::RequestCountTracker::RequestCountTracker(ResourceLoaderHost* hos t, Resource* resource)
51 : m_host(host)
52 , m_resource(resource)
53 {
54 m_host->incrementRequestCount(m_resource);
55 }
56
57 ResourceLoader::RequestCountTracker::~RequestCountTracker()
58 {
59 m_host->decrementRequestCount(m_resource);
60 }
61
62 ResourceLoader::RequestCountTracker::RequestCountTracker(const RequestCountTrack er& other)
63 {
64 m_host = other.m_host;
65 m_resource = other.m_resource;
66 m_host->incrementRequestCount(m_resource);
67 }
68
69 PassRefPtr<ResourceLoader> ResourceLoader::create(ResourceLoaderHost* host, Reso urce* resource, const ResourceRequest& request, const ResourceLoaderOptions& opt ions)
70 {
71 RefPtr<ResourceLoader> loader(adoptRef(new ResourceLoader(host, resource, op tions)));
72 loader->init(request);
73 return loader.release();
74 }
75
76 ResourceLoader::ResourceLoader(ResourceLoaderHost* host, Resource* resource, con st ResourceLoaderOptions& options)
77 : m_host(host)
78 , m_notifiedLoadComplete(false)
79 , m_options(options)
80 , m_resource(resource)
81 , m_state(Initialized)
82 , m_connectionState(ConnectionStateNew)
83 , m_requestCountTracker(adoptPtr(new RequestCountTracker(host, resource)))
84 {
85 }
86
87 ResourceLoader::~ResourceLoader()
88 {
89 ASSERT(m_state == Terminated);
90 }
91
92 void ResourceLoader::releaseResources()
93 {
94 ASSERT(m_state != Terminated);
95 ASSERT(m_notifiedLoadComplete);
96 m_requestCountTracker.clear();
97 m_host->didLoadResource(m_resource);
98 if (m_state == Terminated)
99 return;
100 m_resource->clearLoader();
101 m_resource->deleteIfPossible();
102 m_resource = nullptr;
103 m_host->willTerminateResourceLoader(this);
104
105 ASSERT(m_state != Terminated);
106
107 // It's possible that when we release the loader, it will be
108 // deallocated and release the last reference to this object.
109 // We need to retain to avoid accessing the object after it
110 // has been deallocated and also to avoid reentering this method.
111 RefPtr<ResourceLoader> protector(this);
112
113 m_host.clear();
114 m_state = Terminated;
115
116 if (m_loader) {
117 m_loader->cancel();
118 m_loader.clear();
119 }
120 }
121
122 void ResourceLoader::init(const ResourceRequest& passedRequest)
123 {
124 ASSERT(m_state != Terminated);
125 ResourceRequest request(passedRequest);
126 m_host->willSendRequest(m_resource->identifier(), request, ResourceResponse( ), m_options.initiatorInfo);
127 ASSERT(m_state != Terminated);
128 ASSERT(!request.isNull());
129 m_request = applyOptions(request);
130 m_resource->updateRequest(request);
131 ASSERT(m_state != Terminated);
132 m_host->didInitializeResourceLoader(this);
133 }
134
135 void ResourceLoader::start()
136 {
137 ASSERT(!m_loader);
138 ASSERT(!m_request.isNull());
139
140 m_host->willStartLoadingResource(m_resource, m_request);
141
142 if (m_state == Terminated)
143 return;
144
145 RELEASE_ASSERT(m_connectionState == ConnectionStateNew);
146 m_connectionState = ConnectionStateStarted;
147
148 m_loader = adoptPtr(blink::Platform::current()->createURLLoader());
149 ASSERT(m_loader);
150 blink::WrappedResourceRequest wrappedRequest(m_request);
151 m_loader->loadAsynchronously(wrappedRequest, this);
152 }
153
154 void ResourceLoader::didDownloadData(blink::WebURLLoader*, int length, int encod edDataLength)
155 {
156 ASSERT(m_state != Terminated);
157 RefPtr<ResourceLoader> protect(this);
158 RELEASE_ASSERT(m_connectionState == ConnectionStateReceivedResponse);
159 m_host->didDownloadData(m_resource, length, encodedDataLength);
160 if (m_state == Terminated)
161 return;
162 m_resource->didDownloadData(length);
163 }
164
165 void ResourceLoader::didFinishLoadingOnePart(double finishTime, int64 encodedDat aLength)
166 {
167 // If load has been cancelled after finishing (which could happen with a
168 // JavaScript that changes the window location), do nothing.
169 if (m_state == Terminated)
170 return;
171
172 if (m_notifiedLoadComplete)
173 return;
174 m_notifiedLoadComplete = true;
175 m_host->didFinishLoading(m_resource, finishTime, encodedDataLength);
176 }
177
178 void ResourceLoader::didChangePriority(ResourceLoadPriority loadPriority, int in traPriorityValue)
179 {
180 if (m_loader) {
181 m_host->didChangeLoadingPriority(m_resource, loadPriority, intraPriority Value);
182 ASSERT(m_state != Terminated);
183 m_loader->didChangePriority(static_cast<blink::WebURLRequest::Priority>( loadPriority), intraPriorityValue);
184 }
185 }
186
187 void ResourceLoader::cancelIfNotFinishing()
188 {
189 if (m_state != Initialized)
190 return;
191 cancel();
192 }
193
194 void ResourceLoader::cancel()
195 {
196 cancel(ResourceError());
197 }
198
199 void ResourceLoader::cancel(const ResourceError& error)
200 {
201 // If the load has already completed - succeeded, failed, or previously canc elled - do nothing.
202 if (m_state == Terminated)
203 return;
204 if (m_state == Finishing) {
205 releaseResources();
206 return;
207 }
208
209 ResourceError nonNullError = error.isNull() ? ResourceError::cancelledError( m_request.url()) : error;
210
211 // This function calls out to clients at several points that might do
212 // something that causes the last reference to this object to go away.
213 RefPtr<ResourceLoader> protector(this);
214
215 WTF_LOG(ResourceLoading, "Cancelled load of '%s'.\n", m_resource->url().stri ng().latin1().data());
216 if (m_state == Initialized)
217 m_state = Finishing;
218 m_resource->setResourceError(nonNullError);
219
220 if (m_loader) {
221 m_connectionState = ConnectionStateCanceled;
222 m_loader->cancel();
223 m_loader.clear();
224 }
225
226 if (!m_notifiedLoadComplete) {
227 m_notifiedLoadComplete = true;
228 m_host->didFailLoading(m_resource, nonNullError);
229 }
230
231 if (m_state == Finishing)
232 m_resource->error(Resource::LoadError);
233 if (m_state != Terminated)
234 releaseResources();
235 }
236
237 void ResourceLoader::willSendRequest(blink::WebURLLoader*, blink::WebURLRequest& passedRequest, const blink::WebURLResponse& passedRedirectResponse)
238 {
239 ASSERT(m_state != Terminated);
240 RefPtr<ResourceLoader> protect(this);
241
242 ResourceRequest& request(applyOptions(passedRequest.toMutableResourceRequest ()));
243
244 // FIXME: We should have a real context for redirect requests. Currently, we don't: see WebURLLoaderImpl::Context::OnReceivedRedirect in content/.
245 request.setRequestContext(blink::WebURLRequest::RequestContextInternal);
246
247 ASSERT(!request.isNull());
248 const ResourceResponse& redirectResponse(passedRedirectResponse.toResourceRe sponse());
249 ASSERT(!redirectResponse.isNull());
250 ASSERT(m_state != Terminated);
251
252 applyOptions(request); // canAccessRedirect() can modify m_options so we sho uld re-apply it.
253 ASSERT(m_state != Terminated);
254 m_resource->willSendRequest(request, redirectResponse);
255 if (request.isNull() || m_state == Terminated)
256 return;
257
258 m_host->willSendRequest(m_resource->identifier(), request, redirectResponse, m_options.initiatorInfo);
259 ASSERT(m_state != Terminated);
260 ASSERT(!request.isNull());
261 m_resource->updateRequest(request);
262 m_request = request;
263 }
264
265 void ResourceLoader::didSendData(blink::WebURLLoader*, unsigned long long bytesS ent, unsigned long long totalBytesToBeSent)
266 {
267 ASSERT(m_state == Initialized);
268 RefPtr<ResourceLoader> protect(this);
269 m_resource->didSendData(bytesSent, totalBytesToBeSent);
270 }
271
272 void ResourceLoader::didReceiveResponse(blink::WebURLLoader*, const blink::WebUR LResponse& response)
273 {
274 ASSERT(!response.isNull());
275 ASSERT(m_state == Initialized);
276
277 bool isMultipartPayload = response.isMultipartPayload();
278 bool isValidStateTransition = (m_connectionState == ConnectionStateStarted | | m_connectionState == ConnectionStateReceivedResponse);
279 // In the case of multipart loads, calls to didReceiveData & didReceiveRespo nse can be interleaved.
280 RELEASE_ASSERT(isMultipartPayload || isValidStateTransition);
281 m_connectionState = ConnectionStateReceivedResponse;
282
283 const ResourceResponse& resourceResponse = response.toResourceResponse();
284
285 // Reference the object in this method since the additional processing can d o
286 // anything including removing the last reference to this object.
287 RefPtr<ResourceLoader> protect(this);
288 m_resource->responseReceived(resourceResponse);
289 if (m_state == Terminated)
290 return;
291
292 m_host->didReceiveResponse(m_resource, resourceResponse);
293 if (m_state == Terminated)
294 return;
295
296 if (response.toResourceResponse().isMultipart()) {
297 // We don't count multiParts in a ResourceFetcher's request count
298 m_requestCountTracker.clear();
299 if (!m_resource->isImage()) {
300 cancel();
301 return;
302 }
303 } else if (isMultipartPayload) {
304 // Since a subresource loader does not load multipart sections progressi vely, data was delivered to the loader all at once.
305 // After the first multipart section is complete, signal to delegates th at this load is "finished"
306 m_host->subresourceLoaderFinishedLoadingOnePart(this);
307 ASSERT(m_state != Terminated);
308 didFinishLoadingOnePart(0, blink::WebURLLoaderClient::kUnknownEncodedDat aLength);
309 }
310 if (m_state == Terminated)
311 return;
312
313 if (m_resource->response().httpStatusCode() < 400 || m_resource->shouldIgnor eHTTPStatusCodeErrors())
314 return;
315 m_state = Finishing;
316
317 if (!m_notifiedLoadComplete) {
318 m_notifiedLoadComplete = true;
319 m_host->didFailLoading(m_resource, ResourceError::cancelledError(m_reque st.url()));
320 }
321
322 ASSERT(m_state != Terminated);
323 m_resource->error(Resource::LoadError);
324 cancel();
325 }
326
327 void ResourceLoader::didReceiveData(blink::WebURLLoader*, const char* data, int length, int encodedDataLength)
328 {
329 ASSERT(m_state != Terminated);
330 RELEASE_ASSERT(m_connectionState == ConnectionStateReceivedResponse || m_con nectionState == ConnectionStateReceivingData);
331 m_connectionState = ConnectionStateReceivingData;
332
333 // It is possible to receive data on uninitialized resources if it had an er ror status code, and we are running a nested message
334 // loop. When this occurs, ignoring the data is the correct action.
335 if (m_resource->response().httpStatusCode() >= 400 && !m_resource->shouldIgn oreHTTPStatusCodeErrors())
336 return;
337 ASSERT(m_state == Initialized);
338
339 // Reference the object in this method since the additional processing can d o
340 // anything including removing the last reference to this object.
341 RefPtr<ResourceLoader> protect(this);
342
343 // FIXME: If we get a resource with more than 2B bytes, this code won't do t he right thing.
344 // However, with today's computers and networking speeds, this won't happen in practice.
345 // Could be an issue with a giant local file.
346 m_host->didReceiveData(m_resource, data, length, encodedDataLength);
347 if (m_state == Terminated)
348 return;
349 m_resource->appendData(data, length);
350 }
351
352 void ResourceLoader::didFinishLoading(blink::WebURLLoader*, double finishTime, i nt64 encodedDataLength)
353 {
354 RELEASE_ASSERT(m_connectionState == ConnectionStateReceivedResponse || m_con nectionState == ConnectionStateReceivingData);
355 m_connectionState = ConnectionStateFinishedLoading;
356 if (m_state != Initialized)
357 return;
358 ASSERT(m_state != Terminated);
359 WTF_LOG(ResourceLoading, "Received '%s'.", m_resource->url().string().latin1 ().data());
360
361 RefPtr<ResourceLoader> protect(this);
362 ResourcePtr<Resource> protectResource(m_resource);
363 m_state = Finishing;
364 didFinishLoadingOnePart(finishTime, encodedDataLength);
365 if (m_state == Terminated)
366 return;
367 m_resource->finish(finishTime);
368
369 // If the load has been cancelled by a delegate in response to didFinishLoad (), do not release
370 // the resources a second time, they have been released by cancel.
371 if (m_state == Terminated)
372 return;
373 releaseResources();
374 }
375
376 void ResourceLoader::didFail(blink::WebURLLoader*, const blink::WebURLError& err or)
377 {
378 m_connectionState = ConnectionStateFailed;
379 ASSERT(m_state != Terminated);
380 WTF_LOG(ResourceLoading, "Failed to load '%s'.\n", m_resource->url().string( ).latin1().data());
381
382 RefPtr<ResourceLoader> protect(this);
383 RefPtr<ResourceLoaderHost> protectHost(m_host.get());
384 ResourcePtr<Resource> protectResource(m_resource);
385 m_state = Finishing;
386 m_resource->setResourceError(error);
387
388 if (!m_notifiedLoadComplete) {
389 m_notifiedLoadComplete = true;
390 m_host->didFailLoading(m_resource, error);
391 }
392 if (m_state == Terminated)
393 return;
394
395 m_resource->error(Resource::LoadError);
396
397 if (m_state == Terminated)
398 return;
399
400 releaseResources();
401 }
402
403 bool ResourceLoader::isLoadedBy(ResourceLoaderHost* loader) const
404 {
405 return m_host->isLoadedBy(loader);
406 }
407
408 ResourceRequest& ResourceLoader::applyOptions(ResourceRequest& request) const
409 {
410 request.setAllowStoredCredentials(m_options.allowCredentials == AllowStoredC redentials);
411 return request;
412 }
413
414 }
OLDNEW
« no previous file with comments | « sky/engine/core/fetch/ResourceLoader.h ('k') | sky/engine/core/fetch/ResourceLoaderHost.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698