diff --git a/common/certificate_checker.cc b/common/certificate_checker.cc
deleted file mode 100644
index 86df950..0000000
--- a/common/certificate_checker.cc
+++ /dev/null
@@ -1,204 +0,0 @@
-//
-// Copyright (C) 2012 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/common/certificate_checker.h"
-
-#include <string>
-
-#include <base/logging.h>
-#include <base/strings/string_number_conversions.h>
-#include <base/strings/string_util.h>
-#include <base/strings/stringprintf.h>
-#include <curl/curl.h>
-#include <openssl/evp.h>
-#include <openssl/ssl.h>
-
-#include "update_engine/common/constants.h"
-#include "update_engine/common/prefs_interface.h"
-#include "update_engine/common/utils.h"
-
-using std::string;
-
-namespace chromeos_update_engine {
-
-bool OpenSSLWrapper::GetCertificateDigest(X509_STORE_CTX* x509_ctx,
-                                          int* out_depth,
-                                          unsigned int* out_digest_length,
-                                          uint8_t* out_digest) const {
-  TEST_AND_RETURN_FALSE(out_digest);
-  X509* certificate = X509_STORE_CTX_get_current_cert(x509_ctx);
-  TEST_AND_RETURN_FALSE(certificate);
-  int depth = X509_STORE_CTX_get_error_depth(x509_ctx);
-  if (out_depth)
-    *out_depth = depth;
-
-  unsigned int len;
-  const EVP_MD* digest_function = EVP_sha256();
-  bool success = X509_digest(certificate, digest_function, out_digest, &len);
-
-  if (success && out_digest_length)
-    *out_digest_length = len;
-  return success;
-}
-
-// static
-CertificateChecker* CertificateChecker::cert_checker_singleton_ = nullptr;
-
-CertificateChecker::CertificateChecker(PrefsInterface* prefs,
-                                       OpenSSLWrapper* openssl_wrapper)
-    : prefs_(prefs), openssl_wrapper_(openssl_wrapper) {
-}
-
-CertificateChecker::~CertificateChecker() {
-  if (cert_checker_singleton_ == this)
-    cert_checker_singleton_ = nullptr;
-}
-
-void CertificateChecker::Init() {
-  CHECK(cert_checker_singleton_ == nullptr);
-  cert_checker_singleton_ = this;
-}
-
-// static
-CURLcode CertificateChecker::ProcessSSLContext(CURL* curl_handle,
-                                               SSL_CTX* ssl_ctx,
-                                               void* ptr) {
-  ServerToCheck* server_to_check = reinterpret_cast<ServerToCheck*>(ptr);
-
-  if (!cert_checker_singleton_) {
-    DLOG(WARNING) << "No CertificateChecker singleton initialized.";
-    return CURLE_FAILED_INIT;
-  }
-
-  // From here we set the SSL_CTX to another callback, from the openssl library,
-  // which will be called after each server certificate is validated. However,
-  // since openssl does not allow us to pass our own data pointer to the
-  // callback, the certificate check will have to be done statically. Since we
-  // need to know which update server we are using in order to check the
-  // certificate, we hardcode Chrome OS's two known update servers here, and
-  // define a different static callback for each. Since this code should only
-  // run in official builds, this should not be a problem. However, if an update
-  // server different from the ones listed here is used, the check will not
-  // take place.
-  int (*verify_callback)(int, X509_STORE_CTX*);
-  switch (*server_to_check) {
-    case ServerToCheck::kDownload:
-      verify_callback = &CertificateChecker::VerifySSLCallbackDownload;
-      break;
-    case ServerToCheck::kUpdate:
-      verify_callback = &CertificateChecker::VerifySSLCallbackUpdate;
-      break;
-    case ServerToCheck::kNone:
-      verify_callback = nullptr;
-      break;
-  }
-
-  SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, verify_callback);
-  return CURLE_OK;
-}
-
-// static
-int CertificateChecker::VerifySSLCallbackDownload(int preverify_ok,
-                                                  X509_STORE_CTX* x509_ctx) {
-  return VerifySSLCallback(preverify_ok, x509_ctx, ServerToCheck::kDownload);
-}
-
-// static
-int CertificateChecker::VerifySSLCallbackUpdate(int preverify_ok,
-                                                X509_STORE_CTX* x509_ctx) {
-  return VerifySSLCallback(preverify_ok, x509_ctx, ServerToCheck::kUpdate);
-}
-
-// static
-int CertificateChecker::VerifySSLCallback(int preverify_ok,
-                                          X509_STORE_CTX* x509_ctx,
-                                          ServerToCheck server_to_check) {
-  CHECK(cert_checker_singleton_ != nullptr);
-  return cert_checker_singleton_->CheckCertificateChange(
-      preverify_ok, x509_ctx, server_to_check) ? 1 : 0;
-}
-
-bool CertificateChecker::CheckCertificateChange(int preverify_ok,
-                                                X509_STORE_CTX* x509_ctx,
-                                                ServerToCheck server_to_check) {
-  TEST_AND_RETURN_FALSE(prefs_ != nullptr);
-
-  // If pre-verification failed, we are not interested in the current
-  // certificate. We store a report to UMA and just propagate the fail result.
-  if (!preverify_ok) {
-    NotifyCertificateChecked(server_to_check, CertificateCheckResult::kFailed);
-    return false;
-  }
-
-  int depth;
-  unsigned int digest_length;
-  uint8_t digest[EVP_MAX_MD_SIZE];
-
-  if (!openssl_wrapper_->GetCertificateDigest(x509_ctx,
-                                              &depth,
-                                              &digest_length,
-                                              digest)) {
-    LOG(WARNING) << "Failed to generate digest of X509 certificate "
-                 << "from update server.";
-    NotifyCertificateChecked(server_to_check, CertificateCheckResult::kValid);
-    return true;
-  }
-
-  // We convert the raw bytes of the digest to an hex string, for storage in
-  // prefs.
-  string digest_string = base::HexEncode(digest, digest_length);
-
-  string storage_key =
-      base::StringPrintf("%s-%d-%d", kPrefsUpdateServerCertificate,
-                         static_cast<int>(server_to_check), depth);
-  string stored_digest;
-  // If there's no stored certificate, we just store the current one and return.
-  if (!prefs_->GetString(storage_key, &stored_digest)) {
-    if (!prefs_->SetString(storage_key, digest_string)) {
-      LOG(WARNING) << "Failed to store server certificate on storage key "
-                   << storage_key;
-    }
-    NotifyCertificateChecked(server_to_check, CertificateCheckResult::kValid);
-    return true;
-  }
-
-  // Certificate changed, we store a report to UMA and store the most recent
-  // certificate.
-  if (stored_digest != digest_string) {
-    if (!prefs_->SetString(storage_key, digest_string)) {
-      LOG(WARNING) << "Failed to store server certificate on storage key "
-                   << storage_key;
-    }
-    LOG(INFO) << "Certificate changed from " << stored_digest << " to "
-              << digest_string << ".";
-    NotifyCertificateChecked(server_to_check,
-                             CertificateCheckResult::kValidChanged);
-    return true;
-  }
-
-  NotifyCertificateChecked(server_to_check, CertificateCheckResult::kValid);
-  // Since we don't perform actual SSL verification, we return success.
-  return true;
-}
-
-void CertificateChecker::NotifyCertificateChecked(
-    ServerToCheck server_to_check,
-    CertificateCheckResult result) {
-  if (observer_)
-    observer_->CertificateChecked(server_to_check, result);
-}
-
-}  // namespace chromeos_update_engine
diff --git a/common/certificate_checker.h b/common/certificate_checker.h
deleted file mode 100644
index c785192..0000000
--- a/common/certificate_checker.h
+++ /dev/null
@@ -1,175 +0,0 @@
-//
-// Copyright (C) 2011 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef UPDATE_ENGINE_COMMON_CERTIFICATE_CHECKER_H_
-#define UPDATE_ENGINE_COMMON_CERTIFICATE_CHECKER_H_
-
-#include <curl/curl.h>
-#include <openssl/ssl.h>
-
-#include <string>
-
-#include <base/macros.h>
-#include <gtest/gtest_prod.h>  // for FRIEND_TEST
-
-namespace chromeos_update_engine {
-
-class PrefsInterface;
-
-// Wrapper for openssl operations with the certificates.
-class OpenSSLWrapper {
- public:
-  OpenSSLWrapper() = default;
-  virtual ~OpenSSLWrapper() = default;
-
-  // Takes an openssl X509_STORE_CTX, extracts the corresponding certificate
-  // from it and calculates its fingerprint (SHA256 digest). Returns true on
-  // success and false otherwise.
-  //
-  // |x509_ctx| is the pointer to the openssl object that holds the certificate.
-  // |out_depth| is the depth of the current certificate, in the certificate
-  // chain.
-  // |out_digest_length| is the length of the generated digest.
-  // |out_digest| is the byte array where the digest itself will be written.
-  // It should be big enough to hold a SHA1 digest (e.g. EVP_MAX_MD_SIZE).
-  virtual bool GetCertificateDigest(X509_STORE_CTX* x509_ctx,
-                                    int* out_depth,
-                                    unsigned int* out_digest_length,
-                                    uint8_t* out_digest) const;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(OpenSSLWrapper);
-};
-
-// The values in this enum are replicated in the metrics server. See metrics.h
-// for instructions on how to update these values in the server side.
-enum class CertificateCheckResult {
-  // The certificate is valid and the same as seen before or the first time we
-  // see a certificate.
-  kValid,
-  // The certificate is valid, but is different than a previously seen
-  // certificate for the selected server.
-  kValidChanged,
-  // The certificate validation failed.
-  kFailed,
-
-  // This value must be the last entry.
-  kNumConstants
-};
-
-// These values are used to generate the keys of files persisted via prefs.
-// This means that changing these will cause loss of information on metrics
-// reporting, during the transition. These values are also mapped to a metric
-// name in metrics.cc, so adding values here requires to assign a new metric
-// name in that file.
-enum class ServerToCheck {
-  kUpdate = 0,
-  kDownload,
-
-  // Ignore this server.
-  kNone,
-};
-
-// Responsible for checking whether update server certificates change, and
-// reporting to UMA when this happens. Since all state information is persisted,
-// and openssl forces us to use a static callback with no data pointer, this
-// class is entirely static.
-class CertificateChecker {
- public:
-  class Observer {
-   public:
-    virtual ~Observer() = default;
-
-    // Called whenever a certificate is checked for the server |server_to_check|
-    // passing the result of said certificate check.
-    virtual void CertificateChecked(ServerToCheck server_to_check,
-                                    CertificateCheckResult result) = 0;
-  };
-
-  CertificateChecker(PrefsInterface* prefs, OpenSSLWrapper* openssl_wrapper);
-  ~CertificateChecker();
-
-  // This callback is called by libcurl just before the initialization of an
-  // SSL connection after having processed all other SSL related options. Used
-  // to check if server certificates change. |cert_checker| is expected to be a
-  // pointer to the CertificateChecker instance.
-  static CURLcode ProcessSSLContext(CURL* curl_handle,
-                                    SSL_CTX* ssl_ctx,
-                                    void* cert_checker);
-
-  // Initialize this class as the singleton instance. Only one instance can be
-  // initialized at a time and it should be initialized before other methods
-  // can be used.
-  void Init();
-
-  // Set the certificate observer to the passed instance. To remove the
-  // observer, pass a nullptr. The |observer| instance must be valid while this
-  // CertificateChecker verifies certificates.
-  void SetObserver(Observer* observer) { observer_ = observer; }
-
- private:
-  FRIEND_TEST(CertificateCheckerTest, NewCertificate);
-  FRIEND_TEST(CertificateCheckerTest, SameCertificate);
-  FRIEND_TEST(CertificateCheckerTest, ChangedCertificate);
-  FRIEND_TEST(CertificateCheckerTest, FailedCertificate);
-
-  // These callbacks are asynchronously called by openssl after initial SSL
-  // verification. They are used to perform any additional security verification
-  // on the connection, but we use them here to get hold of the server
-  // certificate, in order to determine if it has changed since the last
-  // connection. Since openssl forces us to do this statically, we define two
-  // different callbacks for the two different official update servers, and only
-  // assign the correspondent one. The assigned callback is then called once per
-  // each certificate on the server and returns 1 for success and 0 for failure.
-  static int VerifySSLCallbackDownload(int preverify_ok,
-                                       X509_STORE_CTX* x509_ctx);
-  static int VerifySSLCallbackUpdate(int preverify_ok,
-                                     X509_STORE_CTX* x509_ctx);
-  static int VerifySSLCallback(int preverify_ok,
-                               X509_STORE_CTX* x509_ctx,
-                               ServerToCheck server_to_check);
-
-  // Checks if server certificate stored in |x509_ctx| has changed since last
-  // connection to that same server, specified by |server_to_check|.
-  // This is called by the callbacks defined above. The result of the
-  // certificate check is passed to the observer, if any. Returns true on
-  // success and false otherwise.
-  bool CheckCertificateChange(int preverify_ok,
-                              X509_STORE_CTX* x509_ctx,
-                              ServerToCheck server_to_check);
-
-  // Notifies the observer, if any, of a certificate checking.
-  void NotifyCertificateChecked(ServerToCheck server_to_check,
-                                CertificateCheckResult result);
-
-  // The CertificateChecker singleton instance.
-  static CertificateChecker* cert_checker_singleton_;
-
-  // Prefs instance used to store the certificates seen in the past.
-  PrefsInterface* prefs_;
-
-  // The wrapper for openssl operations.
-  OpenSSLWrapper* openssl_wrapper_;
-
-  // The observer called whenever a certificate is checked, if not null.
-  Observer* observer_{nullptr};
-
-  DISALLOW_COPY_AND_ASSIGN(CertificateChecker);
-};
-
-}  // namespace chromeos_update_engine
-
-#endif  // UPDATE_ENGINE_COMMON_CERTIFICATE_CHECKER_H_
diff --git a/common/certificate_checker_unittest.cc b/common/certificate_checker_unittest.cc
deleted file mode 100644
index c30acc5..0000000
--- a/common/certificate_checker_unittest.cc
+++ /dev/null
@@ -1,140 +0,0 @@
-//
-// Copyright (C) 2012 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/common/certificate_checker.h"
-
-#include <string>
-
-#include <base/strings/string_util.h>
-#include <base/strings/stringprintf.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include "update_engine/common/constants.h"
-#include "update_engine/common/mock_certificate_checker.h"
-#include "update_engine/common/mock_prefs.h"
-
-using ::testing::DoAll;
-using ::testing::Return;
-using ::testing::SetArgumentPointee;
-using ::testing::SetArrayArgument;
-using ::testing::_;
-using std::string;
-
-namespace chromeos_update_engine {
-
-class MockCertificateCheckObserver : public CertificateChecker::Observer {
- public:
-  MOCK_METHOD2(CertificateChecked,
-               void(ServerToCheck server_to_check,
-                    CertificateCheckResult result));
-};
-
-class CertificateCheckerTest : public testing::Test {
- protected:
-  void SetUp() override {
-    cert_key_ = base::StringPrintf("%s-%d-%d",
-                                   cert_key_prefix_.c_str(),
-                                   static_cast<int>(server_to_check_),
-                                   depth_);
-    cert_checker.Init();
-    cert_checker.SetObserver(&observer_);
-  }
-
-  void TearDown() override {
-    cert_checker.SetObserver(nullptr);
-  }
-
-  MockPrefs prefs_;
-  MockOpenSSLWrapper openssl_wrapper_;
-  // Parameters of our mock certificate digest.
-  int depth_{0};
-  unsigned int length_{4};
-  uint8_t digest_[4]{0x17, 0x7D, 0x07, 0x5F};
-  string digest_hex_{"177D075F"};
-  string diff_digest_hex_{"1234ABCD"};
-  string cert_key_prefix_{kPrefsUpdateServerCertificate};
-  ServerToCheck server_to_check_{ServerToCheck::kUpdate};
-  string cert_key_;
-
-  testing::StrictMock<MockCertificateCheckObserver> observer_;
-  CertificateChecker cert_checker{&prefs_, &openssl_wrapper_};
-};
-
-// check certificate change, new
-TEST_F(CertificateCheckerTest, NewCertificate) {
-  EXPECT_CALL(openssl_wrapper_, GetCertificateDigest(nullptr, _, _, _))
-      .WillOnce(DoAll(
-          SetArgumentPointee<1>(depth_),
-          SetArgumentPointee<2>(length_),
-          SetArrayArgument<3>(digest_, digest_ + 4),
-          Return(true)));
-  EXPECT_CALL(prefs_, GetString(cert_key_, _)).WillOnce(Return(false));
-  EXPECT_CALL(prefs_, SetString(cert_key_, digest_hex_)).WillOnce(Return(true));
-  EXPECT_CALL(observer_,
-              CertificateChecked(server_to_check_,
-                                 CertificateCheckResult::kValid));
-  ASSERT_TRUE(
-      cert_checker.CheckCertificateChange(1, nullptr, server_to_check_));
-}
-
-// check certificate change, unchanged
-TEST_F(CertificateCheckerTest, SameCertificate) {
-  EXPECT_CALL(openssl_wrapper_, GetCertificateDigest(nullptr, _, _, _))
-      .WillOnce(DoAll(
-          SetArgumentPointee<1>(depth_),
-          SetArgumentPointee<2>(length_),
-          SetArrayArgument<3>(digest_, digest_ + 4),
-          Return(true)));
-  EXPECT_CALL(prefs_, GetString(cert_key_, _))
-      .WillOnce(DoAll(SetArgumentPointee<1>(digest_hex_), Return(true)));
-  EXPECT_CALL(prefs_, SetString(_, _)).Times(0);
-  EXPECT_CALL(observer_,
-              CertificateChecked(server_to_check_,
-                                 CertificateCheckResult::kValid));
-  ASSERT_TRUE(
-      cert_checker.CheckCertificateChange(1, nullptr, server_to_check_));
-}
-
-// check certificate change, changed
-TEST_F(CertificateCheckerTest, ChangedCertificate) {
-  EXPECT_CALL(openssl_wrapper_, GetCertificateDigest(nullptr, _, _, _))
-      .WillOnce(DoAll(
-          SetArgumentPointee<1>(depth_),
-          SetArgumentPointee<2>(length_),
-          SetArrayArgument<3>(digest_, digest_ + 4),
-          Return(true)));
-  EXPECT_CALL(prefs_, GetString(cert_key_, _))
-      .WillOnce(DoAll(SetArgumentPointee<1>(diff_digest_hex_), Return(true)));
-  EXPECT_CALL(observer_,
-              CertificateChecked(server_to_check_,
-                                 CertificateCheckResult::kValidChanged));
-  EXPECT_CALL(prefs_, SetString(cert_key_, digest_hex_)).WillOnce(Return(true));
-  ASSERT_TRUE(
-      cert_checker.CheckCertificateChange(1, nullptr, server_to_check_));
-}
-
-// check certificate change, failed
-TEST_F(CertificateCheckerTest, FailedCertificate) {
-  EXPECT_CALL(observer_, CertificateChecked(server_to_check_,
-                                            CertificateCheckResult::kFailed));
-  EXPECT_CALL(prefs_, GetString(_, _)).Times(0);
-  EXPECT_CALL(openssl_wrapper_, GetCertificateDigest(_, _, _, _)).Times(0);
-  ASSERT_FALSE(
-      cert_checker.CheckCertificateChange(0, nullptr, server_to_check_));
-}
-
-}  // namespace chromeos_update_engine
diff --git a/common/file_fetcher.cc b/common/file_fetcher.cc
index 77dadd1..d0a109b 100644
--- a/common/file_fetcher.cc
+++ b/common/file_fetcher.cc
@@ -27,7 +27,6 @@
 #include <base/strings/stringprintf.h>
 #include <brillo/streams/file_stream.h>
 
