/*
 * Copyright (c) 2013, Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"

#include <memory>
#include "base/optional.h"
#include "build/build_config.h"
#include "services/network/public/mojom/request_context_frame_type.mojom-shared.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-shared.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_url_loader.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
#include "third_party/blink/public/platform/web_url_response.h"
#include "third_party/blink/renderer/platform/exported/wrapped_resource_response.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/heap/member.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_info.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
#include "third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h"
#include "third_party/blink/renderer/platform/loader/fetch/raw_resource.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_error.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h"
#include "third_party/blink/renderer/platform/loader/fetch/unique_identifier.h"
#include "third_party/blink/renderer/platform/loader/testing/fetch_testing_platform_support.h"
#include "third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h"
#include "third_party/blink/renderer/platform/loader/testing/mock_resource.h"
#include "third_party/blink/renderer/platform/loader/testing/mock_resource_client.h"
#include "third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/weburl_loader_mock.h"
#include "third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/time.h"

namespace blink {

namespace {

constexpr char kTestResourceFilename[] = "white-1x1.png";
constexpr char kTestResourceMimeType[] = "image/png";
constexpr int kTestResourceSize = 103;  // size of white-1x1.png

void RegisterMockedURLLoadWithCustomResponse(const KURL& url,
                                             const ResourceResponse& response) {
  url_test_helpers::RegisterMockedURLLoadWithCustomResponse(
      url, test::PlatformTestDataPath(kTestResourceFilename),
      WrappedResourceResponse(response));
}

void RegisterMockedURLLoad(const KURL& url) {
  url_test_helpers::RegisterMockedURLLoad(
      url, test::PlatformTestDataPath(kTestResourceFilename),
      kTestResourceMimeType);
}

}  // namespace

class ResourceFetcherTest : public testing::Test {
 public:
  ResourceFetcherTest() = default;
  ~ResourceFetcherTest() override { GetMemoryCache()->EvictResources(); }

  void RunUntilIdle(FetchContext* context) {
    base::SingleThreadTaskRunner* runner =
        context->GetLoadingTaskRunner().get();
    static_cast<scheduler::FakeTaskRunner*>(runner)->RunUntilIdle();
  }

 protected:
  MockFetchContext* CreateFetchContext(
      const scoped_refptr<const SecurityOrigin> security_origin = nullptr) {
    return MakeGarbageCollected<MockFetchContext>(
        MockFetchContext::kShouldLoadNewResource, nullptr,
        std::move(security_origin));
  }
  void AddResourceToMemoryCache(Resource* resource) {
    GetMemoryCache()->Add(resource);
  }

  ScopedTestingPlatformSupport<FetchTestingPlatformSupport> platform_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ResourceFetcherTest);
};

TEST_F(ResourceFetcherTest, StartLoadAfterFrameDetach) {
  KURL secure_url("https://secureorigin.test/image.png");
  // Try to request a url. The request should fail, and a resource in an error
  // state should be returned, and no resource should be present in the cache.
  auto* fetcher = MakeGarbageCollected<ResourceFetcher>(
      *MakeGarbageCollected<NullResourceFetcherProperties>(),
      &FetchContext::NullInstance(platform_->test_task_runner()));
  ResourceRequest resource_request(secure_url);
  resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
  FetchParameters fetch_params(resource_request);
  Resource* resource = RawResource::Fetch(fetch_params, fetcher, nullptr);
  ASSERT_TRUE(resource);
  EXPECT_TRUE(resource->ErrorOccurred());
  EXPECT_TRUE(resource->GetResourceError().IsAccessCheck());
  EXPECT_FALSE(GetMemoryCache()->ResourceForURL(secure_url));

  // Start by calling StartLoad() directly, rather than via RequestResource().
  // This shouldn't crash.
  fetcher->StartLoad(RawResource::CreateForTest(
      secure_url, SecurityOrigin::CreateUniqueOpaque(), ResourceType::kRaw));
}

TEST_F(ResourceFetcherTest, UseExistingResource) {
  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* fetcher =
      MakeGarbageCollected<ResourceFetcher>(*properties, CreateFetchContext());

  KURL url("http://127.0.0.1:8000/foo.html");
  ResourceResponse response(url);
  response.SetHTTPStatusCode(200);
  response.SetHTTPHeaderField(http_names::kCacheControl, "max-age=3600");
  RegisterMockedURLLoadWithCustomResponse(url, response);

  FetchParameters fetch_params{ResourceRequest(url)};
  Resource* resource = MockResource::Fetch(fetch_params, fetcher, nullptr);
  ASSERT_TRUE(resource);
  platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
  EXPECT_TRUE(resource->IsLoaded());
  EXPECT_TRUE(GetMemoryCache()->Contains(resource));

  Resource* new_resource = MockResource::Fetch(fetch_params, fetcher, nullptr);
  EXPECT_EQ(resource, new_resource);
}

// Verify that the ad bit is copied to WillSendRequest's request when the
// response is served from the memory cache.
TEST_F(ResourceFetcherTest, WillSendRequestAdBit) {
  // Add a resource to the memory cache.
  scoped_refptr<const SecurityOrigin> source_origin =
      SecurityOrigin::CreateUniqueOpaque();
  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  MockFetchContext* context = CreateFetchContext(source_origin);
  KURL url("http://127.0.0.1:8000/foo.html");
  Resource* resource =
      RawResource::CreateForTest(url, source_origin, ResourceType::kRaw);
  AddResourceToMemoryCache(resource);
  ResourceResponse response(url);
  response.SetHTTPStatusCode(200);
  response.SetHTTPHeaderField(http_names::kCacheControl, "max-age=3600");
  resource->ResponseReceived(response, nullptr);
  resource->FinishForTest();

  // Fetch the cached resource. The request to DispatchWillSendRequest should
  // preserve the ad bit.
  auto* fetcher = MakeGarbageCollected<ResourceFetcher>(*properties, context);
  ResourceRequest resource_request(url);
  resource_request.SetIsAdResource();
  resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
  FetchParameters fetch_params(resource_request);
  platform_->GetURLLoaderMockFactory()->RegisterURL(url, WebURLResponse(), "");
  Resource* new_resource = RawResource::Fetch(fetch_params, fetcher, nullptr);

  EXPECT_EQ(resource, new_resource);
  base::Optional<ResourceRequest> new_request =
      context->RequestFromWillSendRequest();
  EXPECT_TRUE(new_request.has_value());
  EXPECT_TRUE(new_request.value().IsAdResource());
}

TEST_F(ResourceFetcherTest, Vary) {
  scoped_refptr<const SecurityOrigin> source_origin =
      SecurityOrigin::CreateUniqueOpaque();
  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  MockFetchContext* context = CreateFetchContext(source_origin);

  KURL url("http://127.0.0.1:8000/foo.html");
  Resource* resource =
      RawResource::CreateForTest(url, source_origin, ResourceType::kRaw);
  AddResourceToMemoryCache(resource);

  ResourceResponse response(url);
  response.SetHTTPStatusCode(200);
  response.SetHTTPHeaderField(http_names::kCacheControl, "max-age=3600");
  response.SetHTTPHeaderField(http_names::kVary, "*");
  resource->ResponseReceived(response, nullptr);
  resource->FinishForTest();
  ASSERT_TRUE(resource->MustReloadDueToVaryHeader(ResourceRequest(url)));

  auto* fetcher = MakeGarbageCollected<ResourceFetcher>(*properties, context);
  ResourceRequest resource_request(url);
  resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
  FetchParameters fetch_params(resource_request);
  platform_->GetURLLoaderMockFactory()->RegisterURL(url, WebURLResponse(), "");
  Resource* new_resource = RawResource::Fetch(fetch_params, fetcher, nullptr);
  EXPECT_NE(resource, new_resource);
  new_resource->Loader()->Cancel();
}

TEST_F(ResourceFetcherTest, ResourceTimingInfo) {
  auto info = ResourceTimingInfo::Create(fetch_initiator_type_names::kDocument,
                                         CurrentTimeTicks(),
                                         true /* is_main_resource */);
  info->AddFinalTransferSize(5);
  EXPECT_EQ(info->TransferSize(), 5);
  ResourceResponse redirect_response(KURL("https://example.com"));
  redirect_response.SetHTTPStatusCode(200);
  redirect_response.SetEncodedDataLength(7);
  info->AddRedirect(redirect_response, KURL("https://example.com/redirect"));
  EXPECT_EQ(info->TransferSize(), 12);
}

