base_test_server.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/test/spawned_test_server/base_test_server.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base64.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_reader.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/address_list.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/host_port_pair.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_completion_callback.h"
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/test_root_certs.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/host_resolver.h"
247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetHostname(BaseTestServer::Type type,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const BaseTestServer::SSLOptions& options) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (BaseTestServer::UsingSSL(type) &&
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      options.server_certificate ==
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          BaseTestServer::SSLOptions::CERT_MISMATCHED_NAME) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return a different hostname string that resolves to the same hostname.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return "localhost";
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use the 127.0.0.1 as default.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return BaseTestServer::kLocalhost;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetCiphersList(int cipher, base::ListValue* values) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cipher & BaseTestServer::SSLOptions::BULK_CIPHER_RC4)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values->Append(new base::StringValue("rc4"));
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cipher & BaseTestServer::SSLOptions::BULK_CIPHER_AES128)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values->Append(new base::StringValue("aes128"));
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cipher & BaseTestServer::SSLOptions::BULK_CIPHER_AES256)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values->Append(new base::StringValue("aes256"));
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cipher & BaseTestServer::SSLOptions::BULK_CIPHER_3DES)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    values->Append(new base::StringValue("3des"));
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BaseTestServer::SSLOptions::SSLOptions()
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : server_certificate(CERT_OK),
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ocsp_status(OCSP_OK),
59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      cert_serial(0),
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_client_certificate(false),
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bulk_ciphers(SSLOptions::BULK_CIPHER_ANY),
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      record_resume(false),
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tls_intolerant(TLS_INTOLERANT_NONE) {}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BaseTestServer::SSLOptions::SSLOptions(
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BaseTestServer::SSLOptions::ServerCertificate cert)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : server_certificate(cert),
68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ocsp_status(OCSP_OK),
69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      cert_serial(0),
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_client_certificate(false),
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bulk_ciphers(SSLOptions::BULK_CIPHER_ANY),
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      record_resume(false),
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tls_intolerant(TLS_INTOLERANT_NONE) {}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BaseTestServer::SSLOptions::~SSLOptions() {}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath BaseTestServer::SSLOptions::GetCertificateFile() const {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (server_certificate) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CERT_OK:
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CERT_MISMATCHED_NAME:
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return base::FilePath(FILE_PATH_LITERAL("ok_cert.pem"));
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CERT_EXPIRED:
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return base::FilePath(FILE_PATH_LITERAL("expired_cert.pem"));
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CERT_CHAIN_WRONG_ROOT:
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This chain uses its own dedicated test root certificate to avoid
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // side-effects that may affect testing.
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return base::FilePath(FILE_PATH_LITERAL("redundant-server-chain.pem"));
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CERT_AUTO:
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return base::FilePath();
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::FilePath();
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string BaseTestServer::SSLOptions::GetOCSPArgument() const {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (server_certificate != CERT_AUTO)
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return std::string();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (ocsp_status) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case OCSP_OK:
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "ok";
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case OCSP_REVOKED:
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "revoked";
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case OCSP_INVALID:
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "invalid";
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case OCSP_UNAUTHORIZED:
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "unauthorized";
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case OCSP_UNKNOWN:
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "unknown";
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return std::string();
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char BaseTestServer::kLocalhost[] = "127.0.0.1";
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BaseTestServer::BaseTestServer(Type type, const std::string& host)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : type_(type),
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      started_(false),
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      log_to_console_(false) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Init(host);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BaseTestServer::BaseTestServer(Type type, const SSLOptions& ssl_options)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : ssl_options_(ssl_options),
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type_(type),
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      started_(false),
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      log_to_console_(false) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(UsingSSL(type));
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Init(GetHostname(type, ssl_options));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BaseTestServer::~BaseTestServer() {}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const HostPortPair& BaseTestServer::host_port_pair() const {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(started_);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return host_port_pair_;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::DictionaryValue& BaseTestServer::server_data() const {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(started_);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(server_data_.get());
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *server_data_;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string BaseTestServer::GetScheme() const {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type_) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TYPE_FTP:
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "ftp";
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TYPE_HTTP:
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "http";
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TYPE_HTTPS:
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "https";
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TYPE_WS:
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "ws";
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TYPE_WSS:
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "wss";
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TYPE_TCP_ECHO:
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TYPE_UDP_ECHO:
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::string();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseTestServer::GetAddressList(AddressList* address_list) const {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(address_list);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HostResolver> resolver(HostResolver::CreateDefaultResolver(NULL));
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostResolver::RequestInfo info(host_port_pair_);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
1743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  int rv = resolver->Resolve(info,
1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             DEFAULT_PRIORITY,
1763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             address_list,
1773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             callback.callback(),
1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             NULL,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             BoundNetLog());
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv != net::OK) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to resolve hostname: " << host_port_pair_.host();
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint16 BaseTestServer::GetPort() {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return host_port_pair_.port();
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BaseTestServer::SetPort(uint16 port) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_port_pair_.set_port(port);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL BaseTestServer::GetURL(const std::string& path) const {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GURL(GetScheme() + "://" + host_port_pair_.ToString() + "/" + path);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL BaseTestServer::GetURLWithUser(const std::string& path,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const std::string& user) const {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GURL(GetScheme() + "://" + user + "@" + host_port_pair_.ToString() +
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "/" + path);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL BaseTestServer::GetURLWithUserAndPassword(const std::string& path,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const std::string& user,
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const std::string& password) const {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GURL(GetScheme() + "://" + user + ":" + password + "@" +
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              host_port_pair_.ToString() + "/" + path);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseTestServer::GetFilePathWithReplacements(
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& original_file_path,
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<StringPair>& text_to_replace,
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* replacement_path) {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string new_file_path = original_file_path;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool first_query_parameter = true;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::vector<StringPair>::const_iterator end = text_to_replace.end();
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<StringPair>::const_iterator it = text_to_replace.begin();
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != end;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++it) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& old_text = it->first;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& new_text = it->second;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string base64_old;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string base64_new;
229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::Base64Encode(old_text, &base64_old);
230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::Base64Encode(new_text, &base64_new);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (first_query_parameter) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_file_path += "?";
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      first_query_parameter = false;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_file_path += "&";
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_file_path += "replace_text=";
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_file_path += base64_old;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_file_path += ":";
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_file_path += base64_new;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *replacement_path = new_file_path;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BaseTestServer::Init(const std::string& host) {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_port_pair_ = HostPortPair(host, 0);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(battre) Remove this after figuring out why the TestServer is flaky.
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // http://crbug.com/96594
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log_to_console_ = true;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BaseTestServer::SetResourcePath(const base::FilePath& document_root,
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const base::FilePath& certificates_dir) {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method shouldn't get called twice.
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(certificates_dir_.empty());
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  document_root_ = document_root;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  certificates_dir_ = certificates_dir;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!certificates_dir_.empty());
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseTestServer::ParseServerData(const std::string& server_data) {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "Server data: " << server_data;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::JSONReader json_reader;
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::Value> value(json_reader.ReadToValue(server_data));
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!value.get() || !value->IsType(base::Value::TYPE_DICTIONARY)) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Could not parse server data: "
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << json_reader.GetErrorMessage();
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  server_data_.reset(static_cast<base::DictionaryValue*>(value.release()));
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int port = 0;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!server_data_->GetInteger("port", &port)) {
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Could not find port value";
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((port <= 0) || (port > kuint16max)) {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Invalid port value: " << port;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_port_pair_.set_port(port);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseTestServer::LoadTestRootCert() const {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRootCerts* root_certs = TestRootCerts::GetInstance();
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!root_certs)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should always use absolute path to load the root certificate.
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath root_certificate_path = certificates_dir_;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!certificates_dir_.IsAbsolute()) {
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath src_dir;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!PathService::Get(base::DIR_SOURCE_ROOT, &src_dir))
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_certificate_path = src_dir.Append(certificates_dir_);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return root_certs->AddFromFile(
304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      root_certificate_path.AppendASCII("root_ca_cert.pem"));
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseTestServer::SetupWhenServerStarted() {
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(host_port_pair_.port());
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (UsingSSL(type_) && !LoadTestRootCert())
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  started_ = true;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  allowed_port_.reset(new ScopedPortException(host_port_pair_.port()));
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BaseTestServer::CleanUpWhenStoppingServer() {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRootCerts* root_certs = TestRootCerts::GetInstance();
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  root_certs->Clear();
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_port_pair_.set_port(0);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  allowed_port_.reset();
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  started_ = false;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Generates a dictionary of arguments to pass to the Python test server via
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the test server spawner, in the form of
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// { argument-name: argument-value, ... }
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns false if an invalid configuration is specified.
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseTestServer::GenerateArguments(base::DictionaryValue* arguments) const {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(arguments);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  arguments->SetString("host", host_port_pair_.host());
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  arguments->SetInteger("port", host_port_pair_.port());
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  arguments->SetString("data-dir", document_root_.value());
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (VLOG_IS_ON(1) || log_to_console_)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    arguments->Set("log-to-console", base::Value::CreateNullValue());
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (UsingSSL(type_)) {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check the certificate arguments of the HTTPS server.
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath certificate_path(certificates_dir_);
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath certificate_file(ssl_options_.GetCertificateFile());
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!certificate_file.value().empty()) {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      certificate_path = certificate_path.Append(certificate_file);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (certificate_path.IsAbsolute() &&
3487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          !base::PathExists(certificate_path)) {
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        LOG(ERROR) << "Certificate path " << certificate_path.value()
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   << " doesn't exist. Can't launch https server.";
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      arguments->SetString("cert-and-key-file", certificate_path.value());
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check the client certificate related arguments.
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_options_.request_client_certificate)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      arguments->Set("ssl-client-auth", base::Value::CreateNullValue());
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<base::ListValue> ssl_client_certs(new base::ListValue());
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<base::FilePath>::const_iterator it;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (it = ssl_options_.client_authorities.begin();
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         it != ssl_options_.client_authorities.end(); ++it) {
3647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if (it->IsAbsolute() && !base::PathExists(*it)) {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        LOG(ERROR) << "Client authority path " << it->value()
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   << " doesn't exist. Can't launch https server.";
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ssl_client_certs->Append(new base::StringValue(it->value()));
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_client_certs->GetSize())
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      arguments->Set("ssl-client-ca", ssl_client_certs.release());
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type_ == TYPE_HTTPS) {
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    arguments->Set("https", base::Value::CreateNullValue());
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string ocsp_arg = ssl_options_.GetOCSPArgument();
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ocsp_arg.empty())
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      arguments->SetString("ocsp", ocsp_arg);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
383a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (ssl_options_.cert_serial != 0) {
384a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      arguments->Set("cert-serial",
385a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                     base::Value::CreateIntegerValue(ssl_options_.cert_serial));
386a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
387a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check bulk cipher argument.
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<base::ListValue> bulk_cipher_values(new base::ListValue());
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetCiphersList(ssl_options_.bulk_ciphers, bulk_cipher_values.get());
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (bulk_cipher_values->GetSize())
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      arguments->Set("ssl-bulk-cipher", bulk_cipher_values.release());
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_options_.record_resume)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      arguments->Set("https-record-resume", base::Value::CreateNullValue());
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_options_.tls_intolerant != SSLOptions::TLS_INTOLERANT_NONE) {
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      arguments->Set("tls-intolerant",
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     new base::FundamentalValue(ssl_options_.tls_intolerant));
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
399a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!ssl_options_.signed_cert_timestamps.empty()) {
400a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      std::string b64_scts;
401a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Base64Encode(ssl_options_.signed_cert_timestamps, &b64_scts);
402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      arguments->SetString("signed-cert-timestamps", b64_scts);
403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GenerateAdditionalArguments(arguments);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseTestServer::GenerateAdditionalArguments(
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::DictionaryValue* arguments) const {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
415