// 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);
#if defined(STARBOARD)
  // Cobalt does not currently support text/plain caching.
  http_response->set_content_type("text/html");
#else
  http_response->set_content_type("text/plain");
#endif
  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
