// 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 = SbStringGetLength(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
