/*
 * Copyright 2011 Google Inc.
 *
 * 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.
 */

// Author: sligocki@google.com (Shawn Ligocki)

#include "net/instaweb/http/public/cache_url_async_fetcher.h"

#include <cstddef>

#include "net/instaweb/http/public/async_fetch.h"
#include "net/instaweb/http/public/counting_url_async_fetcher.h"
#include "net/instaweb/http/public/http_cache.h"
#include "net/instaweb/http/public/http_cache_failure.h"
#include "net/instaweb/http/public/http_value.h"
#include "net/instaweb/http/public/log_record.h"
#include "net/instaweb/http/public/logging_proto_impl.h"
#include "net/instaweb/http/public/mock_url_fetcher.h"
#include "net/instaweb/http/public/request_context.h"
#include "pagespeed/kernel/base/abstract_mutex.h"  // for ScopedMutex
#include "pagespeed/kernel/base/function.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/mem_file_system.h"
#include "pagespeed/kernel/base/message_handler.h"
#include "pagespeed/kernel/base/mock_hasher.h"
#include "pagespeed/kernel/base/mock_timer.h"
#include "pagespeed/kernel/base/null_message_handler.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/statistics.h"
#include "pagespeed/kernel/base/statistics_template.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/thread_system.h"
#include "pagespeed/kernel/base/timer.h"
#include "pagespeed/kernel/cache/lru_cache.h"
#include "pagespeed/kernel/http/content_type.h"
#include "pagespeed/kernel/http/http_names.h"
#include "pagespeed/kernel/http/http_options.h"
#include "pagespeed/kernel/http/request_headers.h"
#include "pagespeed/kernel/http/response_headers.h"
#include "pagespeed/kernel/thread/mock_scheduler.h"
#include "pagespeed/kernel/thread/queued_worker_pool.h"
#include "pagespeed/kernel/thread/thread_synchronizer.h"
#include "pagespeed/kernel/util/file_system_lock_manager.h"
#include "pagespeed/kernel/util/platform.h"
#include "pagespeed/kernel/util/simple_stats.h"

namespace net_instaweb {

namespace {

const char kStartFetchPrefix[] = "start_fetch";
const char kFetchTriggeredPrefix[] = "fetch_triggered";
const char kDelayedFetchFinishPrefix[] = "delayed_fetch_finish";

class MockFetch : public AsyncFetch {
 public:
  MockFetch(const RequestContextPtr& ctx,
            GoogleString* content,
            bool* done,
            bool* success,
            bool* is_origin_cacheable)
      : AsyncFetch(ctx),
        content_(content),
        done_(done),
        success_(success),
        is_origin_cacheable_(is_origin_cacheable),
        cache_result_valid_(true) {
  }

  virtual ~MockFetch() {}

  virtual void HandleHeadersComplete() {
    // Make sure that we've called
    // response_headers()->ComputeCaching() before this and that this
    // call succeeds.  We don't care about the return value in this
    // context, we are just trying to ensure that the caching is not
    // dirty when this is called.
    response_headers()->IsProxyCacheable();
  }

  virtual bool HandleWrite(const StringPiece& content,
                           MessageHandler* handler) {
    content.AppendToString(content_);
    return true;
  }
  virtual bool HandleFlush(MessageHandler* handler) {
    return true;
  }

  // Fetch complete.
  virtual void HandleDone(bool success) {
    {
      ScopedMutex lock(log_record()->mutex());
      *is_origin_cacheable_ = log_record()->logging_info()->
          is_original_resource_cacheable();
      *success_ = success;
      *done_ = true;
    }
    delete this;
  }

  virtual bool IsCachedResultValid(const ResponseHeaders& headers) {
    // We simply override AsyncFetch and stub this.
    return cache_result_valid_;
  }

  void set_cache_result_valid(bool cache_result_valid) {
    cache_result_valid_ = cache_result_valid;
  }

 private:
  GoogleString* content_;
  bool* done_;
  bool* success_;
  bool* is_origin_cacheable_;
  bool cache_result_valid_;

  DISALLOW_COPY_AND_ASSIGN(MockFetch);
};

class MockCacheUrlAsyncFetcherAsyncOpHooks
    : public CacheUrlAsyncFetcher::AsyncOpHooks {
 public:
  MockCacheUrlAsyncFetcherAsyncOpHooks()
      : count_(0) {}
  virtual ~MockCacheUrlAsyncFetcherAsyncOpHooks() {
    // Check both StartAsyncOp() and FinishAsyncOp() should be called same
    // number of times.
    EXPECT_EQ(0, count_);
  }

  virtual void StartAsyncOp() {
    ++count_;
  }

  virtual void FinishAsyncOp() {
    --count_;
    ASSERT_GE(count_, 0);
  }

 private:
  int count_;
  DISALLOW_COPY_AND_ASSIGN(MockCacheUrlAsyncFetcherAsyncOpHooks);
};

class DelayedMockUrlFetcher : public MockUrlFetcher {
 public:
  explicit DelayedMockUrlFetcher(ThreadSynchronizer* sync)
      : MockUrlFetcher(),
        sync_(sync) {}
  virtual void Fetch(const GoogleString& url,
                     MessageHandler* message_handler,
                     AsyncFetch* fetch) {
    sync_->Signal(kFetchTriggeredPrefix);
    sync_->Wait(kStartFetchPrefix);
    MockUrlFetcher::Fetch(url, message_handler, fetch);
  }

 private:
  ThreadSynchronizer* sync_;
  DISALLOW_COPY_AND_ASSIGN(DelayedMockUrlFetcher);
};

class CacheUrlAsyncFetcherTest : public ::testing::Test {
 public:
  void TriggerDelayedFetchAndValidate() {
    FetchAndValidate(cache_url_, empty_request_headers_, true, HttpStatus::kOK,
                     cache_body_, kBackendFetch, true);
    thread_synchronizer_->Signal(kDelayedFetchFinishPrefix);
  }

 protected:
  // Helper class for calling Get and Query methods on cache implementations
  // that are blocking in nature (e.g. in-memory LRU or blocking file-system).
  class Callback : public HTTPCache::Callback {
   public:
    explicit Callback(const RequestContextPtr& ctx)
        : HTTPCache::Callback(ctx) {
      Reset();
    }
    Callback* Reset() {
      called_ = false;
      result_ = HTTPCache::FindResult();
      cache_valid_ = true;
      fresh_ = true;
      return this;
    }
    virtual void Done(HTTPCache::FindResult result) {
      called_ = true;
      result_ = result;
    }
    virtual bool IsCacheValid(const GoogleString& key,
                              const ResponseHeaders& headers) {
      // For unit testing, we are simply stubbing IsCacheValid.
      return cache_valid_;
    }
    virtual bool IsFresh(const ResponseHeaders& headers) {
      // For unit testing, we are simply stubbing IsFresh.
      return fresh_;
    }

    // The detailed Vary testing is handled in response_headers_test.cc and
    // is not needed here.
    virtual ResponseHeaders::VaryOption RespectVaryOnResources() const {
      return ResponseHeaders::kRespectVaryOnResources;
    }

    bool called_;
    HTTPCache::FindResult result_;
    bool cache_valid_;
    bool fresh_;
  };

