Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |