// Copyright 2014 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "util/net/http_transport.h"

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#include <memory>
#include <utility>
#include <vector>

#include "base/files/file_path.h"
#include "base/format_macros.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/multiprocess_exec.h"
#include "test/test_paths.h"
#include "util/file/file_io.h"
#include "util/misc/random_string.h"
#include "util/net/http_body.h"
#include "util/net/http_headers.h"
#include "util/net/http_multipart_builder.h"

namespace crashpad {
namespace test {
namespace {

#if defined(OS_WIN)
std::string ToUTF8IfWin(const base::string16& x) {
  return base::UTF16ToUTF8(x);
}
#else
std::string ToUTF8IfWin(const std::string& x) {
  return x;
}
#endif

class HTTPTransportTestFixture : public MultiprocessExec {
 public:
  using RequestValidator = void (*)(HTTPTransportTestFixture*,
                                    const std::string&);

  HTTPTransportTestFixture(const std::string& scheme,
                           const HTTPHeaders& headers,
                           std::unique_ptr<HTTPBodyStream> body_stream,
                           uint16_t http_response_code,
                           RequestValidator request_validator)
      : MultiprocessExec(),
        headers_(headers),
        body_stream_(std::move(body_stream)),
        response_code_(http_response_code),
        request_validator_(request_validator),
        cert_(),
        scheme_and_host_() {
    base::FilePath server_path = TestPaths::Executable().DirName().Append(
        FILE_PATH_LITERAL("http_transport_test_server")
#if defined(OS_WIN)
            FILE_PATH_LITERAL(".exe")
#endif
    );

    if (scheme == "http") {
      scheme_and_host_ = "http://localhost";
      SetChildCommand(server_path, nullptr);
    } else {
      std::vector<std::string> args;
      cert_ = TestPaths::TestDataRoot().Append(
          FILE_PATH_LITERAL("util/net/testdata/crashpad_util_test_cert.pem"));
      args.push_back(ToUTF8IfWin(cert_.value()));
      args.emplace_back(
          ToUTF8IfWin(TestPaths::TestDataRoot()
                          .Append(FILE_PATH_LITERAL(
                              "util/net/testdata/crashpad_util_test_key.pem"))
                          .value()));
      SetChildCommand(server_path, &args);
      scheme_and_host_ = "https://localhost";
    }
  }

  const HTTPHeaders& headers() { return headers_; }

 private:
  void MultiprocessParent() override {
    // Use Logging*File() instead of Checked*File() so that the test can fail
    // gracefully with a gtest assertion if the child does not execute properly.

    // The child will write the HTTP server port number as a packed unsigned
    // short to stdout.
    uint16_t port;
    ASSERT_TRUE(LoggingReadFileExactly(ReadPipeHandle(), &port, sizeof(port)));

    // Then the parent will tell the web server what response code to send
    // for the HTTP request.
    ASSERT_TRUE(LoggingWriteFile(
        WritePipeHandle(), &response_code_, sizeof(response_code_)));

    // The parent will also tell the web server what response body to send back.
    // The web server will only send the response body if the response code is
    // 200.
    const std::string random_string = RandomString();

    ASSERT_TRUE(LoggingWriteFile(
        WritePipeHandle(), random_string.c_str(), random_string.size()));

    // Now execute the HTTP request.
    std::unique_ptr<HTTPTransport> transport(HTTPTransport::Create());
    transport->SetMethod("POST");

    if (!cert_.empty()) {
      transport->SetRootCACertificatePath(cert_);
    }
    transport->SetURL(
        base::StringPrintf("%s:%d/upload", scheme_and_host_.c_str(), port));
    for (const auto& pair : headers_) {
      transport->SetHeader(pair.first, pair.second);
    }
    transport->SetBodyStream(std::move(body_stream_));

    std::string response_body;
    bool success = transport->ExecuteSynchronously(&response_body);
    if (response_code_ >= 200 && response_code_ <= 203) {
      EXPECT_TRUE(success);
      std::string expect_response_body = random_string + "\r\n";
      EXPECT_EQ(response_body, expect_response_body);
    } else {
      EXPECT_FALSE(success);
      EXPECT_TRUE(response_body.empty());
    }

    // Read until the child's stdout closes.
    std::string request;
    char buf[32];
    FileOperationResult bytes_read;
    while ((bytes_read = ReadFile(ReadPipeHandle(), buf, sizeof(buf))) != 0) {
      ASSERT_GE(bytes_read, 0);
      request.append(buf, bytes_read);
    }

    if (request_validator_)
      request_validator_(this, request);
  }