-#include "update_engine/common/certificate_checker.h"
 #include "update_engine/common/hardware_interface.h"
 #include "update_engine/common/platform_constants.h"
 
diff --git a/common/hash_calculator_unittest.cc b/common/hash_calculator_unittest.cc
index 27dbc56..436e6a7 100644
--- a/common/hash_calculator_unittest.cc
+++ b/common/hash_calculator_unittest.cc
@@ -25,7 +25,6 @@
 #include <brillo/secure_blob.h>
 #include <gtest/gtest.h>
 
-#include "update_engine/common/libcurl_http_fetcher.h"
 #include "update_engine/common/utils.h"
 
 using std::string;
diff --git a/common/http_fetcher_unittest.cc b/common/http_fetcher_unittest.cc
index 9bc4373..f99007f 100644
--- a/common/http_fetcher_unittest.cc
+++ b/common/http_fetcher_unittest.cc
@@ -44,11 +44,11 @@
 #include "update_engine/common/fake_hardware.h"
 #include "update_engine/common/file_fetcher.h"
 #include "update_engine/common/http_common.h"
-#include "update_engine/common/libcurl_http_fetcher.h"
 #include "update_engine/common/mock_http_fetcher.h"
 #include "update_engine/common/multi_range_http_fetcher.h"
 #include "update_engine/common/test_utils.h"
 #include "update_engine/common/utils.h"
