| Index: net/http/http_cache.cc | 
| diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc | 
| index b5a79a3a9bfaa019fe0b4df37947e00b22f22403..2eb3c9502a07d60910f7caeef153ccf14577d502 100644 | 
| --- a/net/http/http_cache.cc | 
| +++ b/net/http/http_cache.cc | 
| @@ -21,7 +21,6 @@ | 
| #include "base/memory/ref_counted.h" | 
| #include "base/message_loop/message_loop.h" | 
| #include "base/metrics/field_trial.h" | 
| -#include "base/metrics/histogram.h" | 
| #include "base/pickle.h" | 
| #include "base/stl_util.h" | 
| #include "base/strings/string_number_conversions.h" | 
| @@ -34,7 +33,6 @@ | 
| #include "net/base/io_buffer.h" | 
| #include "net/base/load_flags.h" | 
| #include "net/base/net_errors.h" | 
| -#include "net/base/network_delegate.h" | 
| #include "net/base/upload_data_stream.h" | 
| #include "net/disk_cache/disk_cache.h" | 
| #include "net/http/disk_based_cert_cache.h" | 
| @@ -295,159 +293,6 @@ class HttpCache::QuicServerInfoFactoryAdaptor : public QuicServerInfoFactory { | 
| }; | 
|  | 
| //----------------------------------------------------------------------------- | 
| - | 
| -class HttpCache::AsyncValidation { | 
| - public: | 
| -  AsyncValidation(const HttpRequestInfo& original_request, HttpCache* cache) | 
| -      : request_(original_request), cache_(cache) {} | 
| -  ~AsyncValidation() {} | 
| - | 
| -  void Start(const BoundNetLog& net_log, | 
| -             scoped_ptr<Transaction> transaction, | 
| -             NetworkDelegate* network_delegate); | 
| - | 
| - private: | 
| -  void OnStarted(int result); | 
| -  void DoRead(); | 
| -  void OnRead(int result); | 
| - | 
| -  // Terminate this request with net error code |result|. Logs the transaction | 
| -  // result and asks HttpCache to delete this object. | 
| -  // If there was a client or server certificate error, it cannot be recovered | 
| -  // asynchronously, so we need to prevent future attempts to asynchronously | 
| -  // fetch the resource. In this case, the cache entry is doomed. | 
| -  void Terminate(int result); | 
| - | 
| -  HttpRequestInfo request_; | 
| -  scoped_refptr<IOBuffer> buf_; | 
| -  CompletionCallback read_callback_; | 
| -  scoped_ptr<Transaction> transaction_; | 
| -  base::Time start_time_; | 
| - | 
| -  // The HttpCache object owns this object. This object is always deleted before | 
| -  // the pointer to the cache becomes invalid. | 
| -  HttpCache* cache_; | 
| - | 
| -  DISALLOW_COPY_AND_ASSIGN(AsyncValidation); | 
| -}; | 
| - | 
| -void HttpCache::AsyncValidation::Start(const BoundNetLog& net_log, | 
| -                                       scoped_ptr<Transaction> transaction, | 
| -                                       NetworkDelegate* network_delegate) { | 
| -  transaction_ = transaction.Pass(); | 
| -  if (network_delegate) { | 
| -    // This code is necessary to enable async transactions to pass over the | 
| -    // data-reduction proxy. This is a violation of the "once-and-only-once" | 
| -    // principle, since it copies code from URLRequestHttpJob. We cannot use the | 
| -    // original callback passed to HttpCache::Transaction by URLRequestHttpJob | 
| -    // as it will only be valid as long as the URLRequestHttpJob object is | 
| -    // alive, and that object will be deleted as soon as the synchronous request | 
| -    // completes. | 
| -    // | 
| -    // This code is also an encapsulation violation. We are exploiting the fact | 
| -    // that the |request| parameter to NotifyBeforeSendProxyHeaders() is never | 
| -    // actually used for anything, and so can be NULL. | 
| -    // | 
| -    // TODO(ricea): Do this better. | 
| -    transaction_->SetBeforeProxyHeadersSentCallback( | 
| -        base::Bind(&NetworkDelegate::NotifyBeforeSendProxyHeaders, | 
| -                   base::Unretained(network_delegate), | 
| -                   static_cast<URLRequest*>(NULL))); | 
| -    // The above use of base::Unretained is safe because the NetworkDelegate has | 
| -    // to live at least as long as the HttpNetworkSession which has to live as | 
| -    // least as long as the HttpNetworkLayer which has to live at least as long | 
| -    // this HttpCache object. | 
| -  } | 
| - | 
| -  DCHECK_EQ(0, request_.load_flags & LOAD_ASYNC_REVALIDATION); | 
| -  request_.load_flags |= LOAD_ASYNC_REVALIDATION; | 
| -  start_time_ = cache_->clock()->Now(); | 
| -  // This use of base::Unretained is safe because |transaction_| is owned by | 
| -  // this object. | 
| -  read_callback_ = base::Bind(&AsyncValidation::OnRead, base::Unretained(this)); | 
| -  // This use of base::Unretained is safe as above. | 
| -  int rv = transaction_->Start( | 
| -      &request_, | 
| -      base::Bind(&AsyncValidation::OnStarted, base::Unretained(this)), | 
| -      net_log); | 
| - | 
| -  if (rv == ERR_IO_PENDING) | 
| -    return; | 
| - | 
| -  OnStarted(rv); | 
| -} | 
| - | 
| -void HttpCache::AsyncValidation::OnStarted(int result) { | 
| -  if (result != OK) { | 
| -    DVLOG(1) << "Asynchronous transaction start failed for " << request_.url; | 
| -    Terminate(result); | 
| -    return; | 
| -  } | 
| - | 
| -  while (transaction_->IsReadyToRestartForAuth()) { | 
| -    // This code is based on URLRequestHttpJob::RestartTransactionWithAuth, | 
| -    // however when we do this here cookies on the response will not be | 
| -    // stored. Fortunately only a tiny number of sites set cookies on 401 | 
| -    // responses, and none of them use stale-while-revalidate. | 
| -    result = transaction_->RestartWithAuth( | 
| -        AuthCredentials(), | 
| -        base::Bind(&AsyncValidation::OnStarted, base::Unretained(this))); | 
| -    if (result == ERR_IO_PENDING) | 
| -      return; | 
| -    if (result != OK) { | 
| -      DVLOG(1) << "Synchronous transaction restart with auth failed for " | 
| -               << request_.url; | 
| -      Terminate(result); | 
| -      return; | 
| -    } | 
| -  } | 
| - | 
| -  DoRead(); | 
| -} | 
| - | 
| -void HttpCache::AsyncValidation::DoRead() { | 
| -  const size_t kBufSize = 4096; | 
| -  if (!buf_.get()) | 
| -    buf_ = new IOBuffer(kBufSize); | 
| - | 
| -  int rv = 0; | 
| -  do { | 
| -    rv = transaction_->Read(buf_.get(), kBufSize, read_callback_); | 
| -  } while (rv > 0); | 
| - | 
| -  if (rv == ERR_IO_PENDING) | 
| -    return; | 
| - | 
| -  OnRead(rv); | 
| -} | 
| - | 
| -void HttpCache::AsyncValidation::OnRead(int result) { | 
| -  if (result > 0) { | 
| -    DoRead(); | 
| -    return; | 
| -  } | 
| -  Terminate(result); | 
| -} | 
| - | 
| -void HttpCache::AsyncValidation::Terminate(int result) { | 
| -  if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED || IsCertificateError(result)) { | 
| -    // We should not attempt to access this resource asynchronously again until | 
| -    // the certificate problem has been resolved. | 
| -    // TODO(ricea): For ERR_SSL_CLIENT_AUTH_CERT_NEEDED, mark the entry as | 
| -    // requiring synchronous revalidation rather than just deleting it. Other | 
| -    // certificate errors cause the resource to be considered uncacheable | 
| -    // anyway. | 
| -    cache_->DoomEntry(transaction_->key(), transaction_.get()); | 
| -  } | 
| -  base::TimeDelta duration = cache_->clock()->Now() - start_time_; | 
| -  UMA_HISTOGRAM_TIMES("HttpCache.AsyncValidationDuration", duration); | 
| -  transaction_->net_log().EndEventWithNetErrorCode( | 
| -      NetLog::TYPE_ASYNC_REVALIDATION, result); | 
| -  cache_->DeleteAsyncValidation(cache_->GenerateCacheKey(&request_)); | 
| -  // |this| is deleted. | 
| -} | 
| - | 
| -//----------------------------------------------------------------------------- | 
| HttpCache::HttpCache(const HttpNetworkSession::Params& params, | 
| BackendFactory* backend_factory) | 
| : net_log_(params.net_log), | 
| @@ -455,7 +300,6 @@ HttpCache::HttpCache(const HttpNetworkSession::Params& params, | 
| building_backend_(false), | 
| bypass_lock_for_test_(false), | 
| fail_conditionalization_for_test_(false), | 
| -      use_stale_while_revalidate_(params.use_stale_while_revalidate), | 
| mode_(NORMAL), | 
| network_layer_(new HttpNetworkLayer(new HttpNetworkSession(params))), | 
| clock_(new base::DefaultClock()), | 
| @@ -473,7 +317,6 @@ HttpCache::HttpCache(HttpNetworkSession* session, | 
| building_backend_(false), | 
| bypass_lock_for_test_(false), | 
| fail_conditionalization_for_test_(false), | 
| -      use_stale_while_revalidate_(session->params().use_stale_while_revalidate), | 
| mode_(NORMAL), | 
| network_layer_(new HttpNetworkLayer(session)), | 
| clock_(new base::DefaultClock()), | 
| @@ -488,15 +331,11 @@ HttpCache::HttpCache(HttpTransactionFactory* network_layer, | 
| building_backend_(false), | 
| bypass_lock_for_test_(false), | 
| fail_conditionalization_for_test_(false), | 
| -      use_stale_while_revalidate_(false), | 
| mode_(NORMAL), | 
| network_layer_(network_layer), | 
| clock_(new base::DefaultClock()), | 
| weak_factory_(this) { | 
| SetupQuicServerInfoFactory(network_layer_->GetSession()); | 
| -  HttpNetworkSession* session = network_layer_->GetSession(); | 
| -  if (session) | 
| -    use_stale_while_revalidate_ = session->params().use_stale_while_revalidate; | 
| } | 
|  | 
| HttpCache::~HttpCache() { | 
| @@ -518,7 +357,6 @@ HttpCache::~HttpCache() { | 
| } | 
|  | 
| STLDeleteElements(&doomed_entries_); | 
| -  STLDeleteValues(&async_validations_); | 
|  | 
| // Before deleting pending_ops_, we have to make sure that the disk cache is | 
| // done with said operations, or it will attempt to use deleted data. | 
| @@ -1180,43 +1018,6 @@ void HttpCache::ProcessPendingQueue(ActiveEntry* entry) { | 
| base::Bind(&HttpCache::OnProcessPendingQueue, GetWeakPtr(), entry)); | 
| } | 
|  | 
| -void HttpCache::PerformAsyncValidation(const HttpRequestInfo& original_request, | 
| -                                       const BoundNetLog& net_log) { | 
| -  DCHECK(use_stale_while_revalidate_); | 
| -  std::string key = GenerateCacheKey(&original_request); | 
| -  AsyncValidation* async_validation = | 
| -      new AsyncValidation(original_request, this); | 
| -  typedef AsyncValidationMap::value_type AsyncValidationKeyValue; | 
| -  bool insert_ok = | 
| -      async_validations_.insert(AsyncValidationKeyValue(key, async_validation)) | 
| -          .second; | 
| -  if (!insert_ok) { | 
| -    DVLOG(1) << "Harmless race condition detected on URL " | 
| -             << original_request.url << "; discarding redundant revalidation."; | 
| -    delete async_validation; | 
| -    return; | 
| -  } | 
| -  HttpNetworkSession* network_session = GetSession(); | 
| -  NetworkDelegate* network_delegate = NULL; | 
| -  if (network_session) | 
| -    network_delegate = network_session->network_delegate(); | 
| -  scoped_ptr<HttpTransaction> transaction; | 
| -  CreateTransaction(IDLE, &transaction); | 
| -  scoped_ptr<Transaction> downcast_transaction( | 
| -      static_cast<Transaction*>(transaction.release())); | 
| -  async_validation->Start( | 
| -      net_log, downcast_transaction.Pass(), network_delegate); | 
| -  // |async_validation| may have been deleted here. | 
| -} | 
| - | 
| -void HttpCache::DeleteAsyncValidation(const std::string& url) { | 
| -  AsyncValidationMap::iterator it = async_validations_.find(url); | 
| -  CHECK(it != async_validations_.end());  // security-critical invariant | 
| -  AsyncValidation* async_validation = it->second; | 
| -  async_validations_.erase(it); | 
| -  delete async_validation; | 
| -} | 
| - | 
| void HttpCache::OnProcessPendingQueue(ActiveEntry* entry) { | 
| entry->will_process_pending_queue = false; | 
| DCHECK(!entry->writer); | 
|  |