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

Side by Side Diff: sky/engine/core/fetch/ResourceFetcher.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/ResourceFetcher.h ('k') | sky/engine/core/fetch/ResourceLoader.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) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org)
4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org)
5 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
6 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA.
22
23 This class provides all functionality needed for loading images, style sheet s and html
24 pages from the web. It has a memory cache for these objects.
25 */
26
27 #include "sky/engine/core/fetch/ResourceFetcher.h"
28
29 #include "gen/sky/core/FetchInitiatorTypeNames.h"
30 #include "gen/sky/platform/RuntimeEnabledFeatures.h"
31 #include "sky/engine/core/dom/Document.h"
32 #include "sky/engine/core/fetch/FetchContext.h"
33 #include "sky/engine/core/fetch/FontResource.h"
34 #include "sky/engine/core/fetch/ImageResource.h"
35 #include "sky/engine/core/fetch/MemoryCache.h"
36 #include "sky/engine/core/fetch/RawResource.h"
37 #include "sky/engine/core/fetch/ResourceLoader.h"
38 #include "sky/engine/core/fetch/ResourceLoaderSet.h"
39 #include "sky/engine/core/frame/LocalDOMWindow.h"
40 #include "sky/engine/core/frame/LocalFrame.h"
41 #include "sky/engine/core/frame/Settings.h"
42 #include "sky/engine/core/html/HTMLElement.h"
43 #include "sky/engine/core/inspector/ConsoleMessage.h"
44 #include "sky/engine/core/loader/FrameLoaderClient.h"
45 #include "sky/engine/core/loader/UniqueIdentifier.h"
46 #include "sky/engine/core/page/Page.h"
47 #include "sky/engine/platform/Logging.h"
48 #include "sky/engine/platform/SharedBuffer.h"
49 #include "sky/engine/platform/TraceEvent.h"
50 #include "sky/engine/platform/weborigin/SecurityPolicy.h"
51 #include "sky/engine/public/platform/Platform.h"
52 #include "sky/engine/public/platform/WebURL.h"
53 #include "sky/engine/public/platform/WebURLRequest.h"
54 #include "sky/engine/wtf/text/CString.h"
55 #include "sky/engine/wtf/text/WTFString.h"
56
57 using blink::WebURLRequest;
58
59 namespace blink {
60
61 static Resource* createResource(Resource::Type type, const ResourceRequest& requ est, const String& charset)
62 {
63 switch (type) {
64 case Resource::Image:
65 return new ImageResource(request);
66 case Resource::Font:
67 return new FontResource(request);
68 case Resource::MainResource:
69 case Resource::Raw:
70 case Resource::Media:
71 return new RawResource(request, type);
72 case Resource::LinkPrefetch:
73 return new Resource(request, Resource::LinkPrefetch);
74 case Resource::LinkSubresource:
75 return new Resource(request, Resource::LinkSubresource);
76 case Resource::ImportResource:
77 return new RawResource(request, type);
78 }
79
80 ASSERT_NOT_REACHED();
81 return 0;
82 }
83
84 static ResourceLoadPriority loadPriority(Resource::Type type, const FetchRequest & request)
85 {
86 if (request.priority() != ResourceLoadPriorityUnresolved)
87 return request.priority();
88
89 switch (type) {
90 case Resource::MainResource:
91 return ResourceLoadPriorityVeryHigh;
92 case Resource::Raw:
93 case Resource::Font:
94 case Resource::ImportResource:
95 return ResourceLoadPriorityMedium;
96 case Resource::Image:
97 // We'll default images to VeryLow, and promote whatever is visible. Thi s improves
98 // speed-index by ~5% on average, ~14% at the 99th percentile.
99 return ResourceLoadPriorityVeryLow;
100 case Resource::Media:
101 return ResourceLoadPriorityLow;
102 case Resource::LinkPrefetch:
103 return ResourceLoadPriorityVeryLow;
104 case Resource::LinkSubresource:
105 return ResourceLoadPriorityLow;
106 }
107 ASSERT_NOT_REACHED();
108 return ResourceLoadPriorityUnresolved;
109 }
110
111 static WebURLRequest::RequestContext requestContextFromType(const ResourceFetche r* fetcher, Resource::Type type)
112 {
113 switch (type) {
114 case Resource::MainResource:
115 // FIXME: Change this to a context frame type (once we introduce them): http://fetch.spec.whatwg.org/#concept-request-context-frame-type
116 return WebURLRequest::RequestContextHyperlink;
117 case Resource::Font:
118 return WebURLRequest::RequestContextFont;
119 case Resource::Image:
120 return WebURLRequest::RequestContextImage;
121 case Resource::Raw:
122 return WebURLRequest::RequestContextSubresource;
123 case Resource::ImportResource:
124 return WebURLRequest::RequestContextImport;
125 case Resource::LinkPrefetch:
126 return WebURLRequest::RequestContextPrefetch;
127 case Resource::LinkSubresource:
128 return WebURLRequest::RequestContextSubresource;
129 case Resource::Media: // TODO: Split this.
130 return WebURLRequest::RequestContextVideo;
131 }
132 ASSERT_NOT_REACHED();
133 return WebURLRequest::RequestContextSubresource;
134 }
135
136 ResourceFetcher::ResourceFetcher(Document* document)
137 : m_document(document)
138 , m_requestCount(0)
139 , m_garbageCollectDocumentResourcesTimer(this, &ResourceFetcher::garbageColl ectDocumentResourcesTimerFired)
140 , m_autoLoadImages(true)
141 , m_imagesEnabled(true)
142 , m_allowStaleResources(false)
143 {
144 }
145
146 ResourceFetcher::~ResourceFetcher()
147 {
148 m_document = nullptr;
149
150 // Make sure no requests still point to this ResourceFetcher
151 ASSERT(!m_requestCount);
152 }
153
154 Resource* ResourceFetcher::cachedResource(const KURL& resourceURL) const
155 {
156 KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(resourceURL);
157 return m_documentResources.get(url).get();
158 }
159
160 LocalFrame* ResourceFetcher::frame() const
161 {
162 // FIXME(sky): This used to prefer DocumentLoader::frame
163 // over importsController->master()->frame(), but in our
164 // world we should always just have one frame.
165 if (!m_document)
166 return 0;
167 return m_document->frame();
168 }
169
170 FetchContext& ResourceFetcher::context() const
171 {
172 return FetchContext::nullInstance();
173 }
174
175 ResourcePtr<ImageResource> ResourceFetcher::fetchImage(FetchRequest& request)
176 {
177 request.setDefer(clientDefersImage(request.resourceRequest().url()) ? FetchR equest::DeferredByClient : FetchRequest::NoDefer);
178 ResourcePtr<Resource> resource = requestResource(Resource::Image, request);
179 return resource && resource->type() == Resource::Image ? toImageResource(res ource) : 0;
180 }
181
182 ResourcePtr<FontResource> ResourceFetcher::fetchFont(FetchRequest& request)
183 {
184 ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeNone );
185 request.mutableResourceRequest().setRequestContext(WebURLRequest::RequestCon textFont);
186 return toFontResource(requestResource(Resource::Font, request));
187 }
188
189 bool ResourceFetcher::canRequest(Resource::Type type, const KURL& url, const Res ourceLoaderOptions& options, FetchRequest::OriginRestriction originRestriction) const
190 {
191 // FIXME(sky): Remove
192 return true;
193 }
194
195 bool ResourceFetcher::shouldLoadNewResource(Resource::Type type) const
196 {
197 if (!frame())
198 return false;
199 return true;
200 }
201
202 bool ResourceFetcher::resourceNeedsLoad(Resource* resource, const FetchRequest& request, RevalidationPolicy policy)
203 {
204 if (FetchRequest::DeferredByClient == request.defer())
205 return false;
206 if (policy != Use)
207 return true;
208 return resource->stillNeedsLoad();
209 }
210
211 void ResourceFetcher::requestLoadStarted(Resource* resource, const FetchRequest& request, ResourceLoadStartType type)
212 {
213 if (type == ResourceLoadingFromCache)
214 notifyLoadedFromMemoryCache(resource);
215
216 if (request.resourceRequest().url().protocolIsData())
217 return;
218
219 m_validatedURLs.add(request.resourceRequest().url());
220 }
221
222 ResourcePtr<Resource> ResourceFetcher::requestResource(Resource::Type type, Fetc hRequest& request)
223 {
224 ASSERT(request.options().synchronousPolicy == RequestAsynchronously || type == Resource::Raw);
225
226 TRACE_EVENT0("blink", "ResourceFetcher::requestResource");
227
228 KURL url = request.resourceRequest().url();
229
230 WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource '%s', charset '%s ', priority=%d, type=%s", url.elidedString().latin1().data(), request.charset(). latin1().data(), request.priority(), ResourceTypeName(type));
231
232 // If only the fragment identifiers differ, it is the same resource.
233 url = MemoryCache::removeFragmentIdentifierIfNeeded(url);
234
235 if (!url.isValid())
236 return 0;
237
238 if (!canRequest(type, url, request.options(), request.originRestriction()))
239 return 0;
240
241 if (LocalFrame* f = frame())
242 f->loaderClient()->dispatchWillRequestResource(&request);
243
244 // See if we can use an existing resource from the cache.
245 ResourcePtr<Resource> resource = memoryCache()->resourceForURL(url);
246
247 const RevalidationPolicy policy = determineRevalidationPolicy(type, request, resource.get());
248 switch (policy) {
249 case Reload:
250 memoryCache()->remove(resource.get());
251 // Fall through
252 case Load:
253 resource = createResourceForLoading(type, request, request.charset());
254 break;
255 case Revalidate:
256 resource = createResourceForRevalidation(request, resource.get());
257 break;
258 case Use:
259 memoryCache()->updateForAccess(resource.get());
260 break;
261 }
262
263 if (!resource)
264 return 0;
265
266 if (!resource->hasClients())
267 m_deadStatsRecorder.update(policy);
268
269 if (policy != Use)
270 resource->setIdentifier(createUniqueIdentifier());
271
272 ResourceLoadPriority priority = loadPriority(type, request);
273 if (priority != resource->resourceRequest().priority()) {
274 resource->mutableResourceRequest().setPriority(priority);
275 resource->didChangePriority(priority, 0);
276 }
277
278 if (resourceNeedsLoad(resource.get(), request, policy)) {
279 if (!shouldLoadNewResource(type)) {
280 if (memoryCache()->contains(resource.get()))
281 memoryCache()->remove(resource.get());
282 return 0;
283 }
284
285 resource->load(this, request.options());
286
287 // For asynchronous loads that immediately fail, it's sufficient to retu rn a
288 // null Resource, as it indicates that something prevented the load from starting.
289 // If there's a network error, that failure will happen asynchronously. However, if
290 // a sync load receives a network error, it will have already happened b y this point.
291 // In that case, the requester should have access to the relevant Resour ceError, so
292 // we need to return a non-null Resource.
293 if (resource->errorOccurred()) {
294 if (memoryCache()->contains(resource.get()))
295 memoryCache()->remove(resource.get());
296 return 0;
297 }
298 }
299
300 requestLoadStarted(resource.get(), request, policy == Use ? ResourceLoadingF romCache : ResourceLoadingFromNetwork);
301
302 ASSERT(resource->url() == url.string());
303 m_documentResources.set(resource->url(), resource);
304 return resource;
305 }
306
307 void ResourceFetcher::determineRequestContext(ResourceRequest& request, Resource ::Type type)
308 {
309 WebURLRequest::RequestContext requestContext = requestContextFromType(this, type);
310 request.setRequestContext(requestContext);
311 }
312
313 ResourceRequestCachePolicy ResourceFetcher::resourceRequestCachePolicy(const Res ourceRequest& request, Resource::Type type)
314 {
315 if (request.isConditional())
316 return ReloadIgnoringCacheData;
317
318 return UseProtocolCachePolicy;
319 }
320
321 void ResourceFetcher::addAdditionalRequestHeaders(ResourceRequest& request, Reso urce::Type type)
322 {
323 if (!frame())
324 return;
325
326 if (request.cachePolicy() == UseProtocolCachePolicy)
327 request.setCachePolicy(resourceRequestCachePolicy(request, type));
328 if (request.requestContext() == WebURLRequest::RequestContextUnspecified)
329 determineRequestContext(request, type);
330 if (type == Resource::LinkPrefetch || type == Resource::LinkSubresource)
331 request.setHTTPHeaderField("Purpose", "prefetch");
332
333 context().addAdditionalRequestHeaders(document(), request, (type == Resource ::MainResource) ? FetchMainResource : FetchSubresource);
334 }
335
336 ResourcePtr<Resource> ResourceFetcher::createResourceForRevalidation(const Fetch Request& request, Resource* resource)
337 {
338 ASSERT(resource);
339 ASSERT(memoryCache()->contains(resource));
340 ASSERT(resource->isLoaded());
341 ASSERT(resource->canUseCacheValidator());
342 ASSERT(!resource->resourceToRevalidate());
343
344 ResourceRequest revalidatingRequest(resource->resourceRequest());
345 revalidatingRequest.clearHTTPReferrer();
346 addAdditionalRequestHeaders(revalidatingRequest, resource->type());
347
348 const AtomicString& lastModified = resource->response().httpHeaderField("Las t-Modified");
349 const AtomicString& eTag = resource->response().httpHeaderField("ETag");
350 if (!lastModified.isEmpty() || !eTag.isEmpty()) {
351 ASSERT(context().cachePolicy(document()) != CachePolicyReload);
352 if (context().cachePolicy(document()) == CachePolicyRevalidate)
353 revalidatingRequest.setHTTPHeaderField("Cache-Control", "max-age=0") ;
354 }
355 if (!lastModified.isEmpty())
356 revalidatingRequest.setHTTPHeaderField("If-Modified-Since", lastModified );
357 if (!eTag.isEmpty())
358 revalidatingRequest.setHTTPHeaderField("If-None-Match", eTag);
359
360 ResourcePtr<Resource> newResource = createResource(resource->type(), revalid atingRequest, resource->encoding());
361 WTF_LOG(ResourceLoading, "Resource %p created to revalidate %p", newResource .get(), resource);
362
363 newResource->setResourceToRevalidate(resource);
364
365 memoryCache()->remove(resource);
366 memoryCache()->add(newResource.get());
367 return newResource;
368 }
369
370 ResourcePtr<Resource> ResourceFetcher::createResourceForLoading(Resource::Type t ype, FetchRequest& request, const String& charset)
371 {
372 ASSERT(!memoryCache()->resourceForURL(request.resourceRequest().url()));
373
374 WTF_LOG(ResourceLoading, "Loading Resource for '%s'.", request.resourceReque st().url().elidedString().latin1().data());
375
376 addAdditionalRequestHeaders(request.mutableResourceRequest(), type);
377 ResourcePtr<Resource> resource = createResource(type, request.resourceReques t(), charset);
378
379 memoryCache()->add(resource.get());
380 return resource;
381 }
382
383 ResourceFetcher::RevalidationPolicy ResourceFetcher::determineRevalidationPolicy (Resource::Type type, const FetchRequest& fetchRequest, Resource* existingResour ce) const
384 {
385 const ResourceRequest& request = fetchRequest.resourceRequest();
386
387 if (!existingResource)
388 return Load;
389
390 // If the same URL has been loaded as a different type, we need to reload.
391 if (existingResource->type() != type) {
392 WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicy r eloading due to type mismatch.");
393 return Reload;
394 }
395
396 // Do not load from cache if images are not enabled. The load for this image will be blocked
397 // in ImageResource::load.
398 if (FetchRequest::DeferredByClient == fetchRequest.defer())
399 return Reload;
400
401 // Always use data uris.
402 // FIXME: Extend this to non-images.
403 if (type == Resource::Image && request.url().protocolIsData())
404 return Use;
405
406 if (!existingResource->canReuse(request))
407 return Reload;
408
409 // Never use cache entries for downloadToFile requests. The caller expects t he resource in a file.
410 if (request.downloadToFile())
411 return Reload;
412
413 // Certain requests (e.g., XHRs) might have manually set headers that requir e revalidation.
414 // FIXME: In theory, this should be a Revalidate case. In practice, the Memo ryCache revalidation path assumes a whole bunch
415 // of things about how revalidation works that manual headers violate, so pu nt to Reload instead.
416 if (request.isConditional())
417 return Reload;
418
419 // Don't reload resources while pasting.
420 if (m_allowStaleResources)
421 return Use;
422
423 if (!fetchRequest.options().canReuseRequest(existingResource->options()))
424 return Reload;
425
426 // CachePolicyHistoryBuffer uses the cache no matter what.
427 CachePolicy cachePolicy = context().cachePolicy(document());
428 if (cachePolicy == CachePolicyHistoryBuffer)
429 return Use;
430
431 // Don't reuse resources with Cache-control: no-store.
432 if (existingResource->hasCacheControlNoStoreHeader()) {
433 WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicy r eloading due to Cache-control: no-store.");
434 return Reload;
435 }
436
437 // If credentials were sent with the previous request and won't be
438 // with this one, or vice versa, re-fetch the resource.
439 //
440 // This helps with the case where the server sends back
441 // "Access-Control-Allow-Origin: *" all the time, but some of the
442 // client's requests are made without CORS and some with.
443 if (existingResource->resourceRequest().allowStoredCredentials() != request. allowStoredCredentials()) {
444 WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicy r eloading due to difference in credentials settings.");
445 return Reload;
446 }
447
448 // During the initial load, avoid loading the same resource multiple times f or a single document,
449 // even if the cache policies would tell us to.
450 // We also group loads of the same resource together.
451 // Raw resources are exempted, as XHRs fall into this category and may have user-set Cache-Control:
452 // headers or other factors that require separate requests.
453 if (type != Resource::Raw) {
454 if (document() && !document()->loadEventFinished() && m_validatedURLs.co ntains(existingResource->url()))
455 return Use;
456 if (existingResource->isLoading())
457 return Use;
458 }
459
460 // CachePolicyReload always reloads
461 if (cachePolicy == CachePolicyReload) {
462 WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicy r eloading due to CachePolicyReload.");
463 return Reload;
464 }
465
466 // We'll try to reload the resource if it failed last time.
467 if (existingResource->errorOccurred()) {
468 WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicye reloading due to resource being in the error state");
469 return Reload;
470 }
471
472 // List of available images logic allows images to be re-used without cache validation. We restrict this only to images
473 // from memory cache which are the same as the version in the current docume nt.
474 if (type == Resource::Image && existingResource == cachedResource(request.ur l()))
475 return Use;
476
477 // Check if the cache headers requires us to revalidate (cache expiration fo r example).
478 if (cachePolicy == CachePolicyRevalidate || existingResource->mustRevalidate DueToCacheHeaders()
479 || request.cacheControlContainsNoCache()) {
480 // See if the resource has usable ETag or Last-modified headers.
481 if (existingResource->canUseCacheValidator())
482 return Revalidate;
483
484 // No, must reload.
485 WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicy r eloading due to missing cache validators.");
486 return Reload;
487 }
488
489 return Use;
490 }
491
492 void ResourceFetcher::printAccessDeniedMessage(const KURL& url) const
493 {
494 if (url.isNull())
495 return;
496
497 if (!frame())
498 return;
499
500 String message;
501 if (!m_document || m_document->url().isNull())
502 message = "Unsafe attempt to load URL " + url.elidedString() + '.';
503 else
504 message = "Unsafe attempt to load URL " + url.elidedString() + " from fr ame with URL " + m_document->url().elidedString() + ". Domains, protocols and po rts must match.\n";
505
506 frame()->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessag eSource, ErrorMessageLevel, message));
507 }
508
509 void ResourceFetcher::setAutoLoadImages(bool enable)
510 {
511 if (enable == m_autoLoadImages)
512 return;
513
514 m_autoLoadImages = enable;
515
516 if (!m_autoLoadImages)
517 return;
518
519 reloadImagesIfNotDeferred();
520 }
521
522 void ResourceFetcher::setImagesEnabled(bool enable)
523 {
524 if (enable == m_imagesEnabled)
525 return;
526
527 m_imagesEnabled = enable;
528
529 if (!m_imagesEnabled)
530 return;
531
532 reloadImagesIfNotDeferred();
533 }
534
535 bool ResourceFetcher::clientDefersImage(const KURL& url) const
536 {
537 // FIXME(sky): remove
538 return false;
539 }
540
541 bool ResourceFetcher::shouldDeferImageLoad(const KURL& url) const
542 {
543 return clientDefersImage(url) || !m_autoLoadImages;
544 }
545
546 void ResourceFetcher::reloadImagesIfNotDeferred()
547 {
548 DocumentResourceMap::iterator end = m_documentResources.end();
549 for (DocumentResourceMap::iterator it = m_documentResources.begin(); it != e nd; ++it) {
550 Resource* resource = it->value.get();
551 if (resource->type() == Resource::Image && resource->stillNeedsLoad() && !clientDefersImage(resource->url()))
552 const_cast<Resource*>(resource)->load(this, defaultResourceOptions() );
553 }
554 }
555
556 void ResourceFetcher::didLoadResource(Resource* resource)
557 {
558 RefPtr<Document> protectDocument(m_document);
559 if (m_document)
560 m_document->checkCompleted();
561 scheduleDocumentResourcesGC();
562 }
563
564 void ResourceFetcher::scheduleDocumentResourcesGC()
565 {
566 if (!m_garbageCollectDocumentResourcesTimer.isActive())
567 m_garbageCollectDocumentResourcesTimer.startOneShot(0, FROM_HERE);
568 }
569
570 // Garbage collecting m_documentResources is a workaround for the
571 // ResourcePtrs on the RHS being strong references. Ideally this
572 // would be a weak map, however ResourcePtrs perform additional
573 // bookkeeping on Resources, so instead pseudo-GC them -- when the
574 // reference count reaches 1, m_documentResources is the only reference, so
575 // remove it from the map.
576 void ResourceFetcher::garbageCollectDocumentResourcesTimerFired(Timer<ResourceFe tcher>* timer)
577 {
578 ASSERT_UNUSED(timer, timer == &m_garbageCollectDocumentResourcesTimer);
579 garbageCollectDocumentResources();
580 }
581
582 void ResourceFetcher::garbageCollectDocumentResources()
583 {
584 typedef Vector<String, 10> StringVector;
585 StringVector resourcesToDelete;
586
587 for (DocumentResourceMap::iterator it = m_documentResources.begin(); it != m _documentResources.end(); ++it) {
588 if (it->value->hasOneHandle())
589 resourcesToDelete.append(it->key);
590 }
591
592 m_documentResources.removeAll(resourcesToDelete);
593 }
594
595 void ResourceFetcher::notifyLoadedFromMemoryCache(Resource* resource)
596 {
597 if (!frame() || !frame()->page() || resource->status() != Resource::Cached | | m_validatedURLs.contains(resource->url()))
598 return;
599
600 ResourceRequest request(resource->url());
601 unsigned long identifier = createUniqueIdentifier();
602 context().dispatchDidLoadResourceFromMemoryCache(request, resource->response ());
603 // FIXME: If willSendRequest changes the request, we don't respect it.
604 willSendRequest(identifier, request, ResourceResponse(), resource->options() .initiatorInfo);
605 context().sendRemainingDelegateMessages(m_document, identifier, resource->re sponse(), resource->encodedSize());
606 }
607
608 void ResourceFetcher::incrementRequestCount(const Resource* res)
609 {
610 if (res->ignoreForRequestCount())
611 return;
612
613 ++m_requestCount;
614 }
615
616 void ResourceFetcher::decrementRequestCount(const Resource* res)
617 {
618 if (res->ignoreForRequestCount())
619 return;
620
621 --m_requestCount;
622 ASSERT(m_requestCount > -1);
623 }
624
625 void ResourceFetcher::didFinishLoading(const Resource* resource, double finishTi me, int64_t encodedDataLength)
626 {
627 TRACE_EVENT_ASYNC_END0("net", "Resource", resource);
628 context().dispatchDidFinishLoading(m_document, resource->identifier(), finis hTime, encodedDataLength);
629 }
630
631 void ResourceFetcher::didChangeLoadingPriority(const Resource* resource, Resourc eLoadPriority loadPriority, int intraPriorityValue)
632 {
633 TRACE_EVENT_ASYNC_STEP_INTO1("net", "Resource", resource, "ChangePriority", "priority", loadPriority);
634 context().dispatchDidChangeResourcePriority(resource->identifier(), loadPrio rity, intraPriorityValue);
635 }
636
637 void ResourceFetcher::didFailLoading(const Resource* resource, const ResourceErr or& error)
638 {
639 TRACE_EVENT_ASYNC_END0("net", "Resource", resource);
640 context().dispatchDidFail(m_document, resource->identifier(), error);
641 }
642
643 void ResourceFetcher::willSendRequest(unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse, const FetchInitiatorInfo& in itiatorInfo)
644 {
645 context().dispatchWillSendRequest(m_document, identifier, request, redirectR esponse, initiatorInfo);
646 }
647
648 void ResourceFetcher::didReceiveResponse(const Resource* resource, const Resourc eResponse& response)
649 {
650 context().dispatchDidReceiveResponse(m_document, resource->identifier(), res ponse, resource->loader());
651 }
652
653 void ResourceFetcher::didReceiveData(const Resource* resource, const char* data, int dataLength, int encodedDataLength)
654 {
655 context().dispatchDidReceiveData(m_document, resource->identifier(), data, d ataLength, encodedDataLength);
656 }
657
658 void ResourceFetcher::didDownloadData(const Resource* resource, int dataLength, int encodedDataLength)
659 {
660 context().dispatchDidDownloadData(m_document, resource->identifier(), dataLe ngth, encodedDataLength);
661 }
662
663 void ResourceFetcher::subresourceLoaderFinishedLoadingOnePart(ResourceLoader* lo ader)
664 {
665 if (!m_multipartLoaders)
666 m_multipartLoaders = ResourceLoaderSet::create();
667 m_multipartLoaders->add(loader);
668 m_loaders->remove(loader);
669 }
670
671 void ResourceFetcher::didInitializeResourceLoader(ResourceLoader* loader)
672 {
673 if (!m_document)
674 return;
675 if (!m_loaders)
676 m_loaders = ResourceLoaderSet::create();
677 ASSERT(!m_loaders->contains(loader));
678 m_loaders->add(loader);
679 }
680
681 void ResourceFetcher::willTerminateResourceLoader(ResourceLoader* loader)
682 {
683 if (m_loaders && m_loaders->contains(loader))
684 m_loaders->remove(loader);
685 if (m_multipartLoaders && m_multipartLoaders->contains(loader))
686 m_multipartLoaders->remove(loader);
687 }
688
689 void ResourceFetcher::willStartLoadingResource(Resource* resource, ResourceReque st& request)
690 {
691 TRACE_EVENT_ASYNC_BEGIN2(
692 "net", "Resource", resource, "url",
693 TRACE_STR_COPY(resource->url().string().ascii().data()), "priority",
694 resource->resourceRequest().priority());
695 }
696
697 void ResourceFetcher::stopFetching()
698 {
699 if (m_multipartLoaders)
700 m_multipartLoaders->cancelAll();
701 if (m_loaders)
702 m_loaders->cancelAll();
703 }
704
705 bool ResourceFetcher::isFetching() const
706 {
707 return m_loaders && !m_loaders->isEmpty();
708 }
709
710 bool ResourceFetcher::isLoadedBy(ResourceLoaderHost* possibleOwner) const
711 {
712 return this == possibleOwner;
713 }
714
715 #if !ENABLE(OILPAN)
716 void ResourceFetcher::refResourceLoaderHost()
717 {
718 ref();
719 }
720
721 void ResourceFetcher::derefResourceLoaderHost()
722 {
723 deref();
724 }
725 #endif
726
727 const ResourceLoaderOptions& ResourceFetcher::defaultResourceOptions()
728 {
729 DEFINE_STATIC_LOCAL(ResourceLoaderOptions, options, (BufferData, AllowStored Credentials, ClientRequestedCredentials, DocumentContext));
730 return options;
731 }
732
733 ResourceFetcher::DeadResourceStatsRecorder::DeadResourceStatsRecorder()
734 : m_useCount(0)
735 , m_revalidateCount(0)
736 , m_loadCount(0)
737 {
738 }
739
740 ResourceFetcher::DeadResourceStatsRecorder::~DeadResourceStatsRecorder()
741 {
742 blink::Platform::current()->histogramCustomCounts(
743 "WebCore.ResourceFetcher.HitCount", m_useCount, 0, 1000, 50);
744 blink::Platform::current()->histogramCustomCounts(
745 "WebCore.ResourceFetcher.RevalidateCount", m_revalidateCount, 0, 1000, 5 0);
746 blink::Platform::current()->histogramCustomCounts(
747 "WebCore.ResourceFetcher.LoadCount", m_loadCount, 0, 1000, 50);
748 }
749
750 void ResourceFetcher::DeadResourceStatsRecorder::update(RevalidationPolicy polic y)
751 {
752 switch (policy) {
753 case Reload:
754 case Load:
755 ++m_loadCount;
756 return;
757 case Revalidate:
758 ++m_revalidateCount;
759 return;
760 case Use:
761 ++m_useCount;
762 return;
763 }
764 }
765
766 }
OLDNEW
« no previous file with comments | « sky/engine/core/fetch/ResourceFetcher.h ('k') | sky/engine/core/fetch/ResourceLoader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698