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 |