// Copyright 2017 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 "net/reporting/reporting_uploader.h"

#include <memory>
#include <string>
#include <utility>

#include "base/bind.h"
#include "base/callback.h"
#include "base/run_loop.h"
#include "net/cookies/cookie_store.h"
#include "net/cookies/cookie_store_test_callbacks.h"
#include "net/http/http_status_code.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/test/test_with_scoped_task_environment.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {
namespace {

class ReportingUploaderTest : public TestWithScopedTaskEnvironment {
 protected:
  ReportingUploaderTest()
      : server_(test_server::EmbeddedTestServer::TYPE_HTTPS),
        uploader_(ReportingUploader::Create(&context_)) {}

  TestURLRequestContext context_;
  test_server::EmbeddedTestServer server_;
  std::unique_ptr<ReportingUploader> uploader_;

  const url::Origin kOrigin = url::Origin::Create(GURL("https://origin/"));
};

const char kUploadBody[] = "{}";

void CheckUpload(const test_server::HttpRequest& request) {
  if (request.method_string != "POST") {
    return;
  }
  auto it = request.headers.find("Content-Type");
  EXPECT_TRUE(it != request.headers.end());
  EXPECT_EQ("application/reports+json", it->second);
  EXPECT_TRUE(request.has_content);
  EXPECT_EQ(kUploadBody, request.content);
}

std::unique_ptr<test_server::HttpResponse> AllowPreflight(
    const test_server::HttpRequest& request) {
  if (request.method_string != "OPTIONS") {
    return std::unique_ptr<test_server::HttpResponse>();
  }
  auto it = request.headers.find("Origin");
  EXPECT_TRUE(it != request.headers.end());
  auto response = std::make_unique<test_server::BasicHttpResponse>();
  response->AddCustomHeader("Access-Control-Allow-Origin", it->second);
  response->AddCustomHeader("Access-Control-Allow-Methods", "POST");
  response->AddCustomHeader("Access-Control-Allow-Headers", "Content-Type");
  response->set_code(HTTP_OK);
  response->set_content("");
  response->set_content_type("text/plain");
  return std::move(response);
}

std::unique_ptr<test_server::HttpResponse> ReturnResponse(
    HttpStatusCode code,
    const test_server::HttpRequest& request) {
  auto response = std::make_unique<test_server::BasicHttpResponse>();
  response->set_code(code);
  response->set_content("");
  response->set_content_type("text/plain");
  return std::move(response);
}

std::unique_ptr<test_server::HttpResponse> ReturnInvalidResponse(
    const test_server::HttpRequest& request) {
  return std::make_unique<test_server::RawHttpResponse>(
      "", "Not a valid HTTP response.");
}

class TestUploadCallback {
 public:
  TestUploadCallback() : called_(false), waiting_(false) {}

  ReportingUploader::UploadCallback callback() {
    return base::BindOnce(&TestUploadCallback::OnUploadComplete,
                          base::Unretained(this));
  }

  void WaitForCall() {
    if (called_)
      return;

    base::RunLoop run_loop;

    waiting_ = true;
    closure_ = run_loop.QuitClosure();
    run_loop.Run();
  }

  ReportingUploader::Outcome outcome() const { return outcome_; }

 private:
  void OnUploadComplete(ReportingUploader::Outcome outcome) {
    EXPECT_FALSE(called_);

    called_ = true;
    outcome_ = outcome;

    if (waiting_) {
      waiting_ = false;
      closure_.Run();
    }
  }

  bool called_;
  ReportingUploader::Outcome outcome_;

