Chromium Code Reviews| Index: Source/core/fetch/ResourceFetcher.cpp |
| diff --git a/Source/core/fetch/ResourceFetcher.cpp b/Source/core/fetch/ResourceFetcher.cpp |
| index f8d5da40113916a23bb9c063d83e0b2c81d4258a..ffd705b6735079af5f65eb7c3a68e5630dfcdce5 100644 |
| --- a/Source/core/fetch/ResourceFetcher.cpp |
| +++ b/Source/core/fetch/ResourceFetcher.cpp |
| @@ -226,12 +226,12 @@ bool ResourceFetcher::resourceNeedsLoad(Resource* resource, const FetchRequest& |
| // http://crbug.com/52411 |
| static const int kMaxValidatedURLsSize = 10000; |
| -void ResourceFetcher::requestLoadStarted(Resource* resource, const FetchRequest& request, ResourceLoadStartType type) |
| +void ResourceFetcher::requestLoadStarted(Resource* resource, const FetchRequest& request, ResourceLoadStartType type, bool isStaticData) |
| { |
| if (type == ResourceLoadingFromCache) |
| notifyLoadedFromMemoryCache(resource); |
| - if (request.resourceRequest().url().protocolIsData() || context().hasSubstituteData()) |
| + if (isStaticData) |
| return; |
| if (type == ResourceLoadingFromCache && !resource->stillNeedsLoad() && !m_validatedURLs.contains(request.resourceRequest().url())) { |
| @@ -256,7 +256,52 @@ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> urlForTraceEvent(const K |
| return value.release(); |
| } |
| -ResourcePtr<Resource> ResourceFetcher::requestResource(FetchRequest& request, const ResourceFactory& factory) |
| +void ResourceFetcher::preCacheData(const FetchRequest& request, const ResourceFactory& factory, const SubstituteData& substituteData) |
| +{ |
| + const KURL& url = request.resourceRequest().url(); |
| + ASSERT(url.protocolIsData() || substituteData.isValid()); |
| + if ((factory.type() == Resource::MainResource && !substituteData.isValid()) || factory.type() == Resource::Raw || factory.type() == Resource::Media) |
| + return; |
| + |
| + const String cacheIdentifier = getCacheIdentifier(); |
| + if (Resource* oldResource = memoryCache()->resourceForURL(url, cacheIdentifier)) { |
| + if (!substituteData.isValid()) |
| + return; |
| + memoryCache()->remove(oldResource); |
| + } |
| + |
| + WebString mimetype; |
| + WebString charset; |
| + RefPtr<SharedBuffer> data; |
| + if (substituteData.isValid()) { |
| + mimetype = substituteData.mimeType(); |
| + charset = substituteData.textEncoding(); |
| + data = substituteData.content(); |
| + } else { |
| + data = PassRefPtr<SharedBuffer>(Platform::current()->parseDataURL(url, mimetype, charset)); |
| + if (!data) |
| + return; |
| + } |
| + ResourceResponse response(url, mimetype, data->size(), charset, String()); |
| + response.setHTTPStatusCode(200); |
| + response.setHTTPStatusText("OK"); |
| + |
| + ResourcePtr<Resource> resource = factory.create(request.resourceRequest(), request.charset()); |
| + resource->setNeedsSynchronousCacheHit(substituteData.forceSynchronousLoad()); |
| + resource->setOptions(request.options()); |
| + // FIXME: We should provide a body stream here. |
| + resource->responseReceived(response, nullptr); |
| + resource->setDataBufferingPolicy(BufferData); |
| + if (data->size()) |
| + resource->setResourceBuffer(data); |
| + resource->setIdentifier(createUniqueIdentifier()); |
| + resource->setCacheIdentifier(cacheIdentifier); |
| + resource->finish(); |
| + memoryCache()->add(resource.get()); |
| + scheduleDocumentResourcesGC(); |
| +} |
| + |
| +ResourcePtr<Resource> ResourceFetcher::requestResource(FetchRequest& request, const ResourceFactory& factory, const SubstituteData& substituteData) |
| { |
| ASSERT(request.options().synchronousPolicy == RequestAsynchronously || factory.type() == Resource::Raw); |
| @@ -264,6 +309,10 @@ ResourcePtr<Resource> ResourceFetcher::requestResource(FetchRequest& request, co |
| context().addClientHintsIfNecessary(request); |
| context().addCSPHeaderIfNecessary(factory.type(), request); |
| + bool isStaticData = request.resourceRequest().url().protocolIsData() || substituteData.isValid(); |
| + if (isStaticData) |
| + preCacheData(request, factory, substituteData); |
| + |
| KURL url = request.resourceRequest().url(); |
| TRACE_EVENT1("blink", "ResourceFetcher::requestResource", "url", urlForTraceEvent(url)); |
| @@ -298,7 +347,7 @@ ResourcePtr<Resource> ResourceFetcher::requestResource(FetchRequest& request, co |
| // See if we can use an existing resource from the cache. |
| ResourcePtr<Resource> resource = memoryCache()->resourceForURL(url, getCacheIdentifier()); |
| - const RevalidationPolicy policy = determineRevalidationPolicy(factory.type(), request, resource.get()); |
| + const RevalidationPolicy policy = determineRevalidationPolicy(factory.type(), request, resource.get(), isStaticData); |
| switch (policy) { |
| case Reload: |
| memoryCache()->remove(resource.get()); |
| @@ -369,7 +418,7 @@ ResourcePtr<Resource> ResourceFetcher::requestResource(FetchRequest& request, co |
| // use. |
| // Remove main resource from cache to prevent reuse. |
| if (factory.type() == Resource::MainResource) { |
| - ASSERT(policy != Use || context().hasSubstituteData()); |
| + ASSERT(policy != Use || substituteData.isValid()); |
| ASSERT(policy != Revalidate); |
| memoryCache()->remove(resource.get()); |
| } |
| @@ -481,7 +530,7 @@ void ResourceFetcher::storeResourceTimingInitiatorInformation(Resource* resource |
| m_resourceTimingInfoMap.add(resource, info.release()); |
| } |
| -ResourceFetcher::RevalidationPolicy ResourceFetcher::determineRevalidationPolicy(Resource::Type type, const FetchRequest& fetchRequest, Resource* existingResource) const |
| +ResourceFetcher::RevalidationPolicy ResourceFetcher::determineRevalidationPolicy(Resource::Type type, const FetchRequest& fetchRequest, Resource* existingResource, bool isStaticData) const |
| { |
| const ResourceRequest& request = fetchRequest.resourceRequest(); |
| @@ -507,15 +556,6 @@ ResourceFetcher::RevalidationPolicy ResourceFetcher::determineRevalidationPolicy |
| if (FetchRequest::DeferredByClient == fetchRequest.defer()) |
| return Reload; |
| - // Always use data uris. |
| - // FIXME: Extend this to non-images. |
| - if (type == Resource::Image && request.url().protocolIsData()) |
| - return Use; |
| - |
| - // If a main resource was populated from a SubstituteData load, use it. |
| - if (type == Resource::MainResource && context().hasSubstituteData()) |
| - return Use; |
| - |
| if (!existingResource->canReuse(request)) |
| return Reload; |
| @@ -524,6 +564,10 @@ ResourceFetcher::RevalidationPolicy ResourceFetcher::determineRevalidationPolicy |
| if (request.downloadToFile() || request.useStreamOnResponse()) |
| return Reload; |
| + // If resource was populated from a SubstituteData load or data: url, use it. |
| + if (isStaticData) |
|
Nate Chapin
2015/08/14 20:48:46
This needs to come after downloadToFile(), since d
|
| + return Use; |
| + |
| // Certain requests (e.g., XHRs) might have manually set headers that require revalidation. |
| // FIXME: In theory, this should be a Revalidate case. In practice, the MemoryCache revalidation path assumes a whole bunch |
| // of things about how revalidation works that manual headers violate, so punt to Reload instead. |