+#include "update_engine/libcurl_http_fetcher.h"
 #include "update_engine/mock_proxy_resolver.h"
 #include "update_engine/proxy_resolver.h"
 
diff --git a/common/libcurl_http_fetcher.cc b/common/libcurl_http_fetcher.cc
deleted file mode 100644
index b2dffc2..0000000
--- a/common/libcurl_http_fetcher.cc
+++ /dev/null
@@ -1,690 +0,0 @@
-//
-// Copyright (C) 2009 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/common/libcurl_http_fetcher.h"
-
-#include <algorithm>
-#include <string>
-
-#include <base/bind.h>
-#include <base/format_macros.h>
-#include <base/location.h>
-#include <base/logging.h>
-#include <base/strings/string_util.h>
-#include <base/strings/stringprintf.h>
-
-#include "update_engine/common/certificate_checker.h"
-#include "update_engine/common/hardware_interface.h"
-#include "update_engine/common/platform_constants.h"
-
-using base::TimeDelta;
-using brillo::MessageLoop;
-using std::max;
-using std::string;
-
-// This is a concrete implementation of HttpFetcher that uses libcurl to do the
-// http work.
-
-namespace chromeos_update_engine {
-
-namespace {
-const int kNoNetworkRetrySeconds = 10;
-}  // namespace
-
-LibcurlHttpFetcher::LibcurlHttpFetcher(ProxyResolver* proxy_resolver,
-                                       HardwareInterface* hardware)
-    : HttpFetcher(proxy_resolver), hardware_(hardware) {
-  // Dev users want a longer timeout (180 seconds) because they may
-  // be waiting on the dev server to build an image.
-  if (!hardware_->IsOfficialBuild())
-    low_speed_time_seconds_ = kDownloadDevModeLowSpeedTimeSeconds;
-  if (!hardware_->IsOOBEComplete(nullptr))
-    max_retry_count_ = kDownloadMaxRetryCountOobeNotComplete;
-}
-
-LibcurlHttpFetcher::~LibcurlHttpFetcher() {
-  LOG_IF(ERROR, transfer_in_progress_)
-      << "Destroying the fetcher while a transfer is in progress.";
-  CleanUp();
-}
-
-bool LibcurlHttpFetcher::GetProxyType(const string& proxy,
-                                      curl_proxytype* out_type) {
-  if (base::StartsWith(
-          proxy, "socks5://", base::CompareCase::INSENSITIVE_ASCII) ||
-      base::StartsWith(
-          proxy, "socks://", base::CompareCase::INSENSITIVE_ASCII)) {
-    *out_type = CURLPROXY_SOCKS5_HOSTNAME;
-    return true;
-  }
-  if (base::StartsWith(
-          proxy, "socks4://", base::CompareCase::INSENSITIVE_ASCII)) {
-    *out_type = CURLPROXY_SOCKS4A;
-    return true;
-  }
-  if (base::StartsWith(
-          proxy, "http://", base::CompareCase::INSENSITIVE_ASCII) ||
-      base::StartsWith(
-          proxy, "https://", base::CompareCase::INSENSITIVE_ASCII)) {
-    *out_type = CURLPROXY_HTTP;
-    return true;
-  }
-  if (base::StartsWith(proxy, kNoProxy, base::CompareCase::INSENSITIVE_ASCII)) {
-    // known failure case. don't log.
-    return false;
-  }
-  LOG(INFO) << "Unknown proxy type: " << proxy;
-  return false;
-}
-
-void LibcurlHttpFetcher::ResumeTransfer(const string& url) {
-  LOG(INFO) << "Starting/Resuming transfer";
-  CHECK(!transfer_in_progress_);
-  url_ = url;
-  curl_multi_handle_ = curl_multi_init();
-  CHECK(curl_multi_handle_);
-
-  curl_handle_ = curl_easy_init();
-  CHECK(curl_handle_);
-  ignore_failure_ = false;
-
-  CHECK(HasProxy());
-  bool is_direct = (GetCurrentProxy() == kNoProxy);
-  LOG(INFO) << "Using proxy: " << (is_direct ? "no" : "yes");
-  if (is_direct) {
-    CHECK_EQ(curl_easy_setopt(curl_handle_,
-                              CURLOPT_PROXY,
-                              ""), CURLE_OK);
-  } else {
-    CHECK_EQ(curl_easy_setopt(curl_handle_,
-                              CURLOPT_PROXY,
-                              GetCurrentProxy().c_str()), CURLE_OK);
-    // Curl seems to require us to set the protocol
-    curl_proxytype type;
-    if (GetProxyType(GetCurrentProxy(), &type)) {
-      CHECK_EQ(curl_easy_setopt(curl_handle_,
-                                CURLOPT_PROXYTYPE,
-                                type), CURLE_OK);
-    }
-  }
-
-  if (post_data_set_) {
-    CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_POST, 1), CURLE_OK);
-    CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_POSTFIELDS,
-                              post_data_.data()),
-             CURLE_OK);
-    CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_POSTFIELDSIZE,
-                              post_data_.size()),
-             CURLE_OK);
-  }
-
-  // Setup extra HTTP headers.
-  if (curl_http_headers_) {
-    curl_slist_free_all(curl_http_headers_);
-    curl_http_headers_ = nullptr;
-  }
-  for (const auto& header : extra_headers_) {
-    // curl_slist_append() copies the string.
-    curl_http_headers_ =
-        curl_slist_append(curl_http_headers_, header.second.c_str());
-  }
-  if (post_data_set_) {
-    // Set the Content-Type HTTP header, if one was specifically set.
-    if (post_content_type_ != kHttpContentTypeUnspecified) {
-      const string content_type_attr = base::StringPrintf(
-          "Content-Type: %s", GetHttpContentTypeString(post_content_type_));
-      curl_http_headers_ =
-          curl_slist_append(curl_http_headers_, content_type_attr.c_str());
-    } else {
-      LOG(WARNING) << "no content type set, using libcurl default";
-    }
-  }
-  CHECK_EQ(
-      curl_easy_setopt(curl_handle_, CURLOPT_HTTPHEADER, curl_http_headers_),
-      CURLE_OK);
-
-  if (bytes_downloaded_ > 0 || download_length_) {
-    // Resume from where we left off.
-    resume_offset_ = bytes_downloaded_;
-    CHECK_GE(resume_offset_, 0);
-
-    // Compute end offset, if one is specified. As per HTTP specification, this
-    // is an inclusive boundary. Make sure it doesn't overflow.
-    size_t end_offset = 0;
-    if (download_length_) {
-      end_offset = static_cast<size_t>(resume_offset_) + download_length_ - 1;
-      CHECK_LE((size_t) resume_offset_, end_offset);
-    }
-
-    // Create a string representation of the desired range.
-    string range_str = base::StringPrintf(
-        "%" PRIu64 "-", static_cast<uint64_t>(resume_offset_));
-    if (end_offset)
-      range_str += std::to_string(end_offset);
-    CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_RANGE, range_str.c_str()),
-             CURLE_OK);
-  }
-
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_WRITEDATA, this), CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_WRITEFUNCTION,
-                            StaticLibcurlWrite), CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_URL, url_.c_str()),
-           CURLE_OK);
-
-  // If the connection drops under |low_speed_limit_bps_| (10
-  // bytes/sec by default) for |low_speed_time_seconds_| (90 seconds,
-  // 180 on non-official builds), reconnect.
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_LOW_SPEED_LIMIT,
-                            low_speed_limit_bps_),
-           CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_LOW_SPEED_TIME,
-                            low_speed_time_seconds_),
-           CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_CONNECTTIMEOUT,
-                            connect_timeout_seconds_),
-           CURLE_OK);
-
-  // By default, libcurl doesn't follow redirections. Allow up to
-  // |kDownloadMaxRedirects| redirections.
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_FOLLOWLOCATION, 1), CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_MAXREDIRS,
-                            kDownloadMaxRedirects),
-           CURLE_OK);
-
-  // Lock down the appropriate curl options for HTTP or HTTPS depending on
-  // the url.
-  if (hardware_->IsOfficialBuild()) {
-    if (base::StartsWith(
-            url_, "http://", base::CompareCase::INSENSITIVE_ASCII)) {
-      SetCurlOptionsForHttp();
-    } else if (base::StartsWith(
-                   url_, "https://", base::CompareCase::INSENSITIVE_ASCII)) {
-      SetCurlOptionsForHttps();
-#if !defined(__CHROMEOS__) && !defined(__BRILLO__)
-    } else if (base::StartsWith(
-                   url_, "file://", base::CompareCase::INSENSITIVE_ASCII)) {
-      SetCurlOptionsForFile();
-#endif
-    } else {
-      LOG(ERROR) << "Received invalid URI: " << url_;
-      // Lock down to no protocol supported for the transfer.
-      CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_PROTOCOLS, 0), CURLE_OK);
-    }
-  } else {
-    LOG(INFO) << "Not setting http(s) curl options because we are "
-              << "running a dev/test image";
-  }
-
-  CHECK_EQ(curl_multi_add_handle(curl_multi_handle_, curl_handle_), CURLM_OK);
-  transfer_in_progress_ = true;
-}
-
-// Lock down only the protocol in case of HTTP.
-void LibcurlHttpFetcher::SetCurlOptionsForHttp() {
-  LOG(INFO) << "Setting up curl options for HTTP";
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_PROTOCOLS, CURLPROTO_HTTP),
-           CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_REDIR_PROTOCOLS,
-                            CURLPROTO_HTTP),
-           CURLE_OK);
-}
-
-// Security lock-down in official builds: makes sure that peer certificate
-// verification is enabled, restricts the set of trusted certificates,
-// restricts protocols to HTTPS, restricts ciphers to HIGH.
-void LibcurlHttpFetcher::SetCurlOptionsForHttps() {
-  LOG(INFO) << "Setting up curl options for HTTPS";
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_SSL_VERIFYPEER, 1),
-           CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_CAPATH,
-                            constants::kCACertificatesPath),
-           CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS),
-           CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_REDIR_PROTOCOLS,
-                            CURLPROTO_HTTPS),
-           CURLE_OK);
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_SSL_CIPHER_LIST, "HIGH:!ADH"),
-           CURLE_OK);
-  if (server_to_check_ != ServerToCheck::kNone) {
-    CHECK_EQ(
-        curl_easy_setopt(curl_handle_, CURLOPT_SSL_CTX_DATA, &server_to_check_),
-        CURLE_OK);
-    CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_SSL_CTX_FUNCTION,
-                              CertificateChecker::ProcessSSLContext),
-             CURLE_OK);
-  }
-}
-
-// Lock down only the protocol in case of a local file.
-void LibcurlHttpFetcher::SetCurlOptionsForFile() {
-  LOG(INFO) << "Setting up curl options for FILE";
-  CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_PROTOCOLS, CURLPROTO_FILE),
-           CURLE_OK);
-  CHECK_EQ(
-      curl_easy_setopt(curl_handle_, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_FILE),
-      CURLE_OK);
-}
-
-// Begins the transfer, which must not have already been started.
-void LibcurlHttpFetcher::BeginTransfer(const string& url) {
-  CHECK(!transfer_in_progress_);
-  url_ = url;
-  auto closure = base::Bind(&LibcurlHttpFetcher::ProxiesResolved,
-                            base::Unretained(this));
-  if (!ResolveProxiesForUrl(url_, closure)) {
-    LOG(ERROR) << "Couldn't resolve proxies";
-    if (delegate_)
-      delegate_->TransferComplete(this, false);
-  }
-}
-
-void LibcurlHttpFetcher::ProxiesResolved() {
-  transfer_size_ = -1;
-  resume_offset_ = 0;
-  retry_count_ = 0;
-  no_network_retry_count_ = 0;
-  http_response_code_ = 0;
-  terminate_requested_ = false;
-  sent_byte_ = false;
-
-  // If we are paused, we delay these two operations until Unpause is called.
-  if (transfer_paused_) {
-    restart_transfer_on_unpause_ = true;
-    return;
-  }
-  ResumeTransfer(url_);
-  CurlPerformOnce();
-}
-
-void LibcurlHttpFetcher::ForceTransferTermination() {
-  CleanUp();
-  if (delegate_) {
-    // Note that after the callback returns this object may be destroyed.
-    delegate_->TransferTerminated(this);
-  }
-}
-
-void LibcurlHttpFetcher::TerminateTransfer() {
-  if (in_write_callback_) {
-    terminate_requested_ = true;
-  } else {
-    ForceTransferTermination();
-  }
-}
-
-void LibcurlHttpFetcher::SetHeader(const string& header_name,
-                                   const string& header_value) {
-  string header_line = header_name + ": " + header_value;
-  // Avoid the space if no data on the right side of the semicolon.
-  if (header_value.empty())
-    header_line = header_name + ":";
-  TEST_AND_RETURN(header_line.find('\n') == string::npos);
-  TEST_AND_RETURN(header_name.find(':') == string::npos);
-  extra_headers_[base::ToLowerASCII(header_name)] = header_line;
-}
-
-void LibcurlHttpFetcher::CurlPerformOnce() {
-  CHECK(transfer_in_progress_);
-  int running_handles = 0;
-  CURLMcode retcode = CURLM_CALL_MULTI_PERFORM;
-
-  // libcurl may request that we immediately call curl_multi_perform after it
-  // returns, so we do. libcurl promises that curl_multi_perform will not block.
-  while (CURLM_CALL_MULTI_PERFORM == retcode) {
-    retcode = curl_multi_perform(curl_multi_handle_, &running_handles);
-    if (terminate_requested_) {
-      ForceTransferTermination();
-      return;
-    }
-  }
-
-  // If the transfer completes while paused, we should ignore the failure once
-  // the fetcher is unpaused.
-  if (running_handles == 0 && transfer_paused_ && !ignore_failure_) {
-    LOG(INFO) << "Connection closed while paused, ignoring failure.";
-    ignore_failure_ = true;
-  }
-
-  if (running_handles != 0 || transfer_paused_) {
-    // There's either more work to do or we are paused, so we just keep the
-    // file descriptors to watch up to date and exit, until we are done with the
-    // work and we are not paused.
-    SetupMessageLoopSources();
-    return;
-  }
-
-  // At this point, the transfer was completed in some way (error, connection
-  // closed or download finished).
-
-  GetHttpResponseCode();
-  if (http_response_code_) {
-    LOG(INFO) << "HTTP response code: " << http_response_code_;
-    no_network_retry_count_ = 0;
-  } else {
-    LOG(ERROR) << "Unable to get http response code.";
-  }
-
-  // we're done!
-  CleanUp();
-
-  // TODO(petkov): This temporary code tries to deal with the case where the
-  // update engine performs an update check while the network is not ready
-  // (e.g., right after resume). Longer term, we should check if the network
-  // is online/offline and return an appropriate error code.
-  if (!sent_byte_ &&
-      http_response_code_ == 0 &&
-      no_network_retry_count_ < no_network_max_retries_) {
-    no_network_retry_count_++;
-    MessageLoop::current()->PostDelayedTask(
-        FROM_HERE,
-        base::Bind(&LibcurlHttpFetcher::RetryTimeoutCallback,
-                   base::Unretained(this)),
-        TimeDelta::FromSeconds(kNoNetworkRetrySeconds));
-    LOG(INFO) << "No HTTP response, retry " << no_network_retry_count_;
-  } else if ((!sent_byte_ && !IsHttpResponseSuccess()) ||
-             IsHttpResponseError()) {
-    // The transfer completed w/ error and we didn't get any bytes.
-    // If we have another proxy to try, try that.
-    //
-    // TODO(garnold) in fact there are two separate cases here: one case is an
-    // other-than-success return code (including no return code) and no
-    // received bytes, which is necessary due to the way callbacks are
-    // currently processing error conditions;  the second is an explicit HTTP
-    // error code, where some data may have been received (as in the case of a
-    // semi-successful multi-chunk fetch).  This is a confusing behavior and
-    // should be unified into a complete, coherent interface.
-    LOG(INFO) << "Transfer resulted in an error (" << http_response_code_
-              << "), " << bytes_downloaded_ << " bytes downloaded";
-
-    PopProxy();  // Delete the proxy we just gave up on.
-
-    if (HasProxy()) {
-      // We have another proxy. Retry immediately.
-      LOG(INFO) << "Retrying with next proxy setting";
-      MessageLoop::current()->PostTask(
-          FROM_HERE,
-          base::Bind(&LibcurlHttpFetcher::RetryTimeoutCallback,
-                     base::Unretained(this)));
-    } else {
-      // Out of proxies. Give up.
-      LOG(INFO) << "No further proxies, indicating transfer complete";
-      if (delegate_)
-        delegate_->TransferComplete(this, false);  // signal fail
-    }
-  } else if ((transfer_size_ >= 0) && (bytes_downloaded_ < transfer_size_)) {
-    if (!ignore_failure_)
-      retry_count_++;
-    LOG(INFO) << "Transfer interrupted after downloading "
-              << bytes_downloaded_ << " of " << transfer_size_ << " bytes. "
-              << transfer_size_ - bytes_downloaded_ << " bytes remaining "
-              << "after " << retry_count_ << " attempt(s)";
-
-    if (retry_count_ > max_retry_count_) {
-      LOG(INFO) << "Reached max attempts (" << retry_count_ << ")";
-      if (delegate_)
-        delegate_->TransferComplete(this, false);  // signal fail
-    } else {
-      // Need to restart transfer
-      LOG(INFO) << "Restarting transfer to download the remaining bytes";
-      MessageLoop::current()->PostDelayedTask(
-          FROM_HERE,
-          base::Bind(&LibcurlHttpFetcher::RetryTimeoutCallback,
-                     base::Unretained(this)),
-          TimeDelta::FromSeconds(retry_seconds_));
-    }
-  } else {
-    LOG(INFO) << "Transfer completed (" << http_response_code_
-              << "), " << bytes_downloaded_ << " bytes downloaded";
-    if (delegate_) {
-      bool success = IsHttpResponseSuccess();
-      delegate_->TransferComplete(this, success);
-    }
-  }
-  ignore_failure_ = false;
-}
-
-size_t LibcurlHttpFetcher::LibcurlWrite(void *ptr, size_t size, size_t nmemb) {
-  // Update HTTP response first.
-  GetHttpResponseCode();
-  const size_t payload_size = size * nmemb;
-
-  // Do nothing if no payload or HTTP response is an error.
-  if (payload_size == 0 || !IsHttpResponseSuccess()) {
-    LOG(INFO) << "HTTP response unsuccessful (" << http_response_code_
-              << ") or no payload (" << payload_size << "), nothing to do";
-    return 0;
-  }
-
-  sent_byte_ = true;
-  {
-    double transfer_size_double;
-    CHECK_EQ(curl_easy_getinfo(curl_handle_,
-                               CURLINFO_CONTENT_LENGTH_DOWNLOAD,
-                               &transfer_size_double), CURLE_OK);
-    off_t new_transfer_size = static_cast<off_t>(transfer_size_double);
-    if (new_transfer_size > 0) {
-      transfer_size_ = resume_offset_ + new_transfer_size;
-    }
-  }
-  bytes_downloaded_ += payload_size;
-  in_write_callback_ = true;
-  if (delegate_)
-    delegate_->ReceivedBytes(this, ptr, payload_size);
-  in_write_callback_ = false;
-  return payload_size;
-}
-
-void LibcurlHttpFetcher::Pause() {
-  if (transfer_paused_) {
-    LOG(ERROR) << "Fetcher already paused.";
-    return;
-  }
-  transfer_paused_ = true;
-  if (!transfer_in_progress_) {
-    // If pause before we started a connection, we don't need to notify curl
-    // about that, we will simply not start the connection later.
-    return;
-  }
-  CHECK(curl_handle_);
-  CHECK_EQ(curl_easy_pause(curl_handle_, CURLPAUSE_ALL), CURLE_OK);
-}
-
-void LibcurlHttpFetcher::Unpause() {
-  if (!transfer_paused_) {
-    LOG(ERROR) << "Resume attempted when fetcher not paused.";
-    return;
-  }
-  transfer_paused_ = false;
-  if (restart_transfer_on_unpause_) {
-    restart_transfer_on_unpause_ = false;
-    ResumeTransfer(url_);
-    CurlPerformOnce();
-    return;
-  }
-  if (!transfer_in_progress_) {
-    // If resumed before starting the connection, there's no need to notify
-    // anybody. We will simply start the connection once it is time.
-    return;
-  }
-  CHECK(curl_handle_);
-  CHECK_EQ(curl_easy_pause(curl_handle_, CURLPAUSE_CONT), CURLE_OK);
-  // Since the transfer is in progress, we need to dispatch a CurlPerformOnce()
-  // now to let the connection continue, otherwise it would be called by the
-  // TimeoutCallback but with a delay.
-  CurlPerformOnce();
-}
-
-// This method sets up callbacks with the MessageLoop.
-void LibcurlHttpFetcher::SetupMessageLoopSources() {
-  fd_set fd_read;
-  fd_set fd_write;
-  fd_set fd_exc;
-
-  FD_ZERO(&fd_read);
-  FD_ZERO(&fd_write);
-  FD_ZERO(&fd_exc);
-
-  int fd_max = 0;
-
-  // Ask libcurl for the set of file descriptors we should track on its
-  // behalf.
-  CHECK_EQ(curl_multi_fdset(curl_multi_handle_, &fd_read, &fd_write,
-                            &fd_exc, &fd_max), CURLM_OK);
-
-  // We should iterate through all file descriptors up to libcurl's fd_max or
-  // the highest one we're tracking, whichever is larger.
-  for (size_t t = 0; t < arraysize(fd_task_maps_); ++t) {
-    if (!fd_task_maps_[t].empty())
-      fd_max = max(fd_max, fd_task_maps_[t].rbegin()->first);
-  }
-
-  // For each fd, if we're not tracking it, track it. If we are tracking it, but
-  // libcurl doesn't care about it anymore, stop tracking it. After this loop,
-  // there should be exactly as many tasks scheduled in fd_task_maps_[0|1] as
-  // there are read/write fds that we're tracking.
-  for (int fd = 0; fd <= fd_max; ++fd) {
-    // Note that fd_exc is unused in the current version of libcurl so is_exc
-    // should always be false.
-    bool is_exc = FD_ISSET(fd, &fd_exc) != 0;
-    bool must_track[2] = {
-      is_exc || (FD_ISSET(fd, &fd_read) != 0),  // track 0 -- read
-      is_exc || (FD_ISSET(fd, &fd_write) != 0)  // track 1 -- write
-    };
-    MessageLoop::WatchMode watch_modes[2] = {
-      MessageLoop::WatchMode::kWatchRead,
-      MessageLoop::WatchMode::kWatchWrite,
-    };
-
-    for (size_t t = 0; t < arraysize(fd_task_maps_); ++t) {
-      auto fd_task_it = fd_task_maps_[t].find(fd);
-      bool tracked = fd_task_it != fd_task_maps_[t].end();
-
-      if (!must_track[t]) {
-        // If we have an outstanding io_channel, remove it.
-        if (tracked) {
-          MessageLoop::current()->CancelTask(fd_task_it->second);
-          fd_task_maps_[t].erase(fd_task_it);
-        }
-        continue;
-      }
-
-      // If we are already tracking this fd, continue -- nothing to do.
-      if (tracked)
-        continue;
-
-      // Track a new fd.
-      fd_task_maps_[t][fd] = MessageLoop::current()->WatchFileDescriptor(
-          FROM_HERE,
-          fd,
-          watch_modes[t],
-          true,  // persistent
-          base::Bind(&LibcurlHttpFetcher::CurlPerformOnce,
-                     base::Unretained(this)));
-
-      static int io_counter = 0;
-      io_counter++;
-      if (io_counter % 50 == 0) {
-        LOG(INFO) << "io_counter = " << io_counter;
-      }
-    }
-  }
-
-  // Set up a timeout callback for libcurl.
-  if (timeout_id_ == MessageLoop::kTaskIdNull) {
-    VLOG(1) << "Setting up timeout source: " << idle_seconds_ << " seconds.";
-    timeout_id_ = MessageLoop::current()->PostDelayedTask(
-        FROM_HERE,
-        base::Bind(&LibcurlHttpFetcher::TimeoutCallback,
-                   base::Unretained(this)),
-        TimeDelta::FromSeconds(idle_seconds_));
-  }
-}
-
-void LibcurlHttpFetcher::RetryTimeoutCallback() {
-  if (transfer_paused_) {
-    restart_transfer_on_unpause_ = true;
-    return;
-  }
-  ResumeTransfer(url_);
-  CurlPerformOnce();
-}
-
-void LibcurlHttpFetcher::TimeoutCallback() {
-  // We always re-schedule the callback, even if we don't want to be called
-  // anymore. We will remove the event source separately if we don't want to
-  // be called back.
-  timeout_id_ = MessageLoop::current()->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&LibcurlHttpFetcher::TimeoutCallback, base::Unretained(this)),
-      TimeDelta::FromSeconds(idle_seconds_));
-
-  // CurlPerformOnce() may call CleanUp(), so we need to schedule our callback
-  // first, since it could be canceled by this call.
-  if (transfer_in_progress_)
-    CurlPerformOnce();
-}
-
-void LibcurlHttpFetcher::CleanUp() {
-  MessageLoop::current()->CancelTask(timeout_id_);
-  timeout_id_ = MessageLoop::kTaskIdNull;
-
-  for (size_t t = 0; t < arraysize(fd_task_maps_); ++t) {
-    for (const auto& fd_taks_pair : fd_task_maps_[t]) {
-      if (!MessageLoop::current()->CancelTask(fd_taks_pair.second)) {
-        LOG(WARNING) << "Error canceling the watch task "
-                     << fd_taks_pair.second << " for "
-                     << (t ? "writing" : "reading") << " the fd "
-                     << fd_taks_pair.first;
-      }
-    }
-    fd_task_maps_[t].clear();
-  }
-
-  if (curl_http_headers_) {
-    curl_slist_free_all(curl_http_headers_);
-    curl_http_headers_ = nullptr;
-  }
-  if (curl_handle_) {
-    if (curl_multi_handle_) {
-      CHECK_EQ(curl_multi_remove_handle(curl_multi_handle_, curl_handle_),
-               CURLM_OK);
-    }
-    curl_easy_cleanup(curl_handle_);
-    curl_handle_ = nullptr;
-  }
-  if (curl_multi_handle_) {
-    CHECK_EQ(curl_multi_cleanup(curl_multi_handle_), CURLM_OK);
-    curl_multi_handle_ = nullptr;
-  }
-  transfer_in_progress_ = false;
-  transfer_paused_ = false;
-  restart_transfer_on_unpause_ = false;
-}
-
-void LibcurlHttpFetcher::GetHttpResponseCode() {
-  long http_response_code = 0;  // NOLINT(runtime/int) - curl needs long.
-  if (base::StartsWith(url_, "file://", base::CompareCase::INSENSITIVE_ASCII)) {
-    // Fake out a valid response code for file:// URLs.
-    http_response_code_ = 299;
-  } else if (curl_easy_getinfo(curl_handle_,
-                               CURLINFO_RESPONSE_CODE,
-                               &http_response_code) == CURLE_OK) {
-    http_response_code_ = static_cast<int>(http_response_code);
-  }
-}
-
-}  // namespace chromeos_update_engine
diff --git a/common/libcurl_http_fetcher.h b/common/libcurl_http_fetcher.h
deleted file mode 100644
index d126171..0000000
--- a/common/libcurl_http_fetcher.h
+++ /dev/null
@@ -1,269 +0,0 @@
-//
-// Copyright (C) 2009 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef UPDATE_ENGINE_COMMON_LIBCURL_HTTP_FETCHER_H_
-#define UPDATE_ENGINE_COMMON_LIBCURL_HTTP_FETCHER_H_
-
-#include <map>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include <curl/curl.h>
-
-#include <base/logging.h>
-#include <base/macros.h>
-#include <brillo/message_loops/message_loop.h>
-
-#include "update_engine/common/certificate_checker.h"
-#include "update_engine/common/hardware_interface.h"
-#include "update_engine/common/http_fetcher.h"
-
-// This is a concrete implementation of HttpFetcher that uses libcurl to do the
-// http work.
-
-namespace chromeos_update_engine {
-
-class LibcurlHttpFetcher : public HttpFetcher {
- public:
-  LibcurlHttpFetcher(ProxyResolver* proxy_resolver,
-                     HardwareInterface* hardware);
-
-  // Cleans up all internal state. Does not notify delegate
-  ~LibcurlHttpFetcher() override;
-
-  void SetOffset(off_t offset) override { bytes_downloaded_ = offset; }
-
-  void SetLength(size_t length) override { download_length_ = length; }
-  void UnsetLength() override { SetLength(0); }
-
-  // Begins the transfer if it hasn't already begun.
-  void BeginTransfer(const std::string& url) override;
-
-  // If the transfer is in progress, aborts the transfer early. The transfer
-  // cannot be resumed.
-  void TerminateTransfer() override;
-
-  // Pass the headers to libcurl.
-  void SetHeader(const std::string& header_name,
-                 const std::string& header_value) override;
-
-  // Suspend the transfer by calling curl_easy_pause(CURLPAUSE_ALL).
-  void Pause() override;
-
-  // Resume the transfer by calling curl_easy_pause(CURLPAUSE_CONT).
-  void Unpause() override;
-
-  // Libcurl sometimes asks to be called back after some time while
-  // leaving that time unspecified. In that case, we pick a reasonable
-  // default of one second, but it can be overridden here. This is
-  // primarily useful for testing.
-  // From http://curl.haxx.se/libcurl/c/curl_multi_timeout.html:
-  //     if libcurl returns a -1 timeout here, it just means that libcurl
-  //     currently has no stored timeout value. You must not wait too long
-  //     (more than a few seconds perhaps) before you call
-  //     curl_multi_perform() again.
-  void set_idle_seconds(int seconds) override { idle_seconds_ = seconds; }
-
-  // Sets the retry timeout. Useful for testing.
-  void set_retry_seconds(int seconds) override { retry_seconds_ = seconds; }
-
-  void set_no_network_max_retries(int retries) {
-    no_network_max_retries_ = retries;
-  }
-
-  void set_server_to_check(ServerToCheck server_to_check) {
-    server_to_check_ = server_to_check;
-  }
-
-  size_t GetBytesDownloaded() override {
-    return static_cast<size_t>(bytes_downloaded_);
-  }
-
-  void set_low_speed_limit(int low_speed_bps, int low_speed_sec) override {
-    low_speed_limit_bps_ = low_speed_bps;
-    low_speed_time_seconds_ = low_speed_sec;
-  }
-
-  void set_connect_timeout(int connect_timeout_seconds) override {
-    connect_timeout_seconds_ = connect_timeout_seconds;
-  }
-
-  void set_max_retry_count(int max_retry_count) override {
-    max_retry_count_ = max_retry_count;
-  }
-
- private:
-  // Callback for when proxy resolution has completed. This begins the
-  // transfer.
-  void ProxiesResolved();
-
-  // Asks libcurl for the http response code and stores it in the object.
-  void GetHttpResponseCode();
-
-  // Checks whether stored HTTP response is within the success range.
-  inline bool IsHttpResponseSuccess() {
-    return (http_response_code_ >= 200 && http_response_code_ < 300);
-  }
-
-  // Checks whether stored HTTP response is within the error range. This
-  // includes both errors with the request (4xx) and server errors (5xx).
-  inline bool IsHttpResponseError() {
-    return (http_response_code_ >= 400 && http_response_code_ < 600);
-  }
-
-  // Resumes a transfer where it left off. This will use the
-  // HTTP Range: header to make a new connection from where the last
-  // left off.
-  virtual void ResumeTransfer(const std::string& url);
-
-  void TimeoutCallback();
-  void RetryTimeoutCallback();
-
-  // Calls into curl_multi_perform to let libcurl do its work. Returns after
-  // curl_multi_perform is finished, which may actually be after more than
-  // one call to curl_multi_perform. This method will set up the message
-  // loop with sources for future work that libcurl will do, if any, or complete
-  // the transfer and finish the action if no work left to do.
-  // This method will not block.
-  void CurlPerformOnce();
-
-  // Sets up message loop sources as needed by libcurl. This is generally
-  // the file descriptor of the socket and a timer in case nothing happens
-  // on the fds.
-  void SetupMessageLoopSources();
-
-  // Callback called by libcurl when new data has arrived on the transfer
-  size_t LibcurlWrite(void *ptr, size_t size, size_t nmemb);
-  static size_t StaticLibcurlWrite(void *ptr, size_t size,
-                                   size_t nmemb, void *stream) {
-    return reinterpret_cast<LibcurlHttpFetcher*>(stream)->
-        LibcurlWrite(ptr, size, nmemb);
-  }
-
-  // Cleans up the following if they are non-null:
-  // curl(m) handles, fd_task_maps_, timeout_id_.
-  void CleanUp();
-
-  // Force terminate the transfer. This will invoke the delegate's (if any)
-  // TransferTerminated callback so, after returning, this fetcher instance may
-  // be destroyed.
-  void ForceTransferTermination();
-
-  // Sets the curl options for HTTP URL.
-  void SetCurlOptionsForHttp();
-
-  // Sets the curl options for HTTPS URL.
-  void SetCurlOptionsForHttps();
-
-  // Sets the curl options for file URI.
-  void SetCurlOptionsForFile();
-
-  // Convert a proxy URL into a curl proxy type, if applicable. Returns true iff
-  // conversion was successful, false otherwise (in which case nothing is
-  // written to |out_type|).
-  bool GetProxyType(const std::string& proxy, curl_proxytype* out_type);
-
-  // Hardware interface used to query dev-mode and official build settings.
-  HardwareInterface* hardware_;
-
-  // Handles for the libcurl library
-  CURLM* curl_multi_handle_{nullptr};
-  CURL* curl_handle_{nullptr};
-  struct curl_slist* curl_http_headers_{nullptr};
-
-  // The extra headers that will be sent on each request.
-  std::map<std::string, std::string> extra_headers_;
-
-  // Lists of all read(0)/write(1) file descriptors that we're waiting on from
-  // the message loop. libcurl may open/close descriptors and switch their
-  // directions so maintain two separate lists so that watch conditions can be
-  // set appropriately.
-  std::map<int, brillo::MessageLoop::TaskId> fd_task_maps_[2];
-
-  // The TaskId of the timer we're waiting on. kTaskIdNull if we are not waiting
-  // on it.
-  brillo::MessageLoop::TaskId timeout_id_{brillo::MessageLoop::kTaskIdNull};
-
-  bool transfer_in_progress_{false};
-  bool transfer_paused_{false};
-
-  // Whether it should ignore transfer failures for the purpose of retrying the
-  // connection.
-  bool ignore_failure_{false};
-
-  // Whether we should restart the transfer once Unpause() is called. This can
-  // be caused because either the connection dropped while pause or the proxy
-  // was resolved and we never started the transfer in the first place.
-  bool restart_transfer_on_unpause_{false};
-
-  // The transfer size. -1 if not known.
-  off_t transfer_size_{0};
-
-  // How many bytes have been downloaded and sent to the delegate.
-  off_t bytes_downloaded_{0};
-
-  // The remaining maximum number of bytes to download. Zero represents an
-  // unspecified length.
-  size_t download_length_{0};
-
-  // If we resumed an earlier transfer, data offset that we used for the
-  // new connection.  0 otherwise.
-  // In this class, resume refers to resuming a dropped HTTP connection,
-  // not to resuming an interrupted download.
-  off_t resume_offset_{0};
-
-  // Number of resumes performed so far and the max allowed.
-  int retry_count_{0};
-  int max_retry_count_{kDownloadMaxRetryCount};
-
-  // Seconds to wait before retrying a resume.
-  int retry_seconds_{20};
-
-  // Number of resumes due to no network (e.g., HTTP response code 0).
-  int no_network_retry_count_{0};
-  int no_network_max_retries_{0};
-
-  // Seconds to wait before asking libcurl to "perform".
-  int idle_seconds_{1};
-
-  // If true, we are currently performing a write callback on the delegate.
-  bool in_write_callback_{false};
-
-  // If true, we have returned at least one byte in the write callback
-  // to the delegate.
-  bool sent_byte_{false};
-
-  // We can't clean everything up while we're in a write callback, so
-  // if we get a terminate request, queue it until we can handle it.
-  bool terminate_requested_{false};
-
-  // The ServerToCheck used when checking this connection's certificate. If no
-  // certificate check needs to be performed, this should be set to
-  // ServerToCheck::kNone.
-  ServerToCheck server_to_check_{ServerToCheck::kNone};
-
-  int low_speed_limit_bps_{kDownloadLowSpeedLimitBps};
-  int low_speed_time_seconds_{kDownloadLowSpeedTimeSeconds};
-  int connect_timeout_seconds_{kDownloadConnectTimeoutSeconds};
-  int num_max_retries_;
-
-  DISALLOW_COPY_AND_ASSIGN(LibcurlHttpFetcher);
-};
-
-}  // namespace chromeos_update_engine
-
-#endif  // UPDATE_ENGINE_COMMON_LIBCURL_HTTP_FETCHER_H_
diff --git a/common/mock_certificate_checker.h b/common/mock_certificate_checker.h
deleted file mode 100644
index 1f55ca1..0000000
--- a/common/mock_certificate_checker.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// Copyright (C) 2011 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef UPDATE_ENGINE_COMMON_MOCK_CERTIFICATE_CHECKER_H_
-#define UPDATE_ENGINE_COMMON_MOCK_CERTIFICATE_CHECKER_H_
-
-#include <gmock/gmock.h>
-#include <openssl/ssl.h>
-
-#include "update_engine/common/certificate_checker.h"
-
-namespace chromeos_update_engine {
-
-class MockOpenSSLWrapper : public OpenSSLWrapper {
- public:
-  MOCK_CONST_METHOD4(GetCertificateDigest,
-                     bool(X509_STORE_CTX* x509_ctx,
-                          int* out_depth,
-                          unsigned int* out_digest_length,
-                          uint8_t* out_digest));
-};
-
-}  // namespace chromeos_update_engine
-
-#endif  // UPDATE_ENGINE_COMMON_MOCK_CERTIFICATE_CHECKER_H_
