// Copyright 2018 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/tools/quic/quic_http_proxy_backend_stream.h"
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_task_environment.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/embedded_test_server/request_handler_util.h"
#include "net/third_party/quic/platform/api/quic_test.h"
#include "net/third_party/quic/tools/quic_backend_response.h"
#include "net/tools/quic/quic_http_proxy_backend.h"
#include "starboard/common/string.h"

namespace net {
namespace test {

// Test server path and response body for the default URL used by many of the
// tests.
const char kDefaultResponsePath[] = "/defaultresponse";
const char kDefaultResponseBody[] =
    "Default response given for path: /defaultresponse";
std::string kLargeResponseBody(
    "Default response given for path: /defaultresponselarge");
const char* const kHttp2StatusHeader = ":status";

// To test uploading the contents of a file
base::FilePath GetUploadFileTestPath() {
  base::FilePath path;
  base::PathService::Get(base::DIR_TEST_DATA, &path);
  return path.Append(
      FILE_PATH_LITERAL("net/data/url_request_unittest/BullRunSpeech.txt"));
}

// /defaultresponselarge
// Returns a valid 10 MB response.
std::unique_ptr<test_server::HttpResponse> HandleDefaultResponseLarge(
    const test_server::HttpRequest& request) {
  std::unique_ptr<test_server::BasicHttpResponse> http_response(
      new test_server::BasicHttpResponse);
  http_response->set_content_type("text/html");
  // return 10 MB
  for (int i = 0; i < 200000; ++i)
    kLargeResponseBody += "01234567890123456789012345678901234567890123456789";
  http_response->set_content(kLargeResponseBody);

  return std::move(http_response);
}

int ParseHeaderStatusCode(const spdy::SpdyHeaderBlock& header) {
  int status_code;
  spdy::SpdyHeaderBlock::const_iterator it = header.find(kHttp2StatusHeader);
  if (it == header.end()) {
    return -1;
  }
  const base::StringPiece status(it->second);
  if (status.size() != 3) {
    return -1;
  }
  // First character must be an integer in range [1,5].
  if (status[0] < '1' || status[0] > '5') {
    return -1;
  }
  // The remaining two characters must be integers.
  if (!isdigit(status[1]) || !isdigit(status[2])) {
    return -1;
  }
  if (base::StringToInt(status, &status_code)) {
    return status_code;
  } else {
    return -1;
  }
}

class TestQuicServerStreamDelegate
    : public quic::QuicSimpleServerBackend::RequestHandler {
 public:
  TestQuicServerStreamDelegate()
      : send_success_(false),
        did_complete_(false),
        quic_backend_stream_(nullptr) {}

  ~TestQuicServerStreamDelegate() override {}

  void CreateProxyBackendResponseStreamForTest(
      QuicHttpProxyBackend* proxy_backend) {
    quic_backend_stream_ =
        std::make_unique<QuicHttpProxyBackendStream>(proxy_backend);
    quic_backend_stream_->set_delegate(this);
    quic_backend_stream_->Initialize(connection_id(), stream_id(), peer_host());
  }

  QuicHttpProxyBackendStream* get_proxy_backend_stream() const {
    return quic_backend_stream_.get();
  }

  const net::HttpRequestHeaders& get_request_headers() const {
    return quic_backend_stream_->request_headers();
  }

  void StartHttpRequestToBackendAndWait(
      spdy::SpdyHeaderBlock* incoming_request_headers,
      const std::string& incoming_body) {
    send_success_ = quic_backend_stream_->SendRequestToBackend(
        incoming_request_headers, incoming_body);
    EXPECT_TRUE(send_success_);
    WaitForComplete();
  }

  void WaitForComplete() {
    EXPECT_TRUE(task_runner_->BelongsToCurrentThread());
    run_loop_.Run();
  }

  quic::QuicConnectionId connection_id() const override { return 123; };
  quic::QuicStreamId stream_id() const override { return 5; };
  std::string peer_host() const override { return "127.0.0.1"; };

  void OnResponseBackendComplete(
      const quic::QuicBackendResponse* response,
      std::list<quic::QuicBackendResponse::ServerPushInfo> resources) override {
    EXPECT_TRUE(task_runner_->BelongsToCurrentThread());
    EXPECT_FALSE(did_complete_);
    EXPECT_TRUE(quic_backend_stream_);
    did_complete_ = true;
    task_runner_->PostTask(FROM_HERE, run_loop_.QuitClosure());
  }

 private:
  bool send_success_;
  bool did_complete_;
  std::unique_ptr<QuicHttpProxyBackendStream> quic_backend_stream_;
  base::test::ScopedTaskEnvironment scoped_task_environment;
  const scoped_refptr<base::SingleThreadTaskRunner> task_runner_ =
      base::ThreadTaskRunnerHandle::Get();
  base::RunLoop run_loop_;
};

class QuicHttpProxyBackendStreamTest : public QuicTest {
 public:
  QuicHttpProxyBackendStreamTest() {}

