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

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

Issue 2533683002: Move the code in ResourceFetcher handling calls from WebURLLoaderImpl to ResourceLoader (Closed)
Patch Set: Fixed a bug in resource timing population Created 4 years 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
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 5 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All
6 rights reserved. 6 rights reserved.
7 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ 7 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
8 8
9 This library is free software; you can redistribute it and/or 9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public 10 modify it under the terms of the GNU Library General Public
(...skipping 10 matching lines...) Expand all
21 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA. 22 Boston, MA 02110-1301, USA.
23 23
24 This class provides all functionality needed for loading images, style 24 This class provides all functionality needed for loading images, style
25 sheets and html pages from the web. It has a memory cache for these objects. 25 sheets and html pages from the web. It has a memory cache for these objects.
26 */ 26 */
27 27
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/CrossOriginAccessControl.h"
32 #include "core/fetch/FetchContext.h" 31 #include "core/fetch/FetchContext.h"
33 #include "core/fetch/FetchInitiatorTypeNames.h" 32 #include "core/fetch/FetchInitiatorTypeNames.h"
34 #include "core/fetch/ImageResource.h" 33 #include "core/fetch/ImageResource.h"
35 #include "core/fetch/MemoryCache.h" 34 #include "core/fetch/MemoryCache.h"
36 #include "core/fetch/ResourceLoader.h" 35 #include "core/fetch/ResourceLoader.h"
37 #include "core/fetch/ResourceLoadingLog.h" 36 #include "core/fetch/ResourceLoadingLog.h"
38 #include "core/fetch/UniqueIdentifier.h" 37 #include "core/fetch/UniqueIdentifier.h"
39 #include "platform/Histogram.h" 38 #include "platform/Histogram.h"
40 #include "platform/RuntimeEnabledFeatures.h" 39 #include "platform/RuntimeEnabledFeatures.h"
41 #include "platform/mhtml/ArchiveResource.h" 40 #include "platform/mhtml/ArchiveResource.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, MainResource) \ 89 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, MainResource) \
91 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, Manifest) \ 90 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, Manifest) \
92 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, Media) \ 91 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, Media) \
93 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, Raw) \ 92 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, Raw) \
94 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, Script) \ 93 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, Script) \
95 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, SVGDocument) \ 94 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, SVGDocument) \
96 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, TextTrack) \ 95 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, TextTrack) \
97 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, XSLStyleSheet) \ 96 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, XSLStyleSheet) \
98 } 97 }
99 98
100 bool IsCrossOrigin(const KURL& a, const KURL& b) {
101 RefPtr<SecurityOrigin> originA = SecurityOrigin::create(a);
102 RefPtr<SecurityOrigin> originB = SecurityOrigin::create(b);
103 return !originB->isSameSchemeHostPort(originA.get());
104 }
105
106 } // namespace 99 } // namespace
107 100
108 static void RecordSriResourceIntegrityMismatchEvent( 101 static void RecordSriResourceIntegrityMismatchEvent(
109 SriResourceIntegrityMismatchEvent event) { 102 SriResourceIntegrityMismatchEvent event) {
110 DEFINE_THREAD_SAFE_STATIC_LOCAL( 103 DEFINE_THREAD_SAFE_STATIC_LOCAL(
111 EnumerationHistogram, integrityHistogram, 104 EnumerationHistogram, integrityHistogram,
112 new EnumerationHistogram("sri.resource_integrity_mismatch_event", 105 new EnumerationHistogram("sri.resource_integrity_mismatch_event",
113 SriResourceIntegrityMismatchEventCount)); 106 SriResourceIntegrityMismatchEventCount));
114 integrityHistogram.count(event); 107 integrityHistogram.count(event);
115 } 108 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 184
192 static void populateResourceTiming(ResourceTimingInfo* info, 185 static void populateResourceTiming(ResourceTimingInfo* info,
193 Resource* resource) { 186 Resource* resource) {
194 KURL initialURL = resource->response().redirectResponses().isEmpty() 187 KURL initialURL = resource->response().redirectResponses().isEmpty()
195 ? resource->resourceRequest().url() 188 ? resource->resourceRequest().url()
196 : resource->response().redirectResponses()[0].url(); 189 : resource->response().redirectResponses()[0].url();
197 info->setInitialURL(initialURL); 190 info->setInitialURL(initialURL);
198 info->setFinalResponse(resource->response()); 191 info->setFinalResponse(resource->response());
199 } 192 }
200 193
194 static void populateRedirectResourceTimingOnFinish(ResourceTimingInfo* info,
yhirano 2016/12/12 06:32:04 [optional] I prefer placing this function to the u
tyoshino (SeeGerritForStatus) 2016/12/12 11:10:55 Done.
195 Resource* resource) {
196 // Store redirect responses that were packed inside the final response.
197 const Vector<ResourceResponse>& redirectResponses =
198 resource->response().redirectResponses();
199 for (size_t i = 0; i < redirectResponses.size(); ++i) {
200 const KURL& newURL = i + 1 < redirectResponses.size()
201 ? KURL(redirectResponses[i + 1].url())
202 : resource->resourceRequest().url();
203 bool crossOrigin =
204 !SecurityOrigin::areSameOrigin(redirectResponses[i].url(), newURL);
205 info->addRedirect(redirectResponses[i], crossOrigin);
206 }
207 }
208
201 static WebURLRequest::RequestContext requestContextFromType( 209 static WebURLRequest::RequestContext requestContextFromType(
202 bool isMainFrame, 210 bool isMainFrame,
203 Resource::Type type) { 211 Resource::Type type) {
204 switch (type) { 212 switch (type) {
205 case Resource::MainResource: 213 case Resource::MainResource:
206 if (!isMainFrame) 214 if (!isMainFrame)
207 return WebURLRequest::RequestContextIframe; 215 return WebURLRequest::RequestContextIframe;
208 // FIXME: Change this to a context frame type (once we introduce them): 216 // FIXME: Change this to a context frame type (once we introduce them):
209 // http://fetch.spec.whatwg.org/#concept-request-context-frame-type 217 // http://fetch.spec.whatwg.org/#concept-request-context-frame-type
210 return WebURLRequest::RequestContextHyperlink; 218 return WebURLRequest::RequestContextHyperlink;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 } 259 }
252 260
253 ResourceFetcher::~ResourceFetcher() {} 261 ResourceFetcher::~ResourceFetcher() {}
254 262
255 Resource* ResourceFetcher::cachedResource(const KURL& resourceURL) const { 263 Resource* ResourceFetcher::cachedResource(const KURL& resourceURL) const {
256 KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(resourceURL); 264 KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(resourceURL);
257 const WeakMember<Resource>& resource = m_documentResources.get(url); 265 const WeakMember<Resource>& resource = m_documentResources.get(url);
258 return resource.get(); 266 return resource.get();
259 } 267 }
260 268
261 bool ResourceFetcher::canAccessResponse(
262 Resource* resource,
263 const ResourceResponse& response) const {
264 // Redirects can change the response URL different from one of request.
265 bool forPreload = resource->isUnusedPreload();
266 if (!context().canRequest(resource->getType(), resource->resourceRequest(),
267 response.url(), resource->options(), forPreload,
268 FetchRequest::UseDefaultOriginRestrictionForType))
269 return false;
270
271 SecurityOrigin* sourceOrigin = resource->options().securityOrigin.get();
272 if (!sourceOrigin)
273 sourceOrigin = context().getSecurityOrigin();
274
275 if (sourceOrigin->canRequestNoSuborigin(response.url()))
276 return true;
277
278 // Use the original response instead of the 304 response for a successful
279 // revaldiation.
280 const ResourceResponse& responseForAccessControl =
281 (resource->isCacheValidator() && response.httpStatusCode() == 304)
282 ? resource->response()
283 : response;
284 String errorDescription;
285 if (!passesAccessControlCheck(
286 responseForAccessControl, resource->options().allowCredentials,
287 sourceOrigin, errorDescription,
288 resource->lastResourceRequest().requestContext())) {
289 resource->setCORSFailed();
290 if (!forPreload) {
291 String resourceType = Resource::resourceTypeToString(
292 resource->getType(), resource->options().initiatorInfo);
293 context().addConsoleMessage(
294 "Access to " + resourceType + " at '" + response.url().getString() +
295 "' from origin '" + sourceOrigin->toString() +
296 "' has been blocked by CORS policy: " + errorDescription);
297 }
298 return false;
299 }
300 return true;
301 }
302
303 bool ResourceFetcher::isControlledByServiceWorker() const { 269 bool ResourceFetcher::isControlledByServiceWorker() const {
304 return context().isControlledByServiceWorker(); 270 return context().isControlledByServiceWorker();
305 } 271 }
306 272
307 bool ResourceFetcher::resourceNeedsLoad(Resource* resource, 273 bool ResourceFetcher::resourceNeedsLoad(Resource* resource,
308 const FetchRequest& request, 274 const FetchRequest& request,
309 RevalidationPolicy policy) { 275 RevalidationPolicy policy) {
310 // Defer a font load until it is actually needed unless this is a preload. 276 // Defer a font load until it is actually needed unless this is a preload.
311 if (resource->getType() == Resource::Font && !request.forPreload()) 277 if (resource->getType() == Resource::Font && !request.forPreload())
312 return false; 278 return false;
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 resource->response().httpHeaderField(HTTPNames::Timing_Allow_Origin); 740 resource->response().httpHeaderField(HTTPNames::Timing_Allow_Origin);
775 if (!timingAllowOrigin.isEmpty()) 741 if (!timingAllowOrigin.isEmpty())
776 info->setOriginalTimingAllowOrigin(timingAllowOrigin); 742 info->setOriginalTimingAllowOrigin(timingAllowOrigin);
777 } 743 }
778 744
779 if (!isMainResource || 745 if (!isMainResource ||
780 context().updateTimingInfoForIFrameNavigation(info.get())) 746 context().updateTimingInfoForIFrameNavigation(info.get()))
781 m_resourceTimingInfoMap.add(resource, std::move(info)); 747 m_resourceTimingInfoMap.add(resource, std::move(info));
782 } 748 }
783 749
750 void ResourceFetcher::recordResourceTimingOnRedirect(
751 Resource* resource,
752 const ResourceResponse& redirectResponse,
753 bool crossOrigin) {
754 ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource);
755 if (it != m_resourceTimingInfoMap.end()) {
756 it->value->addRedirect(redirectResponse, crossOrigin);
757 }
758 }
759
784 ResourceFetcher::RevalidationPolicy 760 ResourceFetcher::RevalidationPolicy
785 ResourceFetcher::determineRevalidationPolicy(Resource::Type type, 761 ResourceFetcher::determineRevalidationPolicy(Resource::Type type,
786 const FetchRequest& fetchRequest, 762 const FetchRequest& fetchRequest,
787 Resource* existingResource, 763 Resource* existingResource,
788 bool isStaticData) const { 764 bool isStaticData) const {
789 const ResourceRequest& request = fetchRequest.resourceRequest(); 765 const ResourceRequest& request = fetchRequest.resourceRequest();
790 766
791 if (!existingResource) 767 if (!existingResource)
792 return Load; 768 return Load;
793 769
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 } 1089 }
1114 1090
1115 ArchiveResource* ResourceFetcher::createArchive(Resource* resource) { 1091 ArchiveResource* ResourceFetcher::createArchive(Resource* resource) {
1116 // Only the top-frame can load MHTML. 1092 // Only the top-frame can load MHTML.
1117 if (!context().isMainFrame()) 1093 if (!context().isMainFrame())
1118 return nullptr; 1094 return nullptr;
1119 m_archive = MHTMLArchive::create(resource->url(), resource->resourceBuffer()); 1095 m_archive = MHTMLArchive::create(resource->url(), resource->resourceBuffer());
1120 return m_archive ? m_archive->mainResource() : nullptr; 1096 return m_archive ? m_archive->mainResource() : nullptr;
1121 } 1097 }
1122 1098
1123 void ResourceFetcher::didFinishLoading(Resource* resource, 1099 void ResourceFetcher::handleLoadCompletion(Resource* resource) {
1124 double finishTime, 1100 context().didLoadResource(resource);
1125 DidFinishLoadingReason finishReason) { 1101
1126 network_instrumentation::endResourceLoad( 1102 if (resource->isImage() &&
1127 resource->identifier(), network_instrumentation::RequestOutcome::Success); 1103 toImageResource(resource)->shouldReloadBrokenPlaceholder()) {
1104 toImageResource(resource)->reloadIfLoFiOrPlaceholder(this);
1105 }
1106 }
1107
1108 void ResourceFetcher::handleLoaderFinish(Resource* resource,
1109 double finishTime,
1110 LoaderFinishType type) {
1128 DCHECK(resource); 1111 DCHECK(resource);
1112
1113 ResourceLoader* loader = resource->loader();
1114 if (type == DidFinishFirstPartInMultipart) {
1115 // When loading a multipart resource, make the loader non-block when
1116 // finishing loading the first part.
1117 moveResourceLoaderToNonBlocking(loader);
1118 } else {
1119 removeResourceLoader(loader);
1120 DCHECK(!m_nonBlockingLoaders.contains(loader));
1121 }
1122 DCHECK(!m_loaders.contains(loader));
1123
1129 const int64_t encodedDataLength = resource->response().encodedDataLength(); 1124 const int64_t encodedDataLength = resource->response().encodedDataLength();
1130 1125
1131 // When loading a multipart resource, make the loader non-block when finishing
1132 // loading the first part.
1133 if (finishReason == DidFinishFirstPartInMultipart)
1134 moveResourceLoaderToNonBlocking(resource->loader());
1135 else
1136 removeResourceLoader(resource->loader());
1137 DCHECK(!m_loaders.contains(resource->loader()));
1138 DCHECK(finishReason == DidFinishFirstPartInMultipart ||
1139 !m_nonBlockingLoaders.contains(resource->loader()));
1140
1141 if (std::unique_ptr<ResourceTimingInfo> info = 1126 if (std::unique_ptr<ResourceTimingInfo> info =
1142 m_resourceTimingInfoMap.take(resource)) { 1127 m_resourceTimingInfoMap.take(resource)) {
1143 // Store redirect responses that were packed inside the final response. 1128 populateRedirectResourceTimingOnFinish(info.get(), resource);
1144 const Vector<ResourceResponse>& responses =
1145 resource->response().redirectResponses();
1146 for (size_t i = 0; i < responses.size(); ++i) {
1147 const KURL& newURL = i + 1 < responses.size()
1148 ? KURL(responses[i + 1].url())
1149 : resource->resourceRequest().url();
1150 bool crossOrigin = IsCrossOrigin(responses[i].url(), newURL);
1151 info->addRedirect(responses[i], crossOrigin);
1152 }
1153 1129
1154 if (resource->response().isHTTP() && 1130 if (resource->response().isHTTP() &&
1155 resource->response().httpStatusCode() < 400) { 1131 resource->response().httpStatusCode() < 400) {
1156 populateResourceTiming(info.get(), resource); 1132 populateResourceTiming(info.get(), resource);
1157 info->setLoadFinishTime(finishTime); 1133 info->setLoadFinishTime(finishTime);
1158 // encodedDataLength == -1 means "not available". 1134 // encodedDataLength == -1 means "not available".
1159 // TODO(ricea): Find cases where it is not available but the 1135 // TODO(ricea): Find cases where it is not available but the
1160 // PerformanceResourceTiming spec requires it to be available and fix 1136 // PerformanceResourceTiming spec requires it to be available and fix
1161 // them. 1137 // them.
1162 info->addFinalTransferSize(encodedDataLength == -1 ? 0 1138 info->addFinalTransferSize(encodedDataLength == -1 ? 0
1163 : encodedDataLength); 1139 : encodedDataLength);
1140
1164 if (resource->options().requestInitiatorContext == DocumentContext) 1141 if (resource->options().requestInitiatorContext == DocumentContext)
1165 context().addResourceTiming(*info); 1142 context().addResourceTiming(*info);
1166 resource->reportResourceTimingToClients(*info); 1143 resource->reportResourceTimingToClients(*info);
1167 } 1144 }
1168 } 1145 }
1146
1169 context().dispatchDidFinishLoading(resource->identifier(), finishTime, 1147 context().dispatchDidFinishLoading(resource->identifier(), finishTime,
1170 encodedDataLength); 1148 encodedDataLength);
1171 if (finishReason == DidFinishLoading) 1149
1150 if (type == DidFinishLoading)
1172 resource->finish(finishTime); 1151 resource->finish(finishTime);
1173 context().didLoadResource(resource);
1174 1152
1175 if (resource->isImage() && 1153 handleLoadCompletion(resource);
1176 toImageResource(resource)->shouldReloadBrokenPlaceholder()) {
1177 toImageResource(resource)->reloadIfLoFiOrPlaceholder(this);
1178 }
1179 } 1154 }
1180 1155
1181 void ResourceFetcher::didFailLoading(Resource* resource, 1156 void ResourceFetcher::handleLoaderError(Resource* resource,
1182 const ResourceError& error) { 1157 const ResourceError& error) {
1183 network_instrumentation::endResourceLoad( 1158 DCHECK(resource);
1184 resource->identifier(), network_instrumentation::RequestOutcome::Fail); 1159
1185 removeResourceLoader(resource->loader()); 1160 removeResourceLoader(resource->loader());
1186 m_resourceTimingInfoMap.take(const_cast<Resource*>(resource)); 1161
1162 m_resourceTimingInfoMap.take(resource);
1163
1187 bool isInternalRequest = resource->options().initiatorInfo.name == 1164 bool isInternalRequest = resource->options().initiatorInfo.name ==
1188 FetchInitiatorTypeNames::internal; 1165 FetchInitiatorTypeNames::internal;
1189 context().dispatchDidFail(resource->identifier(), error, isInternalRequest); 1166 context().dispatchDidFail(resource->identifier(), error, isInternalRequest);
1167
1190 resource->error(error); 1168 resource->error(error);
1191 context().didLoadResource(resource);
1192 1169
1193 if (resource->isImage() && 1170 handleLoadCompletion(resource);
1194 toImageResource(resource)->shouldReloadBrokenPlaceholder()) {
1195 toImageResource(resource)->reloadIfLoFiOrPlaceholder(this);
1196 }
1197 }
1198
1199 void ResourceFetcher::didReceiveResponse(
1200 Resource* resource,
1201 const ResourceResponse& response,
1202 std::unique_ptr<WebDataConsumerHandle> handle) {
1203 if (response.wasFetchedViaServiceWorker()) {
1204 if (resource->options().corsEnabled == IsCORSEnabled &&
1205 response.wasFallbackRequiredByServiceWorker()) {
1206 ResourceRequest request = resource->lastResourceRequest();
1207 DCHECK_EQ(request.skipServiceWorker(),
1208 WebURLRequest::SkipServiceWorker::None);
1209 // This code handles the case when a regular controlling service worker
1210 // doesn't handle a cross origin request. When this happens we still want
1211 // to give foreign fetch a chance to handle the request, so only skip the
1212 // controlling service worker for the fallback request. This is currently
1213 // safe because of http://crbug.com/604084 the
1214 // wasFallbackRequiredByServiceWorker flag is never set when foreign fetch
1215 // handled a request.
1216 if (!context().shouldLoadNewResource(resource->getType())) {
1217 // Cancel the request if we should not trigger a reload now.
1218 resource->loader()->didFail(
1219 ResourceError::cancelledError(response.url()));
1220 return;
1221 }
1222 request.setSkipServiceWorker(
1223 WebURLRequest::SkipServiceWorker::Controlling);
1224 resource->loader()->restart(request, context().loadingTaskRunner(),
1225 context().defersLoading());
1226 return;
1227 }
1228
1229 // If the response is fetched via ServiceWorker, the original URL of the
1230 // response could be different from the URL of the request. We check the URL
1231 // not to load the resources which are forbidden by the page CSP.
1232 // https://w3c.github.io/webappsec-csp/#should-block-response
1233 const KURL& originalURL = response.originalURLViaServiceWorker();
1234 if (!originalURL.isEmpty() &&
1235 !context().allowResponse(resource->getType(),
1236 resource->resourceRequest(), originalURL,
1237 resource->options())) {
1238 resource->loader()->didFail(
1239 ResourceError::cancelledDueToAccessCheckError(originalURL));
1240 return;
1241 }
1242 } else if (resource->options().corsEnabled == IsCORSEnabled &&
1243 !canAccessResponse(resource, response)) {
1244 resource->loader()->didFail(
1245 ResourceError::cancelledDueToAccessCheckError(response.url()));
1246 return;
1247 }
1248
1249 context().dispatchDidReceiveResponse(
1250 resource->identifier(), response, resource->resourceRequest().frameType(),
1251 resource->resourceRequest().requestContext(), resource);
1252 resource->responseReceived(response, std::move(handle));
1253 if (resource->loader() && response.httpStatusCode() >= 400 &&
1254 !resource->shouldIgnoreHTTPStatusCodeErrors()) {
1255 resource->loader()->didFail(ResourceError::cancelledError(response.url()));
1256 }
1257 }
1258
1259 void ResourceFetcher::didReceiveData(const Resource* resource,
1260 const char* data,
1261 int dataLength,
1262 int encodedDataLength) {
1263 context().dispatchDidReceiveData(resource->identifier(), data, dataLength,
1264 encodedDataLength);
1265 }
1266
1267 void ResourceFetcher::didDownloadData(const Resource* resource,
1268 int dataLength,
1269 int encodedDataLength) {
1270 context().dispatchDidDownloadData(resource->identifier(), dataLength,
1271 encodedDataLength);
1272 }
1273
1274 void ResourceFetcher::acceptDataFromThreadedReceiver(unsigned long identifier,
1275 const char* data,
1276 int dataLength,
1277 int encodedDataLength) {
1278 context().dispatchDidReceiveData(identifier, data, dataLength,
1279 encodedDataLength);
1280 } 1171 }
1281 1172
1282 void ResourceFetcher::moveResourceLoaderToNonBlocking(ResourceLoader* loader) { 1173 void ResourceFetcher::moveResourceLoaderToNonBlocking(ResourceLoader* loader) {
1283 m_nonBlockingLoaders.add(loader); 1174 m_nonBlockingLoaders.add(loader);
1284 m_loaders.remove(loader); 1175 m_loaders.remove(loader);
1285 } 1176 }
1286 1177
1287 bool ResourceFetcher::startLoad(Resource* resource) { 1178 bool ResourceFetcher::startLoad(Resource* resource) {
1288 DCHECK(resource); 1179 DCHECK(resource);
1289 DCHECK(resource->stillNeedsLoad()); 1180 DCHECK(resource->stillNeedsLoad());
1290 if (!context().shouldLoadNewResource(resource->getType())) { 1181 if (!context().shouldLoadNewResource(resource->getType())) {
1291 memoryCache()->remove(resource); 1182 memoryCache()->remove(resource);
1292 return false; 1183 return false;
1293 } 1184 }
1294 1185
1295 ResourceRequest request(resource->resourceRequest()); 1186 ResourceRequest request(resource->resourceRequest());
1296 willSendRequest(resource->identifier(), request, ResourceResponse(), 1187 context().dispatchWillSendRequest(resource->identifier(), request,
1297 resource->options()); 1188 ResourceResponse(),
1189 resource->options().initiatorInfo);
1298 1190
1299 // TODO(shaochuan): Saving modified ResourceRequest back to |resource|, remove 1191 // TODO(shaochuan): Saving modified ResourceRequest back to |resource|, remove
1300 // once willSendRequest() takes const ResourceRequest. crbug.com/632580 1192 // once dispatchWillSendRequest() takes const ResourceRequest.
1193 // crbug.com/632580
1301 resource->setResourceRequest(request); 1194 resource->setResourceRequest(request);
1302 1195
1303 // Resource requests from suborigins should not be intercepted by the service 1196 // Resource requests from suborigins should not be intercepted by the service
1304 // worker of the physical origin. This has the effect that, for now, 1197 // worker of the physical origin. This has the effect that, for now,
1305 // suborigins do not work with service workers. See 1198 // suborigins do not work with service workers. See
1306 // https://w3c.github.io/webappsec-suborigins/. 1199 // https://w3c.github.io/webappsec-suborigins/.
1307 SecurityOrigin* sourceOrigin = context().getSecurityOrigin(); 1200 SecurityOrigin* sourceOrigin = context().getSecurityOrigin();
1308 if (sourceOrigin && sourceOrigin->hasSuborigin()) 1201 if (sourceOrigin && sourceOrigin->hasSuborigin())
1309 request.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All); 1202 request.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All);
1310 1203
1311 ResourceLoader* loader = ResourceLoader::create(this, resource); 1204 ResourceLoader* loader = ResourceLoader::create(this, resource);
1312 if (resource->shouldBlockLoadEvent()) 1205 if (resource->shouldBlockLoadEvent())
1313 m_loaders.add(loader); 1206 m_loaders.add(loader);
1314 else 1207 else
1315 m_nonBlockingLoaders.add(loader); 1208 m_nonBlockingLoaders.add(loader);
1316 1209
1317 storeResourceTimingInitiatorInformation(resource); 1210 storeResourceTimingInitiatorInformation(resource);
1318 resource->setFetcherSecurityOrigin(sourceOrigin); 1211 resource->setFetcherSecurityOrigin(sourceOrigin);
1319 1212
1320 loader->activateCacheAwareLoadingIfNeeded(request); 1213 loader->activateCacheAwareLoadingIfNeeded(request);
1321 loader->start(request, context().loadingTaskRunner(), 1214 loader->start(request);
1322 context().defersLoading());
1323 return true; 1215 return true;
1324 } 1216 }
1325 1217
1326 void ResourceFetcher::removeResourceLoader(ResourceLoader* loader) { 1218 void ResourceFetcher::removeResourceLoader(ResourceLoader* loader) {
1327 if (m_loaders.contains(loader)) 1219 if (m_loaders.contains(loader))
1328 m_loaders.remove(loader); 1220 m_loaders.remove(loader);
1329 else if (m_nonBlockingLoaders.contains(loader)) 1221 else if (m_nonBlockingLoaders.contains(loader))
1330 m_nonBlockingLoaders.remove(loader); 1222 m_nonBlockingLoaders.remove(loader);
1331 else 1223 else
1332 NOTREACHED(); 1224 NOTREACHED();
(...skipping 16 matching lines...) Expand all
1349 return !m_loaders.isEmpty(); 1241 return !m_loaders.isEmpty();
1350 } 1242 }
1351 1243
1352 void ResourceFetcher::setDefersLoading(bool defers) { 1244 void ResourceFetcher::setDefersLoading(bool defers) {
1353 for (const auto& loader : m_nonBlockingLoaders) 1245 for (const auto& loader : m_nonBlockingLoaders)
1354 loader->setDefersLoading(defers); 1246 loader->setDefersLoading(defers);
1355 for (const auto& loader : m_loaders) 1247 for (const auto& loader : m_loaders)
1356 loader->setDefersLoading(defers); 1248 loader->setDefersLoading(defers);
1357 } 1249 }
1358 1250
1359 bool ResourceFetcher::defersLoading() const {
1360 return context().defersLoading();
1361 }
1362
1363 static bool isManualRedirectFetchRequest(const ResourceRequest& request) {
1364 return request.fetchRedirectMode() ==
1365 WebURLRequest::FetchRedirectModeManual &&
1366 request.requestContext() == WebURLRequest::RequestContextFetch;
1367 }
1368
1369 bool ResourceFetcher::willFollowRedirect(
1370 Resource* resource,
1371 ResourceRequest& newRequest,
1372 const ResourceResponse& redirectResponse) {
1373 if (!isManualRedirectFetchRequest(resource->resourceRequest())) {
1374 if (!context().canRequest(resource->getType(), newRequest, newRequest.url(),
1375 resource->options(), resource->isUnusedPreload(),
1376 FetchRequest::UseDefaultOriginRestrictionForType))
1377 return false;
1378 if (resource->options().corsEnabled == IsCORSEnabled) {
1379 RefPtr<SecurityOrigin> sourceOrigin = resource->options().securityOrigin;
1380 if (!sourceOrigin.get())
1381 sourceOrigin = context().getSecurityOrigin();
1382
1383 String errorMessage;
1384 StoredCredentials withCredentials =
1385 resource->lastResourceRequest().allowStoredCredentials()
1386 ? AllowStoredCredentials
1387 : DoNotAllowStoredCredentials;
1388 if (!CrossOriginAccessControl::handleRedirect(
1389 sourceOrigin, newRequest, redirectResponse, withCredentials,
1390 resource->mutableOptions(), errorMessage)) {
1391 resource->setCORSFailed();
1392 context().addConsoleMessage(errorMessage);
1393 return false;
1394 }
1395 }
1396 if (resource->getType() == Resource::Image &&
1397 shouldDeferImageLoad(newRequest.url()))
1398 return false;
1399 }
1400
1401 ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource);
1402 if (it != m_resourceTimingInfoMap.end()) {
1403 bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url());
1404 it->value->addRedirect(redirectResponse, crossOrigin);
1405 }
1406 newRequest.setAllowStoredCredentials(resource->options().allowCredentials ==
1407 AllowStoredCredentials);
1408 willSendRequest(resource->identifier(), newRequest, redirectResponse,
1409 resource->options());
1410 return true;
1411 }
1412
1413 void ResourceFetcher::willSendRequest(unsigned long identifier,
1414 ResourceRequest& newRequest,
1415 const ResourceResponse& redirectResponse,
1416 const ResourceLoaderOptions& options) {
1417 context().dispatchWillSendRequest(identifier, newRequest, redirectResponse,
1418 options.initiatorInfo);
1419 }
1420
1421 void ResourceFetcher::updateAllImageResourcePriorities() { 1251 void ResourceFetcher::updateAllImageResourcePriorities() {
1422 TRACE_EVENT0( 1252 TRACE_EVENT0(
1423 "blink", 1253 "blink",
1424 "ResourceLoadPriorityOptimizer::updateAllImageResourcePriorities"); 1254 "ResourceLoadPriorityOptimizer::updateAllImageResourcePriorities");
1425 for (const auto& documentResource : m_documentResources) { 1255 for (const auto& documentResource : m_documentResources) {
1426 Resource* resource = documentResource.value.get(); 1256 Resource* resource = documentResource.value.get();
1427 if (!resource || !resource->isImage() || !resource->isLoading()) 1257 if (!resource || !resource->isImage() || !resource->isLoading())
1428 continue; 1258 continue;
1429 1259
1430 ResourcePriority resourcePriority = resource->priorityFromObservers(); 1260 ResourcePriority resourcePriority = resource->priorityFromObservers();
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
1641 visitor->trace(m_context); 1471 visitor->trace(m_context);
1642 visitor->trace(m_archive); 1472 visitor->trace(m_archive);
1643 visitor->trace(m_loaders); 1473 visitor->trace(m_loaders);
1644 visitor->trace(m_nonBlockingLoaders); 1474 visitor->trace(m_nonBlockingLoaders);
1645 visitor->trace(m_documentResources); 1475 visitor->trace(m_documentResources);
1646 visitor->trace(m_preloads); 1476 visitor->trace(m_preloads);
1647 visitor->trace(m_resourceTimingInfoMap); 1477 visitor->trace(m_resourceTimingInfoMap);
1648 } 1478 }
1649 1479
1650 } // namespace blink 1480 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698