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 |