TEST_F(ResourceFetcherTest, VaryOnBack) {
  scoped_refptr<const SecurityOrigin> source_origin =
      SecurityOrigin::CreateUniqueOpaque();
  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  MockFetchContext* context = CreateFetchContext(source_origin);

  auto* fetcher = MakeGarbageCollected<ResourceFetcher>(*properties, context);

  KURL url("http://127.0.0.1:8000/foo.html");
  Resource* resource =
      RawResource::CreateForTest(url, source_origin, ResourceType::kRaw);
  AddResourceToMemoryCache(resource);

  ResourceResponse response(url);
  response.SetHTTPStatusCode(200);
  response.SetHTTPHeaderField(http_names::kCacheControl, "max-age=3600");
  response.SetHTTPHeaderField(http_names::kVary, "*");
  resource->ResponseReceived(response, nullptr);
  resource->FinishForTest();
  ASSERT_TRUE(resource->MustReloadDueToVaryHeader(ResourceRequest(url)));

  ResourceRequest resource_request(url);
  resource_request.SetCacheMode(mojom::FetchCacheMode::kForceCache);
  resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
  FetchParameters fetch_params(resource_request);
  Resource* new_resource = RawResource::Fetch(fetch_params, fetcher, nullptr);
  EXPECT_EQ(resource, new_resource);
}

