// 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 "net/test/embedded_test_server/default_handlers.h"

#include <stdlib.h>

#include <ctime>
#include <map>
#include <memory>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include "base/base64.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/format_macros.h"
#include "base/macros.h"
#include "base/md5.h"
#include "base/path_service.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/unguessable_token.h"
#include "net/base/escape.h"
#include "net/base/host_port_pair.h"
#include "net/base/url_util.h"
#include "net/filter/filter_source_stream_test_util.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 "starboard/types.h"

namespace net {
namespace test_server {
namespace {

const char kDefaultRealm[] = "testrealm";
const char kDefaultPassword[] = "secret";
const char kEtag[] = "abc";
const char kLogoPath[] = "chrome/test/data/google/logo.gif";

// method: CONNECT
// Responses with a BAD_REQUEST to any CONNECT requests.
std::unique_ptr<HttpResponse> HandleDefaultConnect(const HttpRequest& request) {
  if (request.method != METHOD_CONNECT)
    return nullptr;

  std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
  http_response->set_code(HTTP_BAD_REQUEST);
  http_response->set_content(
      "Your client has issued a malformed or illegal request.");
  http_response->set_content_type("text/html");
  return std::move(http_response);
}

// /cachetime
// Returns a cacheable response.
std::unique_ptr<HttpResponse> HandleCacheTime(const HttpRequest& request) {
  std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
  http_response->set_content(
      "<html><head><title>Cache: max-age=60</title></head></html>");
  http_response->set_content_type("text/html");
  http_response->AddCustomHeader("Cache-Control", "max-age=60");
  return std::move(http_response);
}

// /echoheader?HEADERS | /echoheadercache?HEADERS
// Responds with the headers echoed in the message body.
// echoheader does not cache the results, while echoheadercache does.
std::unique_ptr<HttpResponse> HandleEchoHeader(const std::string& url,
                                               const std::string& cache_control,
                                               const HttpRequest& request) {
  if (!ShouldHandle(request, url))
    return nullptr;

  std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);

  GURL request_url = request.GetURL();
  std::string vary;
  std::string content;
  RequestQuery headers = ParseQuery(request_url);
  for (const auto& header : headers) {
    std::string header_name = header.first;
    std::string header_value = "None";
    if (request.headers.find(header_name) != request.headers.end())
      header_value = request.headers.at(header_name);
    if (!vary.empty())
      vary += ",";
    vary += header_name;
    if (!content.empty())
      content += "\n";
    content += header_value;
  }

  http_response->AddCustomHeader("Vary", vary);
  http_response->set_content(content);
  http_response->set_content_type("text/plain");
  http_response->AddCustomHeader("Cache-Control", cache_control);
  return std::move(http_response);
}

// /echo?status=STATUS
// Responds with the request body as the response body and
// a status code of STATUS.
std::unique_ptr<HttpResponse> HandleEcho(const HttpRequest& request) {
  std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);

  GURL request_url = request.GetURL();
  if (request_url.has_query()) {
    RequestQuery query = ParseQuery(request_url);
    if (query.find("status") != query.end())
      http_response->set_code(static_cast<HttpStatusCode>(
          std::atoi(query["status"].front().c_str())));
  }

  http_response->set_content_type("text/html");
  if (request.method != METHOD_POST && request.method != METHOD_PUT)
    http_response->set_content("Echo");
  else
    http_response->set_content(request.content);
  return std::move(http_response);
}

// /echotitle
// Responds with the request body as the title.
std::unique_ptr<HttpResponse> HandleEchoTitle(const HttpRequest& request) {
  std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
  http_response->set_content_type("text/html");
  http_response->set_content("<html><head><title>" + request.content +
                             "</title></head></html>");
  return std::move(http_response);
}

// /echoall?QUERY
// Responds with the list of QUERY and the request headers.
//
// Alternative form:
// /echoall/nocache?QUERY prevents caching of the response.
std::unique_ptr<HttpResponse> HandleEchoAll(const HttpRequest& request) {
  std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);

  std::string body =
      "<html><head><title>EmbeddedTestServer - EchoAll</title><style>"
      "pre { border: 1px solid black; margin: 5px; padding: 5px }"
      "</style></head><body>"
      "<div style=\"float: right\">"
      "<a href=\"/echo\">back to referring page</a></div>"
      "<h1>Request Body:</h1><pre>";