  HTTPHeaders headers_;
  std::unique_ptr<HTTPBodyStream> body_stream_;
  uint16_t response_code_;
  RequestValidator request_validator_;
  base::FilePath cert_;
  std::string scheme_and_host_;
};

constexpr char kMultipartFormData[] = "multipart/form-data";

void GetHeaderField(const std::string& request,
                    const std::string& header,
                    std::string* value) {
  size_t index = request.find(header);
  ASSERT_NE(index, std::string::npos);
  // Since the header is never the first line of the request, it should always
  // be preceded by a CRLF.
  EXPECT_EQ(request[index - 1], '\n');
  EXPECT_EQ(request[index - 2], '\r');

  index += header.length();
  EXPECT_EQ(request[index++], ':');
  // Per RFC 7230 §3.2, there can be one or more spaces or horizontal tabs.
  // For testing purposes, just assume one space.
  EXPECT_EQ(request[index++], ' ');

  size_t header_end = request.find('\r', index);
  ASSERT_NE(header_end, std::string::npos);

  *value = request.substr(index, header_end - index);
}

void GetMultipartBoundary(const std::string& request,
                          std::string* multipart_boundary) {
  std::string content_type;
  GetHeaderField(request, kContentType, &content_type);

  ASSERT_GE(content_type.length(), strlen(kMultipartFormData));
  size_t index = strlen(kMultipartFormData);
  EXPECT_EQ(content_type.substr(0, index), kMultipartFormData);

  EXPECT_EQ(content_type[index++], ';');

  size_t boundary_begin = content_type.find('=', index);
  ASSERT_NE(boundary_begin, std::string::npos);
  EXPECT_EQ(content_type[boundary_begin++], '=');
  if (multipart_boundary) {
    *multipart_boundary = content_type.substr(boundary_begin);
  }
}

constexpr char kBoundaryEq[] = "boundary=";

void ValidFormData(HTTPTransportTestFixture* fixture,
                   const std::string& request) {
  std::string actual_boundary;
  GetMultipartBoundary(request, &actual_boundary);

  const auto& content_type = fixture->headers().find(kContentType);
  ASSERT_NE(content_type, fixture->headers().end());

  size_t boundary = content_type->second.find(kBoundaryEq);
  ASSERT_NE(boundary, std::string::npos);
  std::string expected_boundary =
      content_type->second.substr(boundary + strlen(kBoundaryEq));
  EXPECT_EQ(actual_boundary, expected_boundary);

  size_t body_start = request.find("\r\n\r\n");
  ASSERT_NE(body_start, std::string::npos);
  body_start += 4;

  std::string expected = "--" + expected_boundary + "\r\n";
  expected += "Content-Disposition: form-data; name=\"key1\"\r\n\r\n";
  expected += "test\r\n";
  ASSERT_LT(body_start + expected.length(), request.length());
  EXPECT_EQ(request.substr(body_start, expected.length()), expected);

  body_start += expected.length();

  expected = "--" + expected_boundary + "\r\n";
  expected += "Content-Disposition: form-data; name=\"key2\"\r\n\r\n";
  expected += "--abcdefg123\r\n";
  expected += "--" + expected_boundary + "--\r\n";
  ASSERT_EQ(request.length(), body_start + expected.length());
  EXPECT_EQ(request.substr(body_start), expected);
}

class HTTPTransport : public testing::TestWithParam<std::string> {};

TEST_P(HTTPTransport, ValidFormData) {
  HTTPMultipartBuilder builder;
  builder.SetFormData("key1", "test");
  builder.SetFormData("key2", "--abcdefg123");

  HTTPHeaders headers;
  builder.PopulateContentHeaders(&headers);

  HTTPTransportTestFixture test(
      GetParam(), headers, builder.GetBodyStream(), 200, &ValidFormData);
  test.Run();
}

TEST_P(HTTPTransport, ValidFormData_Gzip) {
  HTTPMultipartBuilder builder;
  builder.SetGzipEnabled(true);
  builder.SetFormData("key1", "test");
  builder.SetFormData("key2", "--abcdefg123");

  HTTPHeaders headers;
  builder.PopulateContentHeaders(&headers);

  HTTPTransportTestFixture test(
      GetParam(), headers, builder.GetBodyStream(), 200, &ValidFormData);
  test.Run();
}

constexpr char kTextPlain[] = "text/plain";

void ErrorResponse(HTTPTransportTestFixture* fixture,
                   const std::string& request) {
  std::string content_type;
  GetHeaderField(request, kContentType, &content_type);
  EXPECT_EQ(content_type, kTextPlain);
}

TEST_P(HTTPTransport, ErrorResponse) {
  HTTPMultipartBuilder builder;
  HTTPHeaders headers;
  headers[kContentType] = kTextPlain;
  HTTPTransportTestFixture test(
      GetParam(), headers, builder.GetBodyStream(), 404, &ErrorResponse);
  test.Run();
}

constexpr char kTextBody[] = "hello world";

void UnchunkedPlainText(HTTPTransportTestFixture* fixture,
                        const std::string& request) {
  std::string header_value;
  GetHeaderField(request, kContentType, &header_value);
  EXPECT_EQ(header_value, kTextPlain);

  GetHeaderField(request, kContentLength, &header_value);
  const auto& content_length = fixture->headers().find(kContentLength);
  ASSERT_NE(content_length, fixture->headers().end());
  EXPECT_EQ(header_value, content_length->second);

  size_t body_start = request.rfind("\r\n");
  ASSERT_NE(body_start, std::string::npos);

  EXPECT_EQ(request.substr(body_start + 2), kTextBody);
}

TEST_P(HTTPTransport, UnchunkedPlainText) {
  std::unique_ptr<HTTPBodyStream> body_stream(
      new StringHTTPBodyStream(kTextBody));

  HTTPHeaders headers;
  headers[kContentType] = kTextPlain;
  headers[kContentLength] = base::StringPrintf("%" PRIuS, strlen(kTextBody));

  HTTPTransportTestFixture test(
      GetParam(), headers, std::move(body_stream), 200, &UnchunkedPlainText);
  test.Run();
}

void RunUpload33k(const std::string& scheme, bool has_content_length) {
  // On macOS, NSMutableURLRequest winds up calling into a CFReadStream’s Read()
  // callback with a 32kB buffer. Make sure that it’s able to get everything
  // when enough is available to fill this buffer, requiring more than one
  // Read().

  std::string request_string(33 * 1024, 'a');
  std::unique_ptr<HTTPBodyStream> body_stream(
      new StringHTTPBodyStream(request_string));

  HTTPHeaders headers;
  headers[kContentType] = "application/octet-stream";
  if (has_content_length) {
    headers[kContentLength] =
        base::StringPrintf("%" PRIuS, request_string.size());
  }
  HTTPTransportTestFixture test(
      scheme,
      headers,
      std::move(body_stream),
      200,
      [](HTTPTransportTestFixture* fixture, const std::string& request) {
        size_t body_start = request.rfind("\r\n");
        EXPECT_EQ(request.size() - body_start, 33 * 1024u + 2);
      });
  test.Run();
}

TEST_P(HTTPTransport, Upload33k) {
  RunUpload33k(GetParam(), true);
}

TEST_P(HTTPTransport, Upload33k_LengthUnknown) {
  // The same as Upload33k, but without declaring Content-Length ahead of time.
  RunUpload33k(GetParam(), false);
}

// This should be on for Fuchsia, but DX-382. Debug and re-enabled.
#if defined(CRASHPAD_USE_BORINGSSL) && !defined(OS_FUCHSIA)
// The test server requires BoringSSL or OpenSSL, so https in tests can only be
// enabled where that's readily available. Additionally on Linux, the bots fail
// lacking libcrypto.so.1.1, so disabled there for now. On Mac, they could also
// likely be enabled relatively easily, if HTTPTransportMac learned to respect
// the user-supplied cert.
//
// If tests with boringssl are failing because of expired certificates, try
// re-running generate_test_server_key.py.
INSTANTIATE_TEST_SUITE_P(HTTPTransport,
                         HTTPTransport,
                         testing::Values("http", "https"),
                         [](const testing::TestParamInfo<std::string>& info) {
                           return info.param;
                         });
#else
INSTANTIATE_TEST_SUITE_P(HTTPTransport,
                         HTTPTransport,
                         testing::Values("http"),
                         [](const testing::TestParamInfo<std::string>& info) {
                           return info.param;
                         });
#endif

}  // namespace
}  // namespace test
}  // namespace crashpad
