| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/http/http_cache_transaction.h" | 5 #include "net/http/http_cache_transaction.h" |
| 6 | 6 |
| 7 #include "build/build_config.h" // For OS_POSIX | 7 #include "build/build_config.h" // For OS_POSIX |
| 8 | 8 |
| 9 #if defined(OS_POSIX) | 9 #if defined(OS_POSIX) |
| 10 #include <unistd.h> | 10 #include <unistd.h> |
| (...skipping 1942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1953 next_state_ = STATE_CACHE_READ_METADATA; | 1953 next_state_ = STATE_CACHE_READ_METADATA; |
| 1954 | 1954 |
| 1955 return OK; | 1955 return OK; |
| 1956 } | 1956 } |
| 1957 | 1957 |
| 1958 int HttpCache::Transaction::BeginCacheValidation() { | 1958 int HttpCache::Transaction::BeginCacheValidation() { |
| 1959 DCHECK_EQ(mode_, READ_WRITE); | 1959 DCHECK_EQ(mode_, READ_WRITE); |
| 1960 | 1960 |
| 1961 ValidationType required_validation = RequiresValidation(); | 1961 ValidationType required_validation = RequiresValidation(); |
| 1962 | 1962 |
| 1963 bool skip_validation = (required_validation == VALIDATION_NONE); | 1963 bool skip_validation = (required_validation == ValidationType::NONE); |
| 1964 | 1964 |
| 1965 if ((effective_load_flags_ & LOAD_SUPPORT_ASYNC_REVALIDATION) && | 1965 if ((effective_load_flags_ & LOAD_SUPPORT_ASYNC_REVALIDATION) && |
| 1966 required_validation == VALIDATION_ASYNCHRONOUS) { | 1966 required_validation == ValidationType::ASYNCHRONOUS) { |
| 1967 DCHECK_EQ(request_->method, "GET"); | 1967 DCHECK_EQ(request_->method, "GET"); |
| 1968 skip_validation = true; | 1968 skip_validation = true; |
| 1969 response_.async_revalidation_required = true; | 1969 response_.async_revalidation_required = true; |
| 1970 } | 1970 } |
| 1971 | 1971 |
| 1972 if (request_->method == "HEAD" && | 1972 if (request_->method == "HEAD" && |
| 1973 (truncated_ || response_.headers->response_code() == 206)) { | 1973 (truncated_ || response_.headers->response_code() == 206)) { |
| 1974 DCHECK(!partial_); | 1974 DCHECK(!partial_); |
| 1975 if (skip_validation) | 1975 if (skip_validation) |
| 1976 return SetupEntryForRead(); | 1976 return SetupEntryForRead(); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2089 } | 2089 } |
| 2090 } | 2090 } |
| 2091 | 2091 |
| 2092 // TODO(ricea): This calculation is expensive to perform just to collect | 2092 // TODO(ricea): This calculation is expensive to perform just to collect |
| 2093 // statistics. Either remove it or use the result, depending on the result of | 2093 // statistics. Either remove it or use the result, depending on the result of |
| 2094 // the experiment. | 2094 // the experiment. |
| 2095 ExternallyConditionalizedType type = | 2095 ExternallyConditionalizedType type = |
| 2096 EXTERNALLY_CONDITIONALIZED_CACHE_USABLE; | 2096 EXTERNALLY_CONDITIONALIZED_CACHE_USABLE; |
| 2097 if (mode_ == NONE) | 2097 if (mode_ == NONE) |
| 2098 type = EXTERNALLY_CONDITIONALIZED_MISMATCHED_VALIDATORS; | 2098 type = EXTERNALLY_CONDITIONALIZED_MISMATCHED_VALIDATORS; |
| 2099 else if (RequiresValidation() != VALIDATION_NONE) | 2099 else if (RequiresValidation() != ValidationType::NONE) |
| 2100 type = EXTERNALLY_CONDITIONALIZED_CACHE_REQUIRES_VALIDATION; | 2100 type = EXTERNALLY_CONDITIONALIZED_CACHE_REQUIRES_VALIDATION; |
| 2101 | 2101 |
| 2102 // TODO(ricea): Add CACHE_USABLE_STALE once stale-while-revalidate CL landed. | 2102 // TODO(ricea): Add CACHE_USABLE_STALE once stale-while-revalidate CL landed. |
| 2103 // TODO(ricea): Either remove this histogram or make it permanent by M40. | 2103 // TODO(ricea): Either remove this histogram or make it permanent by M40. |
| 2104 UMA_HISTOGRAM_ENUMERATION("HttpCache.ExternallyConditionalized", | 2104 UMA_HISTOGRAM_ENUMERATION("HttpCache.ExternallyConditionalized", |
| 2105 type, | 2105 type, |
| 2106 EXTERNALLY_CONDITIONALIZED_MAX); | 2106 EXTERNALLY_CONDITIONALIZED_MAX); |
| 2107 | 2107 |
| 2108 next_state_ = STATE_SEND_REQUEST; | 2108 next_state_ = STATE_SEND_REQUEST; |
| 2109 return OK; | 2109 return OK; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2142 DCHECK(network_trans_.get()); | 2142 DCHECK(network_trans_.get()); |
| 2143 DCHECK_EQ(STATE_NONE, next_state_); | 2143 DCHECK_EQ(STATE_NONE, next_state_); |
| 2144 | 2144 |
| 2145 next_state_ = STATE_SEND_REQUEST_COMPLETE; | 2145 next_state_ = STATE_SEND_REQUEST_COMPLETE; |
| 2146 int rv = network_trans_->RestartWithAuth(credentials, io_callback_); | 2146 int rv = network_trans_->RestartWithAuth(credentials, io_callback_); |
| 2147 if (rv != ERR_IO_PENDING) | 2147 if (rv != ERR_IO_PENDING) |
| 2148 return DoLoop(rv); | 2148 return DoLoop(rv); |
| 2149 return rv; | 2149 return rv; |
| 2150 } | 2150 } |
| 2151 | 2151 |
| 2152 ValidationType HttpCache::Transaction::RequiresValidation() { | 2152 HttpCache::Transaction::ValidationType |
| 2153 HttpCache::Transaction::RequiresValidation() { |
| 2153 // TODO(darin): need to do more work here: | 2154 // TODO(darin): need to do more work here: |
| 2154 // - make sure we have a matching request method | 2155 // - make sure we have a matching request method |
| 2155 // - watch out for cached responses that depend on authentication | 2156 // - watch out for cached responses that depend on authentication |
| 2156 | 2157 |
| 2157 if (response_.vary_data.is_valid() && | 2158 if (response_.vary_data.is_valid() && |
| 2158 !response_.vary_data.MatchesRequest(*request_, | 2159 !response_.vary_data.MatchesRequest(*request_, |
| 2159 *response_.headers.get())) { | 2160 *response_.headers.get())) { |
| 2160 vary_mismatch_ = true; | 2161 vary_mismatch_ = true; |
| 2161 return VALIDATION_SYNCHRONOUS; | 2162 return ValidationType::SYNCHRONOUS; |
| 2162 } | 2163 } |
| 2163 | 2164 |
| 2164 if (effective_load_flags_ & LOAD_PREFERRING_CACHE) | 2165 if (effective_load_flags_ & LOAD_PREFERRING_CACHE) |
| 2165 return VALIDATION_NONE; | 2166 return ValidationType::NONE; |
| 2167 |
| 2168 HttpResponseHeaders::ExpirationTimes expiration_times = |
| 2169 response_.headers->GetExpirationTimes(response_.request_time, |
| 2170 response_.response_time); |
| 2171 base::Time now = cache_->clock_->Now(); |
| 2166 | 2172 |
| 2167 if (response_.unused_since_prefetch && | 2173 if (response_.unused_since_prefetch && |
| 2168 !(effective_load_flags_ & LOAD_PREFETCH) && | 2174 !(effective_load_flags_ & LOAD_PREFETCH) && |
| 2169 response_.headers->GetCurrentAge( | 2175 now - expiration_times.corrected_response_time < |
| 2170 response_.request_time, response_.response_time, | 2176 TimeDelta::FromMinutes(kPrefetchReuseMins)) { |
| 2171 cache_->clock_->Now()) < TimeDelta::FromMinutes(kPrefetchReuseMins)) { | |
| 2172 // The first use of a resource after prefetch within a short window skips | 2177 // The first use of a resource after prefetch within a short window skips |
| 2173 // validation. | 2178 // validation. |
| 2174 return VALIDATION_NONE; | 2179 return ValidationType::NONE; |
| 2175 } | 2180 } |
| 2176 | 2181 |
| 2177 if (effective_load_flags_ & LOAD_VALIDATE_CACHE) | 2182 if (effective_load_flags_ & LOAD_VALIDATE_CACHE) |
| 2178 return VALIDATION_SYNCHRONOUS; | 2183 return ValidationType::SYNCHRONOUS; |
| 2179 | 2184 |
| 2180 if (request_->method == "PUT" || request_->method == "DELETE") | 2185 if (request_->method == "PUT" || request_->method == "DELETE") |
| 2181 return VALIDATION_SYNCHRONOUS; | 2186 return ValidationType::SYNCHRONOUS; |
| 2182 | 2187 |
| 2183 ValidationType validation_required_by_headers = | 2188 if (now < expiration_times.GetExpirationTime()) |
| 2184 response_.headers->RequiresValidation(response_.request_time, | 2189 return ValidationType::NONE; |
| 2185 response_.response_time, | 2190 if (now > expiration_times.GetAsyncExpirationTime()) |
| 2186 cache_->clock_->Now()); | 2191 return ValidationType::SYNCHRONOUS; |
| 2187 | 2192 |
| 2188 if (validation_required_by_headers == VALIDATION_ASYNCHRONOUS) { | 2193 // Asynchronous revalidation is only supported for GET methods. |
| 2189 // Asynchronous revalidation is only supported for GET methods. | 2194 if (request_->method != "GET") |
| 2190 if (request_->method != "GET") | 2195 return ValidationType::SYNCHRONOUS; |
| 2191 return VALIDATION_SYNCHRONOUS; | 2196 return ValidationType::ASYNCHRONOUS; |
| 2192 } | |
| 2193 | |
| 2194 return validation_required_by_headers; | |
| 2195 } | 2197 } |
| 2196 | 2198 |
| 2197 bool HttpCache::Transaction::ConditionalizeRequest() { | 2199 bool HttpCache::Transaction::ConditionalizeRequest() { |
| 2198 DCHECK(response_.headers.get()); | 2200 DCHECK(response_.headers.get()); |
| 2199 | 2201 |
| 2200 if (request_->method == "PUT" || request_->method == "DELETE") | 2202 if (request_->method == "PUT" || request_->method == "DELETE") |
| 2201 return false; | 2203 return false; |
| 2202 | 2204 |
| 2203 // This only makes sense for cached 200 or 206 responses. | 2205 // This only makes sense for cached 200 or 206 responses. |
| 2204 if (response_.headers->response_code() != 200 && | 2206 if (response_.headers->response_code() != 200 && |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2234 request_ = custom_request_.get(); | 2236 request_ = custom_request_.get(); |
| 2235 } | 2237 } |
| 2236 DCHECK(custom_request_.get()); | 2238 DCHECK(custom_request_.get()); |
| 2237 | 2239 |
| 2238 bool use_if_range = | 2240 bool use_if_range = |
| 2239 partial_ && !partial_->IsCurrentRangeCached() && !invalid_range_; | 2241 partial_ && !partial_->IsCurrentRangeCached() && !invalid_range_; |
| 2240 | 2242 |
| 2241 if (!use_if_range) { | 2243 if (!use_if_range) { |
| 2242 // stale-while-revalidate is not useful when we only have a partial response | 2244 // stale-while-revalidate is not useful when we only have a partial response |
| 2243 // cached, so don't set the header in that case. | 2245 // cached, so don't set the header in that case. |
| 2244 HttpResponseHeaders::FreshnessLifetimes lifetimes = | 2246 HttpResponseHeaders::ExpirationTimes expirations = |
| 2245 response_.headers->GetFreshnessLifetimes(response_.response_time); | 2247 response_.headers->GetExpirationTimes(response_.request_time, |
| 2246 if (lifetimes.staleness > TimeDelta()) { | 2248 response_.response_time); |
| 2247 TimeDelta current_age = response_.headers->GetCurrentAge( | 2249 if (!expirations.staleness_lifetime.is_zero()) { |
| 2248 response_.request_time, response_.response_time, | 2250 TimeDelta current_age = |
| 2249 cache_->clock_->Now()); | 2251 cache_->clock_->Now() - expirations.corrected_response_time; |
| 2250 | |
| 2251 custom_request_->extra_headers.SetHeader( | 2252 custom_request_->extra_headers.SetHeader( |
| 2252 kFreshnessHeader, | 2253 kFreshnessHeader, |
| 2253 base::StringPrintf("max-age=%" PRId64 | 2254 base::StringPrintf("max-age=%" PRId64 |
| 2254 ",stale-while-revalidate=%" PRId64 ",age=%" PRId64, | 2255 ",stale-while-revalidate=%" PRId64 ",age=%" PRId64, |
| 2255 lifetimes.freshness.InSeconds(), | 2256 expirations.freshness_lifetime.InSeconds(), |
| 2256 lifetimes.staleness.InSeconds(), | 2257 expirations.staleness_lifetime.InSeconds(), |
| 2257 current_age.InSeconds())); | 2258 current_age.InSeconds())); |
| 2258 } | 2259 } |
| 2259 } | 2260 } |
| 2260 | 2261 |
| 2261 if (!etag_value.empty()) { | 2262 if (!etag_value.empty()) { |
| 2262 if (use_if_range) { | 2263 if (use_if_range) { |
| 2263 // We don't want to switch to WRITE mode if we don't have this block of a | 2264 // We don't want to switch to WRITE mode if we don't have this block of a |
| 2264 // byte-range request because we may have other parts cached. | 2265 // byte-range request because we may have other parts cached. |
| 2265 custom_request_->extra_headers.SetHeader( | 2266 custom_request_->extra_headers.SetHeader( |
| 2266 HttpRequestHeaders::kIfRange, etag_value); | 2267 HttpRequestHeaders::kIfRange, etag_value); |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2815 default: | 2816 default: |
| 2816 NOTREACHED(); | 2817 NOTREACHED(); |
| 2817 } | 2818 } |
| 2818 } | 2819 } |
| 2819 | 2820 |
| 2820 void HttpCache::Transaction::OnIOComplete(int result) { | 2821 void HttpCache::Transaction::OnIOComplete(int result) { |
| 2821 DoLoop(result); | 2822 DoLoop(result); |
| 2822 } | 2823 } |
| 2823 | 2824 |
| 2824 } // namespace net | 2825 } // namespace net |
| OLD | NEW |