  CacheUrlAsyncFetcherTest()
      : lru_cache_(1000),
        thread_system_(Platform::CreateThreadSystem()),
        statistics_(thread_system_.get()),
        timer_(thread_system_->NewMutex(), MockTimer::kApr_5_2010_ms),
        http_options_(kDefaultHttpOptionsForTests),
        cache_url_("http://www.example.com/cacheable.html"),
        cache_css_url_("http://www.example.com/cacheable.css"),
        cache_https_html_url_("https://www.example.com/cacheable.html"),
        cache_https_css_url_("https://www.example.com/cacheable.css"),
        nocache_url_("http://www.example.com/non-cacheable.jpg"),
        bad_url_("http://www.example.com/bad.url"),
        etag_url_("http://www.example.com/etag.jpg"),
        last_modified_url_("http://www.example.com/not_modified.jpg"),
        etag_and_last_modified_url_("http://www.example.com/double.jpg"),
        conditional_last_modified_url_(
            "http://www.example.com/cond_not_modified.jpg"),
        conditional_etag_url_("http://www.example.com/cond_etag.jpg"),
        implicit_cache_url_("http://www.example.com/implicit_cache.jpg"),
        vary_url_("http://www.example.com/vary"),
        fragment_("www.example.com"),
        cache_body_("good"), nocache_body_("bad"), bad_body_("ugly"),
        vary_body_("vary"),
        etag_("123456790ABCDEF"),
        ttl_ms_(Timer::kHourMs),
        implicit_cache_ttl_ms_(500 * Timer::kSecondMs),
        min_cache_ttl_ms_(-1),
        cache_result_valid_(true),
        thread_synchronizer_(new ThreadSynchronizer(thread_system_.get())),
        mock_fetcher_(thread_synchronizer_.get()),
        counting_fetcher_(&mock_fetcher_),
        scheduler_(thread_system_.get(), &timer_),
        file_system_(thread_system_.get(), &timer_),
        lock_manager_(&file_system_, GTestTempDir(), &scheduler_, &handler_) {
    HTTPCache::InitStats(&statistics_);
    http_cache_.reset(new HTTPCache(&lru_cache_, &timer_, &mock_hasher_,
                                    &statistics_));
    cache_fetcher_.reset(
        new CacheUrlAsyncFetcher(
            &mock_hasher_,
            &lock_manager_,
            http_cache_.get(),
            fragment_,
            &mock_async_op_hooks_,
            &counting_fetcher_));
    // Enable serving of stale content if the fetch fails.
    cache_fetcher_->set_serve_stale_if_fetch_error(true);

    Variable* fallback_responses_served = statistics_.AddVariable(
        "fallback_responses_served");
    cache_fetcher_->set_fallback_responses_served(fallback_responses_served);

    Variable* num_conditional_refreshes = statistics_.AddVariable(
        "num_conditional_refreshes");
    cache_fetcher_->set_num_conditional_refreshes(num_conditional_refreshes);

    Variable* fallback_responses_served_while_revalidate_ =
        statistics_.AddVariable("fallback_responses_served_while_revalidate");
    cache_fetcher_->set_fallback_responses_served_while_revalidate(
        fallback_responses_served_while_revalidate_);

    int64 now_ms = timer_.NowMs();

    // Set fetcher result and headers.
    ResponseHeaders cache_headers;
    SetDefaultHeaders(kContentTypeHtml, &cache_headers);
    cache_headers.SetDateAndCaching(now_ms, ttl_ms_);
    mock_fetcher_.SetResponse(cache_url_, cache_headers, cache_body_);
    mock_fetcher_.SetResponse(cache_https_html_url_, cache_headers,
                              cache_body_);
    cache_headers.Replace(HttpAttributes::kContentType,
                          kContentTypeCss.mime_type());
    mock_fetcher_.SetResponse(cache_css_url_, cache_headers, cache_body_);
    mock_fetcher_.SetResponse(cache_https_css_url_, cache_headers,
                              cache_body_);

    ResponseHeaders nocache_headers;
    SetDefaultHeaders(kContentTypeJpeg, &nocache_headers);
    nocache_headers.SetDate(now_ms);
    nocache_headers.Replace(HttpAttributes::kCacheControl, "no-cache");
    mock_fetcher_.SetResponse(nocache_url_, nocache_headers, nocache_body_);

    ResponseHeaders bad_headers;
    bad_headers.set_first_line(1, 1, 404, "Not Found");
    bad_headers.SetDate(now_ms);
    mock_fetcher_.SetResponse(bad_url_, bad_headers, bad_body_);

    ResponseHeaders etag_headers;
    etag_headers.CopyFrom(cache_headers);
    etag_headers.Add(HttpAttributes::kEtag, etag_);
    mock_fetcher_.SetResponse(etag_url_, etag_headers, cache_body_);

    ResponseHeaders last_modified_headers;
    last_modified_headers.CopyFrom(cache_headers);
    last_modified_headers.SetLastModified(
        MockTimer::kApr_5_2010_ms - 2 * Timer::kDayMs);
    mock_fetcher_.SetResponse(last_modified_url_, last_modified_headers,
                              cache_body_);

    ResponseHeaders etag_and_last_modified_headers;
    etag_and_last_modified_headers.CopyFrom(last_modified_headers);
    etag_and_last_modified_headers.Add(HttpAttributes::kEtag, etag_);
    mock_fetcher_.SetResponse(etag_and_last_modified_url_,
        etag_and_last_modified_headers, cache_body_);

    mock_fetcher_.SetConditionalResponse(conditional_last_modified_url_,
        MockTimer::kApr_5_2010_ms - 2 * Timer::kDayMs, "",
        last_modified_headers, cache_body_);

    mock_fetcher_.SetConditionalResponse(conditional_etag_url_,
        -1 , etag_, etag_headers, cache_body_);

    ResponseHeaders implicit_cache_headers;
    SetDefaultHeaders(kContentTypeJpeg, &implicit_cache_headers);
    implicit_cache_headers.SetDate(now_ms);
    implicit_cache_headers.Add(HttpAttributes::kEtag, etag_);
    mock_fetcher_.SetConditionalResponse(implicit_cache_url_, -1, etag_,
                                         implicit_cache_headers, cache_body_);

    mutable_vary_headers_.SetDateAndCaching(now_ms, ttl_ms_);
    mutable_vary_headers_.SetStatusAndReason(HttpStatus::kOK);
    mutable_vary_headers_.Add(HttpAttributes::kContentType,
                              kContentTypePng.mime_type());
    mock_fetcher_.SetResponse(vary_url_, mutable_vary_headers_, vary_body_);
  }

  HTTPCache::FindResult FindWithCallback(
      const GoogleString& key, HTTPValue* value, ResponseHeaders* headers,
      MessageHandler* handler, Callback* callback) {
    http_cache_->Find(key, fragment_, handler, callback);
    EXPECT_TRUE(callback->called_);
    if (callback->result_.status == HTTPCache::kFound) {
      value->Link(callback->http_value());
    }
    headers->CopyFrom(*callback->response_headers());
    return callback->result_;
  }

  HTTPCache::FindResult Find(const GoogleString& key, HTTPValue* value,
                             ResponseHeaders* headers,
                             MessageHandler* handler) {
    Callback callback(
        RequestContext::NewTestRequestContext(thread_system_.get()));
    return FindWithCallback(key, value, headers, handler, &callback);
  }

  HTTPCache::FindResult Find(const GoogleString& key, HTTPValue* value,
                             ResponseHeaders* headers,
                             MessageHandler* handler, bool cache_valid) {
    Callback callback(
        RequestContext::NewTestRequestContext(thread_system_.get()));
    callback.cache_valid_ = cache_valid;
    return FindWithCallback(key, value, headers, handler, &callback);
  }

  enum FetchType {
    kBackendFetch = 0,
    kFallbackFetch = 1,
    kServeStaleContentWhileRevalidate = 2,
  };

  void SetDefaultHeaders(const ContentType& content_type,
                         ResponseHeaders* header) const {
    header->set_major_version(1);
    header->set_minor_version(1);
    header->SetStatusAndReason(HttpStatus::kOK);

    header->Replace(HttpAttributes::kContentType, content_type.mime_type());
  }

  // cache_result_valid_ == false implies that MockFetch will return false for
  // IsCachedResultValid and thus the cache is invalidated.
  void FetchAndValidate(const StringPiece& url,
                        const RequestHeaders& request_headers,
                        bool success,
                        HttpStatus::Code code,
                        const StringPiece& expected_response,
                        FetchType fetch_type,
                        bool is_original_resource_cacheable) {
    GoogleString fetch_content;
    bool fetch_done = false;
    bool fetch_success = false;
    bool is_cacheable = false;
    ResponseHeaders fetch_response_headers;
    fetch_response_headers.set_implicit_cache_ttl_ms(implicit_cache_ttl_ms_);
    fetch_response_headers.set_min_cache_ttl_ms(min_cache_ttl_ms_);
    MockFetch* fetch = new MockFetch(
        RequestContextPtr(new RequestContext(
            http_options_, thread_system_->NewMutex(), NULL)),
        &fetch_content, &fetch_done, &fetch_success, &is_cacheable);
    fetch->set_cache_result_valid(cache_result_valid_);
    fetch->request_headers()->CopyFrom(request_headers);
    fetch->set_response_headers(&fetch_response_headers);
    // TODO(sligocki): Make Fetch take a StringPiece.
    cache_fetcher_->Fetch(url.as_string(), &handler_, fetch);
    // Implementation with LRUCache and MockFetcher should
    // call callbacks synchronously.
    EXPECT_TRUE(fetch_done);
    EXPECT_EQ(success, fetch_success);
    if (success) {
      EXPECT_TRUE(fetch_response_headers.has_status_code());
      EXPECT_EQ(code, fetch_response_headers.status_code());
      EXPECT_EQ(min_cache_ttl_ms_,
                fetch_response_headers.min_cache_ttl_ms());
      EXPECT_EQ(implicit_cache_ttl_ms_,
                fetch_response_headers.implicit_cache_ttl_ms());
    }
    EXPECT_EQ(is_original_resource_cacheable, is_cacheable) << url;
    if (fetch_type == kFallbackFetch) {
      EXPECT_STREQ(
          FallbackSharedAsyncFetch::kStaleWarningHeaderValue,
          fetch_response_headers.Lookup1(HttpAttributes::kWarning));
    }
    if (fetch_type == kServeStaleContentWhileRevalidate) {
      EXPECT_TRUE(
          fetch_response_headers.HasValue(HttpAttributes::kCacheControl,
                                          "private"));
      EXPECT_TRUE(
          fetch_response_headers.HasValue(HttpAttributes::kCacheControl,
                                          "max-age=0"));
      EXPECT_FALSE(fetch_response_headers.Has(HttpAttributes::kExpires));
    }
    // TODO(sligocki): Move this out of this function and just check at caller.
    EXPECT_STREQ(expected_response, fetch_content);
  }