  bool waiting_;
  base::Closure closure_;
};

TEST_F(ReportingUploaderTest, Upload) {
  server_.RegisterRequestMonitor(base::BindRepeating(&CheckUpload));
  server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
  server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
  ASSERT_TRUE(server_.Start());

  TestUploadCallback callback;
  uploader_->StartUpload(kOrigin, server_.GetURL("/"), kUploadBody, 0,
                         callback.callback());
  callback.WaitForCall();
}

TEST_F(ReportingUploaderTest, Success) {
  server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
  server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
  ASSERT_TRUE(server_.Start());

  TestUploadCallback callback;
  uploader_->StartUpload(kOrigin, server_.GetURL("/"), kUploadBody, 0,
                         callback.callback());
  callback.WaitForCall();

  EXPECT_EQ(ReportingUploader::Outcome::SUCCESS, callback.outcome());
}

TEST_F(ReportingUploaderTest, NetworkError1) {
  ASSERT_TRUE(server_.Start());
  GURL url = server_.GetURL("/");
  ASSERT_TRUE(server_.ShutdownAndWaitUntilComplete());

  TestUploadCallback callback;
  uploader_->StartUpload(kOrigin, url, kUploadBody, 0, callback.callback());
  callback.WaitForCall();

  EXPECT_EQ(ReportingUploader::Outcome::FAILURE, callback.outcome());
}

TEST_F(ReportingUploaderTest, NetworkError2) {
  server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
  server_.RegisterRequestHandler(base::BindRepeating(&ReturnInvalidResponse));
  ASSERT_TRUE(server_.Start());

  TestUploadCallback callback;
  uploader_->StartUpload(kOrigin, server_.GetURL("/"), kUploadBody, 0,
                         callback.callback());
  callback.WaitForCall();

  EXPECT_EQ(ReportingUploader::Outcome::FAILURE, callback.outcome());
}

TEST_F(ReportingUploaderTest, ServerError) {
  server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
  server_.RegisterRequestHandler(
      base::BindRepeating(&ReturnResponse, HTTP_INTERNAL_SERVER_ERROR));
  ASSERT_TRUE(server_.Start());

  TestUploadCallback callback;
  uploader_->StartUpload(kOrigin, server_.GetURL("/"), kUploadBody, 0,
                         callback.callback());
  callback.WaitForCall();

  EXPECT_EQ(ReportingUploader::Outcome::FAILURE, callback.outcome());
}

std::unique_ptr<test_server::HttpResponse> VerifyPreflight(
    bool* preflight_received_out,
    const test_server::HttpRequest& request) {
  if (request.method_string != "OPTIONS") {
    return std::unique_ptr<test_server::HttpResponse>();
  }
  *preflight_received_out = true;
  return AllowPreflight(request);
}

TEST_F(ReportingUploaderTest, VerifyPreflight) {
  bool preflight_received = false;
  server_.RegisterRequestHandler(
      base::BindRepeating(&VerifyPreflight, &preflight_received));
  server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
  ASSERT_TRUE(server_.Start());

  TestUploadCallback callback;
  uploader_->StartUpload(kOrigin, server_.GetURL("/"), kUploadBody, 0,
                         callback.callback());
  callback.WaitForCall();

  EXPECT_TRUE(preflight_received);
  EXPECT_EQ(ReportingUploader::Outcome::SUCCESS, callback.outcome());
}

TEST_F(ReportingUploaderTest, SkipPreflightForSameOrigin) {
  bool preflight_received = false;
  server_.RegisterRequestHandler(
      base::BindRepeating(&VerifyPreflight, &preflight_received));
  server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
  ASSERT_TRUE(server_.Start());

  TestUploadCallback callback;
  auto server_origin = url::Origin::Create(server_.base_url());
  uploader_->StartUpload(server_origin, server_.GetURL("/"), kUploadBody, 0,
                         callback.callback());
  callback.WaitForCall();

  EXPECT_FALSE(preflight_received);
  EXPECT_EQ(ReportingUploader::Outcome::SUCCESS, callback.outcome());
}

std::unique_ptr<test_server::HttpResponse> ReturnPreflightError(
    const test_server::HttpRequest& request) {
  if (request.method_string != "OPTIONS") {
    return std::unique_ptr<test_server::HttpResponse>();
  }
  auto response = std::make_unique<test_server::BasicHttpResponse>();
  response->set_code(HTTP_FORBIDDEN);
  response->set_content("");
  response->set_content_type("text/plain");
  return std::move(response);
}

TEST_F(ReportingUploaderTest, FailedCORSPreflight) {
  server_.RegisterRequestHandler(base::BindRepeating(&ReturnPreflightError));
  server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
  ASSERT_TRUE(server_.Start());

  TestUploadCallback callback;
  uploader_->StartUpload(kOrigin, server_.GetURL("/"), kUploadBody, 0,
                         callback.callback());
  callback.WaitForCall();

  EXPECT_EQ(ReportingUploader::Outcome::FAILURE, callback.outcome());
}

std::unique_ptr<test_server::HttpResponse> ReturnPreflightWithoutOrigin(
    const test_server::HttpRequest& request) {
  if (request.method_string != "OPTIONS") {
    return std::unique_ptr<test_server::HttpResponse>();
  }
  auto it = request.headers.find("Origin");
  EXPECT_TRUE(it != request.headers.end());
  auto response = std::make_unique<test_server::BasicHttpResponse>();
  response->AddCustomHeader("Access-Control-Allow-Methods", "POST");
  response->AddCustomHeader("Access-Control-Allow-Headers", "Content-Type");
  response->set_code(HTTP_OK);
  response->set_content("");
  response->set_content_type("text/plain");
  return std::move(response);
}

TEST_F(ReportingUploaderTest, CORSPreflightWithoutOrigin) {
  server_.RegisterRequestHandler(
      base::BindRepeating(&ReturnPreflightWithoutOrigin));
  server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
  ASSERT_TRUE(server_.Start());

  TestUploadCallback callback;
  uploader_->StartUpload(kOrigin, server_.GetURL("/"), kUploadBody, 0,
                         callback.callback());
  callback.WaitForCall();

  EXPECT_EQ(ReportingUploader::Outcome::FAILURE, callback.outcome());
}

std::unique_ptr<test_server::HttpResponse> ReturnPreflightWithoutMethods(
    const test_server::HttpRequest& request) {
  if (request.method_string != "OPTIONS") {
    return std::unique_ptr<test_server::HttpResponse>();
  }
  auto it = request.headers.find("Origin");
  EXPECT_TRUE(it != request.headers.end());
  auto response = std::make_unique<test_server::BasicHttpResponse>();
  response->AddCustomHeader("Access-Control-Allow-Origin", it->second);
  response->AddCustomHeader("Access-Control-Allow-Headers", "Content-Type");
  response->set_code(HTTP_OK);
  response->set_content("");
  response->set_content_type("text/plain");
  return std::move(response);
}

TEST_F(ReportingUploaderTest, CORSPreflightWithoutMethods) {
  server_.RegisterRequestHandler(
      base::BindRepeating(&ReturnPreflightWithoutMethods));
  server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
  ASSERT_TRUE(server_.Start());

  TestUploadCallback callback;
  uploader_->StartUpload(kOrigin, server_.GetURL("/"), kUploadBody, 0,
                         callback.callback());
  callback.WaitForCall();

  EXPECT_EQ(ReportingUploader::Outcome::FAILURE, callback.outcome());
}

std::unique_ptr<test_server::HttpResponse> ReturnPreflightWithoutHeaders(
    const test_server::HttpRequest& request) {
  if (request.method_string != "OPTIONS") {
    return std::unique_ptr<test_server::HttpResponse>();
  }
  auto it = request.headers.find("Origin");
  EXPECT_TRUE(it != request.headers.end());
  auto response = std::make_unique<test_server::BasicHttpResponse>();
  response->AddCustomHeader("Access-Control-Allow-Origin", it->second);
  response->AddCustomHeader("Access-Control-Allow-Methods", "POST");
  response->set_code(HTTP_OK);
  response->set_content("");
  response->set_content_type("text/plain");
  return std::move(response);
}

TEST_F(ReportingUploaderTest, CORSPreflightWithoutHeaders) {
  server_.RegisterRequestHandler(
      base::BindRepeating(&ReturnPreflightWithoutHeaders));
  server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
  ASSERT_TRUE(server_.Start());

  TestUploadCallback callback;
  uploader_->StartUpload(kOrigin, server_.GetURL("/"), kUploadBody, 0,
                         callback.callback());
  callback.WaitForCall();

  EXPECT_EQ(ReportingUploader::Outcome::FAILURE, callback.outcome());
}

TEST_F(ReportingUploaderTest, RemoveEndpoint) {
  server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
  server_.RegisterRequestHandler(
      base::BindRepeating(&ReturnResponse, HTTP_GONE));
  ASSERT_TRUE(server_.Start());

  TestUploadCallback callback;
  uploader_->StartUpload(kOrigin, server_.GetURL("/"), kUploadBody, 0,
                         callback.callback());
  callback.WaitForCall();

  EXPECT_EQ(ReportingUploader::Outcome::REMOVE_ENDPOINT, callback.outcome());
}

const char kRedirectPath[] = "/redirect";

std::unique_ptr<test_server::HttpResponse> ReturnRedirect(
    const std::string& location,
    const test_server::HttpRequest& request) {
  if (request.relative_url != "/")
    return std::unique_ptr<test_server::HttpResponse>();

  auto response = std::make_unique<test_server::BasicHttpResponse>();
  response->set_code(HTTP_FOUND);
  response->AddCustomHeader("Location", location);
  response->set_content(
      "Thank you, Mario! But our Princess is in another castle.");
  response->set_content_type("text/plain");
  return std::move(response);
}

std::unique_ptr<test_server::HttpResponse> CheckRedirect(
    bool* redirect_followed_out,
    const test_server::HttpRequest& request) {
  if (request.relative_url != kRedirectPath)
    return std::unique_ptr<test_server::HttpResponse>();

  *redirect_followed_out = true;
  return ReturnResponse(HTTP_OK, request);
}

TEST_F(ReportingUploaderTest, FollowHttpsRedirect) {
  bool followed = false;
  server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
  server_.RegisterRequestHandler(
      base::BindRepeating(&ReturnRedirect, kRedirectPath));
  server_.RegisterRequestHandler(
      base::BindRepeating(&CheckRedirect, &followed));
  ASSERT_TRUE(server_.Start());

  TestUploadCallback callback;
  uploader_->StartUpload(kOrigin, server_.GetURL("/"), kUploadBody, 0,
                         callback.callback());
  callback.WaitForCall();

  EXPECT_TRUE(followed);
  EXPECT_EQ(ReportingUploader::Outcome::SUCCESS, callback.outcome());
}

TEST_F(ReportingUploaderTest, DontFollowHttpRedirect) {
  bool followed = false;

  test_server::EmbeddedTestServer http_server_;
  http_server_.RegisterRequestHandler(
      base::BindRepeating(&CheckRedirect, &followed));
  ASSERT_TRUE(http_server_.Start());

  const GURL target = http_server_.GetURL(kRedirectPath);
  server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
  server_.RegisterRequestHandler(
      base::BindRepeating(&ReturnRedirect, target.spec()));
  ASSERT_TRUE(server_.Start());

  TestUploadCallback callback;
  uploader_->StartUpload(kOrigin, server_.GetURL("/"), kUploadBody, 0,
                         callback.callback());
  callback.WaitForCall();

  EXPECT_FALSE(followed);
  EXPECT_EQ(ReportingUploader::Outcome::FAILURE, callback.outcome());
}

void CheckNoCookie(const test_server::HttpRequest& request) {
  auto it = request.headers.find("Cookie");
  EXPECT_TRUE(it == request.headers.end());
}

TEST_F(ReportingUploaderTest, DontSendCookies) {
  server_.RegisterRequestMonitor(base::BindRepeating(&CheckNoCookie));
  server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
  server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
  ASSERT_TRUE(server_.Start());

  ResultSavingCookieCallback<bool> cookie_callback;
  context_.cookie_store()->SetCookieWithOptionsAsync(
      server_.GetURL("/"), "foo=bar", CookieOptions(),
      base::BindRepeating(&ResultSavingCookieCallback<bool>::Run,
                          base::Unretained(&cookie_callback)));
  cookie_callback.WaitUntilDone();
  ASSERT_TRUE(cookie_callback.result());

  TestUploadCallback upload_callback;
  uploader_->StartUpload(kOrigin, server_.GetURL("/"), kUploadBody, 0,
                         upload_callback.callback());
  upload_callback.WaitForCall();
}

std::unique_ptr<test_server::HttpResponse> SendCookie(
    const test_server::HttpRequest& request) {
  auto response = std::make_unique<test_server::BasicHttpResponse>();
  response->set_code(HTTP_OK);
  response->AddCustomHeader("Set-Cookie", "foo=bar");
  response->set_content("");
  response->set_content_type("text/plain");
  return std::move(response);
}

TEST_F(ReportingUploaderTest, DontSaveCookies) {
  server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
  server_.RegisterRequestHandler(base::BindRepeating(&SendCookie));
  ASSERT_TRUE(server_.Start());

  TestUploadCallback upload_callback;
  uploader_->StartUpload(kOrigin, server_.GetURL("/"), kUploadBody, 0,
                         upload_callback.callback());
  upload_callback.WaitForCall();

  GetCookieListCallback cookie_callback;
  context_.cookie_store()->GetCookieListWithOptionsAsync(
      server_.GetURL("/"), CookieOptions(),
      base::BindRepeating(&GetCookieListCallback::Run,
                          base::Unretained(&cookie_callback)));
  cookie_callback.WaitUntilDone();

  EXPECT_TRUE(cookie_callback.cookies().empty());
}

std::unique_ptr<test_server::HttpResponse> ReturnCacheableResponse(
    int* request_count_out,
    const test_server::HttpRequest& request) {
  ++*request_count_out;
  auto response = std::make_unique<test_server::BasicHttpResponse>();
  response->set_code(HTTP_OK);
  response->AddCustomHeader("Cache-Control", "max-age=86400");
  response->set_content("");
  response->set_content_type("text/plain");
  return std::move(response);
}

// TODO(juliatuttle): This passes even if the uploader doesn't set
// LOAD_DISABLE_CACHE. Maybe that's okay -- Chromium might not cache POST
// responses ever -- but this test should either not exist or be sure that it is
// testing actual functionality, not a default.
TEST_F(ReportingUploaderTest, DontCacheResponse) {
  int request_count = 0;
  server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
  server_.RegisterRequestHandler(
      base::BindRepeating(&ReturnCacheableResponse, &request_count));
  ASSERT_TRUE(server_.Start());

  {
    TestUploadCallback callback;
    uploader_->StartUpload(kOrigin, server_.GetURL("/"), kUploadBody, 0,
                           callback.callback());
    callback.WaitForCall();
  }
  EXPECT_EQ(1, request_count);

  {
    TestUploadCallback callback;
    uploader_->StartUpload(kOrigin, server_.GetURL("/"), kUploadBody, 0,
                           callback.callback());
    callback.WaitForCall();
  }
  EXPECT_EQ(2, request_count);
}

}  // namespace
}  // namespace net
