Index: net/http/http_cache_transaction.cc |
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc |
index 9bc83264feab97d61d1c8acdcd567b2442cc5ea9..19cfd454a383027a15d69dac34934d056732445f 100644 |
--- a/net/http/http_cache_transaction.cc |
+++ b/net/http/http_cache_transaction.cc |
@@ -2436,40 +2436,57 @@ bool HttpCache::Transaction::RequiresValidation() { |
return validation_required_by_headers; |
} |
-bool HttpCache::Transaction::ConditionalizeRequest() { |
+bool HttpCache::Transaction::ResponseConditionalizable( |
+ std::string* etag_value, |
+ std::string* last_modified_value) { |
DCHECK(response_.headers.get()); |
- if (method_ == "PUT" || method_ == "DELETE") |
- return false; |
- |
// This only makes sense for cached 200 or 206 responses. |
if (response_.headers->response_code() != 200 && |
response_.headers->response_code() != 206) { |
return false; |
} |
- if (fail_conditionalization_for_test_) |
- return false; |
- |
+ // ### this looks scary. |
DCHECK(response_.headers->response_code() != 206 || |
response_.headers->HasStrongValidators()); |
// Just use the first available ETag and/or Last-Modified header value. |
// TODO(darin): Or should we use the last? |
- std::string etag_value; |
if (response_.headers->GetHttpVersion() >= HttpVersion(1, 1)) |
- response_.headers->EnumerateHeader(NULL, "etag", &etag_value); |
+ response_.headers->EnumerateHeader(NULL, "etag", etag_value); |
- std::string last_modified_value; |
- if (!vary_mismatch_) { |
- response_.headers->EnumerateHeader(NULL, "last-modified", |
- &last_modified_value); |
- } |
+ response_.headers->EnumerateHeader(NULL, "last-modified", |
+ last_modified_value); |
- if (etag_value.empty() && last_modified_value.empty()) |
+ if (etag_value->empty() && last_modified_value->empty()) |
return false; |
+ return true; |
+} |
+ |
+bool HttpCache::Transaction::ConditionalizeRequest() { |
+ DCHECK(response_.headers.get()); |
+ |
+ if (method_ == "PUT" || method_ == "DELETE") |
+ return false; |
+ |
+ if (fail_conditionalization_for_test_) |
+ return false; |
+ |
+ std::string etag_value; |
+ std::string last_modified_value; |
+ if (!ResponseConditionalizable(&etag_value, &last_modified_value)) |
+ return false; |
+ |
+ if (vary_mismatch_) { |
+ // Can't rely on last-modified if vary is different. |
+ last_modified_value.clear(); |
+ if (etag_value.empty()) |
+ return false; |
+ } |
+ |
if (!partial_) { |
// Need to customize the request, so this forces us to allocate :( |
custom_request_.reset(new HttpRequestInfo(*request_)); |
@@ -2509,6 +2526,42 @@ bool HttpCache::Transaction::ConditionalizeRequest() { |
return true; |
} |
+bool HttpCache::Transaction::MaybeRejectBasedOnMemoryEntryData( |
+ uint8_t in_memory_info) { |
+ // Not going to be clever with those... though is it even set here? |
+ if (partial_) |
+ return false; |
+ |
+ // We can tell that some entries in cache may be unusable under present |
+ // circumstances if: |
+ // 1) We aren't using everything because of LOAD_SKIP_CACHE_VALIDATION. |
+ // 2) We aren't holding on to results of an unused prefetch. |
+ // 3) The entry has zero freshness (so it's known to be expired!) |
+ // 4) We know the entry can't be revalidated |
+ // (we may be able to match more things here). |
+ if (effective_load_flags_ & LOAD_SKIP_CACHE_VALIDATION) |
+ return false; |
+ |
+ if (in_memory_info & HttpCache::OBH_UNUSED_SINCE_PREFETCH) |
+ return false; |
+ |
+ if (!(in_memory_info & HttpCache::OBH_ZERO_LIFETIME)) |
+ return false; |
+ |
+ if (!(in_memory_info & OBH_RESPONSE_CANT_CONDITIONALIZE)) |
+ return false; |
+ |
+ cache_pending_ = false; |
+ couldnt_conditionalize_request_ = true; |
+ response_.was_cached = true; |
+ UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE); |
+ // ### ugh, this is bad, but just sketching. |
+ // TransitionToState(STATE_SEND_REQUEST); |
+ next_state_ = STATE_SEND_REQUEST; |
Maks Orlovich
2017/06/14 19:59:29
So I just realized that this implementation is bog
|
+ |
+ return true; |
+} |
+ |
// We just received some headers from the server. We may have asked for a range, |
// in which case partial_ has an object. This could be the first network request |
// we make to fulfill the original request, or we may be already reading (from |
@@ -2731,6 +2784,18 @@ int HttpCache::Transaction::WriteResponseInfoToEntry(bool truncated) { |
data->Done(); |
io_buf_len_ = data->pickle()->size(); |
+ |
+ uint8_t hints = 0; |
+ // ### recomputing this too much? |
+ if (response_.headers->GetFreshnessLifetimes(response_.response_time) |
+ .freshness.is_zero()) |
+ hints |= HttpCache::OBH_ZERO_LIFETIME; |
+ std::string etag_ignored, last_modified_ignored; |
+ if (!ResponseConditionalizable(&etag_ignored, &last_modified_ignored)) |
+ hints |= HttpCache::OBH_RESPONSE_CANT_CONDITIONALIZE; |
+ if (response_.unused_since_prefetch) |
+ hints |= HttpCache::OBH_UNUSED_SINCE_PREFETCH; |
+ cache_->GetCurrentBackend()->SetMemoryEntryData(cache_key_, hints); |
return entry_->disk_entry->WriteData(kResponseInfoIndex, 0, data.get(), |
io_buf_len_, io_callback_, true); |
} |