// 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 "content/browser/loader/async_revalidation_manager.h"

#include <deque>
#include <string>
#include <utility>

#include "base/bind.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/shared_memory_handle.h"
#include "base/pickle.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_message_filter.h"
#include "content/browser/loader_delegate_impl.h"
#include "content/common/child_process_host_impl.h"
#include "content/common/resource_messages.h"
#include "content/common/resource_request.h"
#include "content/public/browser/resource_context.h"
#include "content/public/common/appcache_info.h"
#include "content/public/common/resource_type.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "ipc/ipc_param_traits.h"
#include "net/base/load_flags.h"
#include "net/base/network_delegate.h"
#include "net/http/http_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_job_factory.h"
#include "net/url_request/url_request_test_job.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/page_transition_types.h"
#include "url/gurl.h"
#include "url/url_constants.h"

namespace content {

namespace {

// This class is a variation on URLRequestTestJob that
// returns ERR_IO_PENDING before every read, not just the first one.
class URLRequestTestDelayedCompletionJob : public net::URLRequestTestJob {
 public:
  URLRequestTestDelayedCompletionJob(net::URLRequest* request,
                                     net::NetworkDelegate* network_delegate,
                                     const std::string& response_headers,
                                     const std::string& response_data)
      : net::URLRequestTestJob(request,
                               network_delegate,
                               response_headers,
                               response_data,
                               false) {}

 private:
  bool NextReadAsync() override { return true; }
};

// A URLRequestJob implementation which sets the |async_revalidation_required|
// flag on the HttpResponseInfo object to true if the request has the
// LOAD_SUPPORT_ASYNC_REVALIDATION flag.
class AsyncRevalidationRequiredURLRequestTestJob
    : public net::URLRequestTestJob {
 public:
  AsyncRevalidationRequiredURLRequestTestJob(
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate)
      : URLRequestTestJob(request,
                          network_delegate,
                          net::URLRequestTestJob::test_headers(),
                          std::string(),
                          false) {}

  void GetResponseInfo(net::HttpResponseInfo* info) override {
    URLRequestTestJob::GetResponseInfo(info);
    if (request()->load_flags() & net::LOAD_SUPPORT_ASYNC_REVALIDATION)
      info->async_revalidation_required = true;
  }
};

// A URLRequestJob implementation which serves a redirect and sets the
// |async_revalidation_required| flag on the HttpResponseInfo object to true if
// the request has the LOAD_SUPPORT_ASYNC_REVALIDATION flag.
class RedirectAndRevalidateURLRequestTestJob : public net::URLRequestTestJob {
 public:
  RedirectAndRevalidateURLRequestTestJob(net::URLRequest* request,
                                         net::NetworkDelegate* network_delegate)
      : URLRequestTestJob(request,
                          network_delegate,
                          CreateRedirectHeaders(),
                          std::string(),
                          false) {}

  void GetResponseInfo(net::HttpResponseInfo* info) override {
    URLRequestTestJob::GetResponseInfo(info);
    if (request()->load_flags() & net::LOAD_SUPPORT_ASYNC_REVALIDATION)
      info->async_revalidation_required = true;
  }

 private:
  static std::string CreateRedirectHeaders() {
    static const char kRedirectHeaders[] =
        "HTTP/1.1 302 MOVED\n"
        "Location: http://example.com/async-revalidate/from-redirect\n"
        "\n";
    return std::string(kRedirectHeaders, arraysize(kRedirectHeaders) - 1);
  }
};

class TestURLRequestJobFactory : public net::URLRequestJobFactory {
 public:
  TestURLRequestJobFactory() = default;

  // Sets the contents of the response. |headers| should have "\n" as line
  // breaks and end in "\n\n".
  void SetResponse(const std::string& headers, const std::string& data) {
    response_headers_ = headers;
    response_data_ = data;
  }

