Chromium Code Reviews| 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); |
| } |