  void ClearStats() {
    statistics_.Clear();
    counting_fetcher_.Clear();
  }

  void ExpectNoCacheWithOriginalCacheable(
      const StringPiece& url, const StringPiece& expected_body) {
    RequestHeaders request_headers;
    ExpectNoCacheWithRequestHeadersAndIsOriginalCacheable(
        url, expected_body, request_headers, true, true);
  }

  void ExpectNoCache(const StringPiece& url, const StringPiece& expected_body) {
    RequestHeaders request_headers;
    ExpectNoCacheWithRequestHeadersAndIsOriginalCacheable(
        url, expected_body, request_headers, false, true);
  }


  void ExpectNoCacheWithRequestHeaders(const StringPiece& url,
                                       const StringPiece& expected_body,
                                       const RequestHeaders& request_headers) {
    ExpectNoCacheWithRequestHeadersAndIsOriginalCacheable(
        url, expected_body, request_headers, false, true);
  }

  void ExpectNoCacheWithRequestHeadersAndIsOriginalCacheable(
      const StringPiece& url,
      const StringPiece& expected_body,
      const RequestHeaders& request_headers,
      bool is_original_cacheable,
      bool is_servable_from_cache) {
    ClearStats();
    FetchAndValidate(url, request_headers, true, HttpStatus::kOK,
                     expected_body, kBackendFetch, is_original_cacheable);
    // First fetch misses initial cache lookup ...
    EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
    EXPECT_EQ(0, http_cache_->cache_hits()->Get());
    EXPECT_EQ(is_servable_from_cache ? 1 : 0,
              http_cache_->cache_misses()->Get());
    // ... succeeds at fetch ...
    EXPECT_EQ(1, counting_fetcher_.fetch_count());
    // ... but isn't inserted into the cache, because it's not cacheable.
    EXPECT_EQ(0, http_cache_->cache_inserts()->Get());

    ClearStats();
    FetchAndValidate(url, request_headers, true, HttpStatus::kOK,
                     expected_body, kBackendFetch, is_original_cacheable);
    // We don't cache it because it has no Cache-Control header set, so the
    // same thing should happen as first fetch.
    EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
    EXPECT_EQ(0, http_cache_->cache_hits()->Get());
    EXPECT_EQ(is_servable_from_cache ? 1 : 0,
              http_cache_->cache_misses()->Get());
    EXPECT_EQ(1, counting_fetcher_.fetch_count());
    EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
  }

  void ExpectNoCacheWithMethodAndIsServable(const StringPiece& url,
                                            const StringPiece& expected_body,
                                            RequestHeaders::Method method,
                                            bool servable_from_cache) {
    RequestHeaders request_header;
    request_header.set_method(method);
    ExpectNoCacheWithRequestHeadersAndIsOriginalCacheable(
        url, expected_body, request_header, false, servable_from_cache);
  }

  void ExpectNoCacheWithMethod(const StringPiece& url,
                               const StringPiece& expected_body,
                               RequestHeaders::Method method) {
    ExpectNoCacheWithMethodAndIsServable(url, expected_body, method, false);
  }

  void ExpectCache(const StringPiece& url, const StringPiece& expected_body) {
    RequestHeaders request_headers;
    ExpectCacheWithRequestHeaders(url, expected_body, request_headers);
  }

  void ExpectCacheWithRequestHeaders(const StringPiece& url,
                                     const StringPiece& expected_body,
                                     const RequestHeaders& request_headers) {
    ClearStats();
    FetchAndValidate(url, request_headers, true, HttpStatus::kOK,
                     expected_body, kBackendFetch, true);
    // First fetch misses initial cache lookup ...
    EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
    EXPECT_EQ(0, http_cache_->cache_hits()->Get());
    EXPECT_EQ(1, http_cache_->cache_misses()->Get());
    // ... succeeds at fetch ...
    EXPECT_EQ(1, counting_fetcher_.fetch_count());
    // ... and inserts result into cache.
    EXPECT_EQ(1, http_cache_->cache_inserts()->Get());

    ClearStats();
    FetchAndValidate(url, request_headers, true, HttpStatus::kOK,
                     expected_body, kBackendFetch, true);
    // So second fetch hits initial cache lookup ...
    EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
    EXPECT_EQ(1, http_cache_->cache_hits()->Get());
    EXPECT_EQ(0, http_cache_->cache_misses()->Get());
    // ... and no extra fetches or inserts
    EXPECT_EQ(0, counting_fetcher_.fetch_count());
    EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
  }

  void ExpectServedFromCache(const StringPiece& url,
                            const StringPiece& expected_body) {
    RequestHeaders request_headers;
    ExpectServedFromCacheWithRequestHeaders(url, expected_body,
                                            request_headers);
  }

  void ExpectServedFromCacheWithRequestHeaders(
      const StringPiece& url,
      const StringPiece& expected_body,
      const RequestHeaders& request_headers) {
    ClearStats();
    FetchAndValidate(url, request_headers, true, HttpStatus::kOK,
                     expected_body, kBackendFetch, true);
    // First fetch hits the cache.
    EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
    EXPECT_EQ(1, http_cache_->cache_hits()->Get());
    EXPECT_EQ(0, http_cache_->cache_misses()->Get());
    // ... and no extra fetches or inserts
    EXPECT_EQ(0, counting_fetcher_.fetch_count());
    EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
  }

  void DefaultResponseHeaders(const ContentType& content_type, int64 ttl_sec,
                              ResponseHeaders* headers) {
    headers->set_major_version(1);
    headers->set_minor_version(1);
    headers->SetStatusAndReason(HttpStatus::kOK);

    headers->Add(HttpAttributes::kContentType, content_type.mime_type());

    const int64 now_ms = timer_.NowMs();
    headers->SetDateAndCaching(now_ms, ttl_sec * Timer::kSecondMs);
    headers->SetLastModified(now_ms);

    headers->ComputeCaching();
  }

  LRUCache lru_cache_;
  scoped_ptr<ThreadSystem> thread_system_;
  SimpleStats statistics_;
  MockTimer timer_;
  MockHasher mock_hasher_;
  scoped_ptr<HTTPCache> http_cache_;
  HttpOptions http_options_;

  scoped_ptr<CacheUrlAsyncFetcher> cache_fetcher_;

  NullMessageHandler handler_;
  RequestHeaders empty_request_headers_;

  const GoogleString cache_url_;
  const GoogleString cache_css_url_;
  const GoogleString cache_https_html_url_;
  const GoogleString cache_https_css_url_;
  const GoogleString nocache_url_;
  const GoogleString bad_url_;
  const GoogleString etag_url_;
  const GoogleString last_modified_url_;
  const GoogleString etag_and_last_modified_url_;
  const GoogleString conditional_last_modified_url_;
  const GoogleString conditional_etag_url_;
  const GoogleString implicit_cache_url_;
  const GoogleString vary_url_;

  const GoogleString fragment_;

  ResponseHeaders mutable_vary_headers_;

  const GoogleString cache_body_;
  const GoogleString nocache_body_;
  const GoogleString bad_body_;
  const GoogleString vary_body_;

  const GoogleString etag_;

  const int ttl_ms_;
  int64 implicit_cache_ttl_ms_;
  int64 min_cache_ttl_ms_;

  bool cache_result_valid_;

  scoped_ptr<ThreadSynchronizer> thread_synchronizer_;
  DelayedMockUrlFetcher mock_fetcher_;
  CountingUrlAsyncFetcher counting_fetcher_;
  MockScheduler scheduler_;
  MemFileSystem file_system_;
  FileSystemLockManager lock_manager_;
  MockCacheUrlAsyncFetcherAsyncOpHooks mock_async_op_hooks_;
};

TEST_F(CacheUrlAsyncFetcherTest, CacheableUrl) {
  ClearStats();
  FetchAndValidate(cache_url_, empty_request_headers_, true, HttpStatus::kOK,
                   cache_body_, kBackendFetch, true);
  // First fetch misses initial cache lookup ...
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  // ... succeeds at fetch ...
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  // ... and inserts result into cache.
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->fallback_responses_served()->Get());

  ClearStats();
  FetchAndValidate(cache_url_, empty_request_headers_, true, HttpStatus::kOK,
                   cache_body_, kBackendFetch, true);
  // Second fetch hits initial cache lookup ...
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  // ... and no extra fetches or inserts are needed.
  EXPECT_EQ(0, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->fallback_responses_served()->Get());

  cache_fetcher_->set_proactively_freshen_user_facing_request(true);
  // Advance the time so that cache is about to expire.
  timer_.AdvanceMs(ttl_ms_ - 3 * Timer::kMinuteMs);
  ClearStats();