  net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
      const std::string& scheme,
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate) const override {
    std::string path = request->url().path();
    if (base::StartsWith(path, "/async-revalidate",
                         base::CompareCase::SENSITIVE)) {
      return new AsyncRevalidationRequiredURLRequestTestJob(request,
                                                            network_delegate);
    }
    if (base::StartsWith(path, "/redirect", base::CompareCase::SENSITIVE)) {
      return new RedirectAndRevalidateURLRequestTestJob(request,
                                                        network_delegate);
    }
    return new URLRequestTestDelayedCompletionJob(
        request, network_delegate, response_headers_, response_data_);
  }

  net::URLRequestJob* MaybeInterceptRedirect(
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate,
      const GURL& location) const override {
    return nullptr;
  }

  net::URLRequestJob* MaybeInterceptResponse(
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate) const override {
    return nullptr;
  }

  bool IsHandledProtocol(const std::string& scheme) const override {
    // If non-standard schemes need to be tested in future it will be
    // necessary to call ChildProcessSecurityPolicyImpl::
    // RegisterWebSafeScheme() for them.
    return scheme == url::kHttpScheme || scheme == url::kHttpsScheme;
  }

  bool IsHandledURL(const GURL& url) const override {
    return IsHandledProtocol(url.scheme());
  }

  bool IsSafeRedirectTarget(const GURL& location) const override {
    return false;
  }

 private:
  std::string response_headers_;
  std::string response_data_;

  DISALLOW_COPY_AND_ASSIGN(TestURLRequestJobFactory);
};

// On Windows, ResourceMsg_SetDataBuffer supplies a HANDLE which is not
// automatically released.
//
// See ResourceDispatcher::ReleaseResourcesInDataMessage.
//
// TODO(ricea): Maybe share this implementation with
// resource_dispatcher_host_unittest.cc.
void ReleaseHandlesInMessage(const IPC::Message& message) {
  if (message.type() == ResourceMsg_SetDataBuffer::ID) {
    base::PickleIterator iter(message);
    int request_id;
    CHECK(iter.ReadInt(&request_id));
    base::SharedMemoryHandle shm_handle;
    if (IPC::ParamTraits<base::SharedMemoryHandle>::Read(&message, &iter,
                                                         &shm_handle)) {
      if (base::SharedMemory::IsHandleValid(shm_handle))
        base::SharedMemory::CloseHandle(shm_handle);
    }
  }
}

// This filter just deletes any messages that are sent through it.
class BlackholeFilter : public ResourceMessageFilter {
 public:
  explicit BlackholeFilter(ResourceContext* resource_context)
      : ResourceMessageFilter(
            ChildProcessHostImpl::GenerateChildProcessUniqueId(),
            nullptr,
            nullptr,
            nullptr,
            nullptr,
            base::Bind(&BlackholeFilter::GetContexts, base::Unretained(this))),
        resource_context_(resource_context) {
    InitializeForTest();
    ChildProcessSecurityPolicyImpl::GetInstance()->Add(child_id());
  }

  bool Send(IPC::Message* msg) override {
    std::unique_ptr<IPC::Message> take_ownership(msg);
    ReleaseHandlesInMessage(*msg);
    return true;
  }

 private:
  ~BlackholeFilter() override {
    ChildProcessSecurityPolicyImpl::GetInstance()->Remove(child_id());
  }

  void GetContexts(ResourceType resource_type,
                   ResourceContext** resource_context,
                   net::URLRequestContext** request_context) {
    *resource_context = resource_context_;
    *request_context = resource_context_->GetRequestContext();
  }

  ResourceContext* resource_context_;