TEST_F(ResourceFetcherTest, VaryResource) {
  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* fetcher =
      MakeGarbageCollected<ResourceFetcher>(*properties, CreateFetchContext());

  KURL url("http://127.0.0.1:8000/foo.html");
  ResourceResponse response(url);
  response.SetHTTPStatusCode(200);
  response.SetHTTPHeaderField(http_names::kCacheControl, "max-age=3600");
  response.SetHTTPHeaderField(http_names::kVary, "*");
  RegisterMockedURLLoadWithCustomResponse(url, response);

  FetchParameters fetch_params_original{ResourceRequest(url)};
  Resource* resource =
      MockResource::Fetch(fetch_params_original, fetcher, nullptr);
  ASSERT_TRUE(resource);
  platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
  ASSERT_TRUE(resource->MustReloadDueToVaryHeader(ResourceRequest(url)));

  FetchParameters fetch_params{ResourceRequest(url)};
  Resource* new_resource = MockResource::Fetch(fetch_params, fetcher, nullptr);
  EXPECT_EQ(resource, new_resource);
}

class RequestSameResourceOnComplete
    : public GarbageCollectedFinalized<RequestSameResourceOnComplete>,
      public RawResourceClient {
  USING_GARBAGE_COLLECTED_MIXIN(RequestSameResourceOnComplete);

 public:
  explicit RequestSameResourceOnComplete(FetchParameters& params,
                                         ResourceFetcher* fetcher)
      : notify_finished_called_(false),
        source_origin_(fetcher->Context().GetSecurityOrigin()) {
    MockResource::Fetch(params, fetcher, this);
  }

  void NotifyFinished(Resource* resource) override {
    EXPECT_EQ(GetResource(), resource);
    auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
    MockFetchContext* context = MakeGarbageCollected<MockFetchContext>(
        MockFetchContext::kShouldLoadNewResource, nullptr, source_origin_);
    auto* fetcher2 =
        MakeGarbageCollected<ResourceFetcher>(*properties, context);
    ResourceRequest resource_request2(GetResource()->Url());
    resource_request2.SetCacheMode(mojom::FetchCacheMode::kValidateCache);
    FetchParameters fetch_params2(resource_request2);
    Resource* resource2 = MockResource::Fetch(fetch_params2, fetcher2, nullptr);
    EXPECT_EQ(GetResource(), resource2);
    notify_finished_called_ = true;
    ClearResource();
  }
  bool NotifyFinishedCalled() const { return notify_finished_called_; }

  void Trace(blink::Visitor* visitor) override {
    RawResourceClient::Trace(visitor);
  }

  String DebugName() const override { return "RequestSameResourceOnComplete"; }

 private:
  bool notify_finished_called_;
  scoped_refptr<const SecurityOrigin> source_origin_;
};

TEST_F(ResourceFetcherTest, RevalidateWhileFinishingLoading) {
  scoped_refptr<const SecurityOrigin> source_origin =
      SecurityOrigin::CreateUniqueOpaque();
  MockFetchContext* context = CreateFetchContext(source_origin);

  KURL url("http://127.0.0.1:8000/foo.png");

  ResourceResponse response(url);
  response.SetHTTPStatusCode(200);
  response.SetHTTPHeaderField(http_names::kCacheControl, "max-age=3600");
  response.SetHTTPHeaderField(http_names::kETag, "1234567890");
  RegisterMockedURLLoadWithCustomResponse(url, response);

  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  ResourceFetcher* fetcher1 =
      MakeGarbageCollected<ResourceFetcher>(*properties, context);
  ResourceRequest request1(url);
  request1.SetHTTPHeaderField(http_names::kCacheControl, "no-cache");
  FetchParameters fetch_params1(request1);
  Persistent<RequestSameResourceOnComplete> client =
      MakeGarbageCollected<RequestSameResourceOnComplete>(fetch_params1,
                                                          fetcher1);
  platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
  EXPECT_TRUE(client->NotifyFinishedCalled());
}

// TODO(crbug.com/850785): Reenable this.
#if defined(OS_ANDROID)
#define MAYBE_DontReuseMediaDataUrl DISABLED_DontReuseMediaDataUrl
#else
#define MAYBE_DontReuseMediaDataUrl DontReuseMediaDataUrl
#endif
TEST_F(ResourceFetcherTest, MAYBE_DontReuseMediaDataUrl) {
  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* fetcher =
      MakeGarbageCollected<ResourceFetcher>(*properties, CreateFetchContext());
  ResourceRequest request(KURL("data:text/html,foo"));
  request.SetRequestContext(mojom::RequestContextType::VIDEO);
  request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
  ResourceLoaderOptions options;
  options.data_buffering_policy = kDoNotBufferData;
  options.initiator_info.name = fetch_initiator_type_names::kInternal;
  FetchParameters fetch_params(request, options);
  Resource* resource1 = RawResource::FetchMedia(fetch_params, fetcher, nullptr);
  Resource* resource2 = RawResource::FetchMedia(fetch_params, fetcher, nullptr);
  EXPECT_NE(resource1, resource2);
}