  // Make sure that if the request that triggers proactive fetching is a HEAD
  // we don't mess stuff up.
  RequestHeaders head_headers;
  head_headers.CopyFrom(empty_request_headers_);
  head_headers.set_method(RequestHeaders::kHead);
  FetchAndValidate(cache_url_, head_headers, true, HttpStatus::kOK,
                   "", kBackendFetch, false);
  // Fetch hits initial cache lookup ...
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  // Background fetch is triggered to populate the cache with newer value.
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->fallback_responses_served()->Get());

  ClearStats();
  // This one is a GET, so it should actually get the bits.
  FetchAndValidate(cache_url_, empty_request_headers_, true, HttpStatus::kOK,
                   cache_body_, kBackendFetch, true);
  // Fetch hits initial cache lookup ...
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  // No fetch as cache is update with earlier background fetch.
  EXPECT_EQ(0, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->fallback_responses_served()->Get());
  cache_fetcher_->set_proactively_freshen_user_facing_request(false);

  // Induce a fetch failure so we are forced to serve stale data from the cache.
  mock_fetcher_.Disable();

  timer_.AdvanceMs(2 * ttl_ms_);
  ClearStats();
  FetchAndValidate(cache_url_, empty_request_headers_, false,
                   HttpStatus::kNotFound, "", kBackendFetch, false);
  // Cache entry is stale, so we must fetch again. However, the fetch fails.
  // Since the fetcher returns a 404 which is not a server error, we don't
  // return stale content.
  EXPECT_EQ(1, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(1, counting_fetcher_.failure_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->fallback_responses_served()->Get());

  // Re-enable the fetcher.
  mock_fetcher_.Enable();

  ClearStats();
  FetchAndValidate(cache_url_, empty_request_headers_, true, HttpStatus::kOK,
                   cache_body_, kBackendFetch, true);
  // Cache entry is stale, so we must fetch again. This time the fetch succeeds.
  EXPECT_EQ(1, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->fallback_responses_served()->Get());

  // Advance the time so that the response put into cache is now stale.
  timer_.AdvanceMs(2 * ttl_ms_);
  ClearStats();
  ResponseHeaders bad_headers;
  bad_headers.set_first_line(1, 1, 500, "Internal Server Error");
  bad_headers.SetDate(timer_.NowMs());
  mock_fetcher_.SetResponse(cache_url_, bad_headers, bad_body_);
  FetchAndValidate(cache_url_, empty_request_headers_, true, HttpStatus::kOK,
                   cache_body_, kFallbackFetch, false);
  // Since a fallback is present in cache, we don't serve out the 500 and
  // instead serve out the stale response.
  EXPECT_EQ(1, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(1, cache_fetcher_->fallback_responses_served()->Get());

  ClearStats();
  // Disable serving of stale content if the fetch fails.
  cache_fetcher_->set_serve_stale_if_fetch_error(false);
  FetchAndValidate(cache_url_, empty_request_headers_, true,
                   HttpStatus::kInternalServerError, bad_body_,
                   kBackendFetch, false);
  // Since serving of stale content is disabled, we serve out the 500 instead
  // of the fallback value.
  EXPECT_EQ(1, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->fallback_responses_served()->Get());

  // Enable serving of stale content if the fetch fails.
  cache_fetcher_->set_serve_stale_if_fetch_error(true);

  // Clear the LRU cache so that no fallback is available any more.
  lru_cache_.Clear();
  ClearStats();
  FetchAndValidate(cache_url_, empty_request_headers_, true,
                   HttpStatus::kInternalServerError, bad_body_,
                   kBackendFetch, false);
  // The fallback response is no longer available, hence we serve out the 500.
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->fallback_responses_served()->Get());
}

TEST_F(CacheUrlAsyncFetcherTest, ServeStaleContentWhileRevalidate) {
  // First css request to warm the cache.
  ExpectCache(cache_css_url_, cache_body_);
  ClearStats();

  cache_fetcher_->set_serve_stale_while_revalidate_threshold_sec(
      Timer::kDayMs * Timer::kSecondMs);
  // Advance the time so that values in cache is expired.
  timer_.AdvanceMs(ttl_ms_ + Timer::kHourMs);
  ClearStats();
  FetchAndValidate(cache_css_url_, empty_request_headers_, true,
                   HttpStatus::kOK, cache_body_,
                   kServeStaleContentWhileRevalidate, true);
  // Fetch hits initial cache lookup ...
  EXPECT_EQ(1, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  // Background fetch is triggered to populate the cache with newer value.
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->fallback_responses_served()->Get());
  // Stale content is served.
  EXPECT_EQ(1,
            cache_fetcher_
                ->fallback_responses_served_while_revalidate()->Get());

  ClearStats();
  FetchAndValidate(cache_css_url_, empty_request_headers_, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  // Fetch hits initial cache lookup ...
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  // No fetch as cache is update with earlier background fetch.
  EXPECT_EQ(0, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->fallback_responses_served()->Get());
  EXPECT_EQ(0,
            cache_fetcher_
                ->fallback_responses_served_while_revalidate()->Get());

  // First html request to warm the cache.
  ExpectCache(cache_url_, cache_body_);
  ClearStats();

  // Advance the time so that values in cache is expired.
  timer_.AdvanceMs(ttl_ms_ + Timer::kHourMs);
  ClearStats();
  FetchAndValidate(cache_url_, empty_request_headers_, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  // Fetch hits initial cache lookup ...
  EXPECT_EQ(1, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  // Fetch is triggered to populate the cache with newer value.
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->fallback_responses_served()->Get());
  // Stale content is not served for html requests.
  EXPECT_EQ(0,
            cache_fetcher_
                ->fallback_responses_served_while_revalidate()->Get());
}

TEST_F(CacheUrlAsyncFetcherTest, CachingWithHttpsHtmlCachingEnabled) {
  // With caching of html on https enabled, both html and css hosted on https
  // get cached.
  ClearStats();
  ExpectCache(cache_https_html_url_, cache_body_);

  ClearStats();
  ExpectServedFromCache(cache_https_html_url_, cache_body_);

  ClearStats();
  ExpectCache(cache_https_css_url_, cache_body_);

  ClearStats();
  ExpectServedFromCache(cache_https_css_url_, cache_body_);
}


TEST_F(CacheUrlAsyncFetcherTest, CachingWithHttpsHtmlCachingDisabled) {
  // With caching of html on https enabled, html hosted on https does not get
  // cached, while css does get cached.
  http_cache_->set_disable_html_caching_on_https(true);
  ClearStats();
  ExpectNoCacheWithOriginalCacheable(cache_https_html_url_, cache_body_);

  ClearStats();
  ExpectCache(cache_https_css_url_, cache_body_);

  ClearStats();
  ExpectServedFromCache(cache_https_css_url_, cache_body_);
}

TEST_F(CacheUrlAsyncFetcherTest, CacheableUrlCacheInvalidation) {
  ClearStats();
  FetchAndValidate(cache_url_, empty_request_headers_, true, HttpStatus::kOK,
                   cache_body_, kBackendFetch, true);
  // First fetch misses initial cache lookup ...
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  // ... succeeds at fetch ...
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  // ... and inserts result into cache.
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());

  ClearStats();
  FetchAndValidate(cache_url_, empty_request_headers_, true, HttpStatus::kOK,
                   cache_body_, kBackendFetch, true);
  // Second fetch hits initial cache lookup ...
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  // ... and no extra fetches or inserts are needed.
  EXPECT_EQ(0, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());

  ClearStats();
  // Invalidate cache and fetch.
  cache_result_valid_ = false;
  FetchAndValidate(cache_url_, empty_request_headers_, true, HttpStatus::kOK,
                   cache_body_, kBackendFetch, true);
  // Cache entry is invalid, so we must fetch again.
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());
}

TEST_F(CacheUrlAsyncFetcherTest, NonCacheableUrl) {
  ClearStats();
  FetchAndValidate(nocache_url_, empty_request_headers_, true, HttpStatus::kOK,
                   nocache_body_, kBackendFetch, false);
  // First fetch misses initial cache lookup ...
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  // ... succeeds at fetch ...
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  // ... and we don't insert into cache because it's not cacheable.
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());

  // Same thing happens second time.
  ClearStats();
  FetchAndValidate(nocache_url_, empty_request_headers_, true, HttpStatus::kOK,
                   nocache_body_, kBackendFetch, false);
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
}