  DISALLOW_COPY_AND_ASSIGN(BlackholeFilter);
};

ResourceRequest CreateResourceRequest(const char* method,
                                      ResourceType type,
                                      const GURL& url) {
  ResourceRequest request;
  request.method = std::string(method);
  request.url = url;
  request.first_party_for_cookies = url;  // Bypass third-party cookie blocking.
  request.request_initiator = url::Origin(url);  // Ensure initiator is set.
  request.referrer_policy = blink::WebReferrerPolicyDefault;
  request.load_flags = 0;
  request.origin_pid = 0;
  request.resource_type = type;
  request.request_context = 0;
  request.appcache_host_id = kAppCacheNoHostId;
  request.download_to_file = false;
  request.should_reset_appcache = false;
  request.is_main_frame = true;
  request.parent_is_main_frame = false;
  request.parent_render_frame_id = -1;
  request.transition_type = ui::PAGE_TRANSITION_LINK;
  request.allow_download = true;
  return request;
}

class AsyncRevalidationManagerTest : public ::testing::Test {
 protected:
  AsyncRevalidationManagerTest(
      std::unique_ptr<net::TestNetworkDelegate> network_delegate)
      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
        network_delegate_(std::move(network_delegate)) {
    host_.SetLoaderDelegate(&loader_delegate_);
    browser_context_.reset(new TestBrowserContext());
    BrowserContext::EnsureResourceContextInitialized(browser_context_.get());
    base::RunLoop().RunUntilIdle();
    ResourceContext* resource_context = browser_context_->GetResourceContext();
    filter_ = new BlackholeFilter(resource_context);
    net::URLRequestContext* request_context =
        resource_context->GetRequestContext();
    job_factory_.reset(new TestURLRequestJobFactory);
    request_context->set_job_factory(job_factory_.get());
    request_context->set_network_delegate(network_delegate_.get());
    host_.EnableStaleWhileRevalidateForTesting();
  }

  AsyncRevalidationManagerTest()
      : AsyncRevalidationManagerTest(
            base::WrapUnique(new net::TestNetworkDelegate)) {}

  void TearDown() override {
    filter_->OnChannelClosing();
    host_.CancelRequestsForProcess(filter_->child_id());
    host_.Shutdown();
    host_.CancelRequestsForContext(browser_context_->GetResourceContext());
    browser_context_.reset();
    base::RunLoop().RunUntilIdle();
  }

  void SetResponse(const std::string& headers, const std::string& data) {
    job_factory_->SetResponse(headers, data);
  }

  // Creates a request using the current test object as the filter and
  // SubResource as the resource type.
  void MakeTestRequest(int render_view_id, int request_id, const GURL& url) {
    ResourceRequest request =
        CreateResourceRequest("GET", RESOURCE_TYPE_SUB_RESOURCE, url);
    ResourceHostMsg_RequestResource msg(render_view_id, request_id, request);
    filter_->OnMessageReceived(msg);
    base::RunLoop().RunUntilIdle();
  }

  void EnsureSchemeIsAllowed(const std::string& scheme) {
    ChildProcessSecurityPolicyImpl* policy =
        ChildProcessSecurityPolicyImpl::GetInstance();
    if (!policy->IsWebSafeScheme(scheme))
      policy->RegisterWebSafeScheme(scheme);
  }

  content::TestBrowserThreadBundle thread_bundle_;
  std::unique_ptr<TestBrowserContext> browser_context_;
  std::unique_ptr<TestURLRequestJobFactory> job_factory_;
  scoped_refptr<BlackholeFilter> filter_;
  std::unique_ptr<net::TestNetworkDelegate> network_delegate_;
  LoaderDelegateImpl loader_delegate_;
  ResourceDispatcherHostImpl host_;
};

TEST_F(AsyncRevalidationManagerTest, SupportsAsyncRevalidation) {
  SetResponse(net::URLRequestTestJob::test_headers(), "delay complete");
  MakeTestRequest(0, 1, GURL("http://example.com/baz"));

  net::URLRequest* url_request(
      host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1)));
  ASSERT_TRUE(url_request);

  EXPECT_TRUE(url_request->load_flags() & net::LOAD_SUPPORT_ASYNC_REVALIDATION);
}