class ServeRequestsOnCompleteClient final
    : public GarbageCollectedFinalized<ServeRequestsOnCompleteClient>,
      public RawResourceClient {
  USING_GARBAGE_COLLECTED_MIXIN(ServeRequestsOnCompleteClient);

 public:
  void NotifyFinished(Resource*) override {
    Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
    ClearResource();
  }

  // No callbacks should be received except for the NotifyFinished() triggered
  // by ResourceLoader::Cancel().
  void DataSent(Resource*, unsigned long long, unsigned long long) override {
    ASSERT_TRUE(false);
  }
  void ResponseReceived(Resource*,
                        const ResourceResponse&,
                        std::unique_ptr<WebDataConsumerHandle>) override {
    ASSERT_TRUE(false);
  }
  void SetSerializedCachedMetadata(Resource*, const uint8_t*, size_t) override {
    ASSERT_TRUE(false);
  }
  void DataReceived(Resource*, const char*, size_t) override {
    ASSERT_TRUE(false);
  }
  bool RedirectReceived(Resource*,
                        const ResourceRequest&,
                        const ResourceResponse&) override {
    ADD_FAILURE();
    return true;
  }
  void DataDownloaded(Resource*, unsigned long long) override {
    ASSERT_TRUE(false);
  }
  void DidReceiveResourceTiming(Resource*, const ResourceTimingInfo&) override {
    ASSERT_TRUE(false);
  }

  void Trace(blink::Visitor* visitor) override {
    RawResourceClient::Trace(visitor);
  }

  String DebugName() const override { return "ServeRequestsOnCompleteClient"; }
};

// Regression test for http://crbug.com/594072.
// This emulates a modal dialog triggering a nested run loop inside
// ResourceLoader::Cancel(). If the ResourceLoader doesn't promptly cancel its
// WebURLLoader before notifying its clients, a nested run loop  may send a
// network response, leading to an invalid state transition in ResourceLoader.
TEST_F(ResourceFetcherTest, ResponseOnCancel) {
  KURL url("http://127.0.0.1:8000/foo.png");
  RegisterMockedURLLoad(url);

  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* fetcher =
      MakeGarbageCollected<ResourceFetcher>(*properties, CreateFetchContext());
  ResourceRequest resource_request(url);
  resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
  FetchParameters fetch_params(resource_request);
  Persistent<ServeRequestsOnCompleteClient> client =
      MakeGarbageCollected<ServeRequestsOnCompleteClient>();
  Resource* resource = RawResource::Fetch(fetch_params, fetcher, client);
  resource->Loader()->Cancel();
}

class ScopedMockRedirectRequester {
  STACK_ALLOCATED();
  WTF_MAKE_NONCOPYABLE(ScopedMockRedirectRequester);

 public:
  explicit ScopedMockRedirectRequester(MockFetchContext* context)
      : context_(context) {}

  void RegisterRedirect(const WebString& from_url, const WebString& to_url) {
    KURL redirect_url(from_url);
    WebURLResponse redirect_response;
    redirect_response.SetCurrentRequestUrl(redirect_url);
    redirect_response.SetHTTPStatusCode(301);
    redirect_response.SetHTTPHeaderField(http_names::kLocation, to_url);
    redirect_response.SetEncodedDataLength(kRedirectResponseOverheadBytes);
    Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
        redirect_url, redirect_response, "");
  }

  void RegisterFinalResource(const WebString& url) {
    KURL final_url(url);
    RegisterMockedURLLoad(final_url);
  }

  void Request(const WebString& url) {
    auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
    auto* fetcher =
        MakeGarbageCollected<ResourceFetcher>(*properties, context_);
    ResourceRequest resource_request(url);
    resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
    FetchParameters fetch_params(resource_request);
    RawResource::Fetch(fetch_params, fetcher, nullptr);
    Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
  }

 private:
  Member<MockFetchContext> context_;
};

TEST_F(ResourceFetcherTest, SameOriginRedirect) {
  const char kRedirectURL[] = "http://127.0.0.1:8000/redirect.html";
  const char kFinalURL[] = "http://127.0.0.1:8000/final.html";
  MockFetchContext* context = CreateFetchContext();
  ScopedMockRedirectRequester requester(context);
  requester.RegisterRedirect(kRedirectURL, kFinalURL);
  requester.RegisterFinalResource(kFinalURL);
  requester.Request(kRedirectURL);

  EXPECT_EQ(kRedirectResponseOverheadBytes + kTestResourceSize,
            context->GetTransferSize());
}

TEST_F(ResourceFetcherTest, CrossOriginRedirect) {
  const char kRedirectURL[] = "http://otherorigin.test/redirect.html";
  const char kFinalURL[] = "http://127.0.0.1:8000/final.html";
  MockFetchContext* context = CreateFetchContext();
  ScopedMockRedirectRequester requester(context);
  requester.RegisterRedirect(kRedirectURL, kFinalURL);
  requester.RegisterFinalResource(kFinalURL);
  requester.Request(kRedirectURL);

  EXPECT_EQ(kTestResourceSize, context->GetTransferSize());
}