TEST_F(CacheUrlAsyncFetcherTest, CheckEtags) {
  RequestHeaders request_headers;
  ClearStats();
  FetchAndValidate(etag_url_, request_headers, true, HttpStatus::kOK,
                   cache_body_, kBackendFetch, true);
  // First fetch misses initial cache lookup ...
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  // ... succeeds at fetch ...
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  // ... and inserts result into cache.
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());

  ClearStats();
  FetchAndValidate(etag_url_, request_headers, true, HttpStatus::kOK,
                   cache_body_, kBackendFetch, true);
  // Second fetch without the If-None-Match in the request hits initial cache
  // lookup ...
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  // ... and no extra fetches or inserts are needed.
  EXPECT_EQ(0, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());

  ClearStats();
  request_headers.Add(HttpAttributes::kIfNoneMatch, etag_);
  FetchAndValidate(etag_url_, request_headers, true, HttpStatus::kNotModified,
                   "", kBackendFetch, true);
  // The Etag matches and a 304 is served out.
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  EXPECT_EQ(0, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());

  ClearStats();
  request_headers.Replace(HttpAttributes::kIfNoneMatch, "mismatch");
  FetchAndValidate(etag_url_, request_headers, true, HttpStatus::kOK,
                   cache_body_, kBackendFetch, true);
  // The Etag does not match and a 200 is served out.
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  EXPECT_EQ(0, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
}

TEST_F(CacheUrlAsyncFetcherTest, CheckLastModified) {
  RequestHeaders request_headers;
  ClearStats();
  FetchAndValidate(last_modified_url_, request_headers, true, HttpStatus::kOK,
                   cache_body_, kBackendFetch, true);
  // First fetch misses initial cache lookup ...
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  // ... succeeds at fetch ...
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  // ... and inserts result into cache.
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());

  ClearStats();
  FetchAndValidate(last_modified_url_, request_headers, true, HttpStatus::kOK,
                   cache_body_, kBackendFetch, true);
  // Second fetch without the If-Modified-Since in the request hits initial
  // cache lookup ...
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  // ... and no extra fetches or inserts are needed.
  EXPECT_EQ(0, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());

  ClearStats();
  request_headers.Add(HttpAttributes::kIfModifiedSince,
                      "Sat, 03 Apr 2010 18:51:26 GMT");
  FetchAndValidate(last_modified_url_, request_headers, true,
                   HttpStatus::kNotModified, "", kBackendFetch, true);
  // The last modified timestamp matches and a 304 is served out.
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  EXPECT_EQ(0, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());

  ClearStats();
  request_headers.Replace(HttpAttributes::kIfModifiedSince,
                          "Sat, 02 Apr 2010 18:51:26 GMT");
  FetchAndValidate(last_modified_url_, request_headers, true, HttpStatus::kOK,
                   cache_body_, kBackendFetch, true);
  // The last modified timestamp does not match and a 200 is served out.
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  EXPECT_EQ(0, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
}