TEST_F(AsyncRevalidationManagerTest, AsyncRevalidationNotSupportedForPOST) {
  SetResponse(net::URLRequestTestJob::test_headers(), "delay complete");
  // Create POST request.
  ResourceRequest request = CreateResourceRequest(
      "POST", RESOURCE_TYPE_SUB_RESOURCE, GURL("http://example.com/baz.php"));
  ResourceHostMsg_RequestResource msg(0, 1, request);
  filter_->OnMessageReceived(msg);
  base::RunLoop().RunUntilIdle();

  net::URLRequest* url_request(
      host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1)));
  ASSERT_TRUE(url_request);

  EXPECT_FALSE(url_request->load_flags() &
               net::LOAD_SUPPORT_ASYNC_REVALIDATION);
}

TEST_F(AsyncRevalidationManagerTest,
       AsyncRevalidationNotSupportedAfterRedirect) {
  static const char kRedirectHeaders[] =
      "HTTP/1.1 302 MOVED\n"
      "Location: http://example.com/var\n"
      "\n";
  SetResponse(kRedirectHeaders, "");

  MakeTestRequest(0, 1, GURL("http://example.com/baz"));

  net::URLRequest* url_request(
      host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1)));
  ASSERT_TRUE(url_request);

  EXPECT_FALSE(url_request->load_flags() &
               net::LOAD_SUPPORT_ASYNC_REVALIDATION);
}

// A NetworkDelegate that records the URLRequests as they are created.
class URLRequestRecordingNetworkDelegate : public net::TestNetworkDelegate {
 public:
  URLRequestRecordingNetworkDelegate() : requests_() {}

  net::URLRequest* NextRequest() {
    EXPECT_FALSE(requests_.empty());
    if (requests_.empty())
      return nullptr;
    net::URLRequest* request = requests_.front();
    EXPECT_TRUE(request);
    requests_.pop_front();
    return request;
  }

  bool NextRequestWasDestroyed() {
    net::URLRequest* request = requests_.front();
    requests_.pop_front();
    return request == nullptr;
  }

  bool IsEmpty() const { return requests_.empty(); }

  int OnBeforeURLRequest(net::URLRequest* request,
                         const net::CompletionCallback& callback,
                         GURL* new_url) override {
    requests_.push_back(request);
    return TestNetworkDelegate::OnBeforeURLRequest(request, callback, new_url);
  }

  void OnURLRequestDestroyed(net::URLRequest* request) override {
    for (auto*& recorded_request : requests_) {
      if (recorded_request == request)
        recorded_request = nullptr;
    }
    net::TestNetworkDelegate::OnURLRequestDestroyed(request);
  }

 private:
  std::deque<net::URLRequest*> requests_;

  DISALLOW_COPY_AND_ASSIGN(URLRequestRecordingNetworkDelegate);
};

class AsyncRevalidationManagerRecordingTest
    : public AsyncRevalidationManagerTest {
 public:
  AsyncRevalidationManagerRecordingTest()
      : AsyncRevalidationManagerTest(
            base::WrapUnique(new URLRequestRecordingNetworkDelegate)) {}

  void TearDown() override {
    EXPECT_TRUE(IsEmpty());
    AsyncRevalidationManagerTest::TearDown();
  }

  URLRequestRecordingNetworkDelegate* recording_network_delegate() const {
    return static_cast<URLRequestRecordingNetworkDelegate*>(
        network_delegate_.get());
  }

  bool NextRequestWasDestroyed() {
    return recording_network_delegate()->NextRequestWasDestroyed();
  }

  net::URLRequest* NextRequest() {
    return recording_network_delegate()->NextRequest();
  }

  bool IsEmpty() const { return recording_network_delegate()->IsEmpty(); }
};

// Verify that an async revalidation is actually created when needed.
TEST_F(AsyncRevalidationManagerRecordingTest, Issued) {
  // Create the original request.
  MakeTestRequest(0, 1, GURL("http://example.com/async-revalidate"));

  net::URLRequest* initial_request = NextRequest();
  ASSERT_TRUE(initial_request);
  EXPECT_TRUE(initial_request->load_flags() &
              net::LOAD_SUPPORT_ASYNC_REVALIDATION);

  net::URLRequest* async_request = NextRequest();
  ASSERT_TRUE(async_request);
}