  if (request.has_content) {
    std::vector<std::string> query_list = base::SplitString(
        request.content, "&", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
    for (const auto& query : query_list)
      body += query + "\n";
  }

  body +=
      "</pre>"
      "<h1>Request Headers:</h1><pre>" +
      request.all_headers + "</pre>" +
      "<h1>Response nonce:</h1><pre id='response-nonce'>" +
      base::UnguessableToken::Create().ToString() + "</pre></body></html>";

  http_response->set_content_type("text/html");
  http_response->set_content(body);

  if (base::EndsWith(request.GetURL().path_piece(), "/nocache",
                     base::CompareCase::SENSITIVE)) {
    http_response->AddCustomHeader("Cache-Control",
                                   "no-cache, no-store, must-revalidate");
  }

  return std::move(http_response);
}

// /echo-raw
// Returns the query string as the raw response (no HTTP headers).
std::unique_ptr<HttpResponse> HandleEchoRaw(const HttpRequest& request) {
  return std::make_unique<RawHttpResponse>("", request.GetURL().query());
}

// /set-cookie?COOKIES
// Sets response cookies to be COOKIES.
std::unique_ptr<HttpResponse> HandleSetCookie(const HttpRequest& request) {
  std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
  http_response->set_content_type("text/html");
  std::string content;
  GURL request_url = request.GetURL();
  if (request_url.has_query()) {
    std::vector<std::string> cookies = base::SplitString(
        request_url.query(), "&", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
    for (const auto& cookie : cookies) {
      http_response->AddCustomHeader("Set-Cookie", cookie);
      content += cookie;
    }
  }

  http_response->set_content(content);
  return std::move(http_response);
}

// /set-many-cookies?N
// Sets N cookies in the response.
std::unique_ptr<HttpResponse> HandleSetManyCookies(const HttpRequest& request) {
  std::string content;

  GURL request_url = request.GetURL();
  size_t num = 0;
  if (request_url.has_query())
    num = std::atoi(request_url.query().c_str());

  std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
  http_response->set_content_type("text/html");
  for (size_t i = 0; i < num; ++i) {
    http_response->AddCustomHeader("Set-Cookie", "a=");
  }

  http_response->set_content(
      base::StringPrintf("%" PRIuS " cookies were sent", num));
  return std::move(http_response);
}

// /expect-and-set-cookie?expect=EXPECTED&set=SET&data=DATA
// Verifies that the request cookies match EXPECTED and then returns cookies
// that match SET and a content that matches DATA.
std::unique_ptr<HttpResponse> HandleExpectAndSetCookie(
    const HttpRequest& request) {
  std::vector<std::string> received_cookies;
  if (request.headers.find("Cookie") != request.headers.end()) {
    received_cookies =
        base::SplitString(request.headers.at("Cookie"), ";",
                          base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  }

  bool got_all_expected = true;
  GURL request_url = request.GetURL();
  RequestQuery query_list = ParseQuery(request_url);
  if (query_list.find("expect") != query_list.end()) {
    for (const auto& expected_cookie : query_list.at("expect")) {
      bool found = false;
      for (const auto& received_cookie : received_cookies) {
        if (expected_cookie == received_cookie)
          found = true;
      }
      got_all_expected &= found;
    }
  }

  std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
  http_response->set_content_type("text/html");
  if (got_all_expected) {
    for (const auto& cookie : query_list.at("set")) {
      std::string unescaped_cookie;
      UnescapeBinaryURLComponent(cookie, UnescapeRule::REPLACE_PLUS_WITH_SPACE,
                                 &unescaped_cookie);
      http_response->AddCustomHeader("Set-Cookie", unescaped_cookie);
    }
  }

  std::string content;
  if (query_list.find("data") != query_list.end()) {
    for (const auto& item : query_list.at("data"))
      content += item;
  }

  http_response->set_content(content);
  return std::move(http_response);
}

// /set-header?HEADERS
// Returns a response with HEADERS set as the response headers.
std::unique_ptr<HttpResponse> HandleSetHeader(const HttpRequest& request) {
  std::string content;

  GURL request_url = request.GetURL();

  std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
  http_response->set_content_type("text/html");
  if (request_url.has_query()) {
    RequestQuery headers = ParseQuery(request_url);
    for (const auto& header : headers) {
      size_t delimiter = header.first.find(": ");
      if (delimiter == std::string::npos)
        continue;
      std::string key = header.first.substr(0, delimiter);
      std::string value = header.first.substr(delimiter + 2);
      http_response->AddCustomHeader(key, value);
      content += header.first;
    }
  }

  http_response->set_content(content);
  return std::move(http_response);
}

// /nocontent
// Returns a NO_CONTENT response.
std::unique_ptr<HttpResponse> HandleNoContent(const HttpRequest& request) {
  std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
  http_response->set_code(HTTP_NO_CONTENT);
  return std::move(http_response);
}

// /close-socket
// Immediately closes the connection.
std::unique_ptr<HttpResponse> HandleCloseSocket(const HttpRequest& request) {
  std::unique_ptr<RawHttpResponse> http_response(new RawHttpResponse("", ""));
  return std::move(http_response);
}

// /auth-basic?password=PASS&realm=REALM
// Performs "Basic" HTTP authentication using expected password PASS and
// realm REALM.
std::unique_ptr<HttpResponse> HandleAuthBasic(const HttpRequest& request) {
  GURL request_url = request.GetURL();
  RequestQuery query = ParseQuery(request_url);

  std::string expected_password = kDefaultPassword;
  if (query.find("password") != query.end())
    expected_password = query.at("password").front();
  std::string realm = kDefaultRealm;
  if (query.find("realm") != query.end())
    realm = query.at("realm").front();

  bool authed = false;
  std::string error;
  std::string auth;
  std::string username;
  std::string userpass;
  std::string password;
  std::string b64str;
  if (request.headers.find("Authorization") == request.headers.end()) {
    error = "Missing Authorization Header";
  } else {
    auth = request.headers.at("Authorization");
    if (auth.find("Basic ") == std::string::npos) {
      error = "Invalid Authorization Header";
    } else {
      b64str = auth.substr(std::string("Basic ").size());
      base::Base64Decode(b64str, &userpass);
      size_t delimiter = userpass.find(":");
      if (delimiter != std::string::npos) {
        username = userpass.substr(0, delimiter);
        password = userpass.substr(delimiter + 1);
        if (password == expected_password)
          authed = true;
        else
          error = "Invalid Credentials";
      } else {
        error = "Invalid Credentials";
      }
    }
  }

  std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
  if (!authed) {
    http_response->set_code(HTTP_UNAUTHORIZED);
    http_response->set_content_type("text/html");
    http_response->AddCustomHeader("WWW-Authenticate",
                                   "Basic realm=\"" + realm + "\"");
    if (query.find("set-cookie-if-challenged") != query.end())
      http_response->AddCustomHeader("Set-Cookie", "got_challenged=true");
    http_response->set_content(base::StringPrintf(
        "<html><head><title>Denied: %s</title></head>"
        "<body>auth=%s<p>b64str=%s<p>username: %s<p>userpass: %s<p>"
        "password: %s<p>You sent:<br>%s<p></body></html>",
        error.c_str(), auth.c_str(), b64str.c_str(), username.c_str(),
        userpass.c_str(), password.c_str(), request.all_headers.c_str()));
    return std::move(http_response);
  }

  if (request.headers.find("If-None-Match") != request.headers.end() &&
      request.headers.at("If-None-Match") == kEtag) {
    http_response->set_code(HTTP_NOT_MODIFIED);
    return std::move(http_response);
  }

  base::FilePath file_path =
      base::FilePath().AppendASCII(request.relative_url.substr(1));
  if (file_path.FinalExtension() == FILE_PATH_LITERAL("gif")) {
    base::FilePath server_root;
    base::PathService::Get(base::DIR_TEST_DATA, &server_root);
    base::FilePath gif_path = server_root.AppendASCII(kLogoPath);
    std::string gif_data;
    base::ReadFileToString(gif_path, &gif_data);
    http_response->set_content_type("image/gif");
    http_response->set_content(gif_data);
  } else {
    http_response->set_content_type("text/html");
    http_response->set_content(
        base::StringPrintf("<html><head><title>%s/%s</title></head>"
                           "<body>auth=%s<p>You sent:<br>%s<p></body></html>",
                           username.c_str(), password.c_str(), auth.c_str(),
                           request.all_headers.c_str()));
  }

  http_response->AddCustomHeader("Cache-Control", "max-age=60000");
  http_response->AddCustomHeader("Etag", kEtag);
  return std::move(http_response);
}

// /auth-digest
// Performs "Digest" HTTP authentication.
std::unique_ptr<HttpResponse> HandleAuthDigest(const HttpRequest& request) {
  std::string nonce = base::MD5String(
      base::StringPrintf("privatekey%s", request.relative_url.c_str()));
  std::string opaque = base::MD5String("opaque");
  std::string password = kDefaultPassword;
  std::string realm = kDefaultRealm;

  bool authed = false;
  std::string error;
  std::string auth;
  std::string digest_str = "Digest";
  std::string username;
  if (request.headers.find("Authorization") == request.headers.end()) {
    error = "no auth";
  } else if (request.headers.at("Authorization").substr(0, digest_str.size()) !=
             digest_str) {
    error = "not digest";
  } else {
    auth = request.headers.at("Authorization").substr(digest_str.size() + 1);

    std::map<std::string, std::string> auth_pairs;
    base::StringPairs auth_vector;
    base::SplitStringIntoKeyValuePairs(auth, '=', ',', &auth_vector);
    for (const auto& auth_pair : auth_vector) {
      std::string key;
      std::string value;
      base::TrimWhitespaceASCII(auth_pair.first, base::TRIM_ALL, &key);
      base::TrimWhitespaceASCII(auth_pair.second, base::TRIM_ALL, &value);
      if (value.size() > 2 && value.at(0) == '"' &&
          value.at(value.size() - 1) == '"') {
        value = value.substr(1, value.size() - 2);
      }
      auth_pairs[key] = value;
    }

    if (auth_pairs["nonce"] != nonce) {
      error = "wrong nonce";
    } else if (auth_pairs["opaque"] != opaque) {
      error = "wrong opaque";
    } else {
      username = auth_pairs["username"];

      std::string hash1 = base::MD5String(
          base::StringPrintf("%s:%s:%s", auth_pairs["username"].c_str(),
                             realm.c_str(), password.c_str()));
      std::string hash2 = base::MD5String(base::StringPrintf(
          "%s:%s", request.method_string.c_str(), auth_pairs["uri"].c_str()));

      std::string response;
      if (auth_pairs.find("qop") != auth_pairs.end() &&
          auth_pairs.find("nc") != auth_pairs.end() &&
          auth_pairs.find("cnonce") != auth_pairs.end()) {
        response = base::MD5String(base::StringPrintf(
            "%s:%s:%s:%s:%s:%s", hash1.c_str(), nonce.c_str(),
            auth_pairs["nc"].c_str(), auth_pairs["cnonce"].c_str(),
            auth_pairs["qop"].c_str(), hash2.c_str()));
      } else {
        response = base::MD5String(base::StringPrintf(
            "%s:%s:%s", hash1.c_str(), nonce.c_str(), hash2.c_str()));
      }

      if (auth_pairs["response"] == response)
        authed = true;
      else
        error = "wrong password";
    }
  }

  std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
  if (!authed) {
    http_response->set_code(HTTP_UNAUTHORIZED);
    http_response->set_content_type("text/html");
    std::string auth_header = base::StringPrintf(
        "Digest realm=\"%s\", "
        "domain=\"/\", qop=\"auth\", algorithm=MD5, nonce=\"%s\", "
        "opaque=\"%s\"",
        realm.c_str(), nonce.c_str(), opaque.c_str());
    http_response->AddCustomHeader("WWW-Authenticate", auth_header);
    http_response->set_content(base::StringPrintf(
        "<html><head><title>Denied: %s</title></head>"
        "<body>auth=%s<p>"
        "You sent:<br>%s<p>We are replying:<br>%s<p></body></html>",
        error.c_str(), auth.c_str(), request.all_headers.c_str(),
        auth_header.c_str()));
    return std::move(http_response);
  }

  http_response->set_content_type("text/html");
  http_response->set_content(
      base::StringPrintf("<html><head><title>%s/%s</title></head>"
                         "<body>auth=%s<p></body></html>",
                         username.c_str(), password.c_str(), auth.c_str()));

  return std::move(http_response);
}

// /server-redirect?URL (Also /server-redirect-xxx?URL)
// Returns a server redirect to URL.
std::unique_ptr<HttpResponse> HandleServerRedirect(HttpStatusCode redirect_code,
                                                   const HttpRequest& request) {
  GURL request_url = request.GetURL();
  std::string dest;
  UnescapeBinaryURLComponent(request_url.query(), &dest);

  std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
  http_response->set_code(redirect_code);
  http_response->AddCustomHeader("Location", dest);
  http_response->set_content_type("text/html");
  http_response->set_content(base::StringPrintf(
      "<html><head></head><body>Redirecting to %s</body></html>",
      dest.c_str()));
  return std::move(http_response);
}

// /cross-site?URL
// Returns a cross-site redirect to URL.
std::unique_ptr<HttpResponse> HandleCrossSiteRedirect(
    EmbeddedTestServer* server,
    const HttpRequest& request) {
  if (!ShouldHandle(request, "/cross-site"))
    return nullptr;

  std::string dest_all;
  UnescapeBinaryURLComponent(

      request.relative_url.substr(std::string("/cross-site").size() + 1),
      &dest_all);

  std::string dest;
  size_t delimiter = dest_all.find("/");
  if (delimiter != std::string::npos) {
    dest = base::StringPrintf(
        "//%s:%hu/%s", dest_all.substr(0, delimiter).c_str(), server->port(),
        dest_all.substr(delimiter + 1).c_str());
  }

  std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
  http_response->set_code(HTTP_MOVED_PERMANENTLY);
  http_response->AddCustomHeader("Location", dest);
  http_response->set_content_type("text/html");
  http_response->set_content(base::StringPrintf(
      "<html><head></head><body>Redirecting to %s</body></html>",
      dest.c_str()));
  return std::move(http_response);
}

// /client-redirect?URL
// Returns a meta redirect to URL.
std::unique_ptr<HttpResponse> HandleClientRedirect(const HttpRequest& request) {
  GURL request_url = request.GetURL();
  std::string dest;
  UnescapeBinaryURLComponent(request_url.query(), &dest);

  std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
  http_response->set_content_type("text/html");
  http_response->set_content(base::StringPrintf(
      "<html><head><meta http-equiv=\"refresh\" content=\"0;url=%s\"></head>"
      "<body>Redirecting to %s</body></html>",
      dest.c_str(), dest.c_str()));
  return std::move(http_response);
}

// /defaultresponse
// Returns a valid 200 response.
std::unique_ptr<HttpResponse> HandleDefaultResponse(
    const HttpRequest& request) {
  std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
  http_response->set_content_type("text/html");
  http_response->set_content("Default response given for path: " +
                             request.relative_url);
  return std::move(http_response);
}

// /slow?N
// Returns a response to the server delayed by N seconds.
std::unique_ptr<HttpResponse> HandleSlowServer(const HttpRequest& request) {
  double delay = 1.0f;

  GURL request_url = request.GetURL();
  if (request_url.has_query())
    delay = std::atof(request_url.query().c_str());

  std::unique_ptr<BasicHttpResponse> http_response(
      new DelayedHttpResponse(base::TimeDelta::FromSecondsD(delay)));
  http_response->set_content_type("text/plain");
  http_response->set_content(base::StringPrintf("waited %.1f seconds", delay));
  return std::move(http_response);
}

// Never returns a response.
class HungHttpResponse : public HttpResponse {
 public:
  HungHttpResponse() = default;

  void SendResponse(const SendBytesCallback& send,
                    const SendCompleteCallback& done) override {}

 private:
  DISALLOW_COPY_AND_ASSIGN(HungHttpResponse);
};

// /hung
// Never returns a response.
std::unique_ptr<HttpResponse> HandleHungResponse(const HttpRequest& request) {
  return std::make_unique<HungHttpResponse>();
}

// Return headers, then hangs.
class HungAfterHeadersHttpResponse : public HttpResponse {
 public:
  HungAfterHeadersHttpResponse() = default;

  void SendResponse(const SendBytesCallback& send,
                    const SendCompleteCallback& done) override {
    send.Run("HTTP/1.1 OK\r\n\r\n", base::DoNothing());
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(HungAfterHeadersHttpResponse);
};

// /hung-after-headers
// Never returns a response.
std::unique_ptr<HttpResponse> HandleHungAfterHeadersResponse(
    const HttpRequest& request) {
  return std::make_unique<HungAfterHeadersHttpResponse>();
}

// /exabyte_response
// A HttpResponse that is almost never ending (with an Exabyte content-length).
class ExabyteResponse : public net::test_server::BasicHttpResponse {
 public:
  ExabyteResponse() {}

  void SendResponse(
      const net::test_server::SendBytesCallback& send,
      const net::test_server::SendCompleteCallback& done) override {
    // Use 10^18 bytes (exabyte) as the content length so that the client will
    // be expecting data.
    send.Run("HTTP/1.1 200 OK\r\nContent-Length:1000000000000000000\r\n\r\n",
             base::BindRepeating(&ExabyteResponse::SendExabyte, send));
  }

 private:
  // Keeps sending the word "echo" over and over again. It can go further to
  // limit the response to exactly an exabyte, but it shouldn't be necessary
  // for the purpose of testing.
  static void SendExabyte(const net::test_server::SendBytesCallback& send) {
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::BindRepeating(
            send, "echo",
            base::BindRepeating(&ExabyteResponse::SendExabyte, send)));
  }

  DISALLOW_COPY_AND_ASSIGN(ExabyteResponse);
};

// /exabyte_response
// Almost never ending response.
std::unique_ptr<net::test_server::HttpResponse> HandleExabyteResponse(
    const net::test_server::HttpRequest& request) {
  return std::make_unique<ExabyteResponse>();
}

// /gzip-body?<body>
// Returns a response with a gzipped body of "<body>". Attempts to allocate
// enough memory to contain the body, but DCHECKs if that fails.
std::unique_ptr<HttpResponse> HandleGzipBody(const HttpRequest& request) {
  std::string uncompressed_body = request.GetURL().query();
  // Attempt to pick size that's large enough even in the worst case (deflate
  // block headers should be shorter than 512 bytes, and deflating should never
  // double size of data, modulo headers).
  // TODO(mmenke): This is rather awkward. Worth improving CompressGzip?
  std::vector<char> compressed_body(uncompressed_body.size() * 2 + 512);
  size_t compressed_size = compressed_body.size();
  CompressGzip(uncompressed_body.c_str(), uncompressed_body.size(),
               compressed_body.data(), &compressed_size,
               true /* gzip_framing */);
  // CompressGzip should DCHECK itself if this fails, anyways.
  DCHECK_GE(compressed_body.size(), compressed_size);

  std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
  http_response->set_content(
      std::string(compressed_body.data(), compressed_size));
  http_response->AddCustomHeader("Content-Encoding", "gzip");
  return std::move(http_response);
}

// /self.pac
// Returns a response that is a PAC script making requests use the
// EmbeddedTestServer itself as a proxy.
std::unique_ptr<HttpResponse> HandleSelfPac(const HttpRequest& request) {
  std::unique_ptr<BasicHttpResponse> http_response =
      std::make_unique<BasicHttpResponse>();
  http_response->set_content(base::StringPrintf(
      "function FindProxyForURL(url, host) {\n"
      "return 'PROXY %s';\n"
      "}",
      net::HostPortPair::FromURL(request.base_url).ToString().c_str()));
  return std::move(http_response);
}

}  // anonymous namespace

#define PREFIXED_HANDLER(prefix, handler)             \
  base::BindRepeating(&HandlePrefixedRequest, prefix, \
                      base::BindRepeating(handler))
#define SERVER_REDIRECT_HANDLER(prefix, handler, status_code) \
  base::BindRepeating(&HandlePrefixedRequest, prefix,         \
                      base::BindRepeating(handler, status_code))

void RegisterDefaultHandlers(EmbeddedTestServer* server) {
  server->RegisterDefaultHandler(base::BindRepeating(&HandleDefaultConnect));

  server->RegisterDefaultHandler(
      PREFIXED_HANDLER("/cachetime", &HandleCacheTime));
  server->RegisterDefaultHandler(
      base::BindRepeating(&HandleEchoHeader, "/echoheader", "no-cache"));
  server->RegisterDefaultHandler(base::BindRepeating(
      &HandleEchoHeader, "/echoheadercache", "max-age=60000"));
  server->RegisterDefaultHandler(PREFIXED_HANDLER("/echo", &HandleEcho));
  server->RegisterDefaultHandler(
      PREFIXED_HANDLER("/echotitle", &HandleEchoTitle));
  server->RegisterDefaultHandler(PREFIXED_HANDLER("/echoall", &HandleEchoAll));
  server->RegisterDefaultHandler(PREFIXED_HANDLER("/echo-raw", &HandleEchoRaw));
  server->RegisterDefaultHandler(
      PREFIXED_HANDLER("/set-cookie", &HandleSetCookie));
  server->RegisterDefaultHandler(
      PREFIXED_HANDLER("/set-many-cookies", &HandleSetManyCookies));
  server->RegisterDefaultHandler(
      PREFIXED_HANDLER("/expect-and-set-cookie", &HandleExpectAndSetCookie));
  server->RegisterDefaultHandler(
      PREFIXED_HANDLER("/set-header", &HandleSetHeader));
  server->RegisterDefaultHandler(
      PREFIXED_HANDLER("/nocontent", &HandleNoContent));
  server->RegisterDefaultHandler(
      PREFIXED_HANDLER("/close-socket", &HandleCloseSocket));
  server->RegisterDefaultHandler(
      PREFIXED_HANDLER("/auth-basic", &HandleAuthBasic));
  server->RegisterDefaultHandler(
      PREFIXED_HANDLER("/auth-digest", &HandleAuthDigest));

  server->RegisterDefaultHandler(SERVER_REDIRECT_HANDLER(
      "/server-redirect", &HandleServerRedirect, HTTP_MOVED_PERMANENTLY));
  server->RegisterDefaultHandler(SERVER_REDIRECT_HANDLER(
      "/server-redirect-301", &HandleServerRedirect, HTTP_MOVED_PERMANENTLY));
  server->RegisterDefaultHandler(SERVER_REDIRECT_HANDLER(
      "/server-redirect-302", &HandleServerRedirect, HTTP_FOUND));
  server->RegisterDefaultHandler(SERVER_REDIRECT_HANDLER(
      "/server-redirect-303", &HandleServerRedirect, HTTP_SEE_OTHER));
  server->RegisterDefaultHandler(SERVER_REDIRECT_HANDLER(
      "/server-redirect-307", &HandleServerRedirect, HTTP_TEMPORARY_REDIRECT));
  server->RegisterDefaultHandler(SERVER_REDIRECT_HANDLER(
      "/server-redirect-308", &HandleServerRedirect, HTTP_PERMANENT_REDIRECT));

  server->RegisterDefaultHandler(
      base::BindRepeating(&HandleCrossSiteRedirect, server));
  server->RegisterDefaultHandler(
      PREFIXED_HANDLER("/client-redirect", &HandleClientRedirect));
  server->RegisterDefaultHandler(
      PREFIXED_HANDLER("/defaultresponse", &HandleDefaultResponse));
  server->RegisterDefaultHandler(PREFIXED_HANDLER("/slow", &HandleSlowServer));
  server->RegisterDefaultHandler(
      PREFIXED_HANDLER("/hung", &HandleHungResponse));
  server->RegisterDefaultHandler(
      PREFIXED_HANDLER("/hung-after-headers", &HandleHungAfterHeadersResponse));
  server->RegisterDefaultHandler(
      PREFIXED_HANDLER("/exabyte_response", &HandleExabyteResponse));
  server->RegisterDefaultHandler(
      PREFIXED_HANDLER("/gzip-body", &HandleGzipBody));
  server->RegisterDefaultHandler(PREFIXED_HANDLER("/self.pac", &HandleSelfPac));

  // TODO(svaldez): HandleDownload
  // TODO(svaldez): HandleDownloadFinish
  // TODO(svaldez): HandleZipFile
  // TODO(svaldez): HandleSSLManySmallRecords
  // TODO(svaldez): HandleChunkedServer
  // TODO(svaldez): HandleGetSSLSessionCache
  // TODO(svaldez): HandleGetChannelID
  // TODO(svaldez): HandleGetClientCert
  // TODO(svaldez): HandleClientCipherList
  // TODO(svaldez): HandleEchoMultipartPost
}

#undef PREFIXED_HANDLER

}  // namespace test_server
}  // namespace net
