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

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: Phrasing. 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 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 bool ResourceFetcher::defersLoading() const { 1374 bool ResourceFetcher::defersLoading() const {
1365 return context().defersLoading(); 1375 return context().defersLoading();
1366 } 1376 }
1367 1377
1368 static bool isManualRedirectFetchRequest(const ResourceRequest& request) { 1378 static bool isManualRedirectFetchRequest(const ResourceRequest& request) {
1369 return request.fetchRedirectMode() == 1379 return request.fetchRedirectMode() ==
1370 WebURLRequest::FetchRedirectModeManual && 1380 WebURLRequest::FetchRedirectModeManual &&
1371 request.requestContext() == WebURLRequest::RequestContextFetch; 1381 request.requestContext() == WebURLRequest::RequestContextFetch;
1372 } 1382 }
1373 1383
1374 bool ResourceFetcher::willFollowRedirect( 1384 ResourceRequestBlockedReason ResourceFetcher::willFollowRedirect(
1375 Resource* resource, 1385 Resource* resource,
1376 ResourceRequest& newRequest, 1386 ResourceRequest& newRequest,
1377 const ResourceResponse& redirectResponse) { 1387 const ResourceResponse& redirectResponse) {
1378 if (!isManualRedirectFetchRequest(resource->resourceRequest())) { 1388 if (!isManualRedirectFetchRequest(resource->resourceRequest())) {
1379 if (!context().canRequest(resource->getType(), newRequest, newRequest.url(), 1389 ResourceRequestBlockedReason blockedReason =
1380 resource->options(), resource->isUnusedPreload(), 1390 context().canRequest(resource->getType(), newRequest, newRequest.url(),
1381 FetchRequest::UseDefaultOriginRestrictionForType)) 1391 resource->options(), resource->isUnusedPreload(),
1382 return false; 1392 FetchRequest::UseDefaultOriginRestrictionForType);
1393 if (blockedReason != ResourceRequestBlockedReason::None)
1394 return blockedReason;
1383 if (resource->options().corsEnabled == IsCORSEnabled) { 1395 if (resource->options().corsEnabled == IsCORSEnabled) {
1384 RefPtr<SecurityOrigin> sourceOrigin = resource->options().securityOrigin; 1396 RefPtr<SecurityOrigin> sourceOrigin = resource->options().securityOrigin;
1385 if (!sourceOrigin.get()) 1397 if (!sourceOrigin.get())
1386 sourceOrigin = context().getSecurityOrigin(); 1398 sourceOrigin = context().getSecurityOrigin();
1387 1399
1388 String errorMessage; 1400 String errorMessage;
1389 StoredCredentials withCredentials = 1401 StoredCredentials withCredentials =
1390 resource->lastResourceRequest().allowStoredCredentials() 1402 resource->lastResourceRequest().allowStoredCredentials()
1391 ? AllowStoredCredentials 1403 ? AllowStoredCredentials
1392 : DoNotAllowStoredCredentials; 1404 : DoNotAllowStoredCredentials;
1393 if (!CrossOriginAccessControl::handleRedirect( 1405 if (!CrossOriginAccessControl::handleRedirect(
1394 sourceOrigin, newRequest, redirectResponse, withCredentials, 1406 sourceOrigin, newRequest, redirectResponse, withCredentials,
1395 resource->mutableOptions(), errorMessage)) { 1407 resource->mutableOptions(), errorMessage)) {
1396 resource->setCORSFailed(); 1408 resource->setCORSFailed();
1397 context().addConsoleMessage(errorMessage); 1409 context().addConsoleMessage(errorMessage);
1398 return false; 1410 return ResourceRequestBlockedReason::Other;
1399 } 1411 }
1400 } 1412 }
1401 if (resource->getType() == Resource::Image && 1413 if (resource->getType() == Resource::Image &&
1402 shouldDeferImageLoad(newRequest.url())) 1414 shouldDeferImageLoad(newRequest.url())) {
1403 return false; 1415 return ResourceRequestBlockedReason::Other;
1416 }
1404 } 1417 }
1405 1418
1406 ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource); 1419 ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource);
1407 if (it != m_resourceTimingInfoMap.end()) { 1420 if (it != m_resourceTimingInfoMap.end()) {
1408 bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url()); 1421 bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url());
1409 it->value->addRedirect(redirectResponse, crossOrigin); 1422 it->value->addRedirect(redirectResponse, crossOrigin);
1410 } 1423 }
1411 newRequest.setAllowStoredCredentials(resource->options().allowCredentials == 1424 newRequest.setAllowStoredCredentials(resource->options().allowCredentials ==
1412 AllowStoredCredentials); 1425 AllowStoredCredentials);
1413 willSendRequest(resource->identifier(), newRequest, redirectResponse, 1426 willSendRequest(resource->identifier(), newRequest, redirectResponse,
1414 resource->options()); 1427 resource->options());
1415 return true; 1428 return ResourceRequestBlockedReason::None;
1416 } 1429 }
1417 1430
1418 void ResourceFetcher::willSendRequest(unsigned long identifier, 1431 void ResourceFetcher::willSendRequest(unsigned long identifier,
1419 ResourceRequest& newRequest, 1432 ResourceRequest& newRequest,
1420 const ResourceResponse& redirectResponse, 1433 const ResourceResponse& redirectResponse,
1421 const ResourceLoaderOptions& options) { 1434 const ResourceLoaderOptions& options) {
1422 context().dispatchWillSendRequest(identifier, newRequest, redirectResponse, 1435 context().dispatchWillSendRequest(identifier, newRequest, redirectResponse,
1423 options.initiatorInfo); 1436 options.initiatorInfo);
1424 } 1437 }
1425 1438
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
1646 visitor->trace(m_context); 1659 visitor->trace(m_context);
1647 visitor->trace(m_archive); 1660 visitor->trace(m_archive);
1648 visitor->trace(m_loaders); 1661 visitor->trace(m_loaders);
1649 visitor->trace(m_nonBlockingLoaders); 1662 visitor->trace(m_nonBlockingLoaders);
1650 visitor->trace(m_documentResources); 1663 visitor->trace(m_documentResources);
1651 visitor->trace(m_preloads); 1664 visitor->trace(m_preloads);
1652 visitor->trace(m_resourceTimingInfoMap); 1665 visitor->trace(m_resourceTimingInfoMap);
1653 } 1666 }
1654 1667
1655 } // namespace blink 1668 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698