| 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 | 5 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All |
| 6 rights reserved. | 6 rights reserved. |
| 7 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ | 7 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ |
| 8 | 8 |
| 9 This library is free software; you can redistribute it and/or | 9 This library is free software; you can redistribute it and/or |
| 10 modify it under the terms of the GNU Library General Public | 10 modify it under the terms of the GNU Library General Public |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 if (params.IsSpeculativePreload() || params.IsLinkPreload()) { | 486 if (params.IsSpeculativePreload() || params.IsLinkPreload()) { |
| 487 DEFINE_RESOURCE_HISTOGRAM("Preload."); | 487 DEFINE_RESOURCE_HISTOGRAM("Preload."); |
| 488 } else { | 488 } else { |
| 489 DEFINE_RESOURCE_HISTOGRAM(""); | 489 DEFINE_RESOURCE_HISTOGRAM(""); |
| 490 } | 490 } |
| 491 | 491 |
| 492 // Aims to count Resource only referenced from MemoryCache (i.e. what would be | 492 // Aims to count Resource only referenced from MemoryCache (i.e. what would be |
| 493 // dead if MemoryCache holds weak references to Resource). Currently we check | 493 // dead if MemoryCache holds weak references to Resource). Currently we check |
| 494 // references to Resource from ResourceClient and |m_preloads| only, because | 494 // references to Resource from ResourceClient and |m_preloads| only, because |
| 495 // they are major sources of references. | 495 // they are major sources of references. |
| 496 if (resource && !resource->IsAlive() && !ContainsAsPreload(resource)) { | 496 if (resource && !resource->IsAlive() && !preloads_.Contains(resource)) { |
| 497 DEFINE_RESOURCE_HISTOGRAM("Dead."); | 497 DEFINE_RESOURCE_HISTOGRAM("Dead."); |
| 498 } | 498 } |
| 499 } | 499 } |
| 500 | 500 |
| 501 bool ResourceFetcher::ContainsAsPreload(Resource* resource) const { | |
| 502 auto it = preloads_.find(PreloadKey(resource->Url(), resource->GetType())); | |
| 503 return it != preloads_.end() && it->value == resource; | |
| 504 } | |
| 505 | |
| 506 void ResourceFetcher::RemovePreload(Resource* resource) { | |
| 507 auto it = preloads_.find(PreloadKey(resource->Url(), resource->GetType())); | |
| 508 if (it == preloads_.end()) | |
| 509 return; | |
| 510 if (it->value == resource) { | |
| 511 resource->DecreasePreloadCount(); | |
| 512 preloads_.erase(it); | |
| 513 } | |
| 514 } | |
| 515 | |
| 516 ResourceFetcher::PrepareRequestResult ResourceFetcher::PrepareRequest( | 501 ResourceFetcher::PrepareRequestResult ResourceFetcher::PrepareRequest( |
| 517 FetchParameters& params, | 502 FetchParameters& params, |
| 518 const ResourceFactory& factory, | 503 const ResourceFactory& factory, |
| 519 const SubstituteData& substitute_data, | 504 const SubstituteData& substitute_data, |
| 520 unsigned long identifier, | 505 unsigned long identifier, |
| 521 ResourceRequestBlockedReason& blocked_reason) { | 506 ResourceRequestBlockedReason& blocked_reason) { |
| 522 ResourceRequest& resource_request = params.MutableResourceRequest(); | 507 ResourceRequest& resource_request = params.MutableResourceRequest(); |
| 523 | 508 |
| 524 DCHECK(params.Options().synchronous_policy == kRequestAsynchronously || | 509 DCHECK(params.Options().synchronous_policy == kRequestAsynchronously || |
| 525 factory.GetType() == Resource::kRaw || | 510 factory.GetType() == Resource::kRaw || |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 612 bool is_static_data = is_data_url || substitute_data.IsValid() || archive_; | 597 bool is_static_data = is_data_url || substitute_data.IsValid() || archive_; |
| 613 if (is_static_data) { | 598 if (is_static_data) { |
| 614 resource = ResourceForStaticData(params, factory, substitute_data); | 599 resource = ResourceForStaticData(params, factory, substitute_data); |
| 615 // Abort the request if the archive doesn't contain the resource, except in | 600 // Abort the request if the archive doesn't contain the resource, except in |
| 616 // the case of data URLs which might have resources such as fonts that need | 601 // the case of data URLs which might have resources such as fonts that need |
| 617 // to be decoded only on demand. These data URLs are allowed to be | 602 // to be decoded only on demand. These data URLs are allowed to be |
| 618 // processed using the normal ResourceFetcher machinery. | 603 // processed using the normal ResourceFetcher machinery. |
| 619 if (!resource && !is_data_url && archive_) | 604 if (!resource && !is_data_url && archive_) |
| 620 return nullptr; | 605 return nullptr; |
| 621 } | 606 } |
| 622 RevalidationPolicy policy = kLoad; | |
| 623 bool preload_found = false; | |
| 624 if (!resource) { | 607 if (!resource) { |
| 625 resource = MatchPreload(params, factory.GetType()); | 608 resource = |
| 626 if (resource) { | 609 GetMemoryCache()->ResourceForURL(params.Url(), GetCacheIdentifier()); |
| 627 preload_found = true; | |
| 628 policy = kUse; | |
| 629 // If |param| is for a blocking resource and a preloaded resource is | |
| 630 // found, we may need to make it block the onload event. | |
| 631 MakePreloadedResourceBlockOnloadIfNeeded(resource, params); | |
| 632 } | |
| 633 } | 610 } |
| 634 if (!preload_found) { | |
| 635 if (!resource) { | |
| 636 resource = | |
| 637 GetMemoryCache()->ResourceForURL(params.Url(), GetCacheIdentifier()); | |
| 638 } | |
| 639 | 611 |
| 640 policy = DetermineRevalidationPolicy(factory.GetType(), params, resource, | 612 // If we got a preloaded resource from the cache for a non-preload request, |
| 641 is_static_data); | 613 // we may need to make it block the onload event. |
| 642 TRACE_EVENT_INSTANT1( | 614 MakePreloadedResourceBlockOnloadIfNeeded(resource, params); |
| 643 "blink", "ResourceFetcher::determineRevalidationPolicy", | 615 |
| 644 TRACE_EVENT_SCOPE_THREAD, "revalidationPolicy", policy); | 616 const RevalidationPolicy policy = DetermineRevalidationPolicy( |
| 645 } | 617 factory.GetType(), params, resource, is_static_data); |
| 618 TRACE_EVENT_INSTANT1("blink", "ResourceFetcher::determineRevalidationPolicy", |
| 619 TRACE_EVENT_SCOPE_THREAD, "revalidationPolicy", policy); |
| 646 | 620 |
| 647 UpdateMemoryCacheStats(resource, policy, params, factory, is_static_data); | 621 UpdateMemoryCacheStats(resource, policy, params, factory, is_static_data); |
| 648 | 622 |
| 649 switch (policy) { | 623 switch (policy) { |
| 650 case kReload: | 624 case kReload: |
| 651 GetMemoryCache()->Remove(resource); | 625 GetMemoryCache()->Remove(resource); |
| 652 // Fall through | 626 // Fall through |
| 653 case kLoad: | 627 case kLoad: |
| 654 resource = CreateResourceForLoading(params, params.Charset(), factory); | 628 resource = CreateResourceForLoading(params, params.Charset(), factory); |
| 655 break; | 629 break; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 // If only the fragment identifiers differ, it is the same resource. | 662 // If only the fragment identifiers differ, it is the same resource. |
| 689 DCHECK(EqualIgnoringFragmentIdentifier(resource->Url(), params.Url())); | 663 DCHECK(EqualIgnoringFragmentIdentifier(resource->Url(), params.Url())); |
| 690 RequestLoadStarted(identifier, resource, params, policy, is_static_data); | 664 RequestLoadStarted(identifier, resource, params, policy, is_static_data); |
| 691 document_resources_.Set( | 665 document_resources_.Set( |
| 692 MemoryCache::RemoveFragmentIdentifierIfNeeded(params.Url()), resource); | 666 MemoryCache::RemoveFragmentIdentifierIfNeeded(params.Url()), resource); |
| 693 | 667 |
| 694 // Returns with an existing resource if the resource does not need to start | 668 // Returns with an existing resource if the resource does not need to start |
| 695 // loading immediately. If revalidation policy was determined as |Revalidate|, | 669 // loading immediately. If revalidation policy was determined as |Revalidate|, |
| 696 // the resource was already initialized for the revalidation here, but won't | 670 // the resource was already initialized for the revalidation here, but won't |
| 697 // start loading. | 671 // start loading. |
| 698 if (!ResourceNeedsLoad(resource, params, policy)) { | 672 if (!ResourceNeedsLoad(resource, params, policy)) |
| 699 if (policy != kUse) | |
| 700 InsertAsPreloadIfNecessary(resource, params, factory.GetType()); | |
| 701 return resource; | 673 return resource; |
| 702 } | |
| 703 | 674 |
| 704 if (!StartLoad(resource)) | 675 if (!StartLoad(resource)) |
| 705 return nullptr; | 676 return nullptr; |
| 706 | |
| 707 if (policy != kUse) | |
| 708 InsertAsPreloadIfNecessary(resource, params, factory.GetType()); | |
| 709 scoped_resource_load_tracker.ResourceLoadContinuesBeyondScope(); | 677 scoped_resource_load_tracker.ResourceLoadContinuesBeyondScope(); |
| 710 | 678 |
| 711 DCHECK(!resource->ErrorOccurred() || | 679 DCHECK(!resource->ErrorOccurred() || |
| 712 params.Options().synchronous_policy == kRequestSynchronously); | 680 params.Options().synchronous_policy == kRequestSynchronously); |
| 713 return resource; | 681 return resource; |
| 714 } | 682 } |
| 715 | 683 |
| 716 void ResourceFetcher::ResourceTimingReportTimerFired(TimerBase* timer) { | 684 void ResourceFetcher::ResourceTimingReportTimerFired(TimerBase* timer) { |
| 717 DCHECK_EQ(timer, &resource_timing_report_timer_); | 685 DCHECK_EQ(timer, &resource_timing_report_timer_); |
| 718 Vector<RefPtr<ResourceTimingInfo>> timing_reports; | 686 Vector<RefPtr<ResourceTimingInfo>> timing_reports; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 852 if (it != resource_timing_info_map_.end()) { | 820 if (it != resource_timing_info_map_.end()) { |
| 853 it->value->AddRedirect(redirect_response, cross_origin); | 821 it->value->AddRedirect(redirect_response, cross_origin); |
| 854 } | 822 } |
| 855 | 823 |
| 856 if (resource->GetType() == Resource::kMainResource) { | 824 if (resource->GetType() == Resource::kMainResource) { |
| 857 DCHECK(navigation_timing_info_); | 825 DCHECK(navigation_timing_info_); |
| 858 navigation_timing_info_->AddRedirect(redirect_response, cross_origin); | 826 navigation_timing_info_->AddRedirect(redirect_response, cross_origin); |
| 859 } | 827 } |
| 860 } | 828 } |
| 861 | 829 |
| 862 Resource* ResourceFetcher::MatchPreload(const FetchParameters& params, | 830 ResourceFetcher::RevalidationPolicy |
| 863 Resource::Type type) { | 831 ResourceFetcher::DetermineRevalidationPolicy( |
| 864 auto it = preloads_.find(PreloadKey(params.Url(), type)); | 832 Resource::Type type, |
| 865 if (it == preloads_.end()) | 833 const FetchParameters& fetch_params, |
| 866 return nullptr; | 834 Resource* existing_resource, |
| 835 bool is_static_data) const { |
| 836 const ResourceRequest& request = fetch_params.GetResourceRequest(); |
| 867 | 837 |
| 868 Resource* resource = it->value; | 838 if (!existing_resource) |
| 839 return kLoad; |
| 869 | 840 |
| 870 RecordSriResourceIntegrityMismatchEvent(kCheckingForIntegrityMismatch); | 841 // If the existing resource is loading and the associated fetcher is not equal |
| 871 if (resource->MustRefetchDueToIntegrityMetadata(params)) | 842 // to |this|, we must not use the resource. Otherwise, CSP violation may |
| 872 return nullptr; | 843 // happen in redirect handling. |
| 873 | 844 if (existing_resource->Loader() && |
| 874 if (params.IsSpeculativePreload()) | 845 existing_resource->Loader()->Fetcher() != this) { |
| 875 return resource; | 846 return kReload; |
| 876 if (params.IsLinkPreload()) { | |
| 877 resource->SetLinkPreload(true); | |
| 878 return resource; | |
| 879 } | 847 } |
| 880 | 848 |
| 881 if (!IsReusableForPreloading(params, resource, false)) | 849 // Checks if the resource has an explicit policy about integrity metadata. |
| 882 return nullptr; | 850 // |
| 851 // This is necessary because ScriptResource and CSSStyleSheetResource objects |
| 852 // do not keep the raw data around after the source is accessed once, so if |
| 853 // the resource is accessed from the MemoryCache for a second time, there is |
| 854 // no way to redo an integrity check. |
| 855 // |
| 856 // Thus, Blink implements a scheme where it caches the integrity information |
| 857 // for those resources after the first time it is checked, and if there is |
| 858 // another request for that resource, with the same integrity metadata, Blink |
| 859 // skips the integrity calculation. However, if the integrity metadata is a |
| 860 // mismatch, the MemoryCache must be skipped here, and a new request for the |
| 861 // resource must be made to get the raw data. This is expected to be an |
| 862 // uncommon case, however, as it implies two same-origin requests to the same |
| 863 // resource, but with different integrity metadata. |
| 864 RecordSriResourceIntegrityMismatchEvent(kCheckingForIntegrityMismatch); |
| 865 if (existing_resource->MustRefetchDueToIntegrityMetadata(fetch_params)) { |
| 866 RecordSriResourceIntegrityMismatchEvent(kRefetchDueToIntegrityMismatch); |
| 867 return kReload; |
| 868 } |
| 883 | 869 |
| 884 resource->DecreasePreloadCount(); | 870 // If the same URL has been loaded as a different type, we need to reload. |
| 885 preloads_.erase(it); | 871 if (existing_resource->GetType() != type) { |
| 886 return resource; | 872 // FIXME: If existingResource is a Preload and the new type is LinkPrefetch |
| 887 } | 873 // We really should discard the new prefetch since the preload has more |
| 874 // specific type information! crbug.com/379893 |
| 875 // fast/dom/HTMLLinkElement/link-and-subresource-test hits this case. |
| 876 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " |
| 877 "reloading due to type mismatch."; |
| 878 return kReload; |
| 879 } |
| 888 | 880 |
| 889 void ResourceFetcher::InsertAsPreloadIfNecessary(Resource* resource, | 881 // We already have a preload going for this URL. |
| 890 const FetchParameters& params, | 882 if (fetch_params.IsSpeculativePreload() && existing_resource->IsPreloaded()) |
| 891 Resource::Type type) { | 883 return kUse; |
| 892 if (!params.IsSpeculativePreload() && !params.IsLinkPreload()) | |
| 893 return; | |
| 894 // CSP layout tests verify that preloads are subject to access checks by | |
| 895 // seeing if they are in the `preload started` list. Therefore do not add | |
| 896 // them to the list if the load is immediately denied. | |
| 897 if (resource->GetResourceError().IsAccessCheck()) | |
| 898 return; | |
| 899 PreloadKey key(params.Url(), type); | |
| 900 if (preloads_.find(key) == preloads_.end()) { | |
| 901 preloads_.insert(key, resource); | |
| 902 resource->IncreasePreloadCount(); | |
| 903 if (preloaded_urls_for_test_) | |
| 904 preloaded_urls_for_test_->insert(resource->Url().GetString()); | |
| 905 } | |
| 906 } | |
| 907 | 884 |
| 908 bool ResourceFetcher::IsReusableForPreloading(const FetchParameters& params, | |
| 909 Resource* existing_resource, | |
| 910 bool is_static_data) const { | |
| 911 const ResourceRequest& request = params.GetResourceRequest(); | |
| 912 // Do not load from cache if images are not enabled. There are two general | 885 // Do not load from cache if images are not enabled. There are two general |
| 913 // cases: | 886 // cases: |
| 914 // | 887 // |
| 915 // 1. Images are disabled. Don't ever load images, even if the image is cached | 888 // 1. Images are disabled. Don't ever load images, even if the image is cached |
| 916 // or it is a data: url. In this case, we "Reload" the image, then defer it | 889 // or it is a data: url. In this case, we "Reload" the image, then defer it |
| 917 // with resourceNeedsLoad() so that it never actually goes to the network. | 890 // with resourceNeedsLoad() so that it never actually goes to the network. |
| 918 // | 891 // |
| 919 // 2. Images are enabled, but not loaded automatically. In this case, we will | 892 // 2. Images are enabled, but not loaded automatically. In this case, we will |
| 920 // Use cached resources or data: urls, but will similarly fall back to a | 893 // Use cached resources or data: urls, but will similarly fall back to a |
| 921 // deferred network load if we don't have the data available without a network | 894 // deferred network load if we don't have the data available without a network |
| 922 // request. We check allowImage() here, which is affected by m_imagesEnabled | 895 // request. We check allowImage() here, which is affected by m_imagesEnabled |
| 923 // but not m_autoLoadImages, in order to allow for this differing behavior. | 896 // but not m_autoLoadImages, in order to allow for this differing behavior. |
| 924 // | 897 // |
| 925 // TODO(japhet): Can we get rid of one of these settings? | 898 // TODO(japhet): Can we get rid of one of these settings? |
| 926 if (existing_resource->IsImage() && | 899 if (existing_resource->IsImage() && |
| 927 !Context().AllowImage(images_enabled_, existing_resource->Url())) { | 900 !Context().AllowImage(images_enabled_, existing_resource->Url())) { |
| 928 return false; | 901 return kReload; |
| 929 } | 902 } |
| 930 | 903 |
| 931 // Never use cache entries for downloadToFile / useStreamOnResponse requests. | 904 // Never use cache entries for downloadToFile / useStreamOnResponse requests. |
| 932 // The data will be delivered through other paths. | 905 // The data will be delivered through other paths. |
| 933 if (request.DownloadToFile() || request.UseStreamOnResponse()) | 906 if (request.DownloadToFile() || request.UseStreamOnResponse()) |
| 934 return false; | 907 return kReload; |
| 935 | 908 |
| 936 // Never reuse opaque responses from a service worker for requests that are | 909 // Never reuse opaque responses from a service worker for requests that are |
| 937 // not no-cors. https://crbug.com/625575 | 910 // not no-cors. https://crbug.com/625575 |
| 938 if (existing_resource->GetResponse().WasFetchedViaServiceWorker() && | 911 if (existing_resource->GetResponse().WasFetchedViaServiceWorker() && |
| 939 existing_resource->GetResponse().ServiceWorkerResponseType() == | 912 existing_resource->GetResponse().ServiceWorkerResponseType() == |
| 940 kWebServiceWorkerResponseTypeOpaque && | 913 kWebServiceWorkerResponseTypeOpaque && |
| 941 request.GetFetchRequestMode() != WebURLRequest::kFetchRequestModeNoCORS) { | 914 request.GetFetchRequestMode() != WebURLRequest::kFetchRequestModeNoCORS) { |
| 942 return false; | 915 return kReload; |
| 943 } | 916 } |
| 944 | 917 |
| 945 if (!is_static_data && !existing_resource->CanReuse(params)) | 918 if (!is_static_data && !existing_resource->CanReuse(fetch_params)) |
| 946 return false; | 919 return kReload; |
| 947 | 920 |
| 948 // Certain requests (e.g., XHRs) might have manually set headers that require | 921 // Certain requests (e.g., XHRs) might have manually set headers that require |
| 949 // revalidation. In theory, this should be a Revalidate case. In practice, the | 922 // revalidation. In theory, this should be a Revalidate case. In practice, the |
| 950 // MemoryCache revalidation path assumes a whole bunch of things about how | 923 // MemoryCache revalidation path assumes a whole bunch of things about how |
| 951 // revalidation works that manual headers violate, so punt to Reload instead. | 924 // revalidation works that manual headers violate, so punt to Reload instead. |
| 952 // | 925 // |
| 953 // Similarly, a request with manually added revalidation headers can lead to a | 926 // Similarly, a request with manually added revalidation headers can lead to a |
| 954 // 304 response for a request that wasn't flagged as a revalidation attempt. | 927 // 304 response for a request that wasn't flagged as a revalidation attempt. |
| 955 // Normally, successful revalidation will maintain the original response's | 928 // Normally, successful revalidation will maintain the original response's |
| 956 // status code, but for a manual revalidation the response code remains 304. | 929 // status code, but for a manual revalidation the response code remains 304. |
| 957 // In this case, the Resource likely has insufficient context to provide a | 930 // In this case, the Resource likely has insufficient context to provide a |
| 958 // useful cache hit or revalidation. See http://crbug.com/643659 | 931 // useful cache hit or revalidation. See http://crbug.com/643659 |
| 959 if (!is_static_data && | 932 if (!is_static_data && |
| 960 (request.IsConditional() || | 933 (request.IsConditional() || |
| 961 existing_resource->GetResponse().HttpStatusCode() == 304)) { | 934 existing_resource->GetResponse().HttpStatusCode() == 304)) { |
| 962 return false; | 935 return kReload; |
| 963 } | 936 } |
| 964 | 937 |
| 965 if (!is_static_data && | 938 if (!is_static_data && |
| 966 !params.Options().CanReuseRequest(existing_resource->Options())) { | 939 !fetch_params.Options().CanReuseRequest(existing_resource->Options())) { |
| 967 return false; | |
| 968 } | |
| 969 | |
| 970 return true; | |
| 971 } | |
| 972 | |
| 973 ResourceFetcher::RevalidationPolicy | |
| 974 ResourceFetcher::DetermineRevalidationPolicy( | |
| 975 Resource::Type type, | |
| 976 const FetchParameters& fetch_params, | |
| 977 Resource* existing_resource, | |
| 978 bool is_static_data) const { | |
| 979 const ResourceRequest& request = fetch_params.GetResourceRequest(); | |
| 980 | |
| 981 if (!existing_resource) | |
| 982 return kLoad; | |
| 983 | |
| 984 // If the existing resource is loading and the associated fetcher is not equal | |
| 985 // to |this|, we must not use the resource. Otherwise, CSP violation may | |
| 986 // happen in redirect handling. | |
| 987 if (existing_resource->Loader() && | |
| 988 existing_resource->Loader()->Fetcher() != this) { | |
| 989 return kReload; | 940 return kReload; |
| 990 } | 941 } |
| 991 | 942 |
| 992 // Checks if the resource has an explicit policy about integrity metadata. | 943 // Always use preloads. |
| 993 // | 944 if (existing_resource->IsPreloaded()) |
| 994 // This is necessary because ScriptResource and CSSStyleSheetResource objects | 945 return kUse; |
| 995 // do not keep the raw data around after the source is accessed once, so if | |
| 996 // the resource is accessed from the MemoryCache for a second time, there is | |
| 997 // no way to redo an integrity check. | |
| 998 // | |
| 999 // Thus, Blink implements a scheme where it caches the integrity information | |
| 1000 // for those resources after the first time it is checked, and if there is | |
| 1001 // another request for that resource, with the same integrity metadata, Blink | |
| 1002 // skips the integrity calculation. However, if the integrity metadata is a | |
| 1003 // mismatch, the MemoryCache must be skipped here, and a new request for the | |
| 1004 // resource must be made to get the raw data. This is expected to be an | |
| 1005 // uncommon case, however, as it implies two same-origin requests to the same | |
| 1006 // resource, but with different integrity metadata. | |
| 1007 RecordSriResourceIntegrityMismatchEvent(kCheckingForIntegrityMismatch); | |
| 1008 if (existing_resource->MustRefetchDueToIntegrityMetadata(fetch_params)) { | |
| 1009 RecordSriResourceIntegrityMismatchEvent(kRefetchDueToIntegrityMismatch); | |
| 1010 return kReload; | |
| 1011 } | |
| 1012 | |
| 1013 // If the same URL has been loaded as a different type, we need to reload. | |
| 1014 if (existing_resource->GetType() != type) { | |
| 1015 // FIXME: If existingResource is a Preload and the new type is LinkPrefetch | |
| 1016 // We really should discard the new prefetch since the preload has more | |
| 1017 // specific type information! crbug.com/379893 | |
| 1018 // fast/dom/HTMLLinkElement/link-and-subresource-test hits this case. | |
| 1019 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " | |
| 1020 "reloading due to type mismatch."; | |
| 1021 return kReload; | |
| 1022 } | |
| 1023 | |
| 1024 // If |existing_resource| is not reusable as a preloaded resource, it should | |
| 1025 // not be reusable as a normal resource as well. | |
| 1026 if (!IsReusableForPreloading(fetch_params, existing_resource, is_static_data)) | |
| 1027 return kReload; | |
| 1028 | 946 |
| 1029 // If resource was populated from a SubstituteData load or data: url, use it. | 947 // If resource was populated from a SubstituteData load or data: url, use it. |
| 1030 if (is_static_data) | 948 if (is_static_data) |
| 1031 return kUse; | 949 return kUse; |
| 1032 | 950 |
| 1033 // Don't reload resources while pasting. | 951 // Don't reload resources while pasting. |
| 1034 if (allow_stale_resources_) | 952 if (allow_stale_resources_) |
| 1035 return kUse; | 953 return kUse; |
| 1036 | 954 |
| 1037 // WebCachePolicy::ReturnCacheDataElseLoad uses the cache no matter what. | 955 // WebCachePolicy::ReturnCacheDataElseLoad uses the cache no matter what. |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1178 } | 1096 } |
| 1179 | 1097 |
| 1180 int ResourceFetcher::BlockingRequestCount() const { | 1098 int ResourceFetcher::BlockingRequestCount() const { |
| 1181 return loaders_.size(); | 1099 return loaders_.size(); |
| 1182 } | 1100 } |
| 1183 | 1101 |
| 1184 int ResourceFetcher::NonblockingRequestCount() const { | 1102 int ResourceFetcher::NonblockingRequestCount() const { |
| 1185 return non_blocking_loaders_.size(); | 1103 return non_blocking_loaders_.size(); |
| 1186 } | 1104 } |
| 1187 | 1105 |
| 1106 void ResourceFetcher::PreloadStarted(Resource* resource) { |
| 1107 if (preloads_.Contains(resource)) |
| 1108 return; |
| 1109 resource->IncreasePreloadCount(); |
| 1110 |
| 1111 preloads_.insert(resource); |
| 1112 |
| 1113 if (preloaded_urls_for_test_) |
| 1114 preloaded_urls_for_test_->insert(resource->Url().GetString()); |
| 1115 } |
| 1116 |
| 1188 void ResourceFetcher::EnableIsPreloadedForTest() { | 1117 void ResourceFetcher::EnableIsPreloadedForTest() { |
| 1189 if (preloaded_urls_for_test_) | 1118 if (preloaded_urls_for_test_) |
| 1190 return; | 1119 return; |
| 1191 preloaded_urls_for_test_ = WTF::WrapUnique(new HashSet<String>); | 1120 preloaded_urls_for_test_ = WTF::WrapUnique(new HashSet<String>); |
| 1192 | 1121 |
| 1193 for (const auto& pair : preloads_) { | 1122 for (const auto& resource : preloads_) |
| 1194 Resource* resource = pair.value; | |
| 1195 preloaded_urls_for_test_->insert(resource->Url().GetString()); | 1123 preloaded_urls_for_test_->insert(resource->Url().GetString()); |
| 1196 } | |
| 1197 } | 1124 } |
| 1198 | 1125 |
| 1199 bool ResourceFetcher::IsPreloadedForTest(const KURL& url) const { | 1126 bool ResourceFetcher::IsPreloadedForTest(const KURL& url) const { |
| 1200 DCHECK(preloaded_urls_for_test_); | 1127 DCHECK(preloaded_urls_for_test_); |
| 1201 return preloaded_urls_for_test_->Contains(url.GetString()); | 1128 return preloaded_urls_for_test_->Contains(url.GetString()); |
| 1202 } | 1129 } |
| 1203 | 1130 |
| 1204 void ResourceFetcher::ClearPreloads(ClearPreloadsPolicy policy) { | 1131 void ResourceFetcher::ClearPreloads(ClearPreloadsPolicy policy) { |
| 1205 LogPreloadStats(policy); | 1132 LogPreloadStats(policy); |
| 1206 | 1133 |
| 1207 Vector<PreloadKey> keys_to_be_removed; | 1134 for (const auto& resource : preloads_) { |
| 1208 for (const auto& pair : preloads_) { | |
| 1209 Resource* resource = pair.value; | |
| 1210 if (policy == kClearAllPreloads || !resource->IsLinkPreload()) { | 1135 if (policy == kClearAllPreloads || !resource->IsLinkPreload()) { |
| 1211 resource->DecreasePreloadCount(); | 1136 resource->DecreasePreloadCount(); |
| 1212 if (resource->GetPreloadResult() == Resource::kPreloadNotReferenced) | 1137 if (resource->GetPreloadResult() == Resource::kPreloadNotReferenced) |
| 1213 GetMemoryCache()->Remove(resource); | 1138 GetMemoryCache()->Remove(resource.Get()); |
| 1214 keys_to_be_removed.push_back(pair.key); | 1139 preloads_.erase(resource); |
| 1215 } | 1140 } |
| 1216 } | 1141 } |
| 1217 preloads_.RemoveAll(keys_to_be_removed); | |
| 1218 } | 1142 } |
| 1219 | 1143 |
| 1220 void ResourceFetcher::WarnUnusedPreloads() { | 1144 void ResourceFetcher::WarnUnusedPreloads() { |
| 1221 for (const auto& pair : preloads_) { | 1145 for (const auto& resource : preloads_) { |
| 1222 Resource* resource = pair.value; | |
| 1223 if (resource && resource->IsLinkPreload() && | 1146 if (resource && resource->IsLinkPreload() && |
| 1224 resource->GetPreloadResult() == Resource::kPreloadNotReferenced) { | 1147 resource->GetPreloadResult() == Resource::kPreloadNotReferenced) { |
| 1225 Context().AddConsoleMessage( | 1148 Context().AddConsoleMessage( |
| 1226 "The resource " + resource->Url().GetString() + | 1149 "The resource " + resource->Url().GetString() + |
| 1227 " was preloaded using link preload but not used within a few " | 1150 " was preloaded using link preload but not used within a few " |
| 1228 "seconds from the window's load event. Please make sure it " | 1151 "seconds from the window's load event. Please make sure it " |
| 1229 "wasn't preloaded for nothing.", | 1152 "wasn't preloaded for nothing.", |
| 1230 FetchContext::kLogWarningMessage); | 1153 FetchContext::kLogWarningMessage); |
| 1231 } | 1154 } |
| 1232 } | 1155 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1319 | 1242 |
| 1320 resource_timing_info_map_.Take(resource); | 1243 resource_timing_info_map_.Take(resource); |
| 1321 | 1244 |
| 1322 bool is_internal_request = resource->Options().initiator_info.name == | 1245 bool is_internal_request = resource->Options().initiator_info.name == |
| 1323 FetchInitiatorTypeNames::internal; | 1246 FetchInitiatorTypeNames::internal; |
| 1324 | 1247 |
| 1325 Context().DispatchDidFail(resource->Identifier(), error, | 1248 Context().DispatchDidFail(resource->Identifier(), error, |
| 1326 resource->GetResponse().EncodedDataLength(), | 1249 resource->GetResponse().EncodedDataLength(), |
| 1327 is_internal_request); | 1250 is_internal_request); |
| 1328 | 1251 |
| 1329 if (error.IsCancellation()) | |
| 1330 RemovePreload(resource); | |
| 1331 resource->FinishAsError(error); | 1252 resource->FinishAsError(error); |
| 1332 | 1253 |
| 1333 HandleLoadCompletion(resource); | 1254 HandleLoadCompletion(resource); |
| 1334 } | 1255 } |
| 1335 | 1256 |
| 1336 void ResourceFetcher::MoveResourceLoaderToNonBlocking(ResourceLoader* loader) { | 1257 void ResourceFetcher::MoveResourceLoaderToNonBlocking(ResourceLoader* loader) { |
| 1337 DCHECK(loader); | 1258 DCHECK(loader); |
| 1338 // TODO(yoav): Convert CHECK to DCHECK if no crash reports come in. | 1259 // TODO(yoav): Convert CHECK to DCHECK if no crash reports come in. |
| 1339 CHECK(loaders_.Contains(loader)); | 1260 CHECK(loaders_.Contains(loader)); |
| 1340 non_blocking_loaders_.insert(loader); | 1261 non_blocking_loaders_.insert(loader); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1479 unsigned fonts = 0; | 1400 unsigned fonts = 0; |
| 1480 unsigned font_misses = 0; | 1401 unsigned font_misses = 0; |
| 1481 unsigned medias = 0; | 1402 unsigned medias = 0; |
| 1482 unsigned media_misses = 0; | 1403 unsigned media_misses = 0; |
| 1483 unsigned text_tracks = 0; | 1404 unsigned text_tracks = 0; |
| 1484 unsigned text_track_misses = 0; | 1405 unsigned text_track_misses = 0; |
| 1485 unsigned imports = 0; | 1406 unsigned imports = 0; |
| 1486 unsigned import_misses = 0; | 1407 unsigned import_misses = 0; |
| 1487 unsigned raws = 0; | 1408 unsigned raws = 0; |
| 1488 unsigned raw_misses = 0; | 1409 unsigned raw_misses = 0; |
| 1489 for (const auto& pair : preloads_) { | 1410 for (const auto& resource : preloads_) { |
| 1490 Resource* resource = pair.value; | |
| 1491 // Do not double count link rel preloads. These do not get cleared if the | 1411 // Do not double count link rel preloads. These do not get cleared if the |
| 1492 // ClearPreloadsPolicy is only clearing speculative markup preloads. | 1412 // ClearPreloadsPolicy is only clearing speculative markup preloads. |
| 1493 if (resource->IsLinkPreload() && | 1413 if (resource->IsLinkPreload() && |
| 1494 policy == kClearSpeculativeMarkupPreloads) { | 1414 policy == kClearSpeculativeMarkupPreloads) { |
| 1495 continue; | 1415 continue; |
| 1496 } | 1416 } |
| 1497 int miss_count = | 1417 int miss_count = |
| 1498 resource->GetPreloadResult() == Resource::kPreloadNotReferenced ? 1 : 0; | 1418 resource->GetPreloadResult() == Resource::kPreloadNotReferenced ? 1 : 0; |
| 1499 switch (resource->GetType()) { | 1419 switch (resource->GetType()) { |
| 1500 case Resource::kImage: | 1420 case Resource::kImage: |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1638 visitor->Trace(context_); | 1558 visitor->Trace(context_); |
| 1639 visitor->Trace(archive_); | 1559 visitor->Trace(archive_); |
| 1640 visitor->Trace(loaders_); | 1560 visitor->Trace(loaders_); |
| 1641 visitor->Trace(non_blocking_loaders_); | 1561 visitor->Trace(non_blocking_loaders_); |
| 1642 visitor->Trace(document_resources_); | 1562 visitor->Trace(document_resources_); |
| 1643 visitor->Trace(preloads_); | 1563 visitor->Trace(preloads_); |
| 1644 visitor->Trace(resource_timing_info_map_); | 1564 visitor->Trace(resource_timing_info_map_); |
| 1645 } | 1565 } |
| 1646 | 1566 |
| 1647 } // namespace blink | 1567 } // namespace blink |
| OLD | NEW |