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) 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) { | 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(errorDomainBlinkI nternal, 0, originalURL.getString(), "Unsafe attempt to load URL " + originalURL .elidedString() + " fetched by a ServiceWorker.")); |
Nate Chapin
2016/07/29 20:41:29
Ah...that's what it is. didFail() implicitly conve
| |
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); | |
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 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1275 visitor->trace(m_context); | 1301 visitor->trace(m_context); |
1276 visitor->trace(m_archive); | 1302 visitor->trace(m_archive); |
1277 visitor->trace(m_loaders); | 1303 visitor->trace(m_loaders); |
1278 visitor->trace(m_nonBlockingLoaders); | 1304 visitor->trace(m_nonBlockingLoaders); |
1279 visitor->trace(m_documentResources); | 1305 visitor->trace(m_documentResources); |
1280 visitor->trace(m_preloads); | 1306 visitor->trace(m_preloads); |
1281 visitor->trace(m_resourceTimingInfoMap); | 1307 visitor->trace(m_resourceTimingInfoMap); |
1282 } | 1308 } |
1283 | 1309 |
1284 } // namespace blink | 1310 } // namespace blink |
OLD | NEW |