protected function makeHttpRequest($url, $method, $headers, $body = null) {
    if (!$this->context_options['enable_cache']) {
      return parent::makeHttpRequest($url, $method, $headers, $body);
    }

    $cache_key = static::getReadMemcacheKey($url, $headers['Range']);
    $cache_obj = $this->memcache_client->get($cache_key);
    if (false !== $cache_obj) {
      if ($this->context_options['enable_optimistic_cache']) {
        return $cache_obj;
      } else {
        $cache_etag = $this->getHeaderValue('ETag', $cache_obj['headers']);
        if (array_key_exists('If-Match', $headers)) {
          // We will perform a If-None-Match to validate the cache object, only
          // if it has the same ETag value as what we are asking for.
          if ($headers['If-Match'] === $cache_etag) {
            unset($headers['If-Match']);
          } else {
            // We are asking for a different object that what is in the cache.
            $cache_etag = null;
          }
        }
      }
      if (isset($cache_etag)) {
        $headers['If-None-Match'] = $cache_etag;
      }
    }

    $result = parent::makeHttpRequest($url, $method, $headers, $body);

    if (false === $result) {
      return false;
    }
    $status_code = $result['status_code'];
    if (HttpResponse::NOT_MODIFIED === $result['status_code']) {
      return $cache_obj;
    }
    if (in_array($status_code, self::$valid_status_codes)) {
      $this->memcache_client->set($cache_key, $result, 0,
          $this->context_options['read_cache_expiry_seconds']);
    }
    return $result;
  }