  ~QuicHttpProxyBackendStreamTest() override {}

  // testing::Test:
  void SetUp() override {
    SetUpServer();
    ASSERT_TRUE(test_server_->Start());

    backend_url_ = base::StringPrintf("http://127.0.0.1:%d",
                                      test_server_->host_port_pair().port());
    CreateTestBackendProxy();
    CreateTestBackendProxyToTestFailure();
  }

  void CreateTestBackendProxy() {
    ASSERT_TRUE(GURL(backend_url_).is_valid());
    proxy_backend_ = std::make_unique<QuicHttpProxyBackend>();
    proxy_backend_->InitializeBackend(backend_url_);
  }

  void CreateTestBackendProxyToTestFailure() {
    // To test against a non-running backend http server
    std::string backend_fail_url =
        base::StringPrintf("http://127.0.0.1:%d", 52);
    ASSERT_TRUE(GURL(backend_fail_url).is_valid());
    proxy_backend_fail_ = std::make_unique<QuicHttpProxyBackend>();
    proxy_backend_fail_->InitializeBackend(backend_fail_url);
  }

  // Initializes |test_server_| without starting it.  Allows subclasses to use
  // their own server configuration.
  void SetUpServer() {
    test_server_.reset(new EmbeddedTestServer);
    test_server_->AddDefaultHandlers(base::FilePath());
    test_server_->RegisterDefaultHandler(base::BindRepeating(
        &net::test_server::HandlePrefixedRequest, "/defaultresponselarge",
        base::BindRepeating(&HandleDefaultResponseLarge)));
  }

