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

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

Issue 2535383003: Collapse images disallowed by the Safe Browsing Subresource Filter. (Closed)
Patch Set: Rebase. 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 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 } 251 }
252 252
253 ResourceFetcher::~ResourceFetcher() {} 253 ResourceFetcher::~ResourceFetcher() {}
254 254
255 Resource* ResourceFetcher::cachedResource(const KURL& resourceURL) const { 255 Resource* ResourceFetcher::cachedResource(const KURL& resourceURL) const {
256 KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(resourceURL); 256 KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(resourceURL);
257 const WeakMember<Resource>& resource = m_documentResources.get(url); 257 const WeakMember<Resource>& resource = m_documentResources.get(url);
258 return resource.get(); 258 return resource.get();
259 } 259 }
260 260
261 bool ResourceFetcher::canAccessResponse( 261 ResourceRequestBlockedReason ResourceFetcher::canAccessResponse(
262 Resource* resource, 262 Resource* resource,
263 const ResourceResponse& response) const { 263 const ResourceResponse& response) const {
264 // Redirects can change the response URL different from one of request. 264 // Redirects can change the response URL different from one of request.
265 bool forPreload = resource->isUnusedPreload(); 265 bool forPreload = resource->isUnusedPreload();
266 if (!context().canRequest(resource->getType(), resource->resourceRequest(), 266 ResourceRequestBlockedReason blockedReason =
267 response.url(), resource->options(), forPreload, 267 context().canRequest(resource->getType(), resource->resourceRequest(),
268 FetchRequest::UseDefaultOriginRestrictionForType)) 268 response.url(), resource->options(), forPreload,
269 return false; 269 FetchRequest::UseDefaultOriginRestrictionForType);
270 if (blockedReason != ResourceRequestBlockedReason::None)
271 return blockedReason;
270 272
271 SecurityOrigin* sourceOrigin = resource->options().securityOrigin.get(); 273 SecurityOrigin* sourceOrigin = resource->options().securityOrigin.get();
272 if (!sourceOrigin) 274 if (!sourceOrigin)
273 sourceOrigin = context().getSecurityOrigin(); 275 sourceOrigin = context().getSecurityOrigin();
274 276
275 if (sourceOrigin->canRequestNoSuborigin(response.url())) 277 if (sourceOrigin->canRequestNoSuborigin(response.url()))
276 return true; 278 return ResourceRequestBlockedReason::None;
277 279
278 // Use the original response instead of the 304 response for a successful 280 // Use the original response instead of the 304 response for a successful
279 // revaldiation. 281 // revaldiation.
280 const ResourceResponse& responseForAccessControl = 282 const ResourceResponse& responseForAccessControl =
281 (resource->isCacheValidator() && response.httpStatusCode() == 304) 283 (resource->isCacheValidator() && response.httpStatusCode() == 304)
282 ? resource->response() 284 ? resource->response()
283 : response; 285 : response;
284 String errorDescription; 286 String errorDescription;
285 if (!passesAccessControlCheck( 287 if (!passesAccessControlCheck(
286 responseForAccessControl, resource->options().allowCredentials, 288 responseForAccessControl, resource->options().allowCredentials,
287 sourceOrigin, errorDescription, 289 sourceOrigin, errorDescription,
288 resource->lastResourceRequest().requestContext())) { 290 resource->lastResourceRequest().requestContext())) {
289 resource->setCORSFailed(); 291 resource->setCORSFailed();
290 if (!forPreload) { 292 if (!forPreload) {
291 String resourceType = Resource::resourceTypeToString( 293 String resourceType = Resource::resourceTypeToString(
292 resource->getType(), resource->options().initiatorInfo); 294 resource->getType(), resource->options().initiatorInfo);
293 context().addConsoleMessage( 295 context().addConsoleMessage(
294 "Access to " + resourceType + " at '" + response.url().getString() + 296 "Access to " + resourceType + " at '" + response.url().getString() +
295 "' from origin '" + sourceOrigin->toString() + 297 "' from origin '" + sourceOrigin->toString() +
296 "' has been blocked by CORS policy: " + errorDescription); 298 "' has been blocked by CORS policy: " + errorDescription);
297 } 299 }
298 return false; 300 return ResourceRequestBlockedReason::Other;
299 } 301 }
300 return true; 302 return ResourceRequestBlockedReason::None;
301 } 303 }
302 304
303 bool ResourceFetcher::isControlledByServiceWorker() const { 305 bool ResourceFetcher::isControlledByServiceWorker() const {
304 return context().isControlledByServiceWorker(); 306 return context().isControlledByServiceWorker();
305 } 307 }
306 308
307 bool ResourceFetcher::resourceNeedsLoad(Resource* resource, 309 bool ResourceFetcher::resourceNeedsLoad(Resource* resource,
308 const FetchRequest& request, 310 const FetchRequest& request,
309 RevalidationPolicy policy) { 311 RevalidationPolicy policy) {
310 // Defer a font load until it is actually needed unless this is a preload. 312 // Defer a font load until it is actually needed unless this is a preload.
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 resource->finish(); 432 resource->finish();
431 433
432 if (!substituteData.isValid()) 434 if (!substituteData.isValid())
433 memoryCache()->add(resource); 435 memoryCache()->add(resource);
434 436
435 return resource; 437 return resource;
436 } 438 }
437 439
438 Resource* ResourceFetcher::resourceForBlockedRequest( 440 Resource* ResourceFetcher::resourceForBlockedRequest(
439 const FetchRequest& request, 441 const FetchRequest& request,
440 const ResourceFactory& factory) { 442 const ResourceFactory& factory,
443 ResourceRequestBlockedReason blockedReason) {
441 Resource* resource = factory.create(request.resourceRequest(), 444 Resource* resource = factory.create(request.resourceRequest(),
442 request.options(), request.charset()); 445 request.options(), request.charset());
443 resource->error(ResourceError::cancelledDueToAccessCheckError(request.url())); 446 resource->error(ResourceError::cancelledDueToAccessCheckError(request.url(),
447 blockedReason));
444 return resource; 448 return resource;
445 } 449 }
446 450
447 void ResourceFetcher::moveCachedNonBlockingResourceToBlocking( 451 void ResourceFetcher::moveCachedNonBlockingResourceToBlocking(
448 Resource* resource, 452 Resource* resource,
449 const FetchRequest& request) { 453 const FetchRequest& request) {
450 // TODO(yoav): Test that non-blocking resources (video/audio/track) continue 454 // TODO(yoav): Test that non-blocking resources (video/audio/track) continue
451 // to not-block even after being preloaded and discovered. 455 // to not-block even after being preloaded and discovered.
452 if (resource && resource->loader() && 456 if (resource && resource->loader() &&
453 resource->isLoadEventBlockingResourceType() && 457 resource->isLoadEventBlockingResourceType() &&
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 if (!request.url().isValid()) 510 if (!request.url().isValid())
507 return nullptr; 511 return nullptr;
508 512
509 request.mutableResourceRequest().setPriority(computeLoadPriority( 513 request.mutableResourceRequest().setPriority(computeLoadPriority(
510 factory.type(), request, ResourcePriority::NotVisible)); 514 factory.type(), request, ResourcePriority::NotVisible));
511 initializeResourceRequest(request.mutableResourceRequest(), factory.type(), 515 initializeResourceRequest(request.mutableResourceRequest(), factory.type(),
512 request.defer()); 516 request.defer());
513 network_instrumentation::resourcePrioritySet( 517 network_instrumentation::resourcePrioritySet(
514 identifier, request.resourceRequest().priority()); 518 identifier, request.resourceRequest().priority());
515 519
516 if (!context().canRequest( 520 ResourceRequestBlockedReason blockedReason = context().canRequest(
517 factory.type(), request.resourceRequest(), 521 factory.type(), request.resourceRequest(),
518 MemoryCache::removeFragmentIdentifierIfNeeded(request.url()), 522 MemoryCache::removeFragmentIdentifierIfNeeded(request.url()),
519 request.options(), request.forPreload(), 523 request.options(), request.forPreload(), request.getOriginRestriction());
520 request.getOriginRestriction())) { 524 if (blockedReason != ResourceRequestBlockedReason::None) {
521 DCHECK(!substituteData.forceSynchronousLoad()); 525 DCHECK(!substituteData.forceSynchronousLoad());
522 return resourceForBlockedRequest(request, factory); 526 return resourceForBlockedRequest(request, factory, blockedReason);
523 } 527 }
524 528
525 context().willStartLoadingResource( 529 context().willStartLoadingResource(
526 identifier, request.mutableResourceRequest(), factory.type()); 530 identifier, request.mutableResourceRequest(), factory.type());
527 if (!request.url().isValid()) 531 if (!request.url().isValid())
528 return nullptr; 532 return nullptr;
529 533
530 if (!request.forPreload()) { 534 if (!request.forPreload()) {
531 V8DOMActivityLogger* activityLogger = nullptr; 535 V8DOMActivityLogger* activityLogger = nullptr;
532 if (request.options().initiatorInfo.name == 536 if (request.options().initiatorInfo.name ==
(...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after
1225 resource->loader()->restart(request, context().loadingTaskRunner(), 1229 resource->loader()->restart(request, context().loadingTaskRunner(),
1226 context().defersLoading()); 1230 context().defersLoading());
1227 return; 1231 return;
1228 } 1232 }
1229 1233
1230 // If the response is fetched via ServiceWorker, the original URL of the 1234 // If the response is fetched via ServiceWorker, the original URL of the
1231 // response could be different from the URL of the request. We check the URL 1235 // response could be different from the URL of the request. We check the URL
1232 // not to load the resources which are forbidden by the page CSP. 1236 // not to load the resources which are forbidden by the page CSP.
1233 // https://w3c.github.io/webappsec-csp/#should-block-response 1237 // https://w3c.github.io/webappsec-csp/#should-block-response
1234 const KURL& originalURL = response.originalURLViaServiceWorker(); 1238 const KURL& originalURL = response.originalURLViaServiceWorker();
1235 if (!originalURL.isEmpty() && 1239 if (!originalURL.isEmpty()) {
1236 !context().allowResponse(resource->getType(), 1240 ResourceRequestBlockedReason blockedReason = context().allowResponse(
1237 resource->resourceRequest(), originalURL, 1241 resource->getType(), resource->resourceRequest(), originalURL,
1238 resource->options())) { 1242 resource->options());
1239 resource->loader()->didFail( 1243 if (blockedReason != ResourceRequestBlockedReason::None) {
1240 ResourceError::cancelledDueToAccessCheckError(originalURL)); 1244 resource->loader()->didFail(
1245 ResourceError::cancelledDueToAccessCheckError(originalURL,
1246 blockedReason));
1247 return;
1248 }
1249 }
1250 } else if (resource->options().corsEnabled == IsCORSEnabled) {
1251 ResourceRequestBlockedReason blockedReason =
1252 canAccessResponse(resource, response);
1253 if (blockedReason != ResourceRequestBlockedReason::None) {
1254 resource->loader()->didFail(ResourceError::cancelledDueToAccessCheckError(
1255 response.url(), blockedReason));
1241 return; 1256 return;
1242 } 1257 }
1243 } else if (resource->options().corsEnabled == IsCORSEnabled &&
1244 !canAccessResponse(resource, response)) {
1245 resource->loader()->didFail(
1246 ResourceError::cancelledDueToAccessCheckError(response.url()));
1247 return;
1248 } 1258 }
1249 1259
1250 context().dispatchDidReceiveResponse( 1260 context().dispatchDidReceiveResponse(
1251 resource->identifier(), response, resource->resourceRequest().frameType(), 1261 resource->identifier(), response, resource->resourceRequest().frameType(),
1252 resource->resourceRequest().requestContext(), resource); 1262 resource->resourceRequest().requestContext(), resource);
1253 resource->responseReceived(response, std::move(handle)); 1263 resource->responseReceived(response, std::move(handle));
1254 if (resource->loader() && response.httpStatusCode() >= 400 && 1264 if (resource->loader() && response.httpStatusCode() >= 400 &&
1255 !resource->shouldIgnoreHTTPStatusCodeErrors()) { 1265 !resource->shouldIgnoreHTTPStatusCodeErrors()) {
1256 resource->loader()->didFail(ResourceError::cancelledError(response.url())); 1266 resource->loader()->didFail(ResourceError::cancelledError(response.url()));
1257 } 1267 }
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1356 bool ResourceFetcher::defersLoading() const { 1366 bool ResourceFetcher::defersLoading() const {
1357 return context().defersLoading(); 1367 return context().defersLoading();
1358 } 1368 }
1359 1369
1360 static bool isManualRedirectFetchRequest(const ResourceRequest& request) { 1370 static bool isManualRedirectFetchRequest(const ResourceRequest& request) {
1361 return request.fetchRedirectMode() == 1371 return request.fetchRedirectMode() ==
1362 WebURLRequest::FetchRedirectModeManual && 1372 WebURLRequest::FetchRedirectModeManual &&
1363 request.requestContext() == WebURLRequest::RequestContextFetch; 1373 request.requestContext() == WebURLRequest::RequestContextFetch;
1364 } 1374 }
1365 1375
1366 bool ResourceFetcher::willFollowRedirect( 1376 ResourceRequestBlockedReason ResourceFetcher::willFollowRedirect(
1367 Resource* resource, 1377 Resource* resource,
1368 ResourceRequest& newRequest, 1378 ResourceRequest& newRequest,
1369 const ResourceResponse& redirectResponse) { 1379 const ResourceResponse& redirectResponse) {
1370 if (!isManualRedirectFetchRequest(resource->resourceRequest())) { 1380 if (!isManualRedirectFetchRequest(resource->resourceRequest())) {
1371 if (!context().canRequest(resource->getType(), newRequest, newRequest.url(), 1381 ResourceRequestBlockedReason blockedReason =
1372 resource->options(), resource->isUnusedPreload(), 1382 context().canRequest(resource->getType(), newRequest, newRequest.url(),
1373 FetchRequest::UseDefaultOriginRestrictionForType)) 1383 resource->options(), resource->isUnusedPreload(),
1374 return false; 1384 FetchRequest::UseDefaultOriginRestrictionForType);
1385 if (blockedReason != ResourceRequestBlockedReason::None)
1386 return blockedReason;
1375 if (resource->options().corsEnabled == IsCORSEnabled) { 1387 if (resource->options().corsEnabled == IsCORSEnabled) {
1376 RefPtr<SecurityOrigin> sourceOrigin = resource->options().securityOrigin; 1388 RefPtr<SecurityOrigin> sourceOrigin = resource->options().securityOrigin;
1377 if (!sourceOrigin.get()) 1389 if (!sourceOrigin.get())
1378 sourceOrigin = context().getSecurityOrigin(); 1390 sourceOrigin = context().getSecurityOrigin();
1379 1391
1380 String errorMessage; 1392 String errorMessage;
1381 StoredCredentials withCredentials = 1393 StoredCredentials withCredentials =
1382 resource->lastResourceRequest().allowStoredCredentials() 1394 resource->lastResourceRequest().allowStoredCredentials()
1383 ? AllowStoredCredentials 1395 ? AllowStoredCredentials
1384 : DoNotAllowStoredCredentials; 1396 : DoNotAllowStoredCredentials;
1385 if (!CrossOriginAccessControl::handleRedirect( 1397 if (!CrossOriginAccessControl::handleRedirect(
1386 sourceOrigin, newRequest, redirectResponse, withCredentials, 1398 sourceOrigin, newRequest, redirectResponse, withCredentials,
1387 resource->mutableOptions(), errorMessage)) { 1399 resource->mutableOptions(), errorMessage)) {
1388 resource->setCORSFailed(); 1400 resource->setCORSFailed();
1389 context().addConsoleMessage(errorMessage); 1401 context().addConsoleMessage(errorMessage);
1390 return false; 1402 return ResourceRequestBlockedReason::Other;
1391 } 1403 }
1392 } 1404 }
1393 if (resource->getType() == Resource::Image && 1405 if (resource->getType() == Resource::Image &&
1394 shouldDeferImageLoad(newRequest.url())) 1406 shouldDeferImageLoad(newRequest.url())) {
1395 return false; 1407 return ResourceRequestBlockedReason::Other;
1408 }
1396 } 1409 }
1397 1410
1398 ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource); 1411 ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource);
1399 if (it != m_resourceTimingInfoMap.end()) { 1412 if (it != m_resourceTimingInfoMap.end()) {
1400 bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url()); 1413 bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url());
1401 it->value->addRedirect(redirectResponse, crossOrigin); 1414 it->value->addRedirect(redirectResponse, crossOrigin);
1402 } 1415 }
1403 newRequest.setAllowStoredCredentials(resource->options().allowCredentials == 1416 newRequest.setAllowStoredCredentials(resource->options().allowCredentials ==
1404 AllowStoredCredentials); 1417 AllowStoredCredentials);
1405 willSendRequest(resource->identifier(), newRequest, redirectResponse, 1418 willSendRequest(resource->identifier(), newRequest, redirectResponse,
1406 resource->options()); 1419 resource->options());
1407 return true; 1420 return ResourceRequestBlockedReason::None;
1408 } 1421 }
1409 1422
1410 void ResourceFetcher::willSendRequest(unsigned long identifier, 1423 void ResourceFetcher::willSendRequest(unsigned long identifier,
1411 ResourceRequest& newRequest, 1424 ResourceRequest& newRequest,
1412 const ResourceResponse& redirectResponse, 1425 const ResourceResponse& redirectResponse,
1413 const ResourceLoaderOptions& options) { 1426 const ResourceLoaderOptions& options) {
1414 context().dispatchWillSendRequest(identifier, newRequest, redirectResponse, 1427 context().dispatchWillSendRequest(identifier, newRequest, redirectResponse,
1415 options.initiatorInfo); 1428 options.initiatorInfo);
1416 } 1429 }
1417 1430
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1655 visitor->trace(m_context); 1668 visitor->trace(m_context);
1656 visitor->trace(m_archive); 1669 visitor->trace(m_archive);
1657 visitor->trace(m_loaders); 1670 visitor->trace(m_loaders);
1658 visitor->trace(m_nonBlockingLoaders); 1671 visitor->trace(m_nonBlockingLoaders);
1659 visitor->trace(m_documentResources); 1672 visitor->trace(m_documentResources);
1660 visitor->trace(m_preloads); 1673 visitor->trace(m_preloads);
1661 visitor->trace(m_resourceTimingInfoMap); 1674 visitor->trace(m_resourceTimingInfoMap);
1662 } 1675 }
1663 1676
1664 } // namespace blink 1677 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/fetch/ResourceFetcher.h ('k') | third_party/WebKit/Source/core/fetch/ResourceLoader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698