// Verify the the URL of the async revalidation matches the original request.
TEST_F(AsyncRevalidationManagerRecordingTest, URLMatches) {
  // Create the original request.
  MakeTestRequest(0, 1, GURL("http://example.com/async-revalidate/u"));

  // Discard the original request.
  NextRequest();

  net::URLRequest* async_request = NextRequest();
  ASSERT_TRUE(async_request);
  EXPECT_EQ(GURL("http://example.com/async-revalidate/u"),
            async_request->url());
}

TEST_F(AsyncRevalidationManagerRecordingTest,
       AsyncRevalidationsDoNotSupportAsyncRevalidation) {
  // Create the original request.
  MakeTestRequest(0, 1, GURL("http://example.com/async-revalidate"));

  // Discard the original request.
  NextRequest();

  // Get the async revalidation request.
  net::URLRequest* async_request = NextRequest();
  ASSERT_TRUE(async_request);
  EXPECT_FALSE(async_request->load_flags() &
               net::LOAD_SUPPORT_ASYNC_REVALIDATION);
}

TEST_F(AsyncRevalidationManagerRecordingTest, AsyncRevalidationsNotDuplicated) {
  // Create the original request.
  MakeTestRequest(0, 1, GURL("http://example.com/async-revalidate"));

  // Discard the original request.
  NextRequest();

  // Get the async revalidation request.
  net::URLRequest* async_request = NextRequest();
  EXPECT_TRUE(async_request);

  // Start a second request to the same URL.
  MakeTestRequest(0, 2, GURL("http://example.com/async-revalidate"));

  // Discard the second request.
  NextRequest();

  // There should not be another async revalidation request.
  EXPECT_TRUE(IsEmpty());
}

// Async revalidation to different URLs should not be treated as duplicates.
TEST_F(AsyncRevalidationManagerRecordingTest,
       AsyncRevalidationsToSeparateURLsAreSeparate) {
  // Create two requests to two URLs.
  MakeTestRequest(0, 1, GURL("http://example.com/async-revalidate"));
  MakeTestRequest(0, 2, GURL("http://example.com/async-revalidate2"));

  net::URLRequest* initial_request = NextRequest();
  ASSERT_TRUE(initial_request);
  net::URLRequest* initial_async_revalidation = NextRequest();
  ASSERT_TRUE(initial_async_revalidation);
  net::URLRequest* second_request = NextRequest();
  ASSERT_TRUE(second_request);
  net::URLRequest* second_async_revalidation = NextRequest();
  ASSERT_TRUE(second_async_revalidation);

  EXPECT_EQ("http://example.com/async-revalidate",
            initial_request->url().spec());
  EXPECT_EQ("http://example.com/async-revalidate",
            initial_async_revalidation->url().spec());
  EXPECT_EQ("http://example.com/async-revalidate2",
            second_request->url().spec());
  EXPECT_EQ("http://example.com/async-revalidate2",
            second_async_revalidation->url().spec());
}

// Nothing after the first redirect leg has stale-while-revalidate applied.
// TODO(ricea): s-w-r should work with redirects. Change this test when it does.
TEST_F(AsyncRevalidationManagerRecordingTest, NoSWRAfterFirstRedirectLeg) {
  MakeTestRequest(0, 1, GURL("http://example.com/redirect"));

  net::URLRequest* initial_request = NextRequest();
  EXPECT_TRUE(initial_request);

  EXPECT_FALSE(initial_request->load_flags() &
               net::LOAD_SUPPORT_ASYNC_REVALIDATION);

  // An async revalidation happens for the redirect. It has no body, so it has
  // already completed.
  EXPECT_TRUE(NextRequestWasDestroyed());

  // But no others.
  EXPECT_TRUE(IsEmpty());
}

}  // namespace

}  // namespace content