TEST_F(CacheUrlAsyncFetcherTest, CheckEtagAndLastModified) {
  RequestHeaders request_headers;
  ClearStats();
  FetchAndValidate(etag_and_last_modified_url_, request_headers, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  // First fetch misses initial cache lookup ...
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  // ... succeeds at fetch ...
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  // ... and inserts result into cache.
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());

  ClearStats();
  FetchAndValidate(etag_and_last_modified_url_, request_headers, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  // Second fetch without the If-Modified-Since in the request hits initial
  // cache lookup ...
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  // ... and no extra fetches or inserts are needed.
  EXPECT_EQ(0, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());

  ClearStats();
  request_headers.Add(HttpAttributes::kIfModifiedSince,
                      "Sat, 03 Apr 2010 18:51:26 GMT");
  FetchAndValidate(etag_and_last_modified_url_, request_headers, true,
                   HttpStatus::kNotModified, "", kBackendFetch, true);
  // The last modified timestamp matches and a 304 is served out.
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  EXPECT_EQ(0, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());

  ClearStats();
  request_headers.Add(HttpAttributes::kIfNoneMatch, "mismatch");
  FetchAndValidate(etag_and_last_modified_url_, request_headers, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  // Even though the last modified timestamp matches, the Etag doesn't match
  // and a 200 is served out.
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  EXPECT_EQ(0, counting_fetcher_.fetch_count());

  ClearStats();
  request_headers.RemoveAll(HttpAttributes::kIfNoneMatch);
  request_headers.Replace(HttpAttributes::kIfModifiedSince,
                          "Sat, 02 Apr 2010 18:51:26 GMT");
  FetchAndValidate(etag_and_last_modified_url_, request_headers, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  // The last modified timestamp does not match and a 200 is served out.
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  EXPECT_EQ(0, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());

  ClearStats();
  request_headers.Add(HttpAttributes::kIfNoneMatch, etag_);
  FetchAndValidate(etag_and_last_modified_url_, request_headers, true,
                   HttpStatus::kNotModified, "", kBackendFetch, true);
  // The etag matches even though the last modified timestamp doesn't and a 304
  // is served out.
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  EXPECT_EQ(0, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
}

TEST_F(CacheUrlAsyncFetcherTest, CheckLastModifiedBased304Freshening) {
  RequestHeaders request_headers;
  ClearStats();
  FetchAndValidate(conditional_last_modified_url_, request_headers, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  // First fetch misses initial cache lookup ...
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  // ... succeeds at fetch ...
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(4, counting_fetcher_.byte_count());
  // ... and inserts result into cache.
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->num_conditional_refreshes()->Get());

  ClearStats();
  // Advance past expiration.
  timer_.AdvanceMs(2 * ttl_ms_);
  FetchAndValidate(conditional_last_modified_url_, request_headers, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  // Second fetch without the If-Modified-Since in the request finds the expired
  // entry in cache, uses the Last-Modified header stored there in the outgoing
  // fetch ...
  EXPECT_EQ(1, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  // ... receives a 304 from the backend and updates the cache.
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, counting_fetcher_.byte_count());
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(1, cache_fetcher_->num_conditional_refreshes()->Get());

  ClearStats();
  FetchAndValidate(conditional_last_modified_url_, request_headers, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());

  ClearStats();
  // Advance past expiration.
  timer_.AdvanceMs(2 * ttl_ms_);
  // Send a request which already has an If-Modified-Since which is different
  // from the one in the cache and the fetcher.
  request_headers.Replace(HttpAttributes::kIfModifiedSince,
                          "Sat, 02 Apr 2010 18:51:26 GMT");
  FetchAndValidate(conditional_last_modified_url_, request_headers, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  // The last modified timestamp does not match and a 200 is served out.
  EXPECT_EQ(1, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(4, counting_fetcher_.byte_count());
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->num_conditional_refreshes()->Get());
}

TEST_F(CacheUrlAsyncFetcherTest, CheckEtagBased304Freshening) {
  RequestHeaders request_headers;
  ClearStats();
  FetchAndValidate(conditional_etag_url_, request_headers, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  // First fetch misses initial cache lookup ...
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  // ... succeeds at fetch ...
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(4, counting_fetcher_.byte_count());
  // ... and inserts result into cache.
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->num_conditional_refreshes()->Get());

  ClearStats();
  // Advance past expiration.
  timer_.AdvanceMs(2 * ttl_ms_);
  FetchAndValidate(conditional_etag_url_, request_headers, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  // Second fetch without the If-None-Match in the request finds the expired
  // entry in cache, uses the Etag header stored there in the outgoing fetch ...
  EXPECT_EQ(1, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  // ... receives a 304 from the backend and updates the cache.
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, counting_fetcher_.byte_count());
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(1, cache_fetcher_->num_conditional_refreshes()->Get());

  ClearStats();
  // Advance past expiration.
  timer_.AdvanceMs(2 * ttl_ms_);
  // Send a request which already has an If-None-Match which is different
  // from the one in the cache and the fetcher.
  request_headers.Replace(HttpAttributes::kIfNoneMatch, "blah");
  FetchAndValidate(conditional_etag_url_, request_headers, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  // The last modified timestamp does not match and a 200 is served out.
  EXPECT_EQ(1, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(4, counting_fetcher_.byte_count());
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->num_conditional_refreshes()->Get());
}

TEST_F(CacheUrlAsyncFetcherTest, Check304FresheningModifiedImplicitCacheTtl) {
  // First fetch misses initial cache lookup. The fetch succeeds and the result
  // is inserted in cache.
  RequestHeaders request_headers;
  ClearStats();
  FetchAndValidate(implicit_cache_url_, request_headers, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(4, counting_fetcher_.byte_count());
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->num_conditional_refreshes()->Get());

  ResponseHeaders response_headers;
  NullMessageHandler message_handler;
  HTTPValue value;
  StringPiece contents;
  ConstStringStarVector values;

  // Lookup the url in the cache and confirm the implicit cache ttl and the
  // max-age values are as expected.
  HTTPCache::FindResult found = Find(implicit_cache_url_, &value,
                                     &response_headers, &message_handler);
  EXPECT_EQ(HTTPCache::FindResult(HTTPCache::kFound, kFetchStatusOK), found);
  EXPECT_TRUE(response_headers.headers_complete());
  EXPECT_TRUE(value.ExtractContents(&contents));
  EXPECT_TRUE(response_headers.Lookup(HttpAttributes::kCacheControl, &values));
  EXPECT_EQ(static_cast<size_t>(1), values.size());
  EXPECT_EQ(GoogleString("max-age=500"), *(values[0]));
  EXPECT_EQ(cache_body_, contents);

  // Second fetch misses the cache. A conditional fetch is done and the result
  // is inserted in the cache again. Implicit cache ttl is still the same, and
  // hence the max-age is the same as well.
  ClearStats();
  // Advancing by implicit_cache_ttl_ms_.
  timer_.AdvanceMs(implicit_cache_ttl_ms_);
  FetchAndValidate(implicit_cache_url_, request_headers, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  EXPECT_EQ(1, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, counting_fetcher_.byte_count());
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(1, cache_fetcher_->num_conditional_refreshes()->Get());

  // Lookup the url in the cache and confirm the implicit cache ttl and max-age
  // values have not changed.
  found = Find(implicit_cache_url_, &value, &response_headers,
               &message_handler);
  EXPECT_EQ(HTTPCache::FindResult(HTTPCache::kFound, kFetchStatusOK), found);
  EXPECT_TRUE(response_headers.headers_complete());
  EXPECT_TRUE(value.ExtractContents(&contents));
  EXPECT_TRUE(response_headers.Lookup(HttpAttributes::kCacheControl, &values));
  EXPECT_EQ(static_cast<size_t>(1), values.size());
  EXPECT_EQ(GoogleString("max-age=500"), *(values[0]));
  EXPECT_EQ(cache_body_, contents);

  // Change the value of the implicit cache ttl to some other value.
  // Confirm that the new response after the conditional fetch is now
  // inserted in the cache with the new implicit cache ttl and max-age.
  implicit_cache_ttl_ms_ = 700 * Timer::kSecondMs;
  ClearStats();
  // Advancing by implicit_cache_ttl_ms_.
  timer_.AdvanceMs(implicit_cache_ttl_ms_);
  FetchAndValidate(implicit_cache_url_, request_headers, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  EXPECT_EQ(1, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, counting_fetcher_.byte_count());
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(1, cache_fetcher_->num_conditional_refreshes()->Get());

  found = Find(implicit_cache_url_, &value, &response_headers,
               &message_handler);
  EXPECT_EQ(HTTPCache::FindResult(HTTPCache::kFound, kFetchStatusOK), found);
  EXPECT_TRUE(response_headers.headers_complete());
  EXPECT_TRUE(value.ExtractContents(&contents));
  EXPECT_TRUE(response_headers.Lookup(HttpAttributes::kCacheControl, &values));
  EXPECT_EQ(static_cast<size_t>(1), values.size());
  EXPECT_EQ(GoogleString("max-age=700"), *(values[0]));
  EXPECT_EQ(cache_body_, contents);
}

TEST_F(CacheUrlAsyncFetcherTest, Check304FresheningMinCacheTtl) {
  // First fetch misses initial cache lookup. The fetch succeeds and the result
  // is inserted in cache.
  RequestHeaders request_headers;
  ClearStats();
  min_cache_ttl_ms_ = 2 * ttl_ms_;
  FetchAndValidate(conditional_last_modified_url_, request_headers, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(4, counting_fetcher_.byte_count());
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->num_conditional_refreshes()->Get());

  ResponseHeaders response_headers;
  NullMessageHandler message_handler;
  HTTPValue value;
  StringPiece contents;
  ConstStringStarVector values;

  // Lookup the url in the cache and confirm the min cache ttl and the
  // max-age values are as expected.
  HTTPCache::FindResult found = Find(conditional_last_modified_url_, &value,
                                     &response_headers, &message_handler);
  EXPECT_EQ(HTTPCache::FindResult(HTTPCache::kFound, kFetchStatusOK), found);
  EXPECT_TRUE(response_headers.headers_complete());
  EXPECT_TRUE(value.ExtractContents(&contents));
  EXPECT_TRUE(response_headers.Lookup(HttpAttributes::kCacheControl, &values));
  EXPECT_EQ(static_cast<size_t>(1), values.size());
  EXPECT_EQ(GoogleString("max-age=7200"), *(values[0]));
  EXPECT_EQ(cache_body_, contents);

  ClearStats();
  // Advancing by min_cache_ttl_ms_.
  timer_.AdvanceMs(min_cache_ttl_ms_);
  // Second fetch misses the cache. A conditional fetch is done and the result
  // is inserted in the cache again. Min cache ttl is still the same, and
  // hence the max-age is updated this time on conditional fetch.
  FetchAndValidate(conditional_last_modified_url_, request_headers, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  EXPECT_EQ(1, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());

  // Lookup the url in the cache and confirm the min cache ttl and max-age
  // values have not changed.
  found = Find(conditional_last_modified_url_, &value, &response_headers,
               &message_handler);
  EXPECT_EQ(HTTPCache::FindResult(HTTPCache::kFound, kFetchStatusOK), found);
  EXPECT_TRUE(response_headers.headers_complete());
  EXPECT_TRUE(value.ExtractContents(&contents));
  EXPECT_TRUE(response_headers.Lookup(HttpAttributes::kCacheControl, &values));
  EXPECT_EQ(static_cast<size_t>(1), values.size());
  EXPECT_EQ(GoogleString("max-age=7200"), *(values[0]));
  EXPECT_EQ(cache_body_, contents);

  // Change the value of the min cache ttl to some other value.
  // Confirm that the new response after the conditional fetch is now
  // inserted in the cache with the new min cache ttl and max-age.
  min_cache_ttl_ms_ = 3 * ttl_ms_;
  ClearStats();
  // Advancing by min_cache_ttl_ms_.
  timer_.AdvanceMs(min_cache_ttl_ms_);
  FetchAndValidate(conditional_last_modified_url_, request_headers, true,
                   HttpStatus::kOK, cache_body_, kBackendFetch, true);
  EXPECT_EQ(1, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());

  found = Find(conditional_last_modified_url_, &value, &response_headers,
               &message_handler);
  EXPECT_EQ(HTTPCache::FindResult(HTTPCache::kFound, kFetchStatusOK), found);
  EXPECT_TRUE(response_headers.headers_complete());
  EXPECT_TRUE(value.ExtractContents(&contents));
  EXPECT_TRUE(response_headers.Lookup(HttpAttributes::kCacheControl, &values));
  EXPECT_EQ(static_cast<size_t>(1), values.size());
  EXPECT_EQ(GoogleString("max-age=10800"), *(values[0]));
  EXPECT_EQ(cache_body_, contents);
}

TEST_F(CacheUrlAsyncFetcherTest, FetchFailedNoIgnore) {
  cache_fetcher_->set_ignore_recent_fetch_failed(false);

  ClearStats();
  FetchAndValidate(bad_url_, empty_request_headers_, true,
                   HttpStatus::kNotFound, bad_body_, kBackendFetch, false);
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());

  http_cache_->RememberFailure(bad_url_, fragment_, kFetchStatusOtherError,
                               &handler_);
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());

  // bad_url_, is not fetched the second time.
  ClearStats();
  FetchAndValidate(bad_url_, empty_request_headers_, false,
                   HttpStatus::kNotFound, "", kBackendFetch, true);
  EXPECT_EQ(0, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
}

TEST_F(CacheUrlAsyncFetcherTest, FetchFailedIgnore) {
  cache_fetcher_->set_ignore_recent_fetch_failed(true);

  ClearStats();
  FetchAndValidate(bad_url_, empty_request_headers_, true,
                   HttpStatus::kNotFound, bad_body_, kBackendFetch, false);
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());

  http_cache_->RememberFailure(bad_url_, fragment_, kFetchStatusOtherError,
                               &handler_);
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());

  // bad_url_, is fetched again the second time.
  ClearStats();
  FetchAndValidate(bad_url_, empty_request_headers_, true,
                   HttpStatus::kNotFound, bad_body_, kBackendFetch, false);
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
}

TEST_F(CacheUrlAsyncFetcherTest, NoCacheEmpty) {
  const char url[] = "http://www.example.com/empty.html";
  ResponseHeaders response_headers;
  SetDefaultHeaders(kContentTypeHtml, &response_headers);
  int ttl_ms = 5 * Timer::kMinuteMs;
  response_headers.SetDateAndCaching(timer_.NowMs(), ttl_ms);

  GoogleString empty_contents = "";
  mock_fetcher_.SetResponse(url, response_headers, empty_contents);
  FetchAndValidate(url, empty_request_headers_, true, HttpStatus::kOK,
                   empty_contents, kBackendFetch, false);

  GoogleString non_empty_contents = "foobar";
  mock_fetcher_.SetResponse(url, response_headers, non_empty_contents);
  // cache_url_fetcher did not remember the empty contents.
  FetchAndValidate(url, empty_request_headers_, true, HttpStatus::kOK,
                   non_empty_contents, kBackendFetch, true);
}

TEST_F(CacheUrlAsyncFetcherTest, CacheNonEmpty) {
  // Companion test to NoCacheEmpty to make sure we are caching non-empty
  // through the same flow.
  const char url[] = "http://www.example.com/non_empty.html";
  ResponseHeaders response_headers;
  SetDefaultHeaders(kContentTypeHtml, &response_headers);
  int ttl_ms = 5 * Timer::kMinuteMs;
  response_headers.SetDateAndCaching(timer_.NowMs(), ttl_ms);

  GoogleString original_contents = "foo";
  mock_fetcher_.SetResponse(url, response_headers, original_contents);
  FetchAndValidate(url, empty_request_headers_, true, HttpStatus::kOK,
                   original_contents, kBackendFetch, true);

  GoogleString new_contents = "foobar";
  mock_fetcher_.SetResponse(url, response_headers, new_contents);
  // cache_url_fetcher did remember the original content.
  FetchAndValidate(url, empty_request_headers_, true, HttpStatus::kOK,
                   original_contents, kBackendFetch, true);
}

TEST_F(CacheUrlAsyncFetcherTest, NoCacheHtmlOnEmptyHeader) {
  ResponseHeaders response_headers;
  SetDefaultHeaders(kContentTypeHtml, &response_headers);
  response_headers.SetDate(timer_.NowMs());
  response_headers.RemoveAll(HttpAttributes::kCacheControl);
  const char url[] = "http://www.example.com/foo.html";
  mock_fetcher_.SetResponse(url, response_headers, "foo");

  ExpectNoCache(url, "foo");
}

TEST_F(CacheUrlAsyncFetcherTest, DoCacheHtmlOnEmptyHeader) {
  // When an option is set. We do cache things with no caching headers.
  cache_fetcher_->set_default_cache_html(true);

  ResponseHeaders response_headers;
  SetDefaultHeaders(kContentTypeHtml, &response_headers);
  response_headers.SetDate(timer_.NowMs());
  response_headers.RemoveAll(HttpAttributes::kCacheControl);
  const char url[] = "http://www.example.com/foo.html";
  mock_fetcher_.SetResponse(url, response_headers, "foo");

  ExpectCache(url, "foo");
}

// Even when set_default_cache_html(true), we still don't cache responses
// with Set-Cookie headers.
TEST_F(CacheUrlAsyncFetcherTest, NoCacheSetCookie) {
  cache_fetcher_->set_default_cache_html(true);

  ResponseHeaders response_headers;
  SetDefaultHeaders(kContentTypeHtml, &response_headers);
  response_headers.SetDate(timer_.NowMs());
  response_headers.RemoveAll(HttpAttributes::kCacheControl);
  response_headers.Add(HttpAttributes::kSetCookie, "foo=bar");
  const char url[] = "http://www.example.com/foo.html";
  mock_fetcher_.SetResponse(url, response_headers, "foo");

  ExpectNoCache(url, "foo");
}

TEST_F(CacheUrlAsyncFetcherTest, CachePublicSansTtl) {
  // TODO(sligocki): Should this work without default_cache_html == true?
  cache_fetcher_->set_default_cache_html(true);

  ResponseHeaders response_headers;
  SetDefaultHeaders(kContentTypeHtml, &response_headers);
  response_headers.SetDate(timer_.NowMs());
  response_headers.Replace(HttpAttributes::kCacheControl, "public");
  const char url[] = "http://www.example.com/foo.html";
  mock_fetcher_.SetResponse(url, response_headers, "foo");

  ExpectCache(url, "foo");
}

TEST_F(CacheUrlAsyncFetcherTest, CacheVaryForNonHtml) {
  // The content type here is image/png.

  RequestHeaders request_headers_with_cookies;
  request_headers_with_cookies.Add(HttpAttributes::kCookie, "c");

  // Respect Vary is disabled. Vary: Accept-Encoding is cached.
  mutable_vary_headers_.Add(HttpAttributes::kVary, "Accept-Encoding");
  mock_fetcher_.SetResponse(vary_url_, mutable_vary_headers_, vary_body_);
  ExpectCache(vary_url_, vary_body_);
  lru_cache_.Clear();

  // Respect Vary is enabled. Vary: Accept-Encoding is cached.
  cache_fetcher_->set_respect_vary(true);
  http_options_.respect_vary = true;
  ExpectCache(vary_url_, vary_body_);
  lru_cache_.Clear();

  // Respect Vary is enabled. Vary: Accept-Encoding,User-Agent is not cached.
  mutable_vary_headers_.Add(HttpAttributes::kVary, "User-Agent");
  mock_fetcher_.SetResponse(vary_url_, mutable_vary_headers_, vary_body_);
  ExpectNoCache(vary_url_, vary_body_);
  lru_cache_.Clear();

  // Respect Vary is disabled. Vary: Accept-Encoding,User-Agent is cached.
  cache_fetcher_->set_respect_vary(false);
  http_options_.respect_vary = false;
  ExpectCache(vary_url_, vary_body_);
  lru_cache_.Clear();

  // Respect Vary is disabled, but we still respect Vary: Cookie for
  // non-html, whether or not the request has cookies.
  mutable_vary_headers_.Replace(HttpAttributes::kVary, "Cookie");
  mock_fetcher_.SetResponse(vary_url_, mutable_vary_headers_, vary_body_);
  ExpectNoCache(vary_url_, vary_body_);
  lru_cache_.Clear();

  // Respect Vary is enabled. Vary: Cookie is not cached.
  cache_fetcher_->set_respect_vary(true);
  http_options_.respect_vary = true;
  ExpectNoCache(vary_url_, vary_body_);

  // Without clearing the cache send a request with cookies in the request. This
  // is not served from cache.
  ExpectNoCache(vary_url_, vary_body_);
  lru_cache_.Clear();

  // Respect Vary is enabled. Vary: Cookie is not cached.
  ExpectNoCacheWithRequestHeaders(vary_url_, vary_body_,
                                  request_headers_with_cookies);
  lru_cache_.Clear();

  // Respect Vary is disabled, but Vary: Cookie is still not cached.
  cache_fetcher_->set_respect_vary(false);
  http_options_.respect_vary = false;
  ExpectNoCacheWithRequestHeaders(vary_url_, vary_body_,
                                  request_headers_with_cookies);

  // Without clearing the cache, change respect vary to true. We should not
  // fetch the response that was inserted into the cache above.
  cache_fetcher_->set_respect_vary(true);
  http_options_.respect_vary = true;
  ExpectNoCacheWithRequestHeaders(vary_url_, vary_body_,
                                  request_headers_with_cookies);

  lru_cache_.Clear();
}

TEST_F(CacheUrlAsyncFetcherTest, CacheVaryForHtml) {
  // The content type here is text/html. Unlike PNG and other resources, we
  // always respect Vary:Cookie on HTML even if RespectVary is off.

  mutable_vary_headers_.Replace(HttpAttributes::kContentType,
                                kContentTypeHtml.mime_type());

  RequestHeaders request_headers_with_cookies;
  request_headers_with_cookies.Add(HttpAttributes::kCookie, "c");

  // Respect Vary is disabled. Vary: Accept-Encoding is cached.
  mutable_vary_headers_.Add(HttpAttributes::kVary, "Accept-Encoding");
  mock_fetcher_.SetResponse(vary_url_, mutable_vary_headers_, vary_body_);
  ExpectCache(vary_url_, vary_body_);
  lru_cache_.Clear();

  // Respect Vary is enabled. Vary: Accept-Encoding is cached.
  cache_fetcher_->set_respect_vary(true);
  http_options_.respect_vary = true;
  ExpectCache(vary_url_, vary_body_);
  lru_cache_.Clear();

  // Respect Vary is enabled. Vary: Accept-Encoding,User-Agent is not cached.
  mutable_vary_headers_.Add(HttpAttributes::kVary, "User-Agent");
  mock_fetcher_.SetResponse(vary_url_, mutable_vary_headers_, vary_body_);
  ExpectNoCache(vary_url_, vary_body_);
  lru_cache_.Clear();

  // Respect Vary is disabled. Vary: Accept-Encoding,User-Agent is not cached.
  cache_fetcher_->set_respect_vary(false);
  http_options_.respect_vary = false;
  ExpectNoCache(vary_url_, vary_body_);
  lru_cache_.Clear();

  // Respect Vary is disabled. Vary: Cookie is cached. Note that the request has
  // no cookies.
  mutable_vary_headers_.Replace(HttpAttributes::kVary, "Cookie");
  mock_fetcher_.SetResponse(vary_url_, mutable_vary_headers_, vary_body_);
  ExpectCache(vary_url_, vary_body_);
  lru_cache_.Clear();

  // Respect Vary is enabled. Vary: Cookie is cached. Note that the request has
  // no cookies.
  cache_fetcher_->set_respect_vary(true);
  http_options_.respect_vary = true;
  ExpectCache(vary_url_, vary_body_);

  // Without clearing the cache send a request with cookies in the request. This
  // is not served from cache.
  ExpectNoCacheWithRequestHeaders(vary_url_, vary_body_,
                                  request_headers_with_cookies);
  lru_cache_.Clear();

  // Respect Vary is enabled. Vary: Cookie is not cached since the request
  // has cookies set.
  ExpectNoCacheWithRequestHeaders(vary_url_, vary_body_,
                                  request_headers_with_cookies);
  lru_cache_.Clear();

  // Respect Vary is disabled. Vary: Cookie is not cached since the request has
  // cookies set.
  cache_fetcher_->set_respect_vary(false);
  http_options_.respect_vary = false;
  ExpectNoCacheWithRequestHeaders(vary_url_, vary_body_,
                                  request_headers_with_cookies);
  lru_cache_.Clear();
}

TEST_F(CacheUrlAsyncFetcherTest, HeadServedFromCache) {
  ClearStats();

  // Issue a HEAD request.
  RequestHeaders head_request;
  head_request.set_method(RequestHeaders::kHead);
  FetchAndValidate(cache_url_, head_request, true, HttpStatus::kOK,
                   "", kBackendFetch, false);
  // First fetch misses initial cache lookup ...
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  // ... succeeds at fetch ...
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  // ... but should not be inserted into the cache ...
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->fallback_responses_served()->Get());

  ClearStats();
  // Issue another HEAD request.
  FetchAndValidate(cache_url_, head_request, true, HttpStatus::kOK,
                   "", kBackendFetch, false);
  // Second fetch should miss again ...
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->fallback_responses_served()->Get());

  ClearStats();
  // Now issue a GET.
  FetchAndValidate(cache_url_, empty_request_headers_, true, HttpStatus::kOK,
                   cache_body_, kBackendFetch, true);
  // Should miss the cache.
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(0, http_cache_->cache_hits()->Get());
  EXPECT_EQ(1, http_cache_->cache_misses()->Get());
  // ... succeeds at fetch ...
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  // ... and inserts result into cache.
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->fallback_responses_served()->Get());

  ClearStats();
  // Issue the HEAD request again, this time it should be served from cache.
  FetchAndValidate(cache_url_, head_request, true, HttpStatus::kOK,
                   "", kBackendFetch, false);
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  EXPECT_EQ(0, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->fallback_responses_served()->Get());

  ClearStats();
  // Replay the GET and ensure the HEAD request has not affected its cache
  // value.
  FetchAndValidate(cache_url_, empty_request_headers_, true, HttpStatus::kOK,
                   cache_body_, kBackendFetch, true);
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(1, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  EXPECT_EQ(0, counting_fetcher_.fetch_count());
  EXPECT_EQ(0, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->fallback_responses_served()->Get());
}

TEST_F(CacheUrlAsyncFetcherTest, OPTIONS) {
  ExpectNoCacheWithMethod(cache_url_, cache_body_, RequestHeaders::kOptions);
}

TEST_F(CacheUrlAsyncFetcherTest, GET) {
  // This is already tested above, but leave in for completeness.
  RequestHeaders request_header;
  request_header.set_method(RequestHeaders::kGet);
  ExpectCacheWithRequestHeaders(cache_url_, cache_body_, request_header);
}

TEST_F(CacheUrlAsyncFetcherTest, HEAD) {
  ExpectNoCacheWithMethodAndIsServable(
      cache_url_, "", RequestHeaders::kHead, true);
}

TEST_F(CacheUrlAsyncFetcherTest, POST) {
  ExpectNoCacheWithMethod(cache_url_, cache_body_, RequestHeaders::kPost);
}

TEST_F(CacheUrlAsyncFetcherTest, PUT) {
  ExpectNoCacheWithMethod(cache_url_, cache_body_, RequestHeaders::kPut);
}

TEST_F(CacheUrlAsyncFetcherTest, DELETE) {
  ExpectNoCacheWithMethod(cache_url_, cache_body_, RequestHeaders::kDelete);
}

TEST_F(CacheUrlAsyncFetcherTest, TRACE) {
  ExpectNoCacheWithMethod(cache_url_, cache_body_, RequestHeaders::kTrace);
}

TEST_F(CacheUrlAsyncFetcherTest, CONNECT) {
  ExpectNoCacheWithMethod(cache_url_, cache_body_, RequestHeaders::kConnect);
}

TEST_F(CacheUrlAsyncFetcherTest, PATCH) {
  ExpectNoCacheWithMethod(cache_url_, cache_body_, RequestHeaders::kPatch);
}

TEST_F(CacheUrlAsyncFetcherTest, ERROR) {
  ExpectNoCacheWithMethod(cache_url_, cache_body_, RequestHeaders::kError);
}

// Ensure that non-cacheable requests get kNotInCacheStatus set when there
// is no backup fetcher.
TEST_F(CacheUrlAsyncFetcherTest, NotInCache) {
  CacheUrlAsyncFetcher fetcher(
      &mock_hasher_,
      &lock_manager_,
      http_cache_.get(),
      fragment_,
      &mock_async_op_hooks_,
      NULL);
  StringAsyncFetch fetch(
      RequestContext::NewTestRequestContext(thread_system_.get()));
  // Note: nocache_url_ is not even in the cache.
  fetcher.Fetch(nocache_url_, &handler_, &fetch);
  EXPECT_TRUE(fetch.done());
  EXPECT_FALSE(fetch.success());
  EXPECT_EQ(CacheUrlAsyncFetcher::kNotInCacheStatus,
            fetch.response_headers()->status_code());
}

// Ensure that non-GET requests get kNotInCacheStatus set when there is no
// backup fetcher.
TEST_F(CacheUrlAsyncFetcherTest, NotInCachePost) {
  CacheUrlAsyncFetcher fetcher(
      &mock_hasher_,
      &lock_manager_,
      http_cache_.get(),
      fragment_,
      &mock_async_op_hooks_,
      NULL);
  StringAsyncFetch fetch(
      RequestContext::NewTestRequestContext(thread_system_.get()));
  fetch.request_headers()->set_method(RequestHeaders::kPost);

  // Put result in cache.
  ResponseHeaders headers;
  DefaultResponseHeaders(kContentTypeCss, 100, &headers);
  http_cache_->Put(cache_url_, fragment_,
                   fetch.request_headers()->GetProperties(),
                   ResponseHeaders::kRespectVaryOnResources,
                   &headers, ".a { color: red; }", &handler_);
  fetcher.Fetch(cache_url_, &handler_, &fetch);
  EXPECT_TRUE(fetch.done());
  EXPECT_FALSE(fetch.success());
  EXPECT_EQ(CacheUrlAsyncFetcher::kNotInCacheStatus,
            fetch.response_headers()->status_code());
}

TEST_F(CacheUrlAsyncFetcherTest, TestParallelBackgroundFreshenCalls) {
  ClearStats();
  FetchAndValidate(cache_url_, empty_request_headers_, true, HttpStatus::kOK,
                   cache_body_, kBackendFetch, true);
  cache_fetcher_->set_proactively_freshen_user_facing_request(true);
  // Advance the time so that cache is about to expire.
  timer_.AdvanceMs(ttl_ms_ - 3 * Timer::kMinuteMs);
  QueuedWorkerPool pool(1, "test", thread_system_.get());
  QueuedWorkerPool::Sequence* sequence = pool.NewSequence();
  ClearStats();
  thread_synchronizer_->EnableForPrefix(kFetchTriggeredPrefix);
  thread_synchronizer_->EnableForPrefix(kStartFetchPrefix);
  thread_synchronizer_->EnableForPrefix(kDelayedFetchFinishPrefix);

  // Start a fetch on Thread 1. This fetch will be delayed until another fetch
  // finishes on different thread and second fetch fails to acquire lock.
  // Order of the sequence:
  // 1) Fetch is triggered which issue a background fetch and able to acquire
  //    lock but this fetch is delayed until another fetch is also triggered.
  // 2) Second fetch is triggered and tries to acquire a lock but fails to do
  //    so.
  // 3) After second fetch is finished it signals first fetch.
  sequence->Add(
      MakeFunction(
          static_cast<CacheUrlAsyncFetcherTest*>(this),
          &CacheUrlAsyncFetcherTest::TriggerDelayedFetchAndValidate));
  thread_synchronizer_->Wait(kFetchTriggeredPrefix);
  FetchAndValidate(cache_url_, empty_request_headers_, true, HttpStatus::kOK,
                   cache_body_, kBackendFetch, true);
  thread_synchronizer_->Signal(kStartFetchPrefix);
  thread_synchronizer_->Wait(kDelayedFetchFinishPrefix);
  // Fetch hits initial cache lookup for the fetches...
  EXPECT_EQ(0, http_cache_->cache_expirations()->Get());
  EXPECT_EQ(2, http_cache_->cache_hits()->Get());
  EXPECT_EQ(0, http_cache_->cache_misses()->Get());
  // Background fetch is triggered to populate the cache with newer value. But
  // only fetch is able to update the value.
  EXPECT_EQ(1, counting_fetcher_.fetch_count());
  EXPECT_EQ(1, http_cache_->cache_inserts()->Get());
  EXPECT_EQ(0, cache_fetcher_->fallback_responses_served()->Get());
}

}  // namespace

}  // namespace net_instaweb