TEST_F(ResourceFetcherTest, ComplexCrossOriginRedirect) {
  const char kRedirectURL1[] = "http://127.0.0.1:8000/redirect1.html";
  const char kRedirectURL2[] = "http://otherorigin.test/redirect2.html";
  const char kRedirectURL3[] = "http://127.0.0.1:8000/redirect3.html";
  const char kFinalURL[] = "http://127.0.0.1:8000/final.html";
  MockFetchContext* context = CreateFetchContext();
  ScopedMockRedirectRequester requester(context);
  requester.RegisterRedirect(kRedirectURL1, kRedirectURL2);
  requester.RegisterRedirect(kRedirectURL2, kRedirectURL3);
  requester.RegisterRedirect(kRedirectURL3, kFinalURL);
  requester.RegisterFinalResource(kFinalURL);
  requester.Request(kRedirectURL1);

  EXPECT_EQ(kTestResourceSize, context->GetTransferSize());
}

TEST_F(ResourceFetcherTest, SynchronousRequest) {
  KURL url("http://127.0.0.1:8000/foo.png");
  RegisterMockedURLLoad(url);

  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* fetcher =
      MakeGarbageCollected<ResourceFetcher>(*properties, CreateFetchContext());
  ResourceRequest resource_request(url);
  resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
  FetchParameters fetch_params(resource_request);
  fetch_params.MakeSynchronous();
  Resource* resource = RawResource::Fetch(fetch_params, fetcher, nullptr);
  EXPECT_TRUE(resource->IsLoaded());
  EXPECT_EQ(ResourceLoadPriority::kHighest,
            resource->GetResourceRequest().Priority());
}

TEST_F(ResourceFetcherTest, PingPriority) {
  KURL url("http://127.0.0.1:8000/foo.png");
  RegisterMockedURLLoad(url);

  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* fetcher =
      MakeGarbageCollected<ResourceFetcher>(*properties, CreateFetchContext());
  ResourceRequest resource_request(url);
  resource_request.SetRequestContext(mojom::RequestContextType::PING);
  FetchParameters fetch_params(resource_request);
  Resource* resource = RawResource::Fetch(fetch_params, fetcher, nullptr);
  EXPECT_EQ(ResourceLoadPriority::kVeryLow,
            resource->GetResourceRequest().Priority());
}

TEST_F(ResourceFetcherTest, PreloadResourceTwice) {
  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* fetcher =
      MakeGarbageCollected<ResourceFetcher>(*properties, CreateFetchContext());

  KURL url("http://127.0.0.1:8000/foo.png");
  RegisterMockedURLLoad(url);

  FetchParameters fetch_params_original{ResourceRequest(url)};
  fetch_params_original.SetLinkPreload(true);
  Resource* resource =
      MockResource::Fetch(fetch_params_original, fetcher, nullptr);
  ASSERT_TRUE(resource);
  EXPECT_TRUE(resource->IsLinkPreload());
  EXPECT_TRUE(fetcher->ContainsAsPreload(resource));
  platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();

  FetchParameters fetch_params{ResourceRequest(url)};
  fetch_params.SetLinkPreload(true);
  Resource* new_resource = MockResource::Fetch(fetch_params, fetcher, nullptr);
  EXPECT_EQ(resource, new_resource);
  EXPECT_TRUE(fetcher->ContainsAsPreload(resource));

  fetcher->ClearPreloads(ResourceFetcher::kClearAllPreloads);
  EXPECT_FALSE(fetcher->ContainsAsPreload(resource));
  EXPECT_FALSE(GetMemoryCache()->Contains(resource));
  EXPECT_TRUE(resource->IsUnusedPreload());
}

TEST_F(ResourceFetcherTest, LinkPreloadResourceAndUse) {
  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* fetcher =
      MakeGarbageCollected<ResourceFetcher>(*properties, CreateFetchContext());

  KURL url("http://127.0.0.1:8000/foo.png");
  RegisterMockedURLLoad(url);

  // Link preload preload scanner
  FetchParameters fetch_params_original{ResourceRequest(url)};
  fetch_params_original.SetLinkPreload(true);
  Resource* resource =
      MockResource::Fetch(fetch_params_original, fetcher, nullptr);
  ASSERT_TRUE(resource);
  EXPECT_TRUE(resource->IsLinkPreload());
  platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();

  // Resource created by preload scanner
  FetchParameters fetch_params_preload_scanner{ResourceRequest(url)};
  Resource* preload_scanner_resource =
      MockResource::Fetch(fetch_params_preload_scanner, fetcher, nullptr);
  EXPECT_EQ(resource, preload_scanner_resource);
  EXPECT_FALSE(resource->IsLinkPreload());

  // Resource created by parser
  FetchParameters fetch_params{ResourceRequest(url)};
  Persistent<MockResourceClient> client =
      MakeGarbageCollected<MockResourceClient>();
  Resource* new_resource = MockResource::Fetch(fetch_params, fetcher, client);
  EXPECT_EQ(resource, new_resource);
  EXPECT_FALSE(resource->IsLinkPreload());

  // DCL reached
  fetcher->ClearPreloads(ResourceFetcher::kClearSpeculativeMarkupPreloads);
  EXPECT_TRUE(GetMemoryCache()->Contains(resource));
  EXPECT_FALSE(resource->IsUnusedPreload());
}

