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

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

Issue 1975373002: Clean up response handling in ResourceLoader/ResourceFetcher (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address hiroshige's comments Created 4 years, 4 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
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 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 { 232 {
233 } 233 }
234 234
235 Resource* ResourceFetcher::cachedResource(const KURL& resourceURL) const 235 Resource* ResourceFetcher::cachedResource(const KURL& resourceURL) const
236 { 236 {
237 KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(resourceURL); 237 KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(resourceURL);
238 const WeakMember<Resource>& resource = m_documentResources.get(url); 238 const WeakMember<Resource>& resource = m_documentResources.get(url);
239 return resource.get(); 239 return resource.get();
240 } 240 }
241 241
242 bool ResourceFetcher::canAccessResource(Resource* resource, SecurityOrigin* sour ceOrigin, const KURL& url, AccessControlLoggingDecision logErrorsDecision) const 242 bool ResourceFetcher::canAccessResponse(Resource* resource, const ResourceRespon se& response) const
243 { 243 {
244 // Redirects can change the response URL different from one of request. 244 // Redirects can change the response URL different from one of request.
245 bool forPreload = resource->isUnusedPreload(); 245 bool forPreload = resource->isUnusedPreload();
246 if (!context().canRequest(resource->getType(), resource->resourceRequest(), url, resource->options(), forPreload, FetchRequest::UseDefaultOriginRestrictionF orType)) 246 if (!context().canRequest(resource->getType(), resource->resourceRequest(), response.url(), resource->options(), forPreload, FetchRequest::UseDefaultOriginR estrictionForType))
247 return false; 247 return false;
248 248
249 SecurityOrigin* sourceOrigin = resource->options().securityOrigin.get();
249 if (!sourceOrigin) 250 if (!sourceOrigin)
250 sourceOrigin = context().getSecurityOrigin(); 251 sourceOrigin = context().getSecurityOrigin();
251 252
252 if (sourceOrigin->canRequestNoSuborigin(url)) 253 if (sourceOrigin->canRequestNoSuborigin(response.url()))
253 return true; 254 return true;
254 255
256 // Use the original response instead of the 304 response for a successful re valdiation.
257 const ResourceResponse& responseForAccessControl = (resource->isCacheValidat or() && response.httpStatusCode() == 304) ? resource->response() : response;
255 String errorDescription; 258 String errorDescription;
256 if (!resource->passesAccessControlCheck(sourceOrigin, errorDescription)) { 259 if (!passesAccessControlCheck(responseForAccessControl, resource->options(). allowCredentials, sourceOrigin, errorDescription, resource->lastResourceRequest( ).requestContext())) {
257 resource->setCORSFailed(); 260 resource->setCORSFailed();
258 if (!forPreload && (logErrorsDecision == ShouldLogAccessControlErrors)) { 261 if (!forPreload) {
259 String resourceType = Resource::resourceTypeToString(resource->getTy pe(), resource->options().initiatorInfo); 262 String resourceType = Resource::resourceTypeToString(resource->getTy pe(), resource->options().initiatorInfo);
260 context().addConsoleMessage(resourceType + " from origin '" + Securi tyOrigin::create(url)->toString() + "' has been blocked from loading by Cross-Or igin Resource Sharing policy: " + errorDescription); 263 context().addConsoleMessage(resourceType + " from origin '" + Securi tyOrigin::create(response.url())->toString() + "' has been blocked from loading by Cross-Origin Resource Sharing policy: " + errorDescription);
261 } 264 }
262 return false; 265 return false;
263 } 266 }
264 return true; 267 return true;
265 } 268 }
266 269
267 bool ResourceFetcher::isControlledByServiceWorker() const 270 bool ResourceFetcher::isControlledByServiceWorker() const
268 { 271 {
269 return context().isControlledByServiceWorker(); 272 return context().isControlledByServiceWorker();
270 } 273 }
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 { 941 {
939 TRACE_EVENT_ASYNC_END0("blink.net", "Resource", resource->identifier()); 942 TRACE_EVENT_ASYNC_END0("blink.net", "Resource", resource->identifier());
940 removeResourceLoader(resource->loader()); 943 removeResourceLoader(resource->loader());
941 m_resourceTimingInfoMap.take(const_cast<Resource*>(resource)); 944 m_resourceTimingInfoMap.take(const_cast<Resource*>(resource));
942 bool isInternalRequest = resource->options().initiatorInfo.name == FetchInit iatorTypeNames::internal; 945 bool isInternalRequest = resource->options().initiatorInfo.name == FetchInit iatorTypeNames::internal;
943 context().dispatchDidFail(resource->identifier(), error, isInternalRequest); 946 context().dispatchDidFail(resource->identifier(), error, isInternalRequest);
944 resource->error(error); 947 resource->error(error);
945 context().didLoadResource(resource); 948 context().didLoadResource(resource);
946 } 949 }
947 950
948 void ResourceFetcher::didReceiveResponse(Resource* resource, const ResourceRespo nse& response) 951 void ResourceFetcher::didReceiveResponse(Resource* resource, const ResourceRespo nse& response, WebDataConsumerHandle* rawHandle)
949 { 952 {
950 // If the response is fetched via ServiceWorker, the original URL of the res ponse could be different from the URL of the request. 953 // |rawHandle|'s ownership is transferred to the callee.
951 // We check the URL not to load the resources which are forbidden by the pag e CSP. 954 std::unique_ptr<WebDataConsumerHandle> handle = wrapUnique(rawHandle);
952 // https://w3c.github.io/webappsec-csp/#should-block-response 955
953 if (response.wasFetchedViaServiceWorker()) { 956 if (response.wasFetchedViaServiceWorker()) {
957 if (resource->options().corsEnabled == IsCORSEnabled && response.wasFall backRequiredByServiceWorker()) {
958 ResourceRequest request = resource->lastResourceRequest();
959 DCHECK_EQ(request.skipServiceWorker(), WebURLRequest::SkipServiceWor ker::None);
960 // This code handles the case when a regular controlling service wor ker
961 // doesn't handle a cross origin request. When this happens we still
962 // want to give foreign fetch a chance to handle the request, so
963 // only skip the controlling service worker for the fallback request .
964 // This is currently safe because of http://crbug.com/604084 the
965 // wasFallbackRequiredByServiceWorker flag is never set when foreign fetch
966 // handled a request.
967 request.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::Contr olling);
968 resource->loader()->restartForServiceWorkerFallback(request);
969 return;
970 }
971
972 // If the response is fetched via ServiceWorker, the original URL of the response could be different from the URL of the request.
973 // We check the URL not to load the resources which are forbidden by the page CSP.
974 // https://w3c.github.io/webappsec-csp/#should-block-response
954 const KURL& originalURL = response.originalURLViaServiceWorker(); 975 const KURL& originalURL = response.originalURLViaServiceWorker();
955 if (!originalURL.isEmpty() && !context().allowResponse(resource->getType (), resource->resourceRequest(), originalURL, resource->options())) { 976 if (!originalURL.isEmpty() && !context().allowResponse(resource->getType (), resource->resourceRequest(), originalURL, resource->options())) {
956 resource->loader()->cancel(); 977 resource->loader()->didFail(nullptr, ResourceError::cancelledDueToAc cessCheckError(response.url()));
957 bool isInternalRequest = resource->options().initiatorInfo.name == F etchInitiatorTypeNames::internal;
958 context().dispatchDidFail(resource->identifier(), ResourceError(erro rDomainBlinkInternal, 0, originalURL.getString(), "Unsafe attempt to load URL " + originalURL.elidedString() + " fetched by a ServiceWorker."), isInternalReques t);
hiroshige 2016/07/29 08:00:27 FYI +horo@, this changes an error message related
Nate Chapin 2016/07/29 19:04:52 I probably shouldn't have done that. I'll revert i
959 return; 978 return;
960 } 979 }
980 } else if (resource->options().corsEnabled == IsCORSEnabled && !canAccessRes ponse(resource, response)) {
981 resource->loader()->didFail(nullptr, ResourceError::cancelledDueToAccess CheckError(response.url()));
982 return;
961 } 983 }
984
962 context().dispatchDidReceiveResponse(resource->identifier(), response, resou rce->resourceRequest().frameType(), resource->resourceRequest().requestContext() , resource); 985 context().dispatchDidReceiveResponse(resource->identifier(), response, resou rce->resourceRequest().frameType(), resource->resourceRequest().requestContext() , resource);
986 resource->responseReceived(response, std::move(handle));
987 if (resource->loader() && response.httpStatusCode() >= 400 && !resource->sho uldIgnoreHTTPStatusCodeErrors())
988 resource->loader()->didFail(nullptr, ResourceError::cancelledError(respo nse.url()));
963 } 989 }
964 990
965 void ResourceFetcher::didReceiveData(const Resource* resource, const char* data, int dataLength, int encodedDataLength) 991 void ResourceFetcher::didReceiveData(const Resource* resource, const char* data, int dataLength, int encodedDataLength)
966 { 992 {
967 context().dispatchDidReceiveData(resource->identifier(), data, dataLength, e ncodedDataLength); 993 context().dispatchDidReceiveData(resource->identifier(), data, dataLength, e ncodedDataLength);
968 } 994 }
969 995
970 void ResourceFetcher::didDownloadData(const Resource* resource, int dataLength, int encodedDataLength) 996 void ResourceFetcher::didDownloadData(const Resource* resource, int dataLength, int encodedDataLength)
971 { 997 {
972 context().dispatchDidDownloadData(resource->identifier(), dataLength, encode dDataLength); 998 context().dispatchDidDownloadData(resource->identifier(), dataLength, encode dDataLength);
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 visitor->trace(m_context); 1298 visitor->trace(m_context);
1273 visitor->trace(m_archive); 1299 visitor->trace(m_archive);
1274 visitor->trace(m_loaders); 1300 visitor->trace(m_loaders);
1275 visitor->trace(m_nonBlockingLoaders); 1301 visitor->trace(m_nonBlockingLoaders);
1276 visitor->trace(m_documentResources); 1302 visitor->trace(m_documentResources);
1277 visitor->trace(m_preloads); 1303 visitor->trace(m_preloads);
1278 visitor->trace(m_resourceTimingInfoMap); 1304 visitor->trace(m_resourceTimingInfoMap);
1279 } 1305 }
1280 1306
1281 } // namespace blink 1307 } // 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