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::cancelledDueToAc
cessCheckError(originalURL)); |
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 |