TEST_F(ResourceFetcherTest, PreloadMatchWithBypassingCache) {
  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* fetcher =
      MakeGarbageCollected<ResourceFetcher>(*properties, CreateFetchContext());
  KURL url("http://127.0.0.1:8000/foo.png");
  RegisterMockedURLLoad(url);

  FetchParameters fetch_params_original{ResourceRequest(url)};
  fetch_params_original.SetLinkPreload(true);
  Resource* resource =
      MockResource::Fetch(fetch_params_original, fetcher, nullptr);
  ASSERT_TRUE(resource);
  EXPECT_TRUE(resource->IsLinkPreload());
  platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();

  FetchParameters fetch_params_second{ResourceRequest(url)};
  fetch_params_second.MutableResourceRequest().SetCacheMode(
      mojom::FetchCacheMode::kBypassCache);
  Resource* second_resource =
      MockResource::Fetch(fetch_params_second, fetcher, nullptr);
  EXPECT_EQ(resource, second_resource);
  EXPECT_FALSE(resource->IsLinkPreload());
}

TEST_F(ResourceFetcherTest, CrossFramePreloadMatchIsNotAllowed) {
  auto* properties1 = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* properties2 = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* fetcher =
      MakeGarbageCollected<ResourceFetcher>(*properties1, CreateFetchContext());
  ResourceFetcher* fetcher2 =
      MakeGarbageCollected<ResourceFetcher>(*properties2, CreateFetchContext());

  KURL url("http://127.0.0.1:8000/foo.png");
  RegisterMockedURLLoad(url);

  FetchParameters fetch_params_original{ResourceRequest(url)};
  fetch_params_original.SetLinkPreload(true);
  Resource* resource =
      MockResource::Fetch(fetch_params_original, fetcher, nullptr);
  ASSERT_TRUE(resource);
  EXPECT_TRUE(resource->IsLinkPreload());
  platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();

  FetchParameters fetch_params_second{ResourceRequest(url)};
  fetch_params_second.MutableResourceRequest().SetCacheMode(
      mojom::FetchCacheMode::kBypassCache);
  Resource* second_resource =
      MockResource::Fetch(fetch_params_second, fetcher2, nullptr);

  EXPECT_NE(resource, second_resource);
  EXPECT_TRUE(resource->IsLinkPreload());
}

TEST_F(ResourceFetcherTest, RepetitiveLinkPreloadShouldBeMerged) {
  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* fetcher =
      MakeGarbageCollected<ResourceFetcher>(*properties, CreateFetchContext());

  KURL url("http://127.0.0.1:8000/foo.png");
  RegisterMockedURLLoad(url);

  FetchParameters fetch_params_for_request{ResourceRequest(url)};
  FetchParameters fetch_params_for_preload{ResourceRequest(url)};
  fetch_params_for_preload.SetLinkPreload(true);

  Resource* resource1 =
      MockResource::Fetch(fetch_params_for_preload, fetcher, nullptr);
  ASSERT_TRUE(resource1);
  EXPECT_TRUE(resource1->IsUnusedPreload());
  EXPECT_TRUE(fetcher->ContainsAsPreload(resource1));
  platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();

  // The second preload fetch returns the first preload.
  Resource* resource2 =
      MockResource::Fetch(fetch_params_for_preload, fetcher, nullptr);
  EXPECT_TRUE(fetcher->ContainsAsPreload(resource1));
  EXPECT_TRUE(resource1->IsUnusedPreload());
  EXPECT_EQ(resource1, resource2);

  // preload matching
  Resource* resource3 =
      MockResource::Fetch(fetch_params_for_request, fetcher, nullptr);
  EXPECT_EQ(resource1, resource3);
  EXPECT_FALSE(fetcher->ContainsAsPreload(resource1));
  EXPECT_FALSE(resource1->IsUnusedPreload());
}

TEST_F(ResourceFetcherTest, RepetitiveSpeculativePreloadShouldBeMerged) {
  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* fetcher =
      MakeGarbageCollected<ResourceFetcher>(*properties, CreateFetchContext());

  KURL url("http://127.0.0.1:8000/foo.png");
  RegisterMockedURLLoad(url);

  FetchParameters fetch_params_for_request{ResourceRequest(url)};
  FetchParameters fetch_params_for_preload{ResourceRequest(url)};
  fetch_params_for_preload.SetSpeculativePreloadType(
      FetchParameters::SpeculativePreloadType::kInDocument);

  Resource* resource1 =
      MockResource::Fetch(fetch_params_for_preload, fetcher, nullptr);
  ASSERT_TRUE(resource1);
  EXPECT_TRUE(resource1->IsUnusedPreload());
  EXPECT_TRUE(fetcher->ContainsAsPreload(resource1));
  platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();

  // The second preload fetch returns the first preload.
  Resource* resource2 =
      MockResource::Fetch(fetch_params_for_preload, fetcher, nullptr);
  EXPECT_TRUE(fetcher->ContainsAsPreload(resource1));
  EXPECT_TRUE(resource1->IsUnusedPreload());
  EXPECT_EQ(resource1, resource2);

  // preload matching
  Resource* resource3 =
      MockResource::Fetch(fetch_params_for_request, fetcher, nullptr);
  EXPECT_EQ(resource1, resource3);
  EXPECT_FALSE(fetcher->ContainsAsPreload(resource1));
  EXPECT_FALSE(resource1->IsUnusedPreload());
}

TEST_F(ResourceFetcherTest, SpeculativePreloadShouldBePromotedToLinkePreload) {
  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* fetcher =
      MakeGarbageCollected<ResourceFetcher>(*properties, CreateFetchContext());

  KURL url("http://127.0.0.1:8000/foo.png");
  RegisterMockedURLLoad(url);

  FetchParameters fetch_params_for_request{ResourceRequest(url)};
  FetchParameters fetch_params_for_speculative_preload{ResourceRequest(url)};
  fetch_params_for_speculative_preload.SetSpeculativePreloadType(
      FetchParameters::SpeculativePreloadType::kInDocument);
  FetchParameters fetch_params_for_link_preload{ResourceRequest(url)};
  fetch_params_for_link_preload.SetLinkPreload(true);

  Resource* resource1 = MockResource::Fetch(
      fetch_params_for_speculative_preload, fetcher, nullptr);
  ASSERT_TRUE(resource1);
  EXPECT_TRUE(resource1->IsUnusedPreload());
  EXPECT_FALSE(resource1->IsLinkPreload());
  EXPECT_TRUE(fetcher->ContainsAsPreload(resource1));
  platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();

  // The second preload fetch returns the first preload.
  Resource* resource2 =
      MockResource::Fetch(fetch_params_for_link_preload, fetcher, nullptr);
  EXPECT_TRUE(fetcher->ContainsAsPreload(resource1));
  EXPECT_TRUE(resource1->IsUnusedPreload());
  EXPECT_TRUE(resource1->IsLinkPreload());
  EXPECT_EQ(resource1, resource2);

  // preload matching
  Resource* resource3 =
      MockResource::Fetch(fetch_params_for_request, fetcher, nullptr);
  EXPECT_EQ(resource1, resource3);
  EXPECT_FALSE(fetcher->ContainsAsPreload(resource1));
  EXPECT_FALSE(resource1->IsUnusedPreload());
  EXPECT_FALSE(resource1->IsLinkPreload());
}

TEST_F(ResourceFetcherTest, Revalidate304) {
  scoped_refptr<const SecurityOrigin> source_origin =
      SecurityOrigin::CreateUniqueOpaque();
  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  MockFetchContext* context = CreateFetchContext(source_origin);

  KURL url("http://127.0.0.1:8000/foo.html");
  Resource* resource =
      RawResource::CreateForTest(url, source_origin, ResourceType::kRaw);
  AddResourceToMemoryCache(resource);

  ResourceResponse response(url);
  response.SetHTTPStatusCode(304);
  response.SetHTTPHeaderField("etag", "1234567890");
  resource->ResponseReceived(response, nullptr);
  resource->FinishForTest();

  auto* fetcher = MakeGarbageCollected<ResourceFetcher>(*properties, context);
  ResourceRequest resource_request(url);
  resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
  FetchParameters fetch_params(resource_request);
  platform_->GetURLLoaderMockFactory()->RegisterURL(url, WebURLResponse(), "");
  Resource* new_resource = RawResource::Fetch(fetch_params, fetcher, nullptr);
  fetcher->StopFetching();

  EXPECT_NE(resource, new_resource);
}

TEST_F(ResourceFetcherTest, LinkPreloadResourceMultipleFetchersAndMove) {
  auto* properties1 = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* properties2 = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* fetcher =
      MakeGarbageCollected<ResourceFetcher>(*properties1, CreateFetchContext());
  ResourceFetcher* fetcher2 =
      MakeGarbageCollected<ResourceFetcher>(*properties2, CreateFetchContext());

  KURL url("http://127.0.0.1:8000/foo.png");
  RegisterMockedURLLoad(url);

  FetchParameters fetch_params_original{ResourceRequest(url)};
  fetch_params_original.SetLinkPreload(true);
  Resource* resource =
      MockResource::Fetch(fetch_params_original, fetcher, nullptr);
  ASSERT_TRUE(resource);
  EXPECT_TRUE(resource->IsLinkPreload());
  EXPECT_EQ(0, fetcher->BlockingRequestCount());

  // Resource created by parser on the second fetcher
  FetchParameters fetch_params2{ResourceRequest(url)};
  Persistent<MockResourceClient> client2 =
      MakeGarbageCollected<MockResourceClient>();
  Resource* new_resource2 =
      MockResource::Fetch(fetch_params2, fetcher2, client2);
  EXPECT_NE(resource, new_resource2);
  EXPECT_EQ(0, fetcher2->BlockingRequestCount());
  platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
}

// TODO(crbug.com/850785): Reenable this.
#if defined(OS_ANDROID)
#define MAYBE_ContentTypeDataURL DISABLED_ContentTypeDataURL
#else
#define MAYBE_ContentTypeDataURL ContentTypeDataURL
#endif
TEST_F(ResourceFetcherTest, MAYBE_ContentTypeDataURL) {
  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* fetcher =
      MakeGarbageCollected<ResourceFetcher>(*properties, CreateFetchContext());
  FetchParameters fetch_params{ResourceRequest("data:text/testmimetype,foo")};
  Resource* resource = MockResource::Fetch(fetch_params, fetcher, nullptr);
  ASSERT_TRUE(resource);
  EXPECT_EQ(ResourceStatus::kCached, resource->GetStatus());
  EXPECT_EQ("text/testmimetype", resource->GetResponse().MimeType());
  EXPECT_EQ("text/testmimetype", resource->GetResponse().HttpContentType());
}

// Request with the Content-ID scheme must not be canceled, even if there is no
// MHTMLArchive to serve them.
// Note: Not blocking it is important because there are some embedders of
// Android WebView that are intercepting Content-ID URLs and serve their own
// resources. Please see https://crbug.com/739658.
TEST_F(ResourceFetcherTest, ContentIdURL) {
  KURL url("cid:0123456789@example.com");
  ResourceResponse response(url);
  response.SetHTTPStatusCode(200);
  RegisterMockedURLLoadWithCustomResponse(url, response);

  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* fetcher =
      MakeGarbageCollected<ResourceFetcher>(*properties, CreateFetchContext());

  // Main resource case.
  {
    ResourceRequest resource_request(url);
    resource_request.SetRequestContext(mojom::RequestContextType::IFRAME);
    resource_request.SetFrameType(
        network::mojom::RequestContextFrameType::kNested);
    FetchParameters fetch_params(resource_request);
    RawResource* resource = RawResource::FetchMainResource(
        fetch_params, fetcher, nullptr, SubstituteData(),
        CreateUniqueIdentifier());
    ASSERT_NE(nullptr, resource);
    EXPECT_FALSE(resource->ErrorOccurred());
  }

  // Subresource case.
  {
    ResourceRequest resource_request(url);
    resource_request.SetRequestContext(mojom::RequestContextType::VIDEO);
    FetchParameters fetch_params(resource_request);
    RawResource* resource =
        RawResource::FetchMedia(fetch_params, fetcher, nullptr);
    ASSERT_NE(nullptr, resource);
    EXPECT_FALSE(resource->ErrorOccurred());
  }
}

TEST_F(ResourceFetcherTest, StaleWhileRevalidate) {
  scoped_refptr<const SecurityOrigin> source_origin =
      SecurityOrigin::CreateUniqueOpaque();
  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  MockFetchContext* context = CreateFetchContext(source_origin);
  auto* fetcher = MakeGarbageCollected<ResourceFetcher>(*properties, context);

  KURL url("http://127.0.0.1:8000/foo.html");
  FetchParameters fetch_params{ResourceRequest(url)};

  ResourceResponse response(url);
  response.SetHTTPStatusCode(200);
  response.SetHTTPHeaderField(http_names::kCacheControl,
                              "max-age=0, stale-while-revalidate=40");

  RegisterMockedURLLoadWithCustomResponse(url, response);
  Resource* resource = MockResource::Fetch(fetch_params, fetcher, nullptr);
  ASSERT_TRUE(resource);

  platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
  EXPECT_TRUE(resource->IsLoaded());
  EXPECT_TRUE(GetMemoryCache()->Contains(resource));

  fetcher->SetStaleWhileRevalidateEnabled(true);
  ResourceRequest resource_request(url);
  resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
  fetch_params = FetchParameters(resource_request);
  Resource* new_resource = MockResource::Fetch(fetch_params, fetcher, nullptr);
  EXPECT_EQ(resource, new_resource);
  platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
  EXPECT_TRUE(resource->IsLoaded());

  // Advance the clock, make sure the original resource gets removed from the
  // memory cache after the revalidation completes.
  platform_->AdvanceClockSeconds(1);
  ResourceResponse revalidate_response(url);
  revalidate_response.SetHTTPStatusCode(200);
  platform_->GetURLLoaderMockFactory()->UnregisterURL(url);
  RegisterMockedURLLoadWithCustomResponse(url, revalidate_response);
  new_resource = MockResource::Fetch(fetch_params, fetcher, nullptr);
  EXPECT_EQ(resource, new_resource);
  EXPECT_TRUE(GetMemoryCache()->Contains(resource));
  RunUntilIdle(context);
  platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
  EXPECT_FALSE(GetMemoryCache()->Contains(resource));
}

TEST_F(ResourceFetcherTest, CachedResourceShouldNotCrashByNullURL) {
  auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
  auto* fetcher =
      MakeGarbageCollected<ResourceFetcher>(*properties, CreateFetchContext());

  // Make sure |cached_resources_map_| is not empty, so that HashMap lookup
  // won't take a fast path.
  KURL url("http://127.0.0.1:8000/foo.html");
  ResourceResponse response(url);
  response.SetHTTPStatusCode(200);
  RegisterMockedURLLoadWithCustomResponse(url, response);
  FetchParameters fetch_params{ResourceRequest(url)};
  MockResource::Fetch(fetch_params, fetcher, nullptr);
  ASSERT_NE(fetcher->CachedResource(url), nullptr);

  ASSERT_EQ(fetcher->CachedResource(KURL()), nullptr);
}

}  // namespace blink
