| 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 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 , m_decodedSize(0) | 304 , m_decodedSize(0) |
| 305 , m_overheadSize(calculateOverheadSize()) | 305 , m_overheadSize(calculateOverheadSize()) |
| 306 , m_preloadCount(0) | 306 , m_preloadCount(0) |
| 307 , m_preloadDiscoveryTime(0.0) | 307 , m_preloadDiscoveryTime(0.0) |
| 308 , m_cacheIdentifier(MemoryCache::defaultCacheIdentifier()) | 308 , m_cacheIdentifier(MemoryCache::defaultCacheIdentifier()) |
| 309 , m_preloadResult(PreloadNotReferenced) | 309 , m_preloadResult(PreloadNotReferenced) |
| 310 , m_type(type) | 310 , m_type(type) |
| 311 , m_status(NotStarted) | 311 , m_status(NotStarted) |
| 312 , m_needsSynchronousCacheHit(false) | 312 , m_needsSynchronousCacheHit(false) |
| 313 , m_linkPreload(false) | 313 , m_linkPreload(false) |
| 314 , m_isRevalidating(false) |
| 314 { | 315 { |
| 315 ASSERT(m_type == unsigned(type)); // m_type is a bitfield, so this tests car
eless updates of the enum. | 316 ASSERT(m_type == unsigned(type)); // m_type is a bitfield, so this tests car
eless updates of the enum. |
| 316 InstanceCounters::incrementCounter(InstanceCounters::ResourceCounter); | 317 InstanceCounters::incrementCounter(InstanceCounters::ResourceCounter); |
| 317 | 318 |
| 318 // Currently we support the metadata caching only for HTTP family. | 319 // Currently we support the metadata caching only for HTTP family. |
| 319 if (m_resourceRequest.url().protocolIsInHTTPFamily()) | 320 if (m_resourceRequest.url().protocolIsInHTTPFamily()) |
| 320 m_cacheHandler = CachedMetadataHandlerImpl::create(this); | 321 m_cacheHandler = CachedMetadataHandlerImpl::create(this); |
| 321 } | 322 } |
| 322 | 323 |
| 323 Resource::~Resource() | 324 Resource::~Resource() |
| (...skipping 11 matching lines...) Expand all Loading... |
| 335 { | 336 { |
| 336 // TOOD(japhet): Temporary, out of place hack to stop a top crasher. | 337 // TOOD(japhet): Temporary, out of place hack to stop a top crasher. |
| 337 // Make this more organic. | 338 // Make this more organic. |
| 338 if (!fetcher->loadingTaskRunner()) | 339 if (!fetcher->loadingTaskRunner()) |
| 339 return; | 340 return; |
| 340 | 341 |
| 341 RELEASE_ASSERT(!m_loader); | 342 RELEASE_ASSERT(!m_loader); |
| 342 ASSERT(stillNeedsLoad()); | 343 ASSERT(stillNeedsLoad()); |
| 343 m_status = Pending; | 344 m_status = Pending; |
| 344 | 345 |
| 345 ResourceRequest& request(m_revalidatingRequest.isNull() ? m_resourceRequest
: m_revalidatingRequest); | 346 KURL url = m_resourceRequest.url(); |
| 346 KURL url = request.url(); | 347 m_resourceRequest.setAllowStoredCredentials(m_options.allowCredentials == Al
lowStoredCredentials); |
| 347 request.setAllowStoredCredentials(m_options.allowCredentials == AllowStoredC
redentials); | |
| 348 | 348 |
| 349 m_fetcherSecurityOrigin = fetcher->context().getSecurityOrigin(); | 349 m_fetcherSecurityOrigin = fetcher->context().getSecurityOrigin(); |
| 350 m_loader = ResourceLoader::create(fetcher, this); | 350 m_loader = ResourceLoader::create(fetcher, this); |
| 351 m_loader->start(request); | 351 m_loader->start(m_resourceRequest); |
| 352 // If the request reference is null (i.e., a synchronous revalidation will | 352 m_resourceRequest.setURL(url); |
| 353 // null the request), don't make the request non-null by setting the url. | |
| 354 if (!request.isNull()) | |
| 355 request.setURL(url); | |
| 356 } | 353 } |
| 357 | 354 |
| 358 void Resource::checkNotify() | 355 void Resource::checkNotify() |
| 359 { | 356 { |
| 360 if (isLoading()) | 357 if (isLoading()) |
| 361 return; | 358 return; |
| 362 | 359 |
| 363 ResourceClientWalker<ResourceClient> w(m_clients); | 360 ResourceClientWalker<ResourceClient> w(m_clients); |
| 364 while (ResourceClient* c = w.next()) | 361 while (ResourceClient* c = w.next()) |
| 365 c->notifyFinished(this); | 362 c->notifyFinished(this); |
| 366 } | 363 } |
| 367 | 364 |
| 368 void Resource::appendData(const char* data, size_t length) | 365 void Resource::appendData(const char* data, size_t length) |
| 369 { | 366 { |
| 370 TRACE_EVENT0("blink", "Resource::appendData"); | 367 TRACE_EVENT0("blink", "Resource::appendData"); |
| 371 ASSERT(m_revalidatingRequest.isNull()); | 368 DCHECK(!m_isRevalidating); |
| 372 ASSERT(!errorOccurred()); | 369 ASSERT(!errorOccurred()); |
| 373 if (m_options.dataBufferingPolicy == DoNotBufferData) | 370 if (m_options.dataBufferingPolicy == DoNotBufferData) |
| 374 return; | 371 return; |
| 375 if (m_data) | 372 if (m_data) |
| 376 m_data->append(data, length); | 373 m_data->append(data, length); |
| 377 else | 374 else |
| 378 m_data = SharedBuffer::createPurgeable(data, length); | 375 m_data = SharedBuffer::createPurgeable(data, length); |
| 379 setEncodedSize(m_data->size()); | 376 setEncodedSize(m_data->size()); |
| 380 } | 377 } |
| 381 | 378 |
| 382 void Resource::setResourceBuffer(PassRefPtr<SharedBuffer> resourceBuffer) | 379 void Resource::setResourceBuffer(PassRefPtr<SharedBuffer> resourceBuffer) |
| 383 { | 380 { |
| 384 ASSERT(m_revalidatingRequest.isNull()); | 381 DCHECK(!m_isRevalidating); |
| 385 ASSERT(!errorOccurred()); | 382 ASSERT(!errorOccurred()); |
| 386 ASSERT(m_options.dataBufferingPolicy == BufferData); | 383 ASSERT(m_options.dataBufferingPolicy == BufferData); |
| 387 m_data = resourceBuffer; | 384 m_data = resourceBuffer; |
| 388 setEncodedSize(m_data->size()); | 385 setEncodedSize(m_data->size()); |
| 389 } | 386 } |
| 390 | 387 |
| 391 void Resource::setDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy) | 388 void Resource::setDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy) |
| 392 { | 389 { |
| 393 m_options.dataBufferingPolicy = dataBufferingPolicy; | 390 m_options.dataBufferingPolicy = dataBufferingPolicy; |
| 394 m_data.clear(); | 391 m_data.clear(); |
| 395 setEncodedSize(0); | 392 setEncodedSize(0); |
| 396 } | 393 } |
| 397 | 394 |
| 398 void Resource::markClientsAndObserversFinished() | 395 void Resource::markClientsAndObserversFinished() |
| 399 { | 396 { |
| 400 while (!m_clients.isEmpty()) { | 397 while (!m_clients.isEmpty()) { |
| 401 HashCountedSet<ResourceClient*>::iterator it = m_clients.begin(); | 398 HashCountedSet<ResourceClient*>::iterator it = m_clients.begin(); |
| 402 for (int i = it->value; i; i--) { | 399 for (int i = it->value; i; i--) { |
| 403 m_finishedClients.add(it->key); | 400 m_finishedClients.add(it->key); |
| 404 m_clients.remove(it); | 401 m_clients.remove(it); |
| 405 } | 402 } |
| 406 } | 403 } |
| 407 } | 404 } |
| 408 | 405 |
| 409 void Resource::error(const ResourceError& error) | 406 void Resource::error(const ResourceError& error) |
| 410 { | 407 { |
| 411 ASSERT(!error.isNull()); | 408 ASSERT(!error.isNull()); |
| 412 m_error = error; | 409 m_error = error; |
| 413 if (!m_revalidatingRequest.isNull()) | 410 m_isRevalidating = false; |
| 414 m_revalidatingRequest = ResourceRequest(); | |
| 415 | 411 |
| 416 if (m_error.isCancellation() || !isPreloaded()) | 412 if (m_error.isCancellation() || !isPreloaded()) |
| 417 memoryCache()->remove(this); | 413 memoryCache()->remove(this); |
| 418 | 414 |
| 419 setStatus(LoadError); | 415 setStatus(LoadError); |
| 420 ASSERT(errorOccurred()); | 416 ASSERT(errorOccurred()); |
| 421 m_data.clear(); | 417 m_data.clear(); |
| 422 m_loader = nullptr; | 418 m_loader = nullptr; |
| 423 checkNotify(); | 419 checkNotify(); |
| 424 markClientsAndObserversFinished(); | 420 markClientsAndObserversFinished(); |
| 425 } | 421 } |
| 426 | 422 |
| 427 void Resource::finish(double loadFinishTime) | 423 void Resource::finish(double loadFinishTime) |
| 428 { | 424 { |
| 429 ASSERT(m_revalidatingRequest.isNull()); | 425 DCHECK(!m_isRevalidating); |
| 430 m_loadFinishTime = loadFinishTime; | 426 m_loadFinishTime = loadFinishTime; |
| 431 if (!errorOccurred()) | 427 if (!errorOccurred()) |
| 432 m_status = Cached; | 428 m_status = Cached; |
| 433 m_loader = nullptr; | 429 m_loader = nullptr; |
| 434 checkNotify(); | 430 checkNotify(); |
| 435 markClientsAndObserversFinished(); | 431 markClientsAndObserversFinished(); |
| 436 } | 432 } |
| 437 | 433 |
| 438 AtomicString Resource::httpContentType() const | 434 AtomicString Resource::httpContentType() const |
| 439 { | 435 { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 const ResourceRequest& Resource::lastResourceRequest() const | 538 const ResourceRequest& Resource::lastResourceRequest() const |
| 543 { | 539 { |
| 544 if (!m_redirectChain.size()) | 540 if (!m_redirectChain.size()) |
| 545 return m_resourceRequest; | 541 return m_resourceRequest; |
| 546 return m_redirectChain.last().m_request; | 542 return m_redirectChain.last().m_request; |
| 547 } | 543 } |
| 548 | 544 |
| 549 void Resource::setRevalidatingRequest(const ResourceRequest& request) | 545 void Resource::setRevalidatingRequest(const ResourceRequest& request) |
| 550 { | 546 { |
| 551 SECURITY_CHECK(m_redirectChain.isEmpty()); | 547 SECURITY_CHECK(m_redirectChain.isEmpty()); |
| 552 m_revalidatingRequest = request; | 548 DCHECK(!request.isNull()); |
| 549 m_isRevalidating = true; |
| 550 m_resourceRequest = request; |
| 553 m_status = NotStarted; | 551 m_status = NotStarted; |
| 554 } | 552 } |
| 555 | 553 |
| 556 void Resource::willFollowRedirect(ResourceRequest& newRequest, const ResourceRes
ponse& redirectResponse) | 554 void Resource::willFollowRedirect(ResourceRequest& newRequest, const ResourceRes
ponse& redirectResponse) |
| 557 { | 555 { |
| 558 if (!m_revalidatingRequest.isNull()) | 556 if (m_isRevalidating) |
| 559 revalidationFailed(); | 557 revalidationFailed(); |
| 560 | 558 |
| 561 newRequest.setAllowStoredCredentials(m_options.allowCredentials == AllowStor
edCredentials); | 559 newRequest.setAllowStoredCredentials(m_options.allowCredentials == AllowStor
edCredentials); |
| 562 m_redirectChain.append(RedirectPair(newRequest, redirectResponse)); | 560 m_redirectChain.append(RedirectPair(newRequest, redirectResponse)); |
| 563 } | 561 } |
| 564 | 562 |
| 565 void Resource::setResponse(const ResourceResponse& response) | 563 void Resource::setResponse(const ResourceResponse& response) |
| 566 { | 564 { |
| 567 m_response = response; | 565 m_response = response; |
| 568 if (m_response.wasFetchedViaServiceWorker()) | 566 if (m_response.wasFetchedViaServiceWorker()) |
| 569 m_cacheHandler = ServiceWorkerResponseCachedMetadataHandler::create(this
, m_fetcherSecurityOrigin.get()); | 567 m_cacheHandler = ServiceWorkerResponseCachedMetadataHandler::create(this
, m_fetcherSecurityOrigin.get()); |
| 570 } | 568 } |
| 571 | 569 |
| 572 bool Resource::unlock() | 570 bool Resource::unlock() |
| 573 { | 571 { |
| 574 if (!m_data) | 572 if (!m_data) |
| 575 return false; | 573 return false; |
| 576 | 574 |
| 577 if (!m_data->isLocked()) | 575 if (!m_data->isLocked()) |
| 578 return true; | 576 return true; |
| 579 | 577 |
| 580 if (!memoryCache()->contains(this) || hasClientsOrObservers() || !m_revalida
tingRequest.isNull() || !m_loadFinishTime || !isSafeToUnlock()) | 578 if (!memoryCache()->contains(this) || hasClientsOrObservers() || !isLoaded()
|| !isSafeToUnlock()) |
| 581 return false; | 579 return false; |
| 582 | 580 |
| 583 if (RuntimeEnabledFeatures::doNotUnlockSharedBufferEnabled()) | 581 if (RuntimeEnabledFeatures::doNotUnlockSharedBufferEnabled()) |
| 584 return false; | 582 return false; |
| 585 | 583 |
| 586 m_data->unlock(); | 584 m_data->unlock(); |
| 587 return true; | 585 return true; |
| 588 } | 586 } |
| 589 | 587 |
| 590 void Resource::responseReceived(const ResourceResponse& response, PassOwnPtr<Web
DataConsumerHandle>) | 588 void Resource::responseReceived(const ResourceResponse& response, PassOwnPtr<Web
DataConsumerHandle>) |
| 591 { | 589 { |
| 592 m_responseTimestamp = currentTime(); | 590 m_responseTimestamp = currentTime(); |
| 593 if (m_preloadDiscoveryTime) { | 591 if (m_preloadDiscoveryTime) { |
| 594 int timeSinceDiscovery = static_cast<int>(1000 * (monotonicallyIncreasin
gTime() - m_preloadDiscoveryTime)); | 592 int timeSinceDiscovery = static_cast<int>(1000 * (monotonicallyIncreasin
gTime() - m_preloadDiscoveryTime)); |
| 595 DEFINE_STATIC_LOCAL(CustomCountHistogram, preloadDiscoveryToFirstByteHis
togram, ("PreloadScanner.TTFB", 0, 10000, 50)); | 593 DEFINE_STATIC_LOCAL(CustomCountHistogram, preloadDiscoveryToFirstByteHis
togram, ("PreloadScanner.TTFB", 0, 10000, 50)); |
| 596 preloadDiscoveryToFirstByteHistogram.count(timeSinceDiscovery); | 594 preloadDiscoveryToFirstByteHistogram.count(timeSinceDiscovery); |
| 597 } | 595 } |
| 598 | 596 |
| 599 if (!m_revalidatingRequest.isNull()) { | 597 if (m_isRevalidating) { |
| 600 if (response.httpStatusCode() == 304) { | 598 if (response.httpStatusCode() == 304) { |
| 601 revalidationSucceeded(response); | 599 revalidationSucceeded(response); |
| 602 return; | 600 return; |
| 603 } | 601 } |
| 604 revalidationFailed(); | 602 revalidationFailed(); |
| 605 } | 603 } |
| 606 setResponse(response); | 604 setResponse(response); |
| 607 String encoding = response.textEncodingName(); | 605 String encoding = response.textEncodingName(); |
| 608 if (!encoding.isNull()) | 606 if (!encoding.isNull()) |
| 609 setEncoding(encoding); | 607 setEncoding(encoding); |
| 610 } | 608 } |
| 611 | 609 |
| 612 void Resource::setSerializedCachedMetadata(const char* data, size_t size) | 610 void Resource::setSerializedCachedMetadata(const char* data, size_t size) |
| 613 { | 611 { |
| 614 ASSERT(m_revalidatingRequest.isNull()); | 612 DCHECK(!m_isRevalidating); |
| 615 ASSERT(!m_response.isNull()); | 613 ASSERT(!m_response.isNull()); |
| 616 if (m_cacheHandler) | 614 if (m_cacheHandler) |
| 617 m_cacheHandler->setSerializedCachedMetadata(data, size); | 615 m_cacheHandler->setSerializedCachedMetadata(data, size); |
| 618 } | 616 } |
| 619 | 617 |
| 620 CachedMetadataHandler* Resource::cacheHandler() | 618 CachedMetadataHandler* Resource::cacheHandler() |
| 621 { | 619 { |
| 622 return m_cacheHandler.get(); | 620 return m_cacheHandler.get(); |
| 623 } | 621 } |
| 624 | 622 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 707 } | 705 } |
| 708 } | 706 } |
| 709 if (!hasClientsOrObservers()) | 707 if (!hasClientsOrObservers()) |
| 710 memoryCache()->makeLive(this); | 708 memoryCache()->makeLive(this); |
| 711 } | 709 } |
| 712 | 710 |
| 713 void Resource::addClient(ResourceClient* client) | 711 void Resource::addClient(ResourceClient* client) |
| 714 { | 712 { |
| 715 willAddClientOrObserver(); | 713 willAddClientOrObserver(); |
| 716 | 714 |
| 717 if (!m_revalidatingRequest.isNull()) { | 715 if (m_isRevalidating) { |
| 718 m_clients.add(client); | 716 m_clients.add(client); |
| 719 return; | 717 return; |
| 720 } | 718 } |
| 721 | 719 |
| 722 // If we have existing data to send to the new client and the resource type
supprts it, send it asynchronously. | 720 // If we have existing data to send to the new client and the resource type
supprts it, send it asynchronously. |
| 723 if (!m_response.isNull() && !shouldSendCachedDataSynchronouslyForType(getTyp
e()) && !m_needsSynchronousCacheHit) { | 721 if (!m_response.isNull() && !shouldSendCachedDataSynchronouslyForType(getTyp
e()) && !m_needsSynchronousCacheHit) { |
| 724 m_clientsAwaitingCallback.add(client); | 722 m_clientsAwaitingCallback.add(client); |
| 725 ResourceCallback::callbackHandler().schedule(this); | 723 ResourceCallback::callbackHandler().schedule(this); |
| 726 return; | 724 return; |
| 727 } | 725 } |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 928 // Entity headers should not be sent by servers when generating a 304 | 926 // Entity headers should not be sent by servers when generating a 304 |
| 929 // response; misconfigured servers send them anyway. We shouldn't allow | 927 // response; misconfigured servers send them anyway. We shouldn't allow |
| 930 // such headers to update the original request. We'll base this on the | 928 // such headers to update the original request. We'll base this on the |
| 931 // list defined by RFC2616 7.1, with a few additions for extension heade
rs | 929 // list defined by RFC2616 7.1, with a few additions for extension heade
rs |
| 932 // we care about. | 930 // we care about. |
| 933 if (!shouldUpdateHeaderAfterRevalidation(header.key)) | 931 if (!shouldUpdateHeaderAfterRevalidation(header.key)) |
| 934 continue; | 932 continue; |
| 935 m_response.setHTTPHeaderField(header.key, header.value); | 933 m_response.setHTTPHeaderField(header.key, header.value); |
| 936 } | 934 } |
| 937 | 935 |
| 938 m_resourceRequest = m_revalidatingRequest; | 936 m_isRevalidating = false; |
| 939 m_revalidatingRequest = ResourceRequest(); | |
| 940 } | 937 } |
| 941 | 938 |
| 942 void Resource::revalidationFailed() | 939 void Resource::revalidationFailed() |
| 943 { | 940 { |
| 944 m_resourceRequest = m_revalidatingRequest; | |
| 945 m_revalidatingRequest = ResourceRequest(); | |
| 946 SECURITY_CHECK(m_redirectChain.isEmpty()); | 941 SECURITY_CHECK(m_redirectChain.isEmpty()); |
| 947 m_data.clear(); | 942 m_data.clear(); |
| 948 m_cacheHandler.clear(); | 943 m_cacheHandler.clear(); |
| 949 destroyDecodedDataForFailedRevalidation(); | 944 destroyDecodedDataForFailedRevalidation(); |
| 945 m_isRevalidating = false; |
| 950 } | 946 } |
| 951 | 947 |
| 952 bool Resource::canReuseRedirectChain() | 948 bool Resource::canReuseRedirectChain() |
| 953 { | 949 { |
| 954 for (auto& redirect : m_redirectChain) { | 950 for (auto& redirect : m_redirectChain) { |
| 955 if (!canUseResponse(redirect.m_redirectResponse, m_responseTimestamp)) | 951 if (!canUseResponse(redirect.m_redirectResponse, m_responseTimestamp)) |
| 956 return false; | 952 return false; |
| 957 if (redirect.m_request.cacheControlContainsNoCache() || redirect.m_reque
st.cacheControlContainsNoStore()) | 953 if (redirect.m_request.cacheControlContainsNoCache() || redirect.m_reque
st.cacheControlContainsNoStore()) |
| 958 return false; | 954 return false; |
| 959 } | 955 } |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1149 case Resource::Media: | 1145 case Resource::Media: |
| 1150 return "Media"; | 1146 return "Media"; |
| 1151 case Resource::Manifest: | 1147 case Resource::Manifest: |
| 1152 return "Manifest"; | 1148 return "Manifest"; |
| 1153 } | 1149 } |
| 1154 ASSERT_NOT_REACHED(); | 1150 ASSERT_NOT_REACHED(); |
| 1155 return "Unknown"; | 1151 return "Unknown"; |
| 1156 } | 1152 } |
| 1157 | 1153 |
| 1158 } // namespace blink | 1154 } // namespace blink |
| OLD | NEW |