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

Side by Side Diff: Source/core/fetch/ResourceFetcher.cpp

Issue 1170503003: Remove resource type-specific fetching logic from ResourceFetcher (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Null-check Document::loader() before calling startPreload() Created 5 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/fetch/ResourceFetcher.h ('k') | Source/core/fetch/ResourceFetcherTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org)
4 Copyright (C) 2002 Waldo Bastian (bastian@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. 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/ 6 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
7 7
8 This library is free software; you can redistribute it and/or 8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public 9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either 10 License as published by the Free Software Foundation; either
(...skipping 10 matching lines...) Expand all
21 Boston, MA 02110-1301, USA. 21 Boston, MA 02110-1301, USA.
22 22
23 This class provides all functionality needed for loading images, style sheet s and html 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. 24 pages from the web. It has a memory cache for these objects.
25 */ 25 */
26 26
27 #include "config.h" 27 #include "config.h"
28 #include "core/fetch/ResourceFetcher.h" 28 #include "core/fetch/ResourceFetcher.h"
29 29
30 #include "bindings/core/v8/V8DOMActivityLogger.h" 30 #include "bindings/core/v8/V8DOMActivityLogger.h"
31 #include "core/fetch/CSSStyleSheetResource.h"
32 #include "core/fetch/CrossOriginAccessControl.h" 31 #include "core/fetch/CrossOriginAccessControl.h"
33 #include "core/fetch/DocumentResource.h"
34 #include "core/fetch/FetchContext.h" 32 #include "core/fetch/FetchContext.h"
35 #include "core/fetch/FetchInitiatorTypeNames.h" 33 #include "core/fetch/FetchInitiatorTypeNames.h"
36 #include "core/fetch/FontResource.h"
37 #include "core/fetch/ImageResource.h"
38 #include "core/fetch/MemoryCache.h" 34 #include "core/fetch/MemoryCache.h"
39 #include "core/fetch/RawResource.h"
40 #include "core/fetch/ResourceLoader.h" 35 #include "core/fetch/ResourceLoader.h"
41 #include "core/fetch/ResourceLoaderSet.h" 36 #include "core/fetch/ResourceLoaderSet.h"
42 #include "core/fetch/ScriptResource.h"
43 #include "core/fetch/SubstituteData.h"
44 #include "core/fetch/UniqueIdentifier.h" 37 #include "core/fetch/UniqueIdentifier.h"
45 #include "core/fetch/XSLStyleSheetResource.h"
46 #include "core/timing/ResourceTimingInfo.h" 38 #include "core/timing/ResourceTimingInfo.h"
47 #include "platform/Logging.h" 39 #include "platform/Logging.h"
48 #include "platform/RuntimeEnabledFeatures.h" 40 #include "platform/RuntimeEnabledFeatures.h"
49 #include "platform/TraceEvent.h" 41 #include "platform/TraceEvent.h"
50 #include "platform/mhtml/ArchiveResource.h" 42 #include "platform/mhtml/ArchiveResource.h"
51 #include "platform/mhtml/ArchiveResourceCollection.h" 43 #include "platform/mhtml/ArchiveResourceCollection.h"
52 #include "platform/weborigin/KnownPorts.h" 44 #include "platform/weborigin/KnownPorts.h"
53 #include "platform/weborigin/SecurityOrigin.h" 45 #include "platform/weborigin/SecurityOrigin.h"
54 #include "platform/weborigin/SecurityPolicy.h" 46 #include "platform/weborigin/SecurityPolicy.h"
55 #include "public/platform/Platform.h" 47 #include "public/platform/Platform.h"
56 #include "public/platform/WebURL.h" 48 #include "public/platform/WebURL.h"
57 #include "public/platform/WebURLRequest.h" 49 #include "public/platform/WebURLRequest.h"
58 #include "wtf/text/CString.h" 50 #include "wtf/text/CString.h"
59 #include "wtf/text/WTFString.h" 51 #include "wtf/text/WTFString.h"
60 52
61 #define PRELOAD_DEBUG 0 53 #define PRELOAD_DEBUG 0
62 54
63 using blink::WebURLRequest; 55 using blink::WebURLRequest;
64 56
65 namespace blink { 57 namespace blink {
66 58
67 static Resource* createResource(Resource::Type type, const ResourceRequest& requ est, const String& charset)
68 {
69 switch (type) {
70 case Resource::Image:
71 return new ImageResource(request);
72 case Resource::CSSStyleSheet:
73 return new CSSStyleSheetResource(request, charset);
74 case Resource::Script:
75 return ScriptResource::create(request, charset).leakPtr();
76 case Resource::SVGDocument:
77 return new DocumentResource(request, Resource::SVGDocument);
78 case Resource::Font:
79 return new FontResource(request);
80 case Resource::MainResource:
81 case Resource::Raw:
82 case Resource::TextTrack:
83 case Resource::Media:
84 return new RawResource(request, type);
85 case Resource::XSLStyleSheet:
86 return new XSLStyleSheetResource(request, charset);
87 case Resource::LinkPrefetch:
88 return new Resource(request, Resource::LinkPrefetch);
89 case Resource::LinkSubresource:
90 return new Resource(request, Resource::LinkSubresource);
91 case Resource::LinkPreload:
92 return new Resource(request, Resource::LinkPreload);
93 case Resource::ImportResource:
94 return new RawResource(request, type);
95 }
96
97 ASSERT_NOT_REACHED();
98 return 0;
99 }
100
101 ResourceLoadPriority ResourceFetcher::loadPriority(Resource::Type type, const Fe tchRequest& request) 59 ResourceLoadPriority ResourceFetcher::loadPriority(Resource::Type type, const Fe tchRequest& request)
102 { 60 {
103 // TODO(yoav): Change it here so that priority can be changed even after it was resolved. 61 // TODO(yoav): Change it here so that priority can be changed even after it was resolved.
104 if (request.priority() != ResourceLoadPriorityUnresolved) 62 if (request.priority() != ResourceLoadPriorityUnresolved)
105 return request.priority(); 63 return request.priority();
106 64
107 switch (type) { 65 switch (type) {
108 case Resource::MainResource: 66 case Resource::MainResource:
109 return ResourceLoadPriorityVeryHigh; 67 return ResourceLoadPriorityVeryHigh;
110 case Resource::CSSStyleSheet: 68 case Resource::CSSStyleSheet:
(...skipping 25 matching lines...) Expand all
136 return ResourceLoadPriorityVeryLow; 94 return ResourceLoadPriorityVeryLow;
137 case Resource::LinkSubresource: 95 case Resource::LinkSubresource:
138 return ResourceLoadPriorityLow; 96 return ResourceLoadPriorityLow;
139 case Resource::TextTrack: 97 case Resource::TextTrack:
140 return ResourceLoadPriorityLow; 98 return ResourceLoadPriorityLow;
141 } 99 }
142 ASSERT_NOT_REACHED(); 100 ASSERT_NOT_REACHED();
143 return ResourceLoadPriorityUnresolved; 101 return ResourceLoadPriorityUnresolved;
144 } 102 }
145 103
146 static Resource* resourceFromDataURIRequest(const ResourceRequest& request, cons t ResourceLoaderOptions& resourceOptions, const String& cacheIdentifier)
147 {
148 const KURL& url = request.url();
149 ASSERT(url.protocolIsData());
150
151 WebString mimetype;
152 WebString charset;
153 RefPtr<SharedBuffer> data = PassRefPtr<SharedBuffer>(Platform::current()->pa rseDataURL(url, mimetype, charset));
154 if (!data)
155 return nullptr;
156 ResourceResponse response(url, mimetype, data->size(), charset, String());
157
158 Resource* resource = createResource(Resource::Image, request, charset);
159 resource->setOptions(resourceOptions);
160 // FIXME: We should provide a body stream here.
161 resource->responseReceived(response, nullptr);
162 if (data->size())
163 resource->setResourceBuffer(data);
164 resource->setCacheIdentifier(cacheIdentifier);
165 resource->finish();
166 return resource;
167 }
168
169 static void populateResourceTiming(ResourceTimingInfo* info, Resource* resource, bool clearLoadTimings) 104 static void populateResourceTiming(ResourceTimingInfo* info, Resource* resource, bool clearLoadTimings)
170 { 105 {
171 info->setInitialRequest(resource->resourceRequest()); 106 info->setInitialRequest(resource->resourceRequest());
172 info->setFinalResponse(resource->response()); 107 info->setFinalResponse(resource->response());
173 if (clearLoadTimings) { 108 if (clearLoadTimings) {
174 info->clearLoadTimings(); 109 info->clearLoadTimings();
175 info->setLoadFinishTime(info->initialTime()); 110 info->setLoadFinishTime(info->initialTime());
176 } else { 111 } else {
177 info->setLoadFinishTime(resource->loadFinishTime()); 112 info->setLoadFinishTime(resource->loadFinishTime());
178 } 113 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 ASSERT(!m_loaders || m_loaders->isEmpty()); 175 ASSERT(!m_loaders || m_loaders->isEmpty());
241 #endif 176 #endif
242 } 177 }
243 178
244 Resource* ResourceFetcher::cachedResource(const KURL& resourceURL) const 179 Resource* ResourceFetcher::cachedResource(const KURL& resourceURL) const
245 { 180 {
246 KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(resourceURL); 181 KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(resourceURL);
247 return m_documentResources.get(url).get(); 182 return m_documentResources.get(url).get();
248 } 183 }
249 184
250 ResourcePtr<Resource> ResourceFetcher::fetchSynchronously(FetchRequest& request)
251 {
252 request.mutableResourceRequest().setTimeoutInterval(10);
253 ResourceLoaderOptions options(request.options());
254 options.synchronousPolicy = RequestSynchronously;
255 request.setOptions(options);
256 return requestResource(Resource::Raw, request);
257 }
258
259 ResourcePtr<ImageResource> ResourceFetcher::fetchImage(FetchRequest& request)
260 {
261 if (request.resourceRequest().requestContext() == WebURLRequest::RequestCont extUnspecified)
262 request.mutableResourceRequest().setRequestContext(WebURLRequest::Reques tContextImage);
263 if (context().pageDismissalEventBeingDispatched()) {
264 KURL requestURL = request.resourceRequest().url();
265 if (requestURL.isValid() && context().canRequest(Resource::Image, reques t.resourceRequest(), requestURL, request.options(), request.forPreload(), reques t.originRestriction()))
266 context().sendImagePing(requestURL);
267 return 0;
268 }
269
270 if (request.resourceRequest().url().protocolIsData())
271 preCacheDataURIImage(request);
272
273 if (clientDefersImage(request.resourceRequest().url()))
274 request.setDefer(FetchRequest::DeferredByClient);
275 ResourcePtr<Resource> resource = requestResource(Resource::Image, request);
276 return resource && resource->type() == Resource::Image ? toImageResource(res ource) : 0;
277 }
278
279 void ResourceFetcher::preCacheDataURIImage(const FetchRequest& request)
280 {
281 const KURL& url = request.resourceRequest().url();
282 ASSERT(url.protocolIsData());
283
284 const String cacheIdentifier = getCacheIdentifier();
285 if (memoryCache()->resourceForURL(url, cacheIdentifier))
286 return;
287
288 if (Resource* resource = resourceFromDataURIRequest(request.resourceRequest( ), request.options(), cacheIdentifier)) {
289 memoryCache()->add(resource);
290 scheduleDocumentResourcesGC();
291 }
292 }
293
294 ResourcePtr<FontResource> ResourceFetcher::fetchFont(FetchRequest& request)
295 {
296 ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeNone );
297 request.mutableResourceRequest().setRequestContext(WebURLRequest::RequestCon textFont);
298 return toFontResource(requestResource(Resource::Font, request));
299 }
300
301 ResourcePtr<RawResource> ResourceFetcher::fetchImport(FetchRequest& request)
302 {
303 ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeNone );
304 request.mutableResourceRequest().setRequestContext(WebURLRequest::RequestCon textImport);
305 return toRawResource(requestResource(Resource::ImportResource, request));
306 }
307
308 ResourcePtr<CSSStyleSheetResource> ResourceFetcher::fetchCSSStyleSheet(FetchRequ est& request)
309 {
310 ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeNone );
311 request.mutableResourceRequest().setRequestContext(WebURLRequest::RequestCon textStyle);
312 return toCSSStyleSheetResource(requestResource(Resource::CSSStyleSheet, requ est));
313 }
314
315 ResourcePtr<ScriptResource> ResourceFetcher::fetchScript(FetchRequest& request)
316 {
317 ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeNone );
318 request.mutableResourceRequest().setRequestContext(WebURLRequest::RequestCon textScript);
319 return toScriptResource(requestResource(Resource::Script, request));
320 }
321
322 ResourcePtr<XSLStyleSheetResource> ResourceFetcher::fetchXSLStyleSheet(FetchRequ est& request)
323 {
324 ASSERT(RuntimeEnabledFeatures::xsltEnabled());
325 request.mutableResourceRequest().setRequestContext(WebURLRequest::RequestCon textXSLT);
326 return toXSLStyleSheetResource(requestResource(Resource::XSLStyleSheet, requ est));
327 }
328
329 ResourcePtr<DocumentResource> ResourceFetcher::fetchSVGDocument(FetchRequest& re quest)
330 {
331 ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeNone );
332 request.mutableResourceRequest().setRequestContext(WebURLRequest::RequestCon textImage);
333 return toDocumentResource(requestResource(Resource::SVGDocument, request));
334 }
335
336 ResourcePtr<Resource> ResourceFetcher::fetchLinkResource(Resource::Type type, Fe tchRequest& request)
337 {
338 ASSERT(type == Resource::LinkPrefetch || type == Resource::LinkSubresource);
339 ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeNone );
340 request.mutableResourceRequest().setRequestContext(type == Resource::LinkPre fetch ? WebURLRequest::RequestContextPrefetch : WebURLRequest::RequestContextSub resource);
341 return requestResource(type, request);
342 }
343
344 ResourcePtr<Resource> ResourceFetcher::fetchLinkPreloadResource(Resource::Type t ype, FetchRequest& request)
345 {
346 // TODO(yoav): Enforce a LinkPreload context here, once we know we're adding one - https://github.com/whatwg/fetch/issues/36
347 ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeNone );
348 determineRequestContext(request.mutableResourceRequest(), type);
349 return requestResource(type, request);
350 }
351
352 ResourcePtr<RawResource> ResourceFetcher::fetchRawResource(FetchRequest& request )
353 {
354 ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeNone );
355 ASSERT(request.resourceRequest().requestContext() != WebURLRequest::RequestC ontextUnspecified);
356 return toRawResource(requestResource(Resource::Raw, request));
357 }
358
359 ResourcePtr<RawResource> ResourceFetcher::fetchMainResource(FetchRequest& reques t, const SubstituteData& substituteData)
360 {
361 ASSERT(request.resourceRequest().frameType() != WebURLRequest::FrameTypeNone );
362 ASSERT(request.resourceRequest().requestContext() == WebURLRequest::RequestC ontextForm || request.resourceRequest().requestContext() == WebURLRequest::Reque stContextFrame || request.resourceRequest().requestContext() == WebURLRequest::R equestContextHyperlink || request.resourceRequest().requestContext() == WebURLRe quest::RequestContextIframe || request.resourceRequest().requestContext() == Web URLRequest::RequestContextInternal || request.resourceRequest().requestContext() == WebURLRequest::RequestContextLocation);
363
364 if (substituteData.isValid())
365 preCacheSubstituteDataForMainResource(request, substituteData);
366 return toRawResource(requestResource(Resource::MainResource, request));
367 }
368
369 ResourcePtr<RawResource> ResourceFetcher::fetchMedia(FetchRequest& request)
370 {
371 ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeNone );
372 ASSERT(request.resourceRequest().requestContext() == WebURLRequest::RequestC ontextAudio || request.resourceRequest().requestContext() == WebURLRequest::Requ estContextVideo);
373 return toRawResource(requestResource(Resource::Media, request));
374 }
375
376 ResourcePtr<RawResource> ResourceFetcher::fetchTextTrack(FetchRequest& request)
377 {
378 ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeNone );
379 request.mutableResourceRequest().setRequestContext(WebURLRequest::RequestCon textTrack);
380 return toRawResource(requestResource(Resource::TextTrack, request));
381 }
382
383 void ResourceFetcher::preCacheSubstituteDataForMainResource(const FetchRequest& request, const SubstituteData& substituteData)
384 {
385 const String cacheIdentifier = getCacheIdentifier();
386 const KURL& url = request.url();
387 if (Resource* oldResource = memoryCache()->resourceForURL(url, cacheIdentifi er))
388 memoryCache()->remove(oldResource);
389
390 ResourceResponse response(url, substituteData.mimeType(), substituteData.con tent()->size(), substituteData.textEncoding(), emptyString());
391 ResourcePtr<Resource> resource = createResource(Resource::MainResource, requ est.resourceRequest(), substituteData.textEncoding());
392 resource->setNeedsSynchronousCacheHit(substituteData.forceSynchronousLoad()) ;
393 resource->setOptions(request.options());
394 resource->setDataBufferingPolicy(BufferData);
395 resource->responseReceived(response, nullptr);
396 if (substituteData.content()->size())
397 resource->setResourceBuffer(substituteData.content());
398 resource->setCacheIdentifier(cacheIdentifier);
399 resource->finish();
400 memoryCache()->add(resource.get());
401 }
402
403 bool ResourceFetcher::canAccessResource(Resource* resource, SecurityOrigin* sour ceOrigin, const KURL& url, AccessControlLoggingDecision logErrorsDecision) const 185 bool ResourceFetcher::canAccessResource(Resource* resource, SecurityOrigin* sour ceOrigin, const KURL& url, AccessControlLoggingDecision logErrorsDecision) const
404 { 186 {
405 // Redirects can change the response URL different from one of request. 187 // Redirects can change the response URL different from one of request.
406 bool forPreload = resource->isUnusedPreload(); 188 bool forPreload = resource->isUnusedPreload();
407 if (!context().canRequest(resource->type(), resource->resourceRequest(), url , resource->options(), forPreload, FetchRequest::UseDefaultOriginRestrictionForT ype)) 189 if (!context().canRequest(resource->type(), resource->resourceRequest(), url , resource->options(), forPreload, FetchRequest::UseDefaultOriginRestrictionForT ype))
408 return false; 190 return false;
409 191
410 if (!sourceOrigin) 192 if (!sourceOrigin)
411 sourceOrigin = context().securityOrigin(); 193 sourceOrigin = context().securityOrigin();
412 194
413 if (sourceOrigin->canRequest(url)) 195 if (sourceOrigin->canRequest(url))
414 return true; 196 return true;
415 197
416 String errorDescription; 198 String errorDescription;
417 if (!resource->passesAccessControlCheck(sourceOrigin, errorDescription)) { 199 if (!resource->passesAccessControlCheck(sourceOrigin, errorDescription)) {
418 if (resource->type() == Resource::Font) 200 resource->setCORSFailed();
419 toFontResource(resource)->setCORSFailed();
420 if (!forPreload && (logErrorsDecision == ShouldLogAccessControlErrors)) { 201 if (!forPreload && (logErrorsDecision == ShouldLogAccessControlErrors)) {
421 String resourceType = Resource::resourceTypeToString(resource->type( ), resource->options().initiatorInfo); 202 String resourceType = Resource::resourceTypeToString(resource->type( ), resource->options().initiatorInfo);
422 context().addConsoleMessage(resourceType + " from origin '" + Securi tyOrigin::create(url)->toString() + "' has been blocked from loading by Cross-Or igin Resource Sharing policy: " + errorDescription); 203 context().addConsoleMessage(resourceType + " from origin '" + Securi tyOrigin::create(url)->toString() + "' has been blocked from loading by Cross-Or igin Resource Sharing policy: " + errorDescription);
423 } 204 }
424 return false; 205 return false;
425 } 206 }
426 return true; 207 return true;
427 } 208 }
428 209
429 bool ResourceFetcher::isControlledByServiceWorker() const 210 bool ResourceFetcher::isControlledByServiceWorker() const
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 if (!m_resourceTimingReportTimer.isActive()) 243 if (!m_resourceTimingReportTimer.isActive())
463 m_resourceTimingReportTimer.startOneShot(0, FROM_HERE); 244 m_resourceTimingReportTimer.startOneShot(0, FROM_HERE);
464 } 245 }
465 246
466 if (m_validatedURLs.size() >= kMaxValidatedURLsSize) { 247 if (m_validatedURLs.size() >= kMaxValidatedURLsSize) {
467 m_validatedURLs.clear(); 248 m_validatedURLs.clear();
468 } 249 }
469 m_validatedURLs.add(request.resourceRequest().url()); 250 m_validatedURLs.add(request.resourceRequest().url());
470 } 251 }
471 252
472 ResourcePtr<Resource> ResourceFetcher::requestResource(Resource::Type type, Fetc hRequest& request) 253 ResourcePtr<Resource> ResourceFetcher::requestResource(FetchRequest& request, co nst ResourceFactory& factory)
473 { 254 {
474 ASSERT(request.options().synchronousPolicy == RequestAsynchronously || type == Resource::Raw); 255 ASSERT(request.options().synchronousPolicy == RequestAsynchronously || facto ry.type() == Resource::Raw);
475 256
476 TRACE_EVENT0("blink", "ResourceFetcher::requestResource"); 257 TRACE_EVENT0("blink", "ResourceFetcher::requestResource");
477 258
478 context().upgradeInsecureRequest(request); 259 context().upgradeInsecureRequest(request);
479 context().addClientHintsIfNecessary(request); 260 context().addClientHintsIfNecessary(request);
480 context().addCSPHeaderIfNecessary(type, request); 261 context().addCSPHeaderIfNecessary(factory.type(), request);
481 262
482 KURL url = request.resourceRequest().url(); 263 KURL url = request.resourceRequest().url();
483 264
484 WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource '%s', charset '%s ', priority=%d, forPreload=%u, type=%s", url.elidedString().latin1().data(), req uest.charset().latin1().data(), request.priority(), request.forPreload(), Resour ceTypeName(type)); 265 WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource '%s', charset '%s ', priority=%d, forPreload=%u, type=%s", url.elidedString().latin1().data(), req uest.charset().latin1().data(), request.priority(), request.forPreload(), Resour ceTypeName(factory.type()));
485 266
486 // If only the fragment identifiers differ, it is the same resource. 267 // If only the fragment identifiers differ, it is the same resource.
487 url = MemoryCache::removeFragmentIdentifierIfNeeded(url); 268 url = MemoryCache::removeFragmentIdentifierIfNeeded(url);
488 269
489 if (!url.isValid()) 270 if (!url.isValid())
490 return nullptr; 271 return nullptr;
491 272
492 if (!context().canRequest(type, request.resourceRequest(), url, request.opti ons(), request.forPreload(), request.originRestriction())) 273 if (!context().canRequest(factory.type(), request.resourceRequest(), url, re quest.options(), request.forPreload(), request.originRestriction()))
493 return nullptr; 274 return nullptr;
494 275
495 context().dispatchWillRequestResource(&request); 276 context().dispatchWillRequestResource(&request);
496 277
497 if (!request.forPreload()) { 278 if (!request.forPreload()) {
498 V8DOMActivityLogger* activityLogger = nullptr; 279 V8DOMActivityLogger* activityLogger = nullptr;
499 if (request.options().initiatorInfo.name == FetchInitiatorTypeNames::xml httprequest) 280 if (request.options().initiatorInfo.name == FetchInitiatorTypeNames::xml httprequest)
500 activityLogger = V8DOMActivityLogger::currentActivityLogger(); 281 activityLogger = V8DOMActivityLogger::currentActivityLogger();
501 else 282 else
502 activityLogger = V8DOMActivityLogger::currentActivityLoggerIfIsolate dWorld(); 283 activityLogger = V8DOMActivityLogger::currentActivityLoggerIfIsolate dWorld();
503 284
504 if (activityLogger) { 285 if (activityLogger) {
505 Vector<String> argv; 286 Vector<String> argv;
506 argv.append(Resource::resourceTypeToString(type, request.options().i nitiatorInfo)); 287 argv.append(Resource::resourceTypeToString(factory.type(), request.o ptions().initiatorInfo));
507 argv.append(url); 288 argv.append(url);
508 activityLogger->logEvent("blinkRequestResource", argv.size(), argv.d ata()); 289 activityLogger->logEvent("blinkRequestResource", argv.size(), argv.d ata());
509 } 290 }
510 } 291 }
511 292
512 // See if we can use an existing resource from the cache. 293 // See if we can use an existing resource from the cache.
513 ResourcePtr<Resource> resource = memoryCache()->resourceForURL(url, getCache Identifier()); 294 ResourcePtr<Resource> resource = memoryCache()->resourceForURL(url, getCache Identifier());
514 295
515 const RevalidationPolicy policy = determineRevalidationPolicy(type, request, resource.get()); 296 const RevalidationPolicy policy = determineRevalidationPolicy(factory.type() , request, resource.get());
516 switch (policy) { 297 switch (policy) {
517 case Reload: 298 case Reload:
518 memoryCache()->remove(resource.get()); 299 memoryCache()->remove(resource.get());
519 // Fall through 300 // Fall through
520 case Load: 301 case Load:
521 resource = createResourceForLoading(type, request, request.charset()); 302 resource = createResourceForLoading(request, request.charset(), factory) ;
522 break; 303 break;
523 case Revalidate: 304 case Revalidate:
524 resource = createResourceForRevalidation(request, resource.get()); 305 resource = createResourceForRevalidation(request, resource.get(), factor y);
525 break; 306 break;
526 case Use: 307 case Use:
527 memoryCache()->updateForAccess(resource.get()); 308 memoryCache()->updateForAccess(resource.get());
528 break; 309 break;
529 } 310 }
530 311
531 if (!resource) 312 if (!resource)
532 return nullptr; 313 return nullptr;
314 if (resource->type() != factory.type()) {
315 ASSERT(request.forPreload());
316 return nullptr;
317 }
533 318
534 if (!resource->hasClients()) 319 if (!resource->hasClients())
535 m_deadStatsRecorder.update(policy); 320 m_deadStatsRecorder.update(policy);
536 321
537 if (policy != Use) 322 if (policy != Use)
538 resource->setIdentifier(createUniqueIdentifier()); 323 resource->setIdentifier(createUniqueIdentifier());
539 324
540 if (!request.forPreload() || policy != Use) { 325 if (!request.forPreload() || policy != Use) {
541 ResourceLoadPriority priority = loadPriority(type, request); 326 ResourceLoadPriority priority = loadPriority(factory.type(), request);
542 // When issuing another request for a resource that is already in-flight make 327 // When issuing another request for a resource that is already in-flight make
543 // sure to not demote the priority of the in-flight request. If the new request 328 // sure to not demote the priority of the in-flight request. If the new request
544 // isn't at the same priority as the in-flight request, only allow promo tions. 329 // isn't at the same priority as the in-flight request, only allow promo tions.
545 // This can happen when a visible image's priority is increased and then another 330 // This can happen when a visible image's priority is increased and then another
546 // reference to the image is parsed (which would be at a lower priority) . 331 // reference to the image is parsed (which would be at a lower priority) .
547 if (priority > resource->resourceRequest().priority()) { 332 if (priority > resource->resourceRequest().priority()) {
548 resource->mutableResourceRequest().setPriority(priority); 333 resource->mutableResourceRequest().setPriority(priority);
549 resource->didChangePriority(priority, 0); 334 resource->didChangePriority(priority, 0);
550 } 335 }
551 } 336 }
552 337
553 if (resourceNeedsLoad(resource.get(), request, policy)) { 338 if (resourceNeedsLoad(resource.get(), request, policy)) {
554 if (!context().shouldLoadNewResource(type)) { 339 if (!context().shouldLoadNewResource(factory.type())) {
555 if (memoryCache()->contains(resource.get())) 340 if (memoryCache()->contains(resource.get()))
556 memoryCache()->remove(resource.get()); 341 memoryCache()->remove(resource.get());
557 return nullptr; 342 return nullptr;
558 } 343 }
559 344
560 if (!scheduleArchiveLoad(resource.get(), request.resourceRequest())) 345 if (!scheduleArchiveLoad(resource.get(), request.resourceRequest()))
561 resource->load(this, request.options()); 346 resource->load(this, request.options());
562 347
563 // For asynchronous loads that immediately fail, it's sufficient to retu rn a 348 // For asynchronous loads that immediately fail, it's sufficient to retu rn a
564 // null Resource, as it indicates that something prevented the load from starting. 349 // null Resource, as it indicates that something prevented the load from starting.
565 // If there's a network error, that failure will happen asynchronously. However, if 350 // If there's a network error, that failure will happen asynchronously. However, if
566 // a sync load receives a network error, it will have already happened b y this point. 351 // a sync load receives a network error, it will have already happened b y this point.
567 // In that case, the requester should have access to the relevant Resour ceError, so 352 // In that case, the requester should have access to the relevant Resour ceError, so
568 // we need to return a non-null Resource. 353 // we need to return a non-null Resource.
569 if (resource->errorOccurred()) { 354 if (resource->errorOccurred()) {
570 if (memoryCache()->contains(resource.get())) 355 if (memoryCache()->contains(resource.get()))
571 memoryCache()->remove(resource.get()); 356 memoryCache()->remove(resource.get());
572 return request.options().synchronousPolicy == RequestSynchronously ? resource : nullptr; 357 return request.options().synchronousPolicy == RequestSynchronously ? resource : nullptr;
573 } 358 }
574 } 359 }
575 360
576 // FIXME: Temporarily leave main resource caching disabled for chromium, 361 // FIXME: Temporarily leave main resource caching disabled for chromium,
577 // see https://bugs.webkit.org/show_bug.cgi?id=107962. Before caching main 362 // see https://bugs.webkit.org/show_bug.cgi?id=107962. Before caching main
578 // resources, we should be sure to understand the implications for memory 363 // resources, we should be sure to understand the implications for memory
579 // use. 364 // use.
580 // Remove main resource from cache to prevent reuse. 365 // Remove main resource from cache to prevent reuse.
581 if (type == Resource::MainResource) { 366 if (factory.type() == Resource::MainResource) {
582 ASSERT(policy != Use || context().hasSubstituteData()); 367 ASSERT(policy != Use || context().hasSubstituteData());
583 ASSERT(policy != Revalidate); 368 ASSERT(policy != Revalidate);
584 memoryCache()->remove(resource.get()); 369 memoryCache()->remove(resource.get());
585 } 370 }
586 371
587 requestLoadStarted(resource.get(), request, policy == Use ? ResourceLoadingF romCache : ResourceLoadingFromNetwork); 372 requestLoadStarted(resource.get(), request, policy == Use ? ResourceLoadingF romCache : ResourceLoadingFromNetwork);
588 373
589 ASSERT(resource->url() == url.string()); 374 ASSERT(resource->url() == url.string());
590 m_documentResources.set(resource->url(), resource); 375 m_documentResources.set(resource->url(), resource);
591 return resource; 376 return resource;
(...skipping 19 matching lines...) Expand all
611 if (request.cachePolicy() == UseProtocolCachePolicy) 396 if (request.cachePolicy() == UseProtocolCachePolicy)
612 request.setCachePolicy(context().resourceRequestCachePolicy(request, typ e)); 397 request.setCachePolicy(context().resourceRequestCachePolicy(request, typ e));
613 if (request.requestContext() == WebURLRequest::RequestContextUnspecified) 398 if (request.requestContext() == WebURLRequest::RequestContextUnspecified)
614 determineRequestContext(request, type); 399 determineRequestContext(request, type);
615 if (type == Resource::LinkPrefetch || type == Resource::LinkSubresource) 400 if (type == Resource::LinkPrefetch || type == Resource::LinkSubresource)
616 request.setHTTPHeaderField("Purpose", "prefetch"); 401 request.setHTTPHeaderField("Purpose", "prefetch");
617 402
618 context().addAdditionalRequestHeaders(request, (type == Resource::MainResour ce) ? FetchMainResource : FetchSubresource); 403 context().addAdditionalRequestHeaders(request, (type == Resource::MainResour ce) ? FetchMainResource : FetchSubresource);
619 } 404 }
620 405
621 ResourcePtr<Resource> ResourceFetcher::createResourceForRevalidation(const Fetch Request& request, Resource* resource) 406 ResourcePtr<Resource> ResourceFetcher::createResourceForRevalidation(const Fetch Request& request, Resource* resource, const ResourceFactory& factory)
622 { 407 {
623 ASSERT(resource); 408 ASSERT(resource);
624 ASSERT(memoryCache()->contains(resource)); 409 ASSERT(memoryCache()->contains(resource));
625 ASSERT(resource->isLoaded()); 410 ASSERT(resource->isLoaded());
626 ASSERT(resource->canUseCacheValidator()); 411 ASSERT(resource->canUseCacheValidator());
627 ASSERT(!resource->resourceToRevalidate()); 412 ASSERT(!resource->resourceToRevalidate());
628 ASSERT(!context().isControlledByServiceWorker()); 413 ASSERT(!context().isControlledByServiceWorker());
629 414
630 ResourceRequest revalidatingRequest(resource->resourceRequest()); 415 ResourceRequest revalidatingRequest(resource->resourceRequest());
631 revalidatingRequest.clearHTTPReferrer(); 416 revalidatingRequest.clearHTTPReferrer();
632 addAdditionalRequestHeaders(revalidatingRequest, resource->type()); 417 addAdditionalRequestHeaders(revalidatingRequest, resource->type());
633 418
634 const AtomicString& lastModified = resource->response().httpHeaderField("Las t-Modified"); 419 const AtomicString& lastModified = resource->response().httpHeaderField("Las t-Modified");
635 const AtomicString& eTag = resource->response().httpHeaderField("ETag"); 420 const AtomicString& eTag = resource->response().httpHeaderField("ETag");
636 if (!lastModified.isEmpty() || !eTag.isEmpty()) { 421 if (!lastModified.isEmpty() || !eTag.isEmpty()) {
637 ASSERT(context().cachePolicy() != CachePolicyReload); 422 ASSERT(context().cachePolicy() != CachePolicyReload);
638 if (context().cachePolicy() == CachePolicyRevalidate) 423 if (context().cachePolicy() == CachePolicyRevalidate)
639 revalidatingRequest.setHTTPHeaderField("Cache-Control", "max-age=0") ; 424 revalidatingRequest.setHTTPHeaderField("Cache-Control", "max-age=0") ;
640 } 425 }
641 if (!lastModified.isEmpty()) 426 if (!lastModified.isEmpty())
642 revalidatingRequest.setHTTPHeaderField("If-Modified-Since", lastModified ); 427 revalidatingRequest.setHTTPHeaderField("If-Modified-Since", lastModified );
643 if (!eTag.isEmpty()) 428 if (!eTag.isEmpty())
644 revalidatingRequest.setHTTPHeaderField("If-None-Match", eTag); 429 revalidatingRequest.setHTTPHeaderField("If-None-Match", eTag);
645 430
646 double stalenessLifetime = resource->stalenessLifetime(); 431 double stalenessLifetime = resource->stalenessLifetime();
647 if (std::isfinite(stalenessLifetime) && stalenessLifetime > 0) { 432 if (std::isfinite(stalenessLifetime) && stalenessLifetime > 0) {
648 revalidatingRequest.setHTTPHeaderField("Resource-Freshness", AtomicStrin g(String::format("max-age=%.0lf,stale-while-revalidate=%.0lf,age=%.0lf", resourc e->freshnessLifetime(), stalenessLifetime, resource->currentAge()))); 433 revalidatingRequest.setHTTPHeaderField("Resource-Freshness", AtomicStrin g(String::format("max-age=%.0lf,stale-while-revalidate=%.0lf,age=%.0lf", resourc e->freshnessLifetime(), stalenessLifetime, resource->currentAge())));
649 } 434 }
650 435
651 ResourcePtr<Resource> newResource = createResource(resource->type(), revalid atingRequest, resource->encoding()); 436 ResourcePtr<Resource> newResource = factory.create(revalidatingRequest, reso urce->encoding());
652 WTF_LOG(ResourceLoading, "Resource %p created to revalidate %p", newResource .get(), resource); 437 WTF_LOG(ResourceLoading, "Resource %p created to revalidate %p", newResource .get(), resource);
653 438
654 newResource->setResourceToRevalidate(resource); 439 newResource->setResourceToRevalidate(resource);
655 newResource->setCacheIdentifier(resource->cacheIdentifier()); 440 newResource->setCacheIdentifier(resource->cacheIdentifier());
656 441
657 memoryCache()->remove(resource); 442 memoryCache()->remove(resource);
658 memoryCache()->add(newResource.get()); 443 memoryCache()->add(newResource.get());
659 return newResource; 444 return newResource;
660 } 445 }
661 446
662 ResourcePtr<Resource> ResourceFetcher::createResourceForLoading(Resource::Type t ype, FetchRequest& request, const String& charset) 447 ResourcePtr<Resource> ResourceFetcher::createResourceForLoading(FetchRequest& re quest, const String& charset, const ResourceFactory& factory)
663 { 448 {
664 const String cacheIdentifier = getCacheIdentifier(); 449 const String cacheIdentifier = getCacheIdentifier();
665 ASSERT(!memoryCache()->resourceForURL(request.resourceRequest().url(), cache Identifier)); 450 ASSERT(!memoryCache()->resourceForURL(request.resourceRequest().url(), cache Identifier));
666 451
667 WTF_LOG(ResourceLoading, "Loading Resource for '%s'.", request.resourceReque st().url().elidedString().latin1().data()); 452 WTF_LOG(ResourceLoading, "Loading Resource for '%s'.", request.resourceReque st().url().elidedString().latin1().data());
668 453
669 addAdditionalRequestHeaders(request.mutableResourceRequest(), type); 454 addAdditionalRequestHeaders(request.mutableResourceRequest(), factory.type() );
670 ResourcePtr<Resource> resource = createResource(type, request.resourceReques t(), charset); 455 ResourcePtr<Resource> resource = factory.create(request.resourceRequest(), c harset);
671 resource->setCacheIdentifier(cacheIdentifier); 456 resource->setCacheIdentifier(cacheIdentifier);
672 457
673 memoryCache()->add(resource.get()); 458 memoryCache()->add(resource.get());
674 return resource; 459 return resource;
675 } 460 }
676 461
677 void ResourceFetcher::storeResourceTimingInitiatorInformation(Resource* resource ) 462 void ResourceFetcher::storeResourceTimingInitiatorInformation(Resource* resource )
678 { 463 {
679 if (resource->options().requestInitiatorContext != DocumentContext) 464 if (resource->options().requestInitiatorContext != DocumentContext)
680 return; 465 return;
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 // FIXME: If willSendRequest changes the request, we don't respect it. 713 // FIXME: If willSendRequest changes the request, we don't respect it.
929 willSendRequest(identifier, request, ResourceResponse(), resource->options() .initiatorInfo); 714 willSendRequest(identifier, request, ResourceResponse(), resource->options() .initiatorInfo);
930 context().sendRemainingDelegateMessages(identifier, resource->response(), re source->encodedSize()); 715 context().sendRemainingDelegateMessages(identifier, resource->response(), re source->encodedSize());
931 } 716 }
932 717
933 int ResourceFetcher::requestCount() const 718 int ResourceFetcher::requestCount() const
934 { 719 {
935 return m_loaders ? m_loaders->size() : 0; 720 return m_loaders ? m_loaders->size() : 0;
936 } 721 }
937 722
938 void ResourceFetcher::preload(Resource::Type type, FetchRequest& request, const String& charset) 723 void ResourceFetcher::preloadStarted(Resource* resource)
939 { 724 {
940 // Ensure main resources aren't preloaded, since the cache can't actually re use the preload. 725 if (m_preloads && m_preloads->contains(resource))
941 if (type == Resource::MainResource)
942 return; 726 return;
943 727 TRACE_EVENT_ASYNC_STEP_INTO0("blink.net", "Resource", resource, "Preload");
944 ASSERT(type == Resource::Script || type == Resource::CSSStyleSheet || type = = Resource::Image);
945
946 String encoding;
947 if (type == Resource::Script || type == Resource::CSSStyleSheet) {
948 encoding = charset.isEmpty() ? context().charset() : charset;
949
950 // RequestContext for Resource::Image is set in fetchImage below.
951 determineRequestContext(request.mutableResourceRequest(), type);
952 }
953
954 request.setCharset(encoding);
955 request.setForPreload(true);
956
957 ResourcePtr<Resource> resource;
958 // Loading images involves several special cases, so use dedicated fetch met hod instead.
959 if (type == Resource::Image)
960 resource = fetchImage(request);
961 else
962 resource = requestResource(type, request);
963 if (!resource || (m_preloads && m_preloads->contains(resource.get())))
964 return;
965 TRACE_EVENT_ASYNC_STEP_INTO0("blink.net", "Resource", resource.get(), "Prelo ad");
966 resource->increasePreloadCount(); 728 resource->increasePreloadCount();
967 729
968 if (!m_preloads) 730 if (!m_preloads)
969 m_preloads = adoptPtr(new ListHashSet<Resource*>); 731 m_preloads = adoptPtr(new ListHashSet<Resource*>);
970 m_preloads->add(resource.get()); 732 m_preloads->add(resource);
971 733
972 #if PRELOAD_DEBUG 734 #if PRELOAD_DEBUG
973 printf("PRELOADING %s\n", resource->url().string().latin1().data()); 735 printf("PRELOADING %s\n", resource->url().string().latin1().data());
974 #endif 736 #endif
975 } 737 }
976 738
977 bool ResourceFetcher::isPreloaded(const KURL& url) const 739 bool ResourceFetcher::isPreloaded(const KURL& url) const
978 { 740 {
979 if (m_preloads) { 741 if (m_preloads) {
980 for (Resource* resource : *m_preloads) { 742 for (Resource* resource : *m_preloads) {
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 if (!context().canRequest(resource->type(), request, request.url(), options, resource->isUnusedPreload(), FetchRequest::UseDefaultOriginRestrictionForType)) 937 if (!context().canRequest(resource->type(), request, request.url(), options, resource->isUnusedPreload(), FetchRequest::UseDefaultOriginRestrictionForType))
1176 return false; 938 return false;
1177 if (options.corsEnabled == IsCORSEnabled) { 939 if (options.corsEnabled == IsCORSEnabled) {
1178 SecurityOrigin* sourceOrigin = options.securityOrigin.get(); 940 SecurityOrigin* sourceOrigin = options.securityOrigin.get();
1179 if (!sourceOrigin) 941 if (!sourceOrigin)
1180 sourceOrigin = context().securityOrigin(); 942 sourceOrigin = context().securityOrigin();
1181 943
1182 String errorMessage; 944 String errorMessage;
1183 StoredCredentials withCredentials = resource->lastResourceRequest().allo wStoredCredentials() ? AllowStoredCredentials : DoNotAllowStoredCredentials; 945 StoredCredentials withCredentials = resource->lastResourceRequest().allo wStoredCredentials() ? AllowStoredCredentials : DoNotAllowStoredCredentials;
1184 if (!CrossOriginAccessControl::handleRedirect(sourceOrigin, request, red irectResponse, withCredentials, options, errorMessage)) { 946 if (!CrossOriginAccessControl::handleRedirect(sourceOrigin, request, red irectResponse, withCredentials, options, errorMessage)) {
1185 if (resource->type() == Resource::Font) 947 resource->setCORSFailed();
1186 toFontResource(resource)->setCORSFailed();
1187 context().addConsoleMessage(errorMessage); 948 context().addConsoleMessage(errorMessage);
1188 return false; 949 return false;
1189 } 950 }
1190 } 951 }
1191 if (resource->type() == Resource::Image && shouldDeferImageLoad(request.url( ))) 952 if (resource->type() == Resource::Image && shouldDeferImageLoad(request.url( )))
1192 return false; 953 return false;
1193 return true; 954 return true;
1194 } 955 }
1195 956
1196 #if PRELOAD_DEBUG 957 #if PRELOAD_DEBUG
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1291 1052
1292 DEFINE_TRACE(ResourceFetcher) 1053 DEFINE_TRACE(ResourceFetcher)
1293 { 1054 {
1294 visitor->trace(m_context); 1055 visitor->trace(m_context);
1295 visitor->trace(m_archiveResourceCollection); 1056 visitor->trace(m_archiveResourceCollection);
1296 visitor->trace(m_loaders); 1057 visitor->trace(m_loaders);
1297 visitor->trace(m_nonBlockingLoaders); 1058 visitor->trace(m_nonBlockingLoaders);
1298 } 1059 }
1299 1060
1300 } 1061 }
OLDNEW
« no previous file with comments | « Source/core/fetch/ResourceFetcher.h ('k') | Source/core/fetch/ResourceFetcherTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698