// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.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/shared_buffer.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"

namespace blink {

namespace {

class MockPlatform final : public TestingPlatformSupportWithMockScheduler {
 public:
  MockPlatform() = default;
  ~MockPlatform() override = default;

  // From blink::Platform:
  void CacheMetadata(blink::mojom::CodeCacheType cache_type,
                     const WebURL& url,
                     Time,
                     const char*,
                     size_t) override {
    cached_urls_.push_back(url);
  }

  const Vector<WebURL>& CachedURLs() const { return cached_urls_; }

 private:
  Vector<WebURL> cached_urls_;
};

ResourceResponse CreateTestResourceResponse() {
  ResourceResponse response(URLTestHelpers::ToKURL("https://example.com/"));
  response.SetHTTPStatusCode(200);
  return response;
}

void CreateTestResourceAndSetCachedMetadata(const ResourceResponse& response) {
  const char kTestData[] = "test data";
  MockResource* resource = MockResource::Create(response.Url());
  resource->SetResponse(response);
  resource->SendCachedMetadata(kTestData, sizeof(kTestData));
  return;
}

}  // anonymous namespace

TEST(ResourceTest, SetCachedMetadata_SendsMetadataToPlatform) {
  ScopedTestingPlatformSupport<MockPlatform> mock;
  ResourceResponse response(CreateTestResourceResponse());
  CreateTestResourceAndSetCachedMetadata(response);
  EXPECT_EQ(1u, mock->CachedURLs().size());
}

TEST(
    ResourceTest,
    SetCachedMetadata_DoesNotSendMetadataToPlatformWhenFetchedViaServiceWorker) {
  ScopedTestingPlatformSupport<MockPlatform> mock;
  ResourceResponse response(CreateTestResourceResponse());
  response.SetWasFetchedViaServiceWorker(true);
  CreateTestResourceAndSetCachedMetadata(response);
  EXPECT_EQ(0u, mock->CachedURLs().size());
}

TEST(ResourceTest, RevalidateWithFragment) {
  ScopedTestingPlatformSupport<MockPlatform> mock;
  KURL url("http://127.0.0.1:8000/foo.html");
  ResourceResponse response(url);
  response.SetHTTPStatusCode(200);
  MockResource* resource = MockResource::Create(url);
  resource->ResponseReceived(response, nullptr);
  resource->FinishForTest();

  // Revalidating with a url that differs by only the fragment
  // shouldn't trigger a securiy check.
  url.SetFragmentIdentifier("bar");
  resource->SetRevalidatingRequest(ResourceRequest(url));
  ResourceResponse revalidating_response(url);
  revalidating_response.SetHTTPStatusCode(304);
  resource->ResponseReceived(revalidating_response, nullptr);
}

TEST(ResourceTest, Vary) {
  ScopedTestingPlatformSupport<MockPlatform> mock;
  const KURL url("http://127.0.0.1:8000/foo.html");
  ResourceResponse response(url);
  response.SetHTTPStatusCode(200);

  MockResource* resource = MockResource::Create(url);
  resource->ResponseReceived(response, nullptr);
  resource->FinishForTest();

  ResourceRequest new_request(url);
  EXPECT_FALSE(resource->MustReloadDueToVaryHeader(new_request));

  response.SetHTTPHeaderField(HTTPNames::Vary, "*");
  resource->SetResponse(response);
  EXPECT_TRUE(resource->MustReloadDueToVaryHeader(new_request));

  // Irrelevant header
  response.SetHTTPHeaderField(HTTPNames::Vary, "definitelynotarealheader");
  resource->SetResponse(response);
  EXPECT_FALSE(resource->MustReloadDueToVaryHeader(new_request));

  // Header present on new but not old
  new_request.SetHTTPHeaderField(HTTPNames::User_Agent, "something");
  response.SetHTTPHeaderField(HTTPNames::Vary, HTTPNames::User_Agent);
  resource->SetResponse(response);
  EXPECT_TRUE(resource->MustReloadDueToVaryHeader(new_request));
  new_request.ClearHTTPHeaderField(HTTPNames::User_Agent);

  ResourceRequest old_request(url);
  old_request.SetHTTPHeaderField(HTTPNames::User_Agent, "something");
  old_request.SetHTTPHeaderField(HTTPNames::Referer, "http://foo.com");
  resource = MockResource::Create(old_request);
  resource->ResponseReceived(response, nullptr);
  resource->FinishForTest();

  // Header present on old but not new
  new_request.ClearHTTPHeaderField(HTTPNames::User_Agent);
  response.SetHTTPHeaderField(HTTPNames::Vary, HTTPNames::User_Agent);
  resource->SetResponse(response);
  EXPECT_TRUE(resource->MustReloadDueToVaryHeader(new_request));

  // Header present on both
  new_request.SetHTTPHeaderField(HTTPNames::User_Agent, "something");
  EXPECT_FALSE(resource->MustReloadDueToVaryHeader(new_request));

  // One matching, one mismatching
  response.SetHTTPHeaderField(HTTPNames::Vary, "User-Agent, Referer");
  resource->SetResponse(response);
  EXPECT_TRUE(resource->MustReloadDueToVaryHeader(new_request));

  // Two matching
  new_request.SetHTTPHeaderField(HTTPNames::Referer, "http://foo.com");
  EXPECT_FALSE(resource->MustReloadDueToVaryHeader(new_request));
}

TEST(ResourceTest, RevalidationFailed) {
  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
      platform_;
  const KURL url("http://test.example.com/");
  MockResource* resource = MockResource::Create(ResourceRequest(url));
  ResourceResponse response(url);
  response.SetHTTPStatusCode(200);
  resource->ResponseReceived(response, nullptr);
  const char kData[5] = "abcd";
  resource->AppendData(kData, 4);
  resource->FinishForTest();
  GetMemoryCache()->Add(resource);

  MockCacheHandler* original_cache_handler = resource->CacheHandler();
  EXPECT_TRUE(original_cache_handler);

  // Simulate revalidation start.
  resource->SetRevalidatingRequest(ResourceRequest(url));

  EXPECT_EQ(original_cache_handler, resource->CacheHandler());

  Persistent<MockResourceClient> client = new MockResourceClient;
  resource->AddClient(client, nullptr);

  ResourceResponse revalidating_response(url);
  revalidating_response.SetHTTPStatusCode(200);
  resource->ResponseReceived(revalidating_response, nullptr);

  EXPECT_FALSE(resource->IsCacheValidator());
  EXPECT_EQ(200, resource->GetResponse().HttpStatusCode());
  EXPECT_FALSE(resource->ResourceBuffer());
  EXPECT_TRUE(resource->CacheHandler());
  EXPECT_NE(original_cache_handler, resource->CacheHandler());
  EXPECT_EQ(resource, GetMemoryCache()->ResourceForURL(url));

  resource->AppendData(kData, 4);

  EXPECT_FALSE(client->NotifyFinishedCalled());

  resource->FinishForTest();

  EXPECT_TRUE(client->NotifyFinishedCalled());

  resource->RemoveClient(client);
  EXPECT_FALSE(resource->IsAlive());
}

TEST(ResourceTest, RevalidationSucceeded) {
  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
      platform_;
  const KURL url("http://test.example.com/");
  MockResource* resource = MockResource::Create(ResourceRequest(url));
  ResourceResponse response(url);
  response.SetHTTPStatusCode(200);
  resource->ResponseReceived(response, nullptr);
  const char kData[5] = "abcd";
  resource->AppendData(kData, 4);
  resource->FinishForTest();
  GetMemoryCache()->Add(resource);

  MockCacheHandler* original_cache_handler = resource->CacheHandler();
  EXPECT_TRUE(original_cache_handler);

  // Simulate a successful revalidation.
  resource->SetRevalidatingRequest(ResourceRequest(url));

  EXPECT_EQ(original_cache_handler, resource->CacheHandler());

  Persistent<MockResourceClient> client = new MockResourceClient;
  resource->AddClient(client, nullptr);

  ResourceResponse revalidating_response(url);
  revalidating_response.SetHTTPStatusCode(304);
  resource->ResponseReceived(revalidating_response, nullptr);

  EXPECT_FALSE(resource->IsCacheValidator());
  EXPECT_EQ(200, resource->GetResponse().HttpStatusCode());
  EXPECT_EQ(4u, resource->ResourceBuffer()->size());
  EXPECT_EQ(original_cache_handler, resource->CacheHandler());
  EXPECT_EQ(resource, GetMemoryCache()->ResourceForURL(url));

  GetMemoryCache()->Remove(resource);

  resource->RemoveClient(client);
  EXPECT_FALSE(resource->IsAlive());
  EXPECT_FALSE(client->NotifyFinishedCalled());
}

TEST(ResourceTest, RevalidationSucceededForResourceWithoutBody) {
  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
      platform_;
  const KURL url("http://test.example.com/");
  Resource* resource = MockResource::Create(ResourceRequest(url));
  ResourceResponse response(url);
  response.SetHTTPStatusCode(200);
  resource->ResponseReceived(response, nullptr);
  resource->FinishForTest();
  GetMemoryCache()->Add(resource);

  // Simulate a successful revalidation.
  resource->SetRevalidatingRequest(ResourceRequest(url));

  Persistent<MockResourceClient> client = new MockResourceClient;
  resource->AddClient(client, nullptr);

  ResourceResponse revalidating_response(url);
  revalidating_response.SetHTTPStatusCode(304);
  resource->ResponseReceived(revalidating_response, nullptr);
  EXPECT_FALSE(resource->IsCacheValidator());
  EXPECT_EQ(200, resource->GetResponse().HttpStatusCode());
  EXPECT_FALSE(resource->ResourceBuffer());
  EXPECT_EQ(resource, GetMemoryCache()->ResourceForURL(url));
  GetMemoryCache()->Remove(resource);

  resource->RemoveClient(client);
  EXPECT_FALSE(resource->IsAlive());
  EXPECT_FALSE(client->NotifyFinishedCalled());
}

TEST(ResourceTest, RevalidationSucceededUpdateHeaders) {
  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
      platform_;
  const KURL url("http://test.example.com/");
  Resource* resource = MockResource::Create(ResourceRequest(url));
  ResourceResponse response(url);
  response.SetHTTPStatusCode(200);
  response.AddHTTPHeaderField("keep-alive", "keep-alive value");
  response.AddHTTPHeaderField("expires", "expires value");
  response.AddHTTPHeaderField("last-modified", "last-modified value");
  response.AddHTTPHeaderField("proxy-authenticate", "proxy-authenticate value");
  response.AddHTTPHeaderField("proxy-connection", "proxy-connection value");
  response.AddHTTPHeaderField("x-custom", "custom value");
  resource->ResponseReceived(response, nullptr);
  resource->FinishForTest();
  GetMemoryCache()->Add(resource);

  // Simulate a successful revalidation.
  resource->SetRevalidatingRequest(ResourceRequest(url));

  // Validate that these headers pre-update.
  EXPECT_EQ("keep-alive value",
            resource->GetResponse().HttpHeaderField("keep-alive"));
  EXPECT_EQ("expires value",
            resource->GetResponse().HttpHeaderField("expires"));
  EXPECT_EQ("last-modified value",
            resource->GetResponse().HttpHeaderField("last-modified"));
  EXPECT_EQ("proxy-authenticate value",
            resource->GetResponse().HttpHeaderField("proxy-authenticate"));
  EXPECT_EQ("proxy-authenticate value",
            resource->GetResponse().HttpHeaderField("proxy-authenticate"));
  EXPECT_EQ("proxy-connection value",
            resource->GetResponse().HttpHeaderField("proxy-connection"));
  EXPECT_EQ("custom value",
            resource->GetResponse().HttpHeaderField("x-custom"));

  Persistent<MockResourceClient> client = new MockResourceClient;
  resource->AddClient(client, nullptr);

  // Perform a revalidation step.
  ResourceResponse revalidating_response(url);
  revalidating_response.SetHTTPStatusCode(304);
  // Headers that aren't copied with an 304 code.
  revalidating_response.AddHTTPHeaderField("keep-alive", "garbage");
  revalidating_response.AddHTTPHeaderField("expires", "garbage");
  revalidating_response.AddHTTPHeaderField("last-modified", "garbage");
  revalidating_response.AddHTTPHeaderField("proxy-authenticate", "garbage");
  revalidating_response.AddHTTPHeaderField("proxy-connection", "garbage");
  // Header that is updated with 304 code.
  revalidating_response.AddHTTPHeaderField("x-custom", "updated");
  resource->ResponseReceived(revalidating_response, nullptr);

  // Validate the original response.
  EXPECT_EQ(200, resource->GetResponse().HttpStatusCode());

  // Validate that these headers are not updated.
  EXPECT_EQ("keep-alive value",
            resource->GetResponse().HttpHeaderField("keep-alive"));
  EXPECT_EQ("expires value",
            resource->GetResponse().HttpHeaderField("expires"));
  EXPECT_EQ("last-modified value",
            resource->GetResponse().HttpHeaderField("last-modified"));
  EXPECT_EQ("proxy-authenticate value",
            resource->GetResponse().HttpHeaderField("proxy-authenticate"));
  EXPECT_EQ("proxy-authenticate value",
            resource->GetResponse().HttpHeaderField("proxy-authenticate"));
  EXPECT_EQ("proxy-connection value",
            resource->GetResponse().HttpHeaderField("proxy-connection"));
  EXPECT_EQ("updated", resource->GetResponse().HttpHeaderField("x-custom"));

  resource->RemoveClient(client);
  EXPECT_FALSE(resource->IsAlive());
  EXPECT_FALSE(client->NotifyFinishedCalled());
}

TEST(ResourceTest, RedirectDuringRevalidation) {
  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
      platform_;
  const KURL url("http://test.example.com/1");
  const KURL redirect_target_url("http://test.example.com/2");

  MockResource* resource = MockResource::Create(ResourceRequest(url));
  ResourceResponse response(url);
  response.SetHTTPStatusCode(200);
  resource->ResponseReceived(response, nullptr);
  const char kData[5] = "abcd";
  resource->AppendData(kData, 4);
  resource->FinishForTest();
  GetMemoryCache()->Add(resource);

  EXPECT_FALSE(resource->IsCacheValidator());
  EXPECT_EQ(url, resource->GetResourceRequest().Url());
  EXPECT_EQ(url, resource->LastResourceRequest().Url());

  MockCacheHandler* original_cache_handler = resource->CacheHandler();
  EXPECT_TRUE(original_cache_handler);

  // Simulate a revalidation.
  resource->SetRevalidatingRequest(ResourceRequest(url));
  EXPECT_TRUE(resource->IsCacheValidator());
  EXPECT_EQ(url, resource->GetResourceRequest().Url());
  EXPECT_EQ(url, resource->LastResourceRequest().Url());
  EXPECT_EQ(original_cache_handler, resource->CacheHandler());

  Persistent<MockResourceClient> client = new MockResourceClient;
  resource->AddClient(client, nullptr);

  // The revalidating request is redirected.
  ResourceResponse redirect_response(url);
  redirect_response.SetHTTPHeaderField(
      "location", AtomicString(redirect_target_url.GetString()));
  redirect_response.SetHTTPStatusCode(308);
  ResourceRequest redirected_revalidating_request(redirect_target_url);
  resource->WillFollowRedirect(redirected_revalidating_request,
                               redirect_response);
  EXPECT_FALSE(resource->IsCacheValidator());
  EXPECT_EQ(url, resource->GetResourceRequest().Url());
  EXPECT_EQ(redirect_target_url, resource->LastResourceRequest().Url());
  EXPECT_FALSE(resource->CacheHandler());

  // The final response is received.
  ResourceResponse revalidating_response(redirect_target_url);
  revalidating_response.SetHTTPStatusCode(200);
  resource->ResponseReceived(revalidating_response, nullptr);

  EXPECT_TRUE(resource->CacheHandler());

  const char kData2[4] = "xyz";
  resource->AppendData(kData2, 3);
  resource->FinishForTest();
  EXPECT_FALSE(resource->IsCacheValidator());
  EXPECT_EQ(url, resource->GetResourceRequest().Url());
  EXPECT_EQ(redirect_target_url, resource->LastResourceRequest().Url());
  EXPECT_FALSE(resource->IsCacheValidator());
  EXPECT_EQ(200, resource->GetResponse().HttpStatusCode());
  EXPECT_EQ(3u, resource->ResourceBuffer()->size());
  EXPECT_EQ(resource, GetMemoryCache()->ResourceForURL(url));

  EXPECT_TRUE(client->NotifyFinishedCalled());

  // Test the case where a client is added after revalidation is completed.
  Persistent<MockResourceClient> client2 = new MockResourceClient;
  resource->AddClient(
      client2, Platform::Current()->CurrentThread()->GetTaskRunner().get());

  // Because the client is added asynchronously,
  // |runUntilIdle()| is called to make |client2| to be notified.
  platform_->RunUntilIdle();

  EXPECT_TRUE(client2->NotifyFinishedCalled());

  GetMemoryCache()->Remove(resource);

  resource->RemoveClient(client);
  resource->RemoveClient(client2);
  EXPECT_FALSE(resource->IsAlive());
}

TEST(ResourceTest, StaleWhileRevalidateCacheControl) {
  ScopedTestingPlatformSupport<MockPlatform> mock;
  const KURL url("http://127.0.0.1:8000/foo.html");
  ResourceResponse response(url);
  response.SetHTTPStatusCode(200);
  response.SetHTTPHeaderField(HTTPNames::Cache_Control,
                              "max-age=0, stale-while-revalidate=40");

  MockResource* resource = MockResource::Create(url);
  resource->ResponseReceived(response, nullptr);
  resource->FinishForTest();

  EXPECT_FALSE(resource->MustRevalidateDueToCacheHeaders(false));
  EXPECT_FALSE(resource->MustRevalidateDueToCacheHeaders(true));
  EXPECT_FALSE(resource->ShouldRevalidateStaleResponse());

  mock->AdvanceClockSeconds(1);
  EXPECT_TRUE(resource->MustRevalidateDueToCacheHeaders(false));
  EXPECT_FALSE(resource->MustRevalidateDueToCacheHeaders(true));
  EXPECT_TRUE(resource->ShouldRevalidateStaleResponse());

  mock->AdvanceClockSeconds(40);
  EXPECT_TRUE(resource->MustRevalidateDueToCacheHeaders(false));
  EXPECT_TRUE(resource->MustRevalidateDueToCacheHeaders(true));
  EXPECT_TRUE(resource->ShouldRevalidateStaleResponse());
}

TEST(ResourceTest, StaleWhileRevalidateCacheControlWithRedirect) {
  ScopedTestingPlatformSupport<MockPlatform> mock;
  const KURL url("http://127.0.0.1:8000/foo.html");
  const KURL redirect_target_url("http://127.0.0.1:8000/food.html");
  ResourceResponse response(url);
  response.SetHTTPHeaderField(HTTPNames::Cache_Control, "max-age=50");
  response.SetHTTPStatusCode(200);

  // The revalidating request is redirected.
  ResourceResponse redirect_response(url);
  redirect_response.SetHTTPHeaderField(
      "location", AtomicString(redirect_target_url.GetString()));
  redirect_response.SetHTTPStatusCode(302);
  redirect_response.SetHTTPHeaderField(HTTPNames::Cache_Control,
                                       "max-age=0, stale-while-revalidate=40");
  redirect_response.SetAsyncRevalidationRequested(true);
  ResourceRequest redirected_revalidating_request(redirect_target_url);

  MockResource* resource = MockResource::Create(url);
  resource->WillFollowRedirect(redirected_revalidating_request,
                               redirect_response);
  resource->ResponseReceived(response, nullptr);
  resource->FinishForTest();

  EXPECT_FALSE(resource->MustRevalidateDueToCacheHeaders(false));
  EXPECT_FALSE(resource->MustRevalidateDueToCacheHeaders(true));
  EXPECT_FALSE(resource->ShouldRevalidateStaleResponse());

  mock->AdvanceClockSeconds(41);

  // MustRevalidateDueToCacheHeaders only looks at the stored response not
  // any redirects but ShouldRevalidate and AsyncRevalidationRequest look
  // at the entire redirect chain.
  EXPECT_FALSE(resource->MustRevalidateDueToCacheHeaders(false));
  EXPECT_FALSE(resource->MustRevalidateDueToCacheHeaders(true));
  EXPECT_TRUE(resource->ShouldRevalidateStaleResponse());
  EXPECT_TRUE(resource->StaleRevalidationRequested());
}

}  // namespace blink