 protected:
  std::string backend_url_;
  std::unique_ptr<QuicHttpProxyBackend> proxy_backend_;
  std::unique_ptr<QuicHttpProxyBackend> proxy_backend_fail_;
  std::unique_ptr<EmbeddedTestServer> test_server_;
};

TEST_F(QuicHttpProxyBackendStreamTest, SendRequestToBackendGetDefault) {
  spdy::SpdyHeaderBlock request_headers;
  request_headers[":path"] = kDefaultResponsePath;
  request_headers[":authority"] = "www.example.org";
  request_headers[":version"] = "HTTP/1.1";
  request_headers[":method"] = "GET";

  TestQuicServerStreamDelegate delegate;
  delegate.CreateProxyBackendResponseStreamForTest(proxy_backend_.get());
  delegate.StartHttpRequestToBackendAndWait(&request_headers, "");

  quic::QuicBackendResponse* quic_response =
      delegate.get_proxy_backend_stream()->GetBackendResponse();
  EXPECT_EQ(quic::QuicBackendResponse::REGULAR_RESPONSE,
            quic_response->response_type());
  EXPECT_EQ(200, ParseHeaderStatusCode(quic_response->headers()));
  EXPECT_EQ(kDefaultResponseBody, quic_response->body());
}

TEST_F(QuicHttpProxyBackendStreamTest, SendRequestToBackendGetLarge) {
  spdy::SpdyHeaderBlock request_headers;
  request_headers[":path"] = "/defaultresponselarge";
  request_headers[":authority"] = "www.example.org";
  request_headers[":version"] = "HTTP/1.1";
  request_headers[":method"] = "GET";

  TestQuicServerStreamDelegate delegate;
  delegate.CreateProxyBackendResponseStreamForTest(proxy_backend_.get());
  delegate.StartHttpRequestToBackendAndWait(&request_headers, "");

  quic::QuicBackendResponse* quic_response =
      delegate.get_proxy_backend_stream()->GetBackendResponse();
  EXPECT_EQ(quic::QuicBackendResponse::REGULAR_RESPONSE,
            quic_response->response_type());
  EXPECT_EQ(200, ParseHeaderStatusCode(quic_response->headers()));
  // kLargeResponseBody should be populated with huge response
  // already in HandleDefaultResponseLarge()
  EXPECT_EQ(kLargeResponseBody, quic_response->body());
}

TEST_F(QuicHttpProxyBackendStreamTest, SendRequestToBackendPostBody) {
  const char kUploadData[] = "bobsyeruncle";
  spdy::SpdyHeaderBlock request_headers;
  request_headers[":path"] = "/echo";
  request_headers[":version"] = "HTTP/2.0";
  request_headers[":version"] = "HTTP/1.1";
  request_headers[":method"] = "POST";
  request_headers["content-length"] = "12";
  request_headers["content-type"] = "application/x-www-form-urlencoded";

  TestQuicServerStreamDelegate delegate;
  delegate.CreateProxyBackendResponseStreamForTest(proxy_backend_.get());
  delegate.StartHttpRequestToBackendAndWait(&request_headers, kUploadData);

  quic::QuicBackendResponse* quic_response =
      delegate.get_proxy_backend_stream()->GetBackendResponse();

  EXPECT_EQ(quic::QuicBackendResponse::REGULAR_RESPONSE,
            quic_response->response_type());
  EXPECT_EQ(200, ParseHeaderStatusCode(quic_response->headers()));
  EXPECT_EQ(kUploadData, quic_response->body());
}

TEST_F(QuicHttpProxyBackendStreamTest, SendRequestToBackendPostEmptyString) {
  const char kUploadData[] = "";
  spdy::SpdyHeaderBlock request_headers;
  request_headers[":path"] = "/echo";
  request_headers[":authority"] = "www.example.org";
  request_headers[":version"] = "HTTP/2.0";
  request_headers[":method"] = "POST";
  request_headers["content-length"] = "0";
  request_headers["content-type"] = "application/x-www-form-urlencoded";

  TestQuicServerStreamDelegate delegate;
  delegate.CreateProxyBackendResponseStreamForTest(proxy_backend_.get());
  delegate.StartHttpRequestToBackendAndWait(&request_headers, kUploadData);

  quic::QuicBackendResponse* quic_response =
      delegate.get_proxy_backend_stream()->GetBackendResponse();

  EXPECT_EQ(quic::QuicBackendResponse::REGULAR_RESPONSE,
            quic_response->response_type());
  EXPECT_EQ(200, ParseHeaderStatusCode(quic_response->headers()));
  EXPECT_EQ(kUploadData, quic_response->body());
}

TEST_F(QuicHttpProxyBackendStreamTest, SendRequestToBackendPostFile) {
  std::string kUploadData;
  base::FilePath upload_path = GetUploadFileTestPath();
  ASSERT_TRUE(base::ReadFileToString(upload_path, &kUploadData));

  spdy::SpdyHeaderBlock request_headers;
  request_headers[":path"] = "/echo";
  request_headers[":authority"] = "www.example.org";
  request_headers[":version"] = "HTTP/2.0";
  request_headers[":method"] = "POST";
  request_headers["content-type"] = "application/x-www-form-urlencoded";

  TestQuicServerStreamDelegate delegate;
  delegate.CreateProxyBackendResponseStreamForTest(proxy_backend_.get());
  delegate.StartHttpRequestToBackendAndWait(&request_headers, kUploadData);

  quic::QuicBackendResponse* quic_response =
      delegate.get_proxy_backend_stream()->GetBackendResponse();

  EXPECT_EQ(quic::QuicBackendResponse::REGULAR_RESPONSE,
            quic_response->response_type());
  EXPECT_EQ(200, ParseHeaderStatusCode(quic_response->headers()));
  EXPECT_EQ(kUploadData, quic_response->body());
}

TEST_F(QuicHttpProxyBackendStreamTest, SendRequestToBackendResponse500) {
  const char kUploadData[] = "bobsyeruncle";
  spdy::SpdyHeaderBlock request_headers;
  request_headers[":path"] = "/echo?status=500";
  request_headers[":authority"] = "www.example.org";
  request_headers[":version"] = "HTTP/2.0";
  request_headers[":method"] = "POST";

  TestQuicServerStreamDelegate delegate;
  delegate.CreateProxyBackendResponseStreamForTest(proxy_backend_.get());
  delegate.StartHttpRequestToBackendAndWait(&request_headers, kUploadData);

  quic::QuicBackendResponse* quic_response =
      delegate.get_proxy_backend_stream()->GetBackendResponse();

  EXPECT_EQ(quic::QuicBackendResponse::REGULAR_RESPONSE,
            quic_response->response_type());
  EXPECT_EQ(500, ParseHeaderStatusCode(quic_response->headers()));
}

TEST_F(QuicHttpProxyBackendStreamTest, SendRequestToBackendFail) {
  const char kUploadData[] = "bobsyeruncle";
  spdy::SpdyHeaderBlock request_headers;
  request_headers[":path"] = "/echo";
  request_headers[":authority"] = "www.example.org";
  request_headers[":version"] = "HTTP/2.0";
  request_headers[":method"] = "POST";

  TestQuicServerStreamDelegate delegate;
  delegate.CreateProxyBackendResponseStreamForTest(proxy_backend_fail_.get());
  delegate.StartHttpRequestToBackendAndWait(&request_headers, kUploadData);

  quic::QuicBackendResponse* quic_response =
      delegate.get_proxy_backend_stream()->GetBackendResponse();

  EXPECT_EQ(quic::QuicBackendResponse::BACKEND_ERR_RESPONSE,
            quic_response->response_type());
}

TEST_F(QuicHttpProxyBackendStreamTest, SendRequestToBackendOnRedirect) {
  const std::string kRedirectTarget = backend_url_.append("/echo");
  spdy::SpdyHeaderBlock request_headers;
  request_headers[":path"] = std::string("/server-redirect?") + kRedirectTarget;
  request_headers[":authority"] = "www.example.org";
  request_headers[":version"] = "HTTP/2.0";
  request_headers[":method"] = "GET";

  TestQuicServerStreamDelegate delegate;
  delegate.CreateProxyBackendResponseStreamForTest(proxy_backend_.get());
  delegate.StartHttpRequestToBackendAndWait(&request_headers, "");

  quic::QuicBackendResponse* quic_response =
      delegate.get_proxy_backend_stream()->GetBackendResponse();

  EXPECT_EQ(quic::QuicBackendResponse::REGULAR_RESPONSE,
            quic_response->response_type());
  EXPECT_EQ(200, ParseHeaderStatusCode(quic_response->headers()));
}

// Ensure that the proxy rewrites the content-length when receiving a Gzipped
// response
TEST_F(QuicHttpProxyBackendStreamTest, SendRequestToBackendHandleGzip) {
  const char kGzipData[] =
      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!!";
  uint64_t rawBodyLength = strlen(kGzipData);
  spdy::SpdyHeaderBlock request_headers;
  request_headers[":path"] = std::string("/gzip-body?") + kGzipData;
  request_headers[":authority"] = "www.example.org";
  request_headers[":version"] = "HTTP/2.0";
  request_headers[":method"] = "GET";

  TestQuicServerStreamDelegate delegate;
  delegate.CreateProxyBackendResponseStreamForTest(proxy_backend_.get());
  delegate.StartHttpRequestToBackendAndWait(&request_headers, "");

  quic::QuicBackendResponse* quic_response =
      delegate.get_proxy_backend_stream()->GetBackendResponse();

  EXPECT_EQ(quic::QuicBackendResponse::REGULAR_RESPONSE,
            quic_response->response_type());
  EXPECT_EQ(200, ParseHeaderStatusCode(quic_response->headers()));
  EXPECT_EQ(kGzipData, quic_response->body());
  spdy::SpdyHeaderBlock quic_response_headers =
      quic_response->headers().Clone();

  // Ensure that the content length is set to the raw body size (unencoded)
  auto responseLength = quic_response_headers.find("content-length");
  uint64_t response_header_content_length = 0;
  if (responseLength != quic_response_headers.end()) {
    base::StringToUint64(responseLength->second,
                         &response_header_content_length);
  }
  EXPECT_EQ(rawBodyLength, response_header_content_length);

  // Ensure the content-encoding header is removed for the quic response
  EXPECT_EQ(quic_response_headers.end(),
            quic_response_headers.find("content-encoding"));
}

// Ensure cookies are not saved/updated at the proxy
TEST_F(QuicHttpProxyBackendStreamTest, SendRequestToBackendCookiesNotSaved) {
  spdy::SpdyHeaderBlock request_headers;
  request_headers[":authority"] = "www.example.org";
  request_headers[":method"] = "GET";

  {
    TestQuicServerStreamDelegate delegate;
    request_headers[":path"] =
        "/set-cookie?CookieToNotSave=1&CookieToNotUpdate=1";
    delegate.CreateProxyBackendResponseStreamForTest(proxy_backend_.get());
    delegate.StartHttpRequestToBackendAndWait(&request_headers, "");

    quic::QuicBackendResponse* quic_response =
        delegate.get_proxy_backend_stream()->GetBackendResponse();

    EXPECT_EQ(200, ParseHeaderStatusCode(quic_response->headers()));
    spdy::SpdyHeaderBlock quic_response_headers =
        quic_response->headers().Clone();
    EXPECT_TRUE(quic_response_headers.end() !=
                quic_response_headers.find("set-cookie"));
    auto cookie = quic_response_headers.find("set-cookie");
    EXPECT_TRUE(cookie->second.find("CookieToNotSave=1") != std::string::npos);
    EXPECT_TRUE(cookie->second.find("CookieToNotUpdate=1") !=
                std::string::npos);
  }
  {
    TestQuicServerStreamDelegate delegate;
    request_headers[":path"] = "/echoheader?Cookie";
    delegate.CreateProxyBackendResponseStreamForTest(proxy_backend_.get());
    delegate.StartHttpRequestToBackendAndWait(&request_headers, "");

    quic::QuicBackendResponse* quic_response =
        delegate.get_proxy_backend_stream()->GetBackendResponse();

    EXPECT_EQ(200, ParseHeaderStatusCode(quic_response->headers()));
    EXPECT_TRUE(quic_response->body().find("CookieToNotSave=1") ==
                std::string::npos);
    EXPECT_TRUE(quic_response->body().find("CookieToNotUpdate=1") ==
                std::string::npos);
  }
}

// Ensure hop-by-hop headers are removed from the request and response to the
// backend
TEST_F(QuicHttpProxyBackendStreamTest, SendRequestToBackendHopHeaders) {
  spdy::SpdyHeaderBlock request_headers;
  request_headers[":path"] = "/echoall";
  request_headers[":authority"] = "www.example.org";
  request_headers[":method"] = "GET";
  std::set<std::string>::iterator it;
  for (it = QuicHttpProxyBackendStream::kHopHeaders.begin();
       it != QuicHttpProxyBackendStream::kHopHeaders.end(); ++it) {
    request_headers[*it] = "SomeString";
  }

  TestQuicServerStreamDelegate delegate;
  delegate.CreateProxyBackendResponseStreamForTest(proxy_backend_.get());
  delegate.StartHttpRequestToBackendAndWait(&request_headers, "");
  const net::HttpRequestHeaders& actual_request_headers =
      delegate.get_request_headers();
  for (it = QuicHttpProxyBackendStream::kHopHeaders.begin();
       it != QuicHttpProxyBackendStream::kHopHeaders.end(); ++it) {
    EXPECT_FALSE(actual_request_headers.HasHeader(*it));
  }

  quic::QuicBackendResponse* quic_response =
      delegate.get_proxy_backend_stream()->GetBackendResponse();
  EXPECT_EQ(200, ParseHeaderStatusCode(quic_response->headers()));
  spdy::SpdyHeaderBlock quic_response_headers =
      quic_response->headers().Clone();
  for (it = QuicHttpProxyBackendStream::kHopHeaders.begin();
       it != QuicHttpProxyBackendStream::kHopHeaders.end(); ++it) {
    EXPECT_EQ(quic_response_headers.end(), quic_response_headers.find(*it));
  }
}

}  // namespace test
}  // namespace net
