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) 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) |
| 6 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. | 6 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. |
| 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 161 , m_requestedFromNetworkingLayer(false) | 161 , m_requestedFromNetworkingLayer(false) |
| 162 , m_loading(false) | 162 , m_loading(false) |
| 163 , m_switchingClientsToRevalidatedResource(false) | 163 , m_switchingClientsToRevalidatedResource(false) |
| 164 , m_type(type) | 164 , m_type(type) |
| 165 , m_status(Pending) | 165 , m_status(Pending) |
| 166 , m_wasPurged(false) | 166 , m_wasPurged(false) |
| 167 , m_needsSynchronousCacheHit(false) | 167 , m_needsSynchronousCacheHit(false) |
| 168 #ifdef ENABLE_RESOURCE_IS_DELETED_CHECK | 168 #ifdef ENABLE_RESOURCE_IS_DELETED_CHECK |
| 169 , m_deleted(false) | 169 , m_deleted(false) |
| 170 #endif | 170 #endif |
| 171 , m_resourceToRevalidate(nullptr) | |
| 172 , m_proxyResource(nullptr) | |
| 173 { | 171 { |
| 174 ASSERT(m_type == unsigned(type)); // m_type is a bitfield, so this tests car eless updates of the enum. | 172 ASSERT(m_type == unsigned(type)); // m_type is a bitfield, so this tests car eless updates of the enum. |
| 175 InstanceCounters::incrementCounter(InstanceCounters::ResourceCounter); | 173 InstanceCounters::incrementCounter(InstanceCounters::ResourceCounter); |
| 176 #ifndef NDEBUG | 174 #ifndef NDEBUG |
| 177 cachedResourceLeakCounter.increment(); | 175 cachedResourceLeakCounter.increment(); |
| 178 #endif | 176 #endif |
| 179 memoryCache()->registerLiveResource(*this); | 177 memoryCache()->registerLiveResource(*this); |
| 180 | 178 |
| 181 // Currently we support the metadata caching only for HTTP family. | 179 // Currently we support the metadata caching only for HTTP family. |
| 182 if (m_resourceRequest.url().protocolIsInHTTPFamily()) | 180 if (m_resourceRequest.url().protocolIsInHTTPFamily()) |
| 183 m_cacheHandler = CacheHandler::create(this); | 181 m_cacheHandler = CacheHandler::create(this); |
| 184 | 182 |
| 185 if (!m_resourceRequest.url().hasFragmentIdentifier()) | 183 if (!m_resourceRequest.url().hasFragmentIdentifier()) |
| 186 return; | 184 return; |
| 187 KURL urlForCache = MemoryCache::removeFragmentIdentifierIfNeeded(m_resourceR equest.url()); | 185 KURL urlForCache = MemoryCache::removeFragmentIdentifierIfNeeded(m_resourceR equest.url()); |
| 188 if (urlForCache.hasFragmentIdentifier()) | 186 if (urlForCache.hasFragmentIdentifier()) |
| 189 return; | 187 return; |
| 190 m_fragmentIdentifierForRequest = m_resourceRequest.url().fragmentIdentifier( ); | 188 m_fragmentIdentifierForRequest = m_resourceRequest.url().fragmentIdentifier( ); |
| 191 m_resourceRequest.setURL(urlForCache); | 189 m_resourceRequest.setURL(urlForCache); |
| 192 } | 190 } |
| 193 | 191 |
| 194 Resource::~Resource() | 192 Resource::~Resource() |
| 195 { | 193 { |
| 196 ASSERT(!m_resourceToRevalidate); // Should be true because canDelete() check s this. | |
| 197 ASSERT(canDelete()); | 194 ASSERT(canDelete()); |
| 198 RELEASE_ASSERT(!memoryCache()->contains(this)); | 195 RELEASE_ASSERT(!memoryCache()->contains(this)); |
| 199 RELEASE_ASSERT(!ResourceCallback::callbackHandler()->isScheduled(this)); | 196 RELEASE_ASSERT(!ResourceCallback::callbackHandler()->isScheduled(this)); |
| 200 assertAlive(); | 197 assertAlive(); |
| 201 | 198 |
| 202 #ifdef ENABLE_RESOURCE_IS_DELETED_CHECK | 199 #ifdef ENABLE_RESOURCE_IS_DELETED_CHECK |
| 203 m_deleted = true; | 200 m_deleted = true; |
| 204 #endif | 201 #endif |
| 205 #ifndef NDEBUG | 202 #ifndef NDEBUG |
| 206 cachedResourceLeakCounter.decrement(); | 203 cachedResourceLeakCounter.decrement(); |
| 207 #endif | 204 #endif |
| 208 InstanceCounters::decrementCounter(InstanceCounters::ResourceCounter); | 205 InstanceCounters::decrementCounter(InstanceCounters::ResourceCounter); |
| 209 } | 206 } |
| 210 | 207 |
| 211 void Resource::dispose() | 208 void Resource::dispose() |
| 212 { | 209 { |
| 213 } | 210 } |
| 214 | 211 |
| 215 DEFINE_TRACE(Resource) | 212 DEFINE_TRACE(Resource) |
| 216 { | 213 { |
| 217 visitor->trace(m_loader); | 214 visitor->trace(m_loader); |
| 218 visitor->trace(m_resourceToRevalidate); | |
| 219 visitor->trace(m_proxyResource); | |
| 220 #if ENABLE(OILPAN) | 215 #if ENABLE(OILPAN) |
| 221 visitor->trace(m_cacheHandler); | 216 visitor->trace(m_cacheHandler); |
| 222 #endif | 217 #endif |
| 223 } | 218 } |
| 224 | 219 |
| 225 void Resource::load(ResourceFetcher* fetcher, const ResourceLoaderOptions& optio ns) | 220 void Resource::load(ResourceFetcher* fetcher, const ResourceLoaderOptions& optio ns) |
| 226 { | 221 { |
| 227 m_options = options; | 222 m_options = options; |
| 228 m_loading = true; | 223 m_loading = true; |
| 229 | 224 |
| 225 ResourceRequest request(m_revalidatingRequest.isNull() ? m_resourceRequest : m_revalidatingRequest); | |
| 230 if (!accept().isEmpty()) | 226 if (!accept().isEmpty()) |
| 231 m_resourceRequest.setHTTPAccept(accept()); | 227 request.setHTTPAccept(accept()); |
| 232 | 228 |
| 233 // FIXME: It's unfortunate that the cache layer and below get to know anythi ng about fragment identifiers. | 229 // FIXME: It's unfortunate that the cache layer and below get to know anythi ng about fragment identifiers. |
| 234 // We should look into removing the expectation of that knowledge from the p latform network stacks. | 230 // We should look into removing the expectation of that knowledge from the p latform network stacks. |
| 235 ResourceRequest request(m_resourceRequest); | |
| 236 if (!m_fragmentIdentifierForRequest.isNull()) { | 231 if (!m_fragmentIdentifierForRequest.isNull()) { |
| 237 KURL url = request.url(); | 232 KURL url = request.url(); |
| 238 url.setFragmentIdentifier(m_fragmentIdentifierForRequest); | 233 url.setFragmentIdentifier(m_fragmentIdentifierForRequest); |
| 239 request.setURL(url); | 234 request.setURL(url); |
| 240 m_fragmentIdentifierForRequest = String(); | 235 m_fragmentIdentifierForRequest = String(); |
| 241 } | 236 } |
| 242 m_status = Pending; | 237 m_status = Pending; |
| 243 if (m_loader) { | 238 if (m_loader) { |
| 239 ASSERT(m_revalidatingRequest.isNull()); | |
| 244 RELEASE_ASSERT(m_options.synchronousPolicy == RequestSynchronously); | 240 RELEASE_ASSERT(m_options.synchronousPolicy == RequestSynchronously); |
| 245 m_loader->changeToSynchronous(); | 241 m_loader->changeToSynchronous(); |
| 246 return; | 242 return; |
| 247 } | 243 } |
| 248 m_loader = ResourceLoader::create(fetcher, this, request, options); | 244 m_loader = ResourceLoader::create(fetcher, this, request, options); |
| 249 m_loader->start(); | 245 m_loader->start(); |
| 250 } | 246 } |
| 251 | 247 |
| 252 void Resource::checkNotify() | 248 void Resource::checkNotify() |
| 253 { | 249 { |
| 254 if (isLoading()) | 250 if (isLoading()) |
| 255 return; | 251 return; |
| 256 | 252 |
| 257 ResourceClientWalker<ResourceClient> w(m_clients); | 253 ResourceClientWalker<ResourceClient> w(m_clients); |
| 258 while (ResourceClient* c = w.next()) | 254 while (ResourceClient* c = w.next()) |
| 259 c->notifyFinished(this); | 255 c->notifyFinished(this); |
| 260 } | 256 } |
| 261 | 257 |
| 262 void Resource::appendData(const char* data, unsigned length) | 258 void Resource::appendData(const char* data, unsigned length) |
| 263 { | 259 { |
| 264 TRACE_EVENT0("blink", "Resource::appendData"); | 260 TRACE_EVENT0("blink", "Resource::appendData"); |
| 265 ASSERT(!m_resourceToRevalidate); | 261 ASSERT(m_revalidatingRequest.isNull()); |
| 266 ASSERT(!errorOccurred()); | 262 ASSERT(!errorOccurred()); |
| 267 if (m_options.dataBufferingPolicy == DoNotBufferData) | 263 if (m_options.dataBufferingPolicy == DoNotBufferData) |
| 268 return; | 264 return; |
| 269 if (m_data) | 265 if (m_data) |
| 270 m_data->append(data, length); | 266 m_data->append(data, length); |
| 271 else | 267 else |
| 272 m_data = SharedBuffer::createPurgeable(data, length); | 268 m_data = SharedBuffer::createPurgeable(data, length); |
| 273 setEncodedSize(m_data->size()); | 269 setEncodedSize(m_data->size()); |
| 274 } | 270 } |
| 275 | 271 |
| 276 void Resource::setResourceBuffer(PassRefPtr<SharedBuffer> resourceBuffer) | 272 void Resource::setResourceBuffer(PassRefPtr<SharedBuffer> resourceBuffer) |
| 277 { | 273 { |
| 278 ASSERT(!m_resourceToRevalidate); | 274 ASSERT(m_revalidatingRequest.isNull()); |
| 279 ASSERT(!errorOccurred()); | 275 ASSERT(!errorOccurred()); |
| 280 ASSERT(m_options.dataBufferingPolicy == BufferData); | 276 ASSERT(m_options.dataBufferingPolicy == BufferData); |
| 281 m_data = resourceBuffer; | 277 m_data = resourceBuffer; |
| 282 setEncodedSize(m_data->size()); | 278 setEncodedSize(m_data->size()); |
| 283 } | 279 } |
| 284 | 280 |
| 285 void Resource::setDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy) | 281 void Resource::setDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy) |
| 286 { | 282 { |
| 287 m_options.dataBufferingPolicy = dataBufferingPolicy; | 283 m_options.dataBufferingPolicy = dataBufferingPolicy; |
| 288 m_data.clear(); | 284 m_data.clear(); |
| 289 setEncodedSize(0); | 285 setEncodedSize(0); |
| 290 } | 286 } |
| 291 | 287 |
| 292 void Resource::error(Resource::Status status) | 288 void Resource::error(Resource::Status status) |
| 293 { | 289 { |
| 294 if (m_resourceToRevalidate) | 290 if (!m_revalidatingRequest.isNull()) |
| 295 revalidationFailed(); | 291 m_revalidatingRequest = ResourceRequest(); |
|
Nate Chapin
2015/07/16 23:35:27
The only difference between this and the original
Yoav Weiss
2015/07/17 08:57:03
Do we have tests that caught this logic change?
| |
| 296 | 292 |
| 297 if (!m_error.isNull() && (m_error.isCancellation() || !isPreloaded())) | 293 if (!m_error.isNull() && (m_error.isCancellation() || !isPreloaded())) |
| 298 memoryCache()->remove(this); | 294 memoryCache()->remove(this); |
| 299 | 295 |
| 300 setStatus(status); | 296 setStatus(status); |
| 301 ASSERT(errorOccurred()); | 297 ASSERT(errorOccurred()); |
| 302 m_data.clear(); | 298 m_data.clear(); |
| 303 | 299 |
| 304 setLoading(false); | 300 setLoading(false); |
| 305 checkNotify(); | 301 checkNotify(); |
| 306 } | 302 } |
| 307 | 303 |
| 308 void Resource::finishOnePart() | 304 void Resource::finishOnePart() |
| 309 { | 305 { |
| 310 setLoading(false); | 306 setLoading(false); |
| 311 checkNotify(); | 307 checkNotify(); |
| 312 } | 308 } |
| 313 | 309 |
| 314 void Resource::finish() | 310 void Resource::finish() |
| 315 { | 311 { |
| 316 ASSERT(!m_resourceToRevalidate); | 312 ASSERT(m_revalidatingRequest.isNull()); |
| 317 ASSERT(!errorOccurred()); | 313 ASSERT(!errorOccurred()); |
| 318 finishOnePart(); | 314 finishOnePart(); |
| 319 if (!errorOccurred()) | 315 if (!errorOccurred()) |
| 320 m_status = Cached; | 316 m_status = Cached; |
| 321 } | 317 } |
| 322 | 318 |
| 323 bool Resource::passesAccessControlCheck(SecurityOrigin* securityOrigin) const | 319 bool Resource::passesAccessControlCheck(SecurityOrigin* securityOrigin) const |
| 324 { | 320 { |
| 325 String ignoredErrorDescription; | 321 String ignoredErrorDescription; |
| 326 return passesAccessControlCheck(securityOrigin, ignoredErrorDescription); | 322 return passesAccessControlCheck(securityOrigin, ignoredErrorDescription); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 433 } | 429 } |
| 434 | 430 |
| 435 bool Resource::unlock() | 431 bool Resource::unlock() |
| 436 { | 432 { |
| 437 if (!m_data) | 433 if (!m_data) |
| 438 return false; | 434 return false; |
| 439 | 435 |
| 440 if (!m_data->isLocked()) | 436 if (!m_data->isLocked()) |
| 441 return true; | 437 return true; |
| 442 | 438 |
| 443 if (!memoryCache()->contains(this) || hasClients() || m_handleCount > 1 || m _proxyResource || m_resourceToRevalidate || !m_loadFinishTime || !isSafeToUnlock ()) | 439 if (!memoryCache()->contains(this) || hasClients() || m_handleCount > 1 || ! m_revalidatingRequest.isNull() || !m_loadFinishTime || !isSafeToUnlock()) |
| 444 return false; | 440 return false; |
| 445 | 441 |
| 446 m_data->unlock(); | 442 m_data->unlock(); |
| 447 return true; | 443 return true; |
| 448 } | 444 } |
| 449 | 445 |
| 450 bool Resource::hasRightHandleCountApartFromCache(unsigned targetCount) const | 446 bool Resource::hasRightHandleCountApartFromCache(unsigned targetCount) const |
| 451 { | 447 { |
| 452 return m_handleCount == targetCount + (memoryCache()->contains(this) ? 1 : 0 ); | 448 return m_handleCount == targetCount + (memoryCache()->contains(this) ? 1 : 0 ); |
| 453 } | 449 } |
| 454 | 450 |
| 455 void Resource::responseReceived(const ResourceResponse& response, PassOwnPtr<Web DataConsumerHandle>) | 451 void Resource::responseReceived(const ResourceResponse& response, PassOwnPtr<Web DataConsumerHandle>) |
| 456 { | 452 { |
| 453 m_responseTimestamp = currentTime(); | |
| 454 | |
| 455 if (!m_revalidatingRequest.isNull()) { | |
| 456 if (response.httpStatusCode() == 304) { | |
| 457 revalidationSucceeded(response); | |
| 458 return; | |
| 459 } | |
| 460 revalidationFailed(); | |
| 461 } | |
| 462 | |
| 457 setResponse(response); | 463 setResponse(response); |
| 458 m_responseTimestamp = currentTime(); | |
| 459 String encoding = response.textEncodingName(); | 464 String encoding = response.textEncodingName(); |
| 460 if (!encoding.isNull()) | 465 if (!encoding.isNull()) |
| 461 setEncoding(encoding); | 466 setEncoding(encoding); |
| 462 | |
| 463 if (!m_resourceToRevalidate) | |
| 464 return; | |
| 465 if (response.httpStatusCode() == 304) | |
| 466 revalidationSucceeded(response); | |
| 467 else | |
| 468 revalidationFailed(); | |
| 469 } | 467 } |
| 470 | 468 |
| 471 void Resource::setSerializedCachedMetadata(const char* data, size_t size) | 469 void Resource::setSerializedCachedMetadata(const char* data, size_t size) |
| 472 { | 470 { |
| 473 // We only expect to receive cached metadata from the platform once. | 471 // We only expect to receive cached metadata from the platform once. |
| 474 // If this triggers, it indicates an efficiency problem which is most | 472 // If this triggers, it indicates an efficiency problem which is most |
| 475 // likely unexpected in code designed to improve performance. | 473 // likely unexpected in code designed to improve performance. |
| 476 ASSERT(!m_cachedMetadata); | 474 ASSERT(!m_cachedMetadata); |
| 477 ASSERT(!m_resourceToRevalidate); | 475 ASSERT(m_revalidatingRequest.isNull()); |
| 478 | 476 |
| 479 m_cachedMetadata = CachedMetadata::deserialize(data, size); | 477 m_cachedMetadata = CachedMetadata::deserialize(data, size); |
| 480 } | 478 } |
| 481 | 479 |
| 482 CachedMetadataHandler* Resource::cacheHandler() | 480 CachedMetadataHandler* Resource::cacheHandler() |
| 483 { | 481 { |
| 484 return m_cacheHandler.get(); | 482 return m_cacheHandler.get(); |
| 485 } | 483 } |
| 486 | 484 |
| 487 void Resource::setCachedMetadata(unsigned dataTypeID, const char* data, size_t s ize, CachedMetadataHandler::CacheType cacheType) | 485 void Resource::setCachedMetadata(unsigned dataTypeID, const char* data, size_t s ize, CachedMetadataHandler::CacheType cacheType) |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 508 { | 506 { |
| 509 m_cachedMetadata.clear(); | 507 m_cachedMetadata.clear(); |
| 510 | 508 |
| 511 if (cacheType == CachedMetadataHandler::SendToPlatform) | 509 if (cacheType == CachedMetadataHandler::SendToPlatform) |
| 512 Platform::current()->cacheMetadata(m_response.url(), m_response.response Time(), 0, 0); | 510 Platform::current()->cacheMetadata(m_response.url(), m_response.response Time(), 0, 0); |
| 513 } | 511 } |
| 514 | 512 |
| 515 bool Resource::canDelete() const | 513 bool Resource::canDelete() const |
| 516 { | 514 { |
| 517 return !hasClients() && !m_loader && !m_preloadCount && hasRightHandleCountA partFromCache(0) | 515 return !hasClients() && !m_loader && !m_preloadCount && hasRightHandleCountA partFromCache(0) |
| 518 && !m_protectorCount && !m_resourceToRevalidate && !m_proxyResource; | 516 && !m_protectorCount; |
| 519 } | 517 } |
| 520 | 518 |
| 521 bool Resource::hasOneHandle() const | 519 bool Resource::hasOneHandle() const |
| 522 { | 520 { |
| 523 return hasRightHandleCountApartFromCache(1); | 521 return hasRightHandleCountApartFromCache(1); |
| 524 } | 522 } |
| 525 | 523 |
| 526 CachedMetadata* Resource::cachedMetadata(unsigned dataTypeID) const | 524 CachedMetadata* Resource::cachedMetadata(unsigned dataTypeID) const |
| 527 { | 525 { |
| 528 if (!m_cachedMetadata || m_cachedMetadata->dataTypeID() != dataTypeID) | 526 if (!m_cachedMetadata || m_cachedMetadata->dataTypeID() != dataTypeID) |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 575 m_preloadResult = PreloadReferencedWhileComplete; | 573 m_preloadResult = PreloadReferencedWhileComplete; |
| 576 else if (m_requestedFromNetworkingLayer) | 574 else if (m_requestedFromNetworkingLayer) |
| 577 m_preloadResult = PreloadReferencedWhileLoading; | 575 m_preloadResult = PreloadReferencedWhileLoading; |
| 578 else | 576 else |
| 579 m_preloadResult = PreloadReferenced; | 577 m_preloadResult = PreloadReferenced; |
| 580 } | 578 } |
| 581 if (!hasClients()) | 579 if (!hasClients()) |
| 582 memoryCache()->makeLive(this); | 580 memoryCache()->makeLive(this); |
| 583 | 581 |
| 584 // If we have existing data to send to the new client and the resource type supprts it, send it asynchronously. | 582 // If we have existing data to send to the new client and the resource type supprts it, send it asynchronously. |
| 585 if (!m_response.isNull() && !m_proxyResource && !shouldSendCachedDataSynchro nouslyForType(type()) && !m_needsSynchronousCacheHit) { | 583 if (!m_response.isNull() && !shouldSendCachedDataSynchronouslyForType(type() ) && !m_needsSynchronousCacheHit) { |
| 586 m_clientsAwaitingCallback.add(client); | 584 m_clientsAwaitingCallback.add(client); |
| 587 ResourceCallback::callbackHandler()->schedule(this); | 585 ResourceCallback::callbackHandler()->schedule(this); |
| 588 return false; | 586 return false; |
| 589 } | 587 } |
| 590 | 588 |
| 591 m_clients.add(client); | 589 m_clients.add(client); |
| 592 return true; | 590 return true; |
| 593 } | 591 } |
| 594 | 592 |
| 595 void Resource::removeClient(ResourceClient* client) | 593 void Resource::removeClient(ResourceClient* client) |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 719 // Prevent the case when there are clients waiting but no callback scheduled . | 717 // Prevent the case when there are clients waiting but no callback scheduled . |
| 720 ASSERT(m_clientsAwaitingCallback.isEmpty() || scheduled); | 718 ASSERT(m_clientsAwaitingCallback.isEmpty() || scheduled); |
| 721 } | 719 } |
| 722 | 720 |
| 723 void Resource::prune() | 721 void Resource::prune() |
| 724 { | 722 { |
| 725 destroyDecodedDataIfPossible(); | 723 destroyDecodedDataIfPossible(); |
| 726 unlock(); | 724 unlock(); |
| 727 } | 725 } |
| 728 | 726 |
| 729 void Resource::setResourceToRevalidate(Resource* resource) | 727 |
| 728 void Resource::revalidationSucceeded(const ResourceResponse& validatingResponse) | |
| 730 { | 729 { |
| 731 ASSERT(resource); | 730 // Calling evict() can potentially delete revalidatingResource, which we use |
| 732 ASSERT(!m_resourceToRevalidate); | 731 // below. This mustn't be the case since revalidation means it is loaded |
| 733 ASSERT(resource != this); | 732 // and so canDelete() is false. |
| 734 ASSERT(m_handlesToRevalidate.isEmpty()); | 733 ASSERT(!canDelete()); |
| 735 ASSERT(resource->type() == type()); | |
| 736 | 734 |
| 737 WTF_LOG(ResourceLoading, "Resource %p setResourceToRevalidate %p", this, res ource); | |
| 738 | |
| 739 // The following assert should be investigated whenever it occurs. Although it should never fire, it currently does in rare circumstances. | |
| 740 // https://bugs.webkit.org/show_bug.cgi?id=28604. | |
| 741 // So the code needs to be robust to this assert failing thus the "if (m_res ourceToRevalidate->m_proxyResource == this)" in Resource::clearResourceToRevalid ate. | |
| 742 ASSERT(!resource->m_proxyResource); | |
| 743 | |
| 744 resource->m_proxyResource = this; | |
| 745 m_resourceToRevalidate = resource; | |
| 746 } | |
| 747 | |
| 748 void Resource::clearResourceToRevalidate() | |
| 749 { | |
| 750 ASSERT(m_resourceToRevalidate); | |
| 751 if (m_switchingClientsToRevalidatedResource) | |
| 752 return; | |
| 753 | |
| 754 // A resource may start revalidation before this method has been called, so check that this resource is still the proxy resource before clearing it out. | |
| 755 if (m_resourceToRevalidate->m_proxyResource == this) { | |
| 756 m_resourceToRevalidate->m_proxyResource = nullptr; | |
| 757 m_resourceToRevalidate->deleteIfPossible(); | |
| 758 } | |
| 759 m_handlesToRevalidate.clear(); | |
| 760 m_resourceToRevalidate = nullptr; | |
| 761 deleteIfPossible(); | |
| 762 } | |
| 763 | |
| 764 void Resource::switchClientsToRevalidatedResource() | |
| 765 { | |
| 766 ASSERT(m_resourceToRevalidate); | |
| 767 ASSERT(memoryCache()->contains(m_resourceToRevalidate)); | |
| 768 ASSERT(!memoryCache()->contains(this)); | |
| 769 | |
| 770 WTF_LOG(ResourceLoading, "Resource %p switchClientsToRevalidatedResource %p" , this, m_resourceToRevalidate.get()); | |
| 771 | |
| 772 m_resourceToRevalidate->m_identifier = m_identifier; | |
| 773 | |
| 774 m_switchingClientsToRevalidatedResource = true; | |
| 775 for (ResourcePtrBase* handle : m_handlesToRevalidate) { | |
| 776 handle->m_resource = m_resourceToRevalidate; | |
| 777 m_resourceToRevalidate->registerHandle(handle); | |
| 778 --m_handleCount; | |
| 779 } | |
| 780 ASSERT(!m_handleCount); | |
| 781 m_handlesToRevalidate.clear(); | |
| 782 | |
| 783 Vector<ResourceClient*> clientsToMove; | |
| 784 for (const auto& clientHashEntry : m_clients) { | |
| 785 unsigned count = clientHashEntry.value; | |
| 786 while (count--) | |
| 787 clientsToMove.append(clientHashEntry.key); | |
| 788 } | |
| 789 | |
| 790 unsigned moveCount = clientsToMove.size(); | |
| 791 for (unsigned n = 0; n < moveCount; ++n) | |
| 792 removeClient(clientsToMove[n]); | |
| 793 ASSERT(m_clients.isEmpty()); | |
| 794 | |
| 795 for (unsigned n = 0; n < moveCount; ++n) | |
| 796 m_resourceToRevalidate->addClientToSet(clientsToMove[n]); | |
| 797 for (unsigned n = 0; n < moveCount; ++n) { | |
| 798 // Calling didAddClient may do anything, including trying to cancel reva lidation. | |
| 799 // Assert that it didn't succeed. | |
| 800 ASSERT(m_resourceToRevalidate); | |
| 801 // Calling didAddClient for a client may end up removing another client. In that case it won't be in the set anymore. | |
| 802 if (m_resourceToRevalidate->m_clients.contains(clientsToMove[n])) | |
| 803 m_resourceToRevalidate->didAddClient(clientsToMove[n]); | |
| 804 } | |
| 805 m_switchingClientsToRevalidatedResource = false; | |
| 806 } | |
| 807 | |
| 808 void Resource::updateResponseAfterRevalidation(const ResourceResponse& validatin gResponse) | |
| 809 { | |
| 810 m_responseTimestamp = currentTime(); | 735 m_responseTimestamp = currentTime(); |
| 736 m_response.setResourceLoadTiming(validatingResponse.resourceLoadTiming()); | |
| 811 | 737 |
| 812 // RFC2616 10.3.5 | 738 // RFC2616 10.3.5 |
| 813 // Update cached headers from the 304 response | 739 // Update cached headers from the 304 response |
| 814 const HTTPHeaderMap& newHeaders = validatingResponse.httpHeaderFields(); | 740 const HTTPHeaderMap& newHeaders = validatingResponse.httpHeaderFields(); |
| 815 for (const auto& header : newHeaders) { | 741 for (const auto& header : newHeaders) { |
| 816 // Entity headers should not be sent by servers when generating a 304 | 742 // Entity headers should not be sent by servers when generating a 304 |
| 817 // response; misconfigured servers send them anyway. We shouldn't allow | 743 // response; misconfigured servers send them anyway. We shouldn't allow |
| 818 // such headers to update the original request. We'll base this on the | 744 // such headers to update the original request. We'll base this on the |
| 819 // list defined by RFC2616 7.1, with a few additions for extension heade rs | 745 // list defined by RFC2616 7.1, with a few additions for extension heade rs |
| 820 // we care about. | 746 // we care about. |
| 821 if (!shouldUpdateHeaderAfterRevalidation(header.key)) | 747 if (!shouldUpdateHeaderAfterRevalidation(header.key)) |
| 822 continue; | 748 continue; |
| 823 m_response.setHTTPHeaderField(header.key, header.value); | 749 m_response.setHTTPHeaderField(header.key, header.value); |
| 824 } | 750 } |
| 825 } | |
| 826 | 751 |
| 827 void Resource::revalidationSucceeded(const ResourceResponse& response) | |
| 828 { | |
| 829 ASSERT(m_resourceToRevalidate); | |
| 830 ASSERT(!memoryCache()->contains(m_resourceToRevalidate)); | |
| 831 ASSERT(m_resourceToRevalidate->isLoaded()); | |
| 832 | |
| 833 // Calling evict() can potentially delete revalidatingResource, which we use | |
| 834 // below. This mustn't be the case since revalidation means it is loaded | |
| 835 // and so canDelete() is false. | |
| 836 ASSERT(!canDelete()); | |
| 837 | |
| 838 m_resourceToRevalidate->updateResponseAfterRevalidation(response); | |
| 839 memoryCache()->replace(m_resourceToRevalidate, this); | |
| 840 | |
| 841 switchClientsToRevalidatedResource(); | |
| 842 assertAlive(); | 752 assertAlive(); |
| 843 // clearResourceToRevalidate deletes this. | 753 m_resourceRequest = m_revalidatingRequest; |
| 844 clearResourceToRevalidate(); | 754 m_revalidatingRequest = ResourceRequest(); |
| 845 } | 755 } |
| 846 | 756 |
| 847 void Resource::revalidationFailed() | 757 void Resource::revalidationFailed() |
| 848 { | 758 { |
| 849 ASSERT(WTF::isMainThread()); | 759 m_resourceRequest = m_revalidatingRequest; |
| 850 WTF_LOG(ResourceLoading, "Revalidation failed for %p", this); | 760 m_revalidatingRequest = ResourceRequest(); |
| 851 ASSERT(resourceToRevalidate()); | 761 m_data.clear(); |
| 852 clearResourceToRevalidate(); | 762 destroyDecodedDataForFailedRevalidation(); |
| 853 } | 763 } |
| 854 | 764 |
| 855 void Resource::registerHandle(ResourcePtrBase* h) | 765 void Resource::registerHandle(ResourcePtrBase* h) |
| 856 { | 766 { |
| 857 assertAlive(); | 767 assertAlive(); |
| 858 ++m_handleCount; | 768 ++m_handleCount; |
| 859 if (m_resourceToRevalidate) | |
| 860 m_handlesToRevalidate.add(h); | |
| 861 } | 769 } |
| 862 | 770 |
| 863 void Resource::unregisterHandle(ResourcePtrBase* h) | 771 void Resource::unregisterHandle(ResourcePtrBase* h) |
| 864 { | 772 { |
| 865 assertAlive(); | 773 assertAlive(); |
| 866 ASSERT(m_handleCount > 0); | 774 ASSERT(m_handleCount > 0); |
| 867 --m_handleCount; | 775 --m_handleCount; |
| 868 | 776 |
| 869 if (m_resourceToRevalidate) | |
| 870 m_handlesToRevalidate.remove(h); | |
| 871 | |
| 872 if (!m_handleCount) { | 777 if (!m_handleCount) { |
| 873 if (deleteIfPossible()) | 778 if (deleteIfPossible()) |
| 874 return; | 779 return; |
| 875 unlock(); | 780 unlock(); |
| 876 } else if (m_handleCount == 1 && memoryCache()->contains(this)) { | 781 } else if (m_handleCount == 1 && memoryCache()->contains(this)) { |
| 877 unlock(); | 782 unlock(); |
| 878 if (!hasClients()) | 783 if (!hasClients()) |
| 879 memoryCache()->prune(this); | 784 memoryCache()->prune(this); |
| 880 } | 785 } |
| 881 } | 786 } |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1090 return "ImportResource"; | 995 return "ImportResource"; |
| 1091 case Resource::Media: | 996 case Resource::Media: |
| 1092 return "Media"; | 997 return "Media"; |
| 1093 } | 998 } |
| 1094 ASSERT_NOT_REACHED(); | 999 ASSERT_NOT_REACHED(); |
| 1095 return "Unknown"; | 1000 return "Unknown"; |
| 1096 } | 1001 } |
| 1097 #endif // !LOG_DISABLED | 1002 #endif // !LOG_DISABLED |
| 1098 | 1003 |
| 1099 } // namespace blink | 1004 } // namespace blink |
| OLD | NEW |