Chromium Code Reviews| 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 30 matching lines...) Expand all Loading... | |
| 41 #include "net/http/http_util.h" | 41 #include "net/http/http_util.h" |
| 42 #include "net/ssl/ssl_cert_request_info.h" | 42 #include "net/ssl/ssl_cert_request_info.h" |
| 43 #include "net/ssl/ssl_config_service.h" | 43 #include "net/ssl/ssl_config_service.h" |
| 44 | 44 |
| 45 using base::Time; | 45 using base::Time; |
| 46 using base::TimeDelta; | 46 using base::TimeDelta; |
| 47 using base::TimeTicks; | 47 using base::TimeTicks; |
| 48 | 48 |
| 49 namespace net { | 49 namespace net { |
| 50 | 50 |
| 51 using CacheEntryStatus = HttpResponseInfo::CacheEntryStatus; | |
| 52 | |
| 51 namespace { | 53 namespace { |
| 52 | 54 |
| 53 // TODO(ricea): Move this to HttpResponseHeaders once it is standardised. | 55 // TODO(ricea): Move this to HttpResponseHeaders once it is standardised. |
| 54 static const char kFreshnessHeader[] = "Resource-Freshness"; | 56 static const char kFreshnessHeader[] = "Resource-Freshness"; |
| 55 | 57 |
| 56 // From http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache-21#section-6 | 58 // From http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache-21#section-6 |
| 57 // a "non-error response" is one with a 2xx (Successful) or 3xx | 59 // a "non-error response" is one with a 2xx (Successful) or 3xx |
| 58 // (Redirection) status code. | 60 // (Redirection) status code. |
| 59 bool NonErrorResponse(int status_code) { | 61 bool NonErrorResponse(int status_code) { |
| 60 int status_code_range = status_code / 100; | 62 int status_code_range = status_code / 100; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 158 cache_pending_(false), | 160 cache_pending_(false), |
| 159 done_reading_(false), | 161 done_reading_(false), |
| 160 vary_mismatch_(false), | 162 vary_mismatch_(false), |
| 161 couldnt_conditionalize_request_(false), | 163 couldnt_conditionalize_request_(false), |
| 162 bypass_lock_for_test_(false), | 164 bypass_lock_for_test_(false), |
| 163 fail_conditionalization_for_test_(false), | 165 fail_conditionalization_for_test_(false), |
| 164 io_buf_len_(0), | 166 io_buf_len_(0), |
| 165 read_offset_(0), | 167 read_offset_(0), |
| 166 effective_load_flags_(0), | 168 effective_load_flags_(0), |
| 167 write_len_(0), | 169 write_len_(0), |
| 168 transaction_pattern_(PATTERN_UNDEFINED), | 170 cache_entry_status_(CacheEntryStatus::UNDEFINED), |
| 169 validation_cause_(VALIDATION_CAUSE_UNDEFINED), | 171 validation_cause_(VALIDATION_CAUSE_UNDEFINED), |
| 170 total_received_bytes_(0), | 172 total_received_bytes_(0), |
| 171 total_sent_bytes_(0), | 173 total_sent_bytes_(0), |
| 172 websocket_handshake_stream_base_create_helper_(NULL), | 174 websocket_handshake_stream_base_create_helper_(NULL), |
| 173 weak_factory_(this) { | 175 weak_factory_(this) { |
| 174 static_assert(HttpCache::Transaction::kNumValidationHeaders == | 176 static_assert(HttpCache::Transaction::kNumValidationHeaders == |
| 175 arraysize(kValidationHeaders), | 177 arraysize(kValidationHeaders), |
| 176 "invalid number of validation headers"); | 178 "invalid number of validation headers"); |
| 177 | 179 |
| 178 io_callback_ = base::Bind(&Transaction::OnIOComplete, | 180 io_callback_ = base::Bind(&Transaction::OnIOComplete, |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 357 | 359 |
| 358 DCHECK(callback_.is_null()); | 360 DCHECK(callback_.is_null()); |
| 359 | 361 |
| 360 if (!cache_.get()) | 362 if (!cache_.get()) |
| 361 return ERR_UNEXPECTED; | 363 return ERR_UNEXPECTED; |
| 362 | 364 |
| 363 // If we have an intermediate auth response at this point, then it means the | 365 // If we have an intermediate auth response at this point, then it means the |
| 364 // user wishes to read the network response (the error page). If there is a | 366 // user wishes to read the network response (the error page). If there is a |
| 365 // previous response in the cache then we should leave it intact. | 367 // previous response in the cache then we should leave it intact. |
| 366 if (auth_response_.headers.get() && mode_ != NONE) { | 368 if (auth_response_.headers.get() && mode_ != NONE) { |
| 367 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 369 UpdateCacheEntryStatus(CacheEntryStatus::OTHER); |
| 368 DCHECK(mode_ & WRITE); | 370 DCHECK(mode_ & WRITE); |
| 369 DoneWritingToEntry(mode_ == READ_WRITE); | 371 DoneWritingToEntry(mode_ == READ_WRITE); |
| 370 mode_ = NONE; | 372 mode_ = NONE; |
| 371 } | 373 } |
| 372 | 374 |
| 373 reading_ = true; | 375 reading_ = true; |
| 374 read_buf_ = buf; | 376 read_buf_ = buf; |
| 375 io_buf_len_ = buf_len; | 377 io_buf_len_ = buf_len; |
| 376 if (network_trans_) { | 378 if (network_trans_) { |
| 377 DCHECK(mode_ == WRITE || mode_ == NONE || | 379 DCHECK(mode_ == WRITE || mode_ == NONE || |
| (...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1243 // to be validated and then issue a network request if needed or just read | 1245 // to be validated and then issue a network request if needed or just read |
| 1244 // from the cache if the cache entry is already valid. | 1246 // from the cache if the cache entry is already valid. |
| 1245 // | 1247 // |
| 1246 // o if we are set to UPDATE, then we are handling an externally | 1248 // o if we are set to UPDATE, then we are handling an externally |
| 1247 // conditionalized request (if-modified-since / if-none-match). We check | 1249 // conditionalized request (if-modified-since / if-none-match). We check |
| 1248 // if the request headers define a validation request. | 1250 // if the request headers define a validation request. |
| 1249 // | 1251 // |
| 1250 int result = ERR_FAILED; | 1252 int result = ERR_FAILED; |
| 1251 switch (mode_) { | 1253 switch (mode_) { |
| 1252 case READ: | 1254 case READ: |
| 1253 UpdateTransactionPattern(PATTERN_ENTRY_USED); | 1255 UpdateCacheEntryStatus(CacheEntryStatus::USED); |
| 1254 result = BeginCacheRead(); | 1256 result = BeginCacheRead(); |
| 1255 break; | 1257 break; |
| 1256 case READ_WRITE: | 1258 case READ_WRITE: |
| 1257 result = BeginPartialCacheValidation(); | 1259 result = BeginPartialCacheValidation(); |
| 1258 break; | 1260 break; |
| 1259 case UPDATE: | 1261 case UPDATE: |
| 1260 result = BeginExternallyConditionalizedRequest(); | 1262 result = BeginExternallyConditionalizedRequest(); |
| 1261 break; | 1263 break; |
| 1262 case WRITE: | 1264 case WRITE: |
| 1263 default: | 1265 default: |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1352 | 1354 |
| 1353 if (result == OK) { | 1355 if (result == OK) { |
| 1354 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; | 1356 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; |
| 1355 return OK; | 1357 return OK; |
| 1356 } | 1358 } |
| 1357 | 1359 |
| 1358 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); | 1360 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); |
| 1359 response_.network_accessed = response->network_accessed; | 1361 response_.network_accessed = response->network_accessed; |
| 1360 | 1362 |
| 1361 // Do not record requests that have network errors or restarts. | 1363 // Do not record requests that have network errors or restarts. |
| 1362 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 1364 UpdateCacheEntryStatus(CacheEntryStatus::OTHER); |
| 1363 if (IsCertificateError(result)) { | 1365 if (IsCertificateError(result)) { |
| 1364 // If we get a certificate error, then there is a certificate in ssl_info, | 1366 // If we get a certificate error, then there is a certificate in ssl_info, |
| 1365 // so GetResponseInfo() should never return NULL here. | 1367 // so GetResponseInfo() should never return NULL here. |
| 1366 DCHECK(response); | 1368 DCHECK(response); |
| 1367 response_.ssl_info = response->ssl_info; | 1369 response_.ssl_info = response->ssl_info; |
| 1368 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 1370 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
| 1369 DCHECK(response); | 1371 DCHECK(response); |
| 1370 response_.cert_request_info = response->cert_request_info; | 1372 response_.cert_request_info = response->cert_request_info; |
| 1371 } else if (response_.was_cached) { | 1373 } else if (response_.was_cached) { |
| 1372 DoneWritingToEntry(true); | 1374 DoneWritingToEntry(true); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1410 return ERR_CACHE_AUTH_FAILURE_AFTER_READ; | 1412 return ERR_CACHE_AUTH_FAILURE_AFTER_READ; |
| 1411 } | 1413 } |
| 1412 | 1414 |
| 1413 new_response_ = new_response; | 1415 new_response_ = new_response; |
| 1414 if (!ValidatePartialResponse() && !auth_response_.headers.get()) { | 1416 if (!ValidatePartialResponse() && !auth_response_.headers.get()) { |
| 1415 // Something went wrong with this request and we have to restart it. | 1417 // Something went wrong with this request and we have to restart it. |
| 1416 // If we have an authentication response, we are exposed to weird things | 1418 // If we have an authentication response, we are exposed to weird things |
| 1417 // hapenning if the user cancels the authentication before we receive | 1419 // hapenning if the user cancels the authentication before we receive |
| 1418 // the new response. | 1420 // the new response. |
| 1419 net_log_.AddEvent(NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST); | 1421 net_log_.AddEvent(NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST); |
| 1420 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 1422 UpdateCacheEntryStatus(CacheEntryStatus::OTHER); |
| 1421 response_ = HttpResponseInfo(); | 1423 set_response(HttpResponseInfo()); |
| 1422 ResetNetworkTransaction(); | 1424 ResetNetworkTransaction(); |
| 1423 new_response_ = NULL; | 1425 new_response_ = NULL; |
| 1424 next_state_ = STATE_SEND_REQUEST; | 1426 next_state_ = STATE_SEND_REQUEST; |
| 1425 return OK; | 1427 return OK; |
| 1426 } | 1428 } |
| 1427 | 1429 |
| 1428 if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) { | 1430 if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) { |
| 1429 // We have stored the full entry, but it changed and the server is | 1431 // We have stored the full entry, but it changed and the server is |
| 1430 // sending a range. We have to delete the old entry. | 1432 // sending a range. We have to delete the old entry. |
| 1431 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 1433 UpdateCacheEntryStatus(CacheEntryStatus::OTHER); |
| 1432 DoneWritingToEntry(false); | 1434 DoneWritingToEntry(false); |
| 1433 } | 1435 } |
| 1434 | 1436 |
| 1435 if (mode_ == WRITE && | 1437 if (mode_ == WRITE && |
| 1436 transaction_pattern_ != PATTERN_ENTRY_CANT_CONDITIONALIZE) { | 1438 cache_entry_status_ != CacheEntryStatus::CANT_CONDITIONALIZE) { |
| 1437 UpdateTransactionPattern(PATTERN_ENTRY_NOT_CACHED); | 1439 UpdateCacheEntryStatus(CacheEntryStatus::NOT_IN_CACHE); |
| 1438 } | 1440 } |
| 1439 | 1441 |
| 1440 // Invalidate any cached GET with a successful PUT or DELETE. | 1442 // Invalidate any cached GET with a successful PUT or DELETE. |
| 1441 if (mode_ == WRITE && | 1443 if (mode_ == WRITE && |
| 1442 (request_->method == "PUT" || request_->method == "DELETE")) { | 1444 (request_->method == "PUT" || request_->method == "DELETE")) { |
| 1443 if (NonErrorResponse(new_response->headers->response_code())) { | 1445 if (NonErrorResponse(new_response->headers->response_code())) { |
| 1444 int ret = cache_->DoomEntry(cache_key_, NULL); | 1446 int ret = cache_->DoomEntry(cache_key_, NULL); |
| 1445 DCHECK_EQ(OK, ret); | 1447 DCHECK_EQ(OK, ret); |
| 1446 } | 1448 } |
| 1447 cache_->DoneWritingToEntry(entry_, true); | 1449 cache_->DoneWritingToEntry(entry_, true); |
| 1448 entry_ = NULL; | 1450 entry_ = NULL; |
| 1449 mode_ = NONE; | 1451 mode_ = NONE; |
| 1450 } | 1452 } |
| 1451 | 1453 |
| 1452 // Invalidate any cached GET with a successful POST. | 1454 // Invalidate any cached GET with a successful POST. |
| 1453 if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) && | 1455 if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) && |
| 1454 request_->method == "POST" && | 1456 request_->method == "POST" && |
| 1455 NonErrorResponse(new_response->headers->response_code())) { | 1457 NonErrorResponse(new_response->headers->response_code())) { |
| 1456 cache_->DoomMainEntryForUrl(request_->url); | 1458 cache_->DoomMainEntryForUrl(request_->url); |
| 1457 } | 1459 } |
| 1458 | 1460 |
| 1459 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); | 1461 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); |
| 1460 | 1462 |
| 1461 if (new_response_->headers->response_code() == 416 && | 1463 if (new_response_->headers->response_code() == 416 && |
| 1462 (request_->method == "GET" || request_->method == "POST")) { | 1464 (request_->method == "GET" || request_->method == "POST")) { |
| 1463 // If there is an active entry it may be destroyed with this transaction. | 1465 // If there is an active entry it may be destroyed with this transaction. |
| 1464 response_ = *new_response_; | 1466 set_response(*new_response_); |
| 1465 return OK; | 1467 return OK; |
| 1466 } | 1468 } |
| 1467 | 1469 |
| 1468 // Are we expecting a response to a conditional query? | 1470 // Are we expecting a response to a conditional query? |
| 1469 if (mode_ == READ_WRITE || mode_ == UPDATE) { | 1471 if (mode_ == READ_WRITE || mode_ == UPDATE) { |
| 1470 if (new_response->headers->response_code() == 304 || handling_206_) { | 1472 if (new_response->headers->response_code() == 304 || handling_206_) { |
| 1471 UpdateTransactionPattern(PATTERN_ENTRY_VALIDATED); | 1473 UpdateCacheEntryStatus(CacheEntryStatus::VALIDATED); |
| 1472 next_state_ = STATE_UPDATE_CACHED_RESPONSE; | 1474 next_state_ = STATE_UPDATE_CACHED_RESPONSE; |
| 1473 return OK; | 1475 return OK; |
| 1474 } | 1476 } |
| 1475 UpdateTransactionPattern(PATTERN_ENTRY_UPDATED); | 1477 UpdateCacheEntryStatus(CacheEntryStatus::UPDATED); |
| 1476 mode_ = WRITE; | 1478 mode_ = WRITE; |
| 1477 } | 1479 } |
| 1478 | 1480 |
| 1479 next_state_ = STATE_OVERWRITE_CACHED_RESPONSE; | 1481 next_state_ = STATE_OVERWRITE_CACHED_RESPONSE; |
| 1480 return OK; | 1482 return OK; |
| 1481 } | 1483 } |
| 1482 | 1484 |
| 1483 // We received 304 or 206 and we want to update the cached response headers. | 1485 // We received 304 or 206 and we want to update the cached response headers. |
| 1484 int HttpCache::Transaction::DoUpdateCachedResponse() { | 1486 int HttpCache::Transaction::DoUpdateCachedResponse() { |
| 1485 next_state_ = STATE_UPDATE_CACHED_RESPONSE_COMPLETE; | 1487 next_state_ = STATE_UPDATE_CACHED_RESPONSE_COMPLETE; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1564 int HttpCache::Transaction::DoOverwriteCachedResponse() { | 1566 int HttpCache::Transaction::DoOverwriteCachedResponse() { |
| 1565 if (mode_ & READ) { | 1567 if (mode_ & READ) { |
| 1566 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | 1568 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; |
| 1567 return OK; | 1569 return OK; |
| 1568 } | 1570 } |
| 1569 | 1571 |
| 1570 // We change the value of Content-Length for partial content. | 1572 // We change the value of Content-Length for partial content. |
| 1571 if (handling_206_ && partial_) | 1573 if (handling_206_ && partial_) |
| 1572 partial_->FixContentLength(new_response_->headers.get()); | 1574 partial_->FixContentLength(new_response_->headers.get()); |
| 1573 | 1575 |
| 1574 response_ = *new_response_; | 1576 set_response(*new_response_); |
| 1575 | 1577 |
| 1576 if (request_->method == "HEAD") { | 1578 if (request_->method == "HEAD") { |
| 1577 // This response is replacing the cached one. | 1579 // This response is replacing the cached one. |
| 1578 DoneWritingToEntry(false); | 1580 DoneWritingToEntry(false); |
| 1579 mode_ = NONE; | 1581 mode_ = NONE; |
| 1580 new_response_ = NULL; | 1582 new_response_ = NULL; |
| 1581 return OK; | 1583 return OK; |
| 1582 } | 1584 } |
| 1583 | 1585 |
| 1584 if (handling_206_ && !CanResume(false)) { | 1586 if (handling_206_ && !CanResume(false)) { |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1737 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_DATA, | 1739 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_DATA, |
| 1738 result); | 1740 result); |
| 1739 } | 1741 } |
| 1740 | 1742 |
| 1741 if (!cache_.get()) | 1743 if (!cache_.get()) |
| 1742 return ERR_UNEXPECTED; | 1744 return ERR_UNEXPECTED; |
| 1743 | 1745 |
| 1744 if (partial_) { | 1746 if (partial_) { |
| 1745 // Partial requests are confusing to report in histograms because they may | 1747 // Partial requests are confusing to report in histograms because they may |
| 1746 // have multiple underlying requests. | 1748 // have multiple underlying requests. |
| 1747 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 1749 UpdateCacheEntryStatus(CacheEntryStatus::OTHER); |
| 1748 return DoPartialCacheReadCompleted(result); | 1750 return DoPartialCacheReadCompleted(result); |
| 1749 } | 1751 } |
| 1750 | 1752 |
| 1751 if (result > 0) { | 1753 if (result > 0) { |
| 1752 read_offset_ += result; | 1754 read_offset_ += result; |
| 1753 } else if (result == 0) { // End of file. | 1755 } else if (result == 0) { // End of file. |
| 1754 RecordHistograms(); | 1756 RecordHistograms(); |
| 1755 cache_->DoneReadingFromEntry(entry_, this); | 1757 cache_->DoneReadingFromEntry(entry_, this); |
| 1756 entry_ = NULL; | 1758 entry_ = NULL; |
| 1757 } else { | 1759 } else { |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1906 | 1908 |
| 1907 // If there is more than one validation header, we can't treat this request as | 1909 // If there is more than one validation header, we can't treat this request as |
| 1908 // a cache validation, since we don't know for sure which header the server | 1910 // a cache validation, since we don't know for sure which header the server |
| 1909 // will give us a response for (and they could be contradictory). | 1911 // will give us a response for (and they could be contradictory). |
| 1910 if (external_validation_error) { | 1912 if (external_validation_error) { |
| 1911 LOG(WARNING) << "Multiple or malformed validation headers found."; | 1913 LOG(WARNING) << "Multiple or malformed validation headers found."; |
| 1912 effective_load_flags_ |= LOAD_DISABLE_CACHE; | 1914 effective_load_flags_ |= LOAD_DISABLE_CACHE; |
| 1913 } | 1915 } |
| 1914 | 1916 |
| 1915 if (range_found && !(effective_load_flags_ & LOAD_DISABLE_CACHE)) { | 1917 if (range_found && !(effective_load_flags_ & LOAD_DISABLE_CACHE)) { |
| 1916 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 1918 UpdateCacheEntryStatus(CacheEntryStatus::OTHER); |
| 1917 partial_.reset(new PartialData); | 1919 partial_.reset(new PartialData); |
| 1918 if (request_->method == "GET" && partial_->Init(request_->extra_headers)) { | 1920 if (request_->method == "GET" && partial_->Init(request_->extra_headers)) { |
| 1919 // We will be modifying the actual range requested to the server, so | 1921 // We will be modifying the actual range requested to the server, so |
| 1920 // let's remove the header here. | 1922 // let's remove the header here. |
| 1921 custom_request_.reset(new HttpRequestInfo(*request_)); | 1923 custom_request_.reset(new HttpRequestInfo(*request_)); |
| 1922 custom_request_->extra_headers.RemoveHeader(HttpRequestHeaders::kRange); | 1924 custom_request_->extra_headers.RemoveHeader(HttpRequestHeaders::kRange); |
| 1923 request_ = custom_request_.get(); | 1925 request_ = custom_request_.get(); |
| 1924 partial_->SetHeaders(custom_request_->extra_headers); | 1926 partial_->SetHeaders(custom_request_->extra_headers); |
| 1925 } else { | 1927 } else { |
| 1926 // The range is invalid or we cannot handle it properly. | 1928 // The range is invalid or we cannot handle it properly. |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1999 | 2001 |
| 2000 // Bail out! | 2002 // Bail out! |
| 2001 next_state_ = STATE_SEND_REQUEST; | 2003 next_state_ = STATE_SEND_REQUEST; |
| 2002 mode_ = NONE; | 2004 mode_ = NONE; |
| 2003 return OK; | 2005 return OK; |
| 2004 } | 2006 } |
| 2005 | 2007 |
| 2006 if (truncated_) { | 2008 if (truncated_) { |
| 2007 // Truncated entries can cause partial gets, so we shouldn't record this | 2009 // Truncated entries can cause partial gets, so we shouldn't record this |
| 2008 // load in histograms. | 2010 // load in histograms. |
| 2009 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 2011 UpdateCacheEntryStatus(CacheEntryStatus::OTHER); |
| 2010 skip_validation = !partial_->initial_validation(); | 2012 skip_validation = !partial_->initial_validation(); |
| 2011 } | 2013 } |
| 2012 | 2014 |
| 2013 if (partial_ && (is_sparse_ || truncated_) && | 2015 if (partial_ && (is_sparse_ || truncated_) && |
| 2014 (!partial_->IsCurrentRangeCached() || invalid_range_)) { | 2016 (!partial_->IsCurrentRangeCached() || invalid_range_)) { |
| 2015 // Force revalidation for sparse or truncated entries. Note that we don't | 2017 // Force revalidation for sparse or truncated entries. Note that we don't |
| 2016 // want to ignore the regular validation logic just because a byte range was | 2018 // want to ignore the regular validation logic just because a byte range was |
| 2017 // part of the request. | 2019 // part of the request. |
| 2018 skip_validation = false; | 2020 skip_validation = false; |
| 2019 } | 2021 } |
| 2020 | 2022 |
| 2021 if (skip_validation) { | 2023 if (skip_validation) { |
| 2022 UpdateTransactionPattern(PATTERN_ENTRY_USED); | 2024 UpdateCacheEntryStatus(CacheEntryStatus::USED); |
| 2023 return SetupEntryForRead(); | 2025 return SetupEntryForRead(); |
| 2024 } else { | 2026 } else { |
| 2025 // Make the network request conditional, to see if we may reuse our cached | 2027 // Make the network request conditional, to see if we may reuse our cached |
| 2026 // response. If we cannot do so, then we just resort to a normal fetch. | 2028 // response. If we cannot do so, then we just resort to a normal fetch. |
| 2027 // Our mode remains READ_WRITE for a conditional request. Even if the | 2029 // Our mode remains READ_WRITE for a conditional request. Even if the |
| 2028 // conditionalization fails, we don't switch to WRITE mode until we | 2030 // conditionalization fails, we don't switch to WRITE mode until we |
| 2029 // know we won't be falling back to using the cache entry in the | 2031 // know we won't be falling back to using the cache entry in the |
| 2030 // LOAD_FROM_CACHE_IF_OFFLINE case. | 2032 // LOAD_FROM_CACHE_IF_OFFLINE case. |
| 2031 if (!ConditionalizeRequest()) { | 2033 if (!ConditionalizeRequest()) { |
| 2032 couldnt_conditionalize_request_ = true; | 2034 couldnt_conditionalize_request_ = true; |
| 2033 UpdateTransactionPattern(PATTERN_ENTRY_CANT_CONDITIONALIZE); | 2035 UpdateCacheEntryStatus(CacheEntryStatus::CANT_CONDITIONALIZE); |
| 2034 if (partial_) | 2036 if (partial_) |
| 2035 return DoRestartPartialRequest(); | 2037 return DoRestartPartialRequest(); |
| 2036 | 2038 |
| 2037 DCHECK_NE(206, response_.headers->response_code()); | 2039 DCHECK_NE(206, response_.headers->response_code()); |
| 2038 } | 2040 } |
| 2039 next_state_ = STATE_SEND_REQUEST; | 2041 next_state_ = STATE_SEND_REQUEST; |
| 2040 } | 2042 } |
| 2041 return OK; | 2043 return OK; |
| 2042 } | 2044 } |
| 2043 | 2045 |
| 2044 int HttpCache::Transaction::BeginPartialCacheValidation() { | 2046 int HttpCache::Transaction::BeginPartialCacheValidation() { |
| 2045 DCHECK_EQ(mode_, READ_WRITE); | 2047 DCHECK_EQ(mode_, READ_WRITE); |
| 2046 | 2048 |
| 2047 if (response_.headers->response_code() != 206 && !partial_ && !truncated_) | 2049 if (response_.headers->response_code() != 206 && !partial_ && !truncated_) |
| 2048 return BeginCacheValidation(); | 2050 return BeginCacheValidation(); |
| 2049 | 2051 |
| 2050 // Partial requests should not be recorded in histograms. | 2052 // Partial requests should not be recorded in histograms. |
| 2051 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 2053 UpdateCacheEntryStatus(CacheEntryStatus::OTHER); |
| 2052 if (request_->method == "HEAD") | 2054 if (request_->method == "HEAD") |
| 2053 return BeginCacheValidation(); | 2055 return BeginCacheValidation(); |
| 2054 | 2056 |
| 2055 if (!range_requested_) { | 2057 if (!range_requested_) { |
| 2056 // The request is not for a range, but we have stored just ranges. | 2058 // The request is not for a range, but we have stored just ranges. |
| 2057 | 2059 |
| 2058 partial_.reset(new PartialData()); | 2060 partial_.reset(new PartialData()); |
| 2059 partial_->SetHeaders(request_->extra_headers); | 2061 partial_->SetHeaders(request_->extra_headers); |
| 2060 if (!custom_request_.get()) { | 2062 if (!custom_request_.get()) { |
| 2061 custom_request_.reset(new HttpRequestInfo(*request_)); | 2063 custom_request_.reset(new HttpRequestInfo(*request_)); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2099 std::string validator; | 2101 std::string validator; |
| 2100 response_.headers->EnumerateHeader( | 2102 response_.headers->EnumerateHeader( |
| 2101 NULL, | 2103 NULL, |
| 2102 kValidationHeaders[i].related_response_header_name, | 2104 kValidationHeaders[i].related_response_header_name, |
| 2103 &validator); | 2105 &validator); |
| 2104 | 2106 |
| 2105 if (response_.headers->response_code() != 200 || truncated_ || | 2107 if (response_.headers->response_code() != 200 || truncated_ || |
| 2106 validator.empty() || validator != external_validation_.values[i]) { | 2108 validator.empty() || validator != external_validation_.values[i]) { |
| 2107 // The externally conditionalized request is not a validation request | 2109 // The externally conditionalized request is not a validation request |
| 2108 // for our existing cache entry. Proceed with caching disabled. | 2110 // for our existing cache entry. Proceed with caching disabled. |
| 2109 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 2111 UpdateCacheEntryStatus(CacheEntryStatus::OTHER); |
| 2110 DoneWritingToEntry(true); | 2112 DoneWritingToEntry(true); |
| 2111 } | 2113 } |
| 2112 } | 2114 } |
| 2113 | 2115 |
| 2114 // TODO(ricea): This calculation is expensive to perform just to collect | 2116 // TODO(ricea): This calculation is expensive to perform just to collect |
| 2115 // statistics. Either remove it or use the result, depending on the result of | 2117 // statistics. Either remove it or use the result, depending on the result of |
| 2116 // the experiment. | 2118 // the experiment. |
| 2117 ExternallyConditionalizedType type = | 2119 ExternallyConditionalizedType type = |
| 2118 EXTERNALLY_CONDITIONALIZED_CACHE_USABLE; | 2120 EXTERNALLY_CONDITIONALIZED_CACHE_USABLE; |
| 2119 if (mode_ == NONE) | 2121 if (mode_ == NONE) |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2358 // server is ok with the request, delete the entry, otherwise just ignore | 2360 // server is ok with the request, delete the entry, otherwise just ignore |
| 2359 // this request | 2361 // this request |
| 2360 DCHECK(!reading_); | 2362 DCHECK(!reading_); |
| 2361 if (partial_response || response_code == 200) { | 2363 if (partial_response || response_code == 200) { |
| 2362 DoomPartialEntry(true); | 2364 DoomPartialEntry(true); |
| 2363 mode_ = NONE; | 2365 mode_ = NONE; |
| 2364 } else { | 2366 } else { |
| 2365 if (response_code == 304) { | 2367 if (response_code == 304) { |
| 2366 // Change the response code of the request to be 416 (Requested range | 2368 // Change the response code of the request to be 416 (Requested range |
| 2367 // not satisfiable). | 2369 // not satisfiable). |
| 2368 response_ = *new_response_; | 2370 set_response(*new_response_); |
| 2369 partial_->FixResponseHeaders(response_.headers.get(), false); | 2371 partial_->FixResponseHeaders(response_.headers.get(), false); |
| 2370 } | 2372 } |
| 2371 IgnoreRangeRequest(); | 2373 IgnoreRangeRequest(); |
| 2372 } | 2374 } |
| 2373 return true; | 2375 return true; |
| 2374 } | 2376 } |
| 2375 | 2377 |
| 2376 if (!partial_) { | 2378 if (!partial_) { |
| 2377 // We are not expecting 206 but we may have one. | 2379 // We are not expecting 206 but we may have one. |
| 2378 if (partial_response) | 2380 if (partial_response) |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2418 } | 2420 } |
| 2419 | 2421 |
| 2420 // 304 is not expected here, but we'll spare the entry (unless it was | 2422 // 304 is not expected here, but we'll spare the entry (unless it was |
| 2421 // truncated). | 2423 // truncated). |
| 2422 if (truncated_) | 2424 if (truncated_) |
| 2423 failure = true; | 2425 failure = true; |
| 2424 } | 2426 } |
| 2425 | 2427 |
| 2426 if (failure) { | 2428 if (failure) { |
| 2427 // We cannot truncate this entry, it has to be deleted. | 2429 // We cannot truncate this entry, it has to be deleted. |
| 2428 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 2430 UpdateCacheEntryStatus(CacheEntryStatus::OTHER); |
| 2429 mode_ = NONE; | 2431 mode_ = NONE; |
| 2430 if (is_sparse_ || truncated_) { | 2432 if (is_sparse_ || truncated_) { |
| 2431 // There was something cached to start with, either sparsed data (206), or | 2433 // There was something cached to start with, either sparsed data (206), or |
| 2432 // a truncated 200, which means that we probably modified the request, | 2434 // a truncated 200, which means that we probably modified the request, |
| 2433 // adding a byte range or modifying the range requested by the caller. | 2435 // adding a byte range or modifying the range requested by the caller. |
| 2434 if (!reading_ && !partial_->IsLastRange()) { | 2436 if (!reading_ && !partial_->IsLastRange()) { |
| 2435 // We have not returned anything to the caller yet so it should be safe | 2437 // We have not returned anything to the caller yet so it should be safe |
| 2436 // to issue another network request, this time without us messing up the | 2438 // to issue another network request, this time without us messing up the |
| 2437 // headers. | 2439 // headers. |
| 2438 ResetPartialState(true); | 2440 ResetPartialState(true); |
| 2439 return false; | 2441 return false; |
| 2440 } | 2442 } |
| 2441 LOG(WARNING) << "Failed to revalidate partial entry"; | 2443 LOG(WARNING) << "Failed to revalidate partial entry"; |
| 2442 } | 2444 } |
| 2443 DoomPartialEntry(true); | 2445 DoomPartialEntry(true); |
| 2444 return true; | 2446 return true; |
| 2445 } | 2447 } |
| 2446 | 2448 |
| 2447 IgnoreRangeRequest(); | 2449 IgnoreRangeRequest(); |
| 2448 return true; | 2450 return true; |
| 2449 } | 2451 } |
| 2450 | 2452 |
| 2451 void HttpCache::Transaction::IgnoreRangeRequest() { | 2453 void HttpCache::Transaction::IgnoreRangeRequest() { |
| 2452 // We have a problem. We may or may not be reading already (in which case we | 2454 // We have a problem. We may or may not be reading already (in which case we |
| 2453 // returned the headers), but we'll just pretend that this request is not | 2455 // returned the headers), but we'll just pretend that this request is not |
| 2454 // using the cache and see what happens. Most likely this is the first | 2456 // using the cache and see what happens. Most likely this is the first |
| 2455 // response from the server (it's not changing its mind midway, right?). | 2457 // response from the server (it's not changing its mind midway, right?). |
| 2456 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 2458 UpdateCacheEntryStatus(CacheEntryStatus::OTHER); |
| 2457 if (mode_ & WRITE) | 2459 if (mode_ & WRITE) |
| 2458 DoneWritingToEntry(mode_ != WRITE); | 2460 DoneWritingToEntry(mode_ != WRITE); |
| 2459 else if (mode_ & READ && entry_) | 2461 else if (mode_ & READ && entry_) |
| 2460 cache_->DoneReadingFromEntry(entry_, this); | 2462 cache_->DoneReadingFromEntry(entry_, this); |
| 2461 | 2463 |
| 2462 partial_.reset(NULL); | 2464 partial_.reset(NULL); |
| 2463 entry_ = NULL; | 2465 entry_ = NULL; |
| 2464 mode_ = NONE; | 2466 mode_ = NONE; |
| 2465 } | 2467 } |
| 2466 | 2468 |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2720 // PartialData::ResponseHeadersOK(). | 2722 // PartialData::ResponseHeadersOK(). |
| 2721 if (response_.headers->GetContentLength() <= 0 || | 2723 if (response_.headers->GetContentLength() <= 0 || |
| 2722 response_.headers->HasHeaderValue("Accept-Ranges", "none") || | 2724 response_.headers->HasHeaderValue("Accept-Ranges", "none") || |
| 2723 !response_.headers->HasStrongValidators()) { | 2725 !response_.headers->HasStrongValidators()) { |
| 2724 return false; | 2726 return false; |
| 2725 } | 2727 } |
| 2726 | 2728 |
| 2727 return true; | 2729 return true; |
| 2728 } | 2730 } |
| 2729 | 2731 |
| 2730 void HttpCache::Transaction::UpdateTransactionPattern( | 2732 void HttpCache::Transaction::set_response(const HttpResponseInfo& response) { |
| 2731 TransactionPattern new_transaction_pattern) { | 2733 response_ = response; |
| 2732 if (transaction_pattern_ == PATTERN_NOT_COVERED) | 2734 SyncCacheEntryStatusToResponse(); |
| 2735 } | |
| 2736 | |
| 2737 void HttpCache::Transaction::UpdateCacheEntryStatus( | |
| 2738 CacheEntryStatus new_cache_entry_status) { | |
| 2739 if (cache_entry_status_ == CacheEntryStatus::OTHER) | |
| 2733 return; | 2740 return; |
| 2734 DCHECK(transaction_pattern_ == PATTERN_UNDEFINED || | 2741 DCHECK(cache_entry_status_ == CacheEntryStatus::UNDEFINED || |
| 2735 new_transaction_pattern == PATTERN_NOT_COVERED); | 2742 new_cache_entry_status == CacheEntryStatus::OTHER); |
| 2736 transaction_pattern_ = new_transaction_pattern; | 2743 cache_entry_status_ = new_cache_entry_status; |
| 2744 SyncCacheEntryStatusToResponse(); | |
| 2745 } | |
| 2746 | |
| 2747 void HttpCache::Transaction::SyncCacheEntryStatusToResponse() { | |
| 2748 response_.cache_entry_status = cache_entry_status_; | |
| 2749 auth_response_.cache_entry_status = cache_entry_status_; | |
|
jkarlin
2016/07/06 17:09:41
To prevent an incorrect auth status, let's guard t
jamartin
2016/07/07 21:36:38
Done. Please note, though, that the status actuall
jamartin
2016/07/08 14:59:59
Josh has confirmed via email that he is OK with au
| |
| 2737 } | 2750 } |
| 2738 | 2751 |
| 2739 void HttpCache::Transaction::RecordHistograms() { | 2752 void HttpCache::Transaction::RecordHistograms() { |
| 2740 DCHECK_NE(PATTERN_UNDEFINED, transaction_pattern_); | 2753 DCHECK_NE(CacheEntryStatus::UNDEFINED, cache_entry_status_); |
| 2741 if (!cache_.get() || !cache_->GetCurrentBackend() || | 2754 if (!cache_.get() || !cache_->GetCurrentBackend() || |
| 2742 cache_->GetCurrentBackend()->GetCacheType() != DISK_CACHE || | 2755 cache_->GetCurrentBackend()->GetCacheType() != DISK_CACHE || |
| 2743 cache_->mode() != NORMAL || request_->method != "GET") { | 2756 cache_->mode() != NORMAL || request_->method != "GET") { |
| 2744 return; | 2757 return; |
| 2745 } | 2758 } |
| 2746 | 2759 |
| 2747 bool validation_request = transaction_pattern_ == PATTERN_ENTRY_VALIDATED || | 2760 bool validation_request = |
| 2748 transaction_pattern_ == PATTERN_ENTRY_UPDATED; | 2761 cache_entry_status_ == CacheEntryStatus::VALIDATED || |
| 2762 cache_entry_status_ == CacheEntryStatus::UPDATED; | |
| 2749 | 2763 |
| 2750 bool stale_request = | 2764 bool stale_request = |
| 2751 validation_cause_ == VALIDATION_CAUSE_STALE && | 2765 validation_cause_ == VALIDATION_CAUSE_STALE && |
| 2752 (validation_request || | 2766 (validation_request || |
| 2753 transaction_pattern_ == PATTERN_ENTRY_CANT_CONDITIONALIZE); | 2767 cache_entry_status_ == CacheEntryStatus::CANT_CONDITIONALIZE); |
| 2754 int64_t freshness_periods_since_last_used = 0; | 2768 int64_t freshness_periods_since_last_used = 0; |
| 2755 | 2769 |
| 2756 if (stale_request) { | 2770 if (stale_request) { |
| 2757 // For stale entries, record how many freshness periods have elapsed since | 2771 // For stale entries, record how many freshness periods have elapsed since |
| 2758 // the entry was last used. | 2772 // the entry was last used. |
| 2759 DCHECK(!open_entry_last_used_.is_null()); | 2773 DCHECK(!open_entry_last_used_.is_null()); |
| 2760 DCHECK(!stale_entry_freshness_.is_zero()); | 2774 DCHECK(!stale_entry_freshness_.is_zero()); |
| 2761 base::TimeDelta time_since_use = base::Time::Now() - open_entry_last_used_; | 2775 base::TimeDelta time_since_use = base::Time::Now() - open_entry_last_used_; |
| 2762 freshness_periods_since_last_used = | 2776 freshness_periods_since_last_used = |
| 2763 (time_since_use * 1000) / stale_entry_freshness_; | 2777 (time_since_use * 1000) / stale_entry_freshness_; |
| 2764 | 2778 |
| 2765 UMA_HISTOGRAM_COUNTS("HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed", | 2779 UMA_HISTOGRAM_COUNTS("HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed", |
| 2766 freshness_periods_since_last_used); | 2780 freshness_periods_since_last_used); |
| 2767 | 2781 |
| 2768 if (validation_request) { | 2782 if (validation_request) { |
| 2769 int64_t age_in_freshness_periods = | 2783 int64_t age_in_freshness_periods = |
| 2770 (stale_entry_age_ * 100) / stale_entry_freshness_; | 2784 (stale_entry_age_ * 100) / stale_entry_freshness_; |
| 2771 if (transaction_pattern_ == PATTERN_ENTRY_VALIDATED) { | 2785 if (cache_entry_status_ == CacheEntryStatus::VALIDATED) { |
| 2772 UMA_HISTOGRAM_COUNTS("HttpCache.StaleEntry.Validated.Age", | 2786 UMA_HISTOGRAM_COUNTS("HttpCache.StaleEntry.Validated.Age", |
| 2773 stale_entry_age_.InSeconds()); | 2787 stale_entry_age_.InSeconds()); |
| 2774 UMA_HISTOGRAM_COUNTS( | 2788 UMA_HISTOGRAM_COUNTS( |
| 2775 "HttpCache.StaleEntry.Validated.AgeInFreshnessPeriods", | 2789 "HttpCache.StaleEntry.Validated.AgeInFreshnessPeriods", |
| 2776 age_in_freshness_periods); | 2790 age_in_freshness_periods); |
| 2777 | 2791 |
| 2778 } else { | 2792 } else { |
| 2779 UMA_HISTOGRAM_COUNTS("HttpCache.StaleEntry.Updated.Age", | 2793 UMA_HISTOGRAM_COUNTS("HttpCache.StaleEntry.Updated.Age", |
| 2780 stale_entry_age_.InSeconds()); | 2794 stale_entry_age_.InSeconds()); |
| 2781 UMA_HISTOGRAM_COUNTS( | 2795 UMA_HISTOGRAM_COUNTS( |
| 2782 "HttpCache.StaleEntry.Updated.AgeInFreshnessPeriods", | 2796 "HttpCache.StaleEntry.Updated.AgeInFreshnessPeriods", |
| 2783 age_in_freshness_periods); | 2797 age_in_freshness_periods); |
| 2784 } | 2798 } |
| 2785 } | 2799 } |
| 2786 } | 2800 } |
| 2787 | 2801 |
| 2788 std::string mime_type; | 2802 std::string mime_type; |
| 2789 HttpResponseHeaders* response_headers = GetResponseInfo()->headers.get(); | 2803 HttpResponseHeaders* response_headers = GetResponseInfo()->headers.get(); |
| 2790 if (response_headers && response_headers->GetMimeType(&mime_type)) { | 2804 if (response_headers && response_headers->GetMimeType(&mime_type)) { |
| 2791 // Record the cache pattern by resource type. The type is inferred by | 2805 // Record the cache pattern by resource type. The type is inferred by |
| 2792 // response header mime type, which could be incorrect, so this is just an | 2806 // response header mime type, which could be incorrect, so this is just an |
| 2793 // estimate. | 2807 // estimate. |
| 2794 if (mime_type == "text/html" && (request_->load_flags & LOAD_MAIN_FRAME)) { | 2808 if (mime_type == "text/html" && (request_->load_flags & LOAD_MAIN_FRAME)) { |
| 2795 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern.MainFrameHTML", | 2809 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern.MainFrameHTML", |
| 2796 transaction_pattern_, PATTERN_MAX); | 2810 cache_entry_status_, CacheEntryStatus::MAX); |
| 2797 if (validation_request) { | 2811 if (validation_request) { |
| 2798 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause.MainFrameHTML", | 2812 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause.MainFrameHTML", |
| 2799 validation_cause_, VALIDATION_CAUSE_MAX); | 2813 validation_cause_, VALIDATION_CAUSE_MAX); |
| 2800 } | 2814 } |
| 2801 if (stale_request) { | 2815 if (stale_request) { |
| 2802 UMA_HISTOGRAM_COUNTS( | 2816 UMA_HISTOGRAM_COUNTS( |
| 2803 "HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed.MainFrameHTML", | 2817 "HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed.MainFrameHTML", |
| 2804 freshness_periods_since_last_used); | 2818 freshness_periods_since_last_used); |
| 2805 } | 2819 } |
| 2806 } else if (mime_type == "text/html") { | 2820 } else if (mime_type == "text/html") { |
| 2807 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern.NonMainFrameHTML", | 2821 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern.NonMainFrameHTML", |
| 2808 transaction_pattern_, PATTERN_MAX); | 2822 cache_entry_status_, CacheEntryStatus::MAX); |
| 2809 if (validation_request) { | 2823 if (validation_request) { |
| 2810 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause.NonMainFrameHTML", | 2824 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause.NonMainFrameHTML", |
| 2811 validation_cause_, VALIDATION_CAUSE_MAX); | 2825 validation_cause_, VALIDATION_CAUSE_MAX); |
| 2812 } | 2826 } |
| 2813 if (stale_request) { | 2827 if (stale_request) { |
| 2814 UMA_HISTOGRAM_COUNTS( | 2828 UMA_HISTOGRAM_COUNTS( |
| 2815 "HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed." | 2829 "HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed." |
| 2816 "NonMainFrameHTML", | 2830 "NonMainFrameHTML", |
| 2817 freshness_periods_since_last_used); | 2831 freshness_periods_since_last_used); |
| 2818 } | 2832 } |
| 2819 } else if (mime_type == "text/css") { | 2833 } else if (mime_type == "text/css") { |
| 2820 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern.CSS", transaction_pattern_, | 2834 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern.CSS", cache_entry_status_, |
| 2821 PATTERN_MAX); | 2835 CacheEntryStatus::MAX); |
| 2822 if (validation_request) { | 2836 if (validation_request) { |
| 2823 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause.CSS", | 2837 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause.CSS", |
| 2824 validation_cause_, VALIDATION_CAUSE_MAX); | 2838 validation_cause_, VALIDATION_CAUSE_MAX); |
| 2825 } | 2839 } |
| 2826 if (stale_request) { | 2840 if (stale_request) { |
| 2827 UMA_HISTOGRAM_COUNTS( | 2841 UMA_HISTOGRAM_COUNTS( |
| 2828 "HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed.CSS", | 2842 "HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed.CSS", |
| 2829 freshness_periods_since_last_used); | 2843 freshness_periods_since_last_used); |
| 2830 } | 2844 } |
| 2831 } else if (base::StartsWith(mime_type, "image/", | 2845 } else if (base::StartsWith(mime_type, "image/", |
| 2832 base::CompareCase::SENSITIVE)) { | 2846 base::CompareCase::SENSITIVE)) { |
| 2833 int64_t content_length = response_headers->GetContentLength(); | 2847 int64_t content_length = response_headers->GetContentLength(); |
| 2834 if (content_length >= 0 && content_length < 100) { | 2848 if (content_length >= 0 && content_length < 100) { |
| 2835 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern.TinyImage", | 2849 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern.TinyImage", |
| 2836 transaction_pattern_, PATTERN_MAX); | 2850 cache_entry_status_, CacheEntryStatus::MAX); |
| 2837 if (validation_request) { | 2851 if (validation_request) { |
| 2838 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause.TinyImage", | 2852 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause.TinyImage", |
| 2839 validation_cause_, VALIDATION_CAUSE_MAX); | 2853 validation_cause_, VALIDATION_CAUSE_MAX); |
| 2840 } | 2854 } |
| 2841 if (stale_request) { | 2855 if (stale_request) { |
| 2842 UMA_HISTOGRAM_COUNTS( | 2856 UMA_HISTOGRAM_COUNTS( |
| 2843 "HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed.TinyImage", | 2857 "HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed.TinyImage", |
| 2844 freshness_periods_since_last_used); | 2858 freshness_periods_since_last_used); |
| 2845 } | 2859 } |
| 2846 } else if (content_length >= 100) { | 2860 } else if (content_length >= 100) { |
| 2847 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern.NonTinyImage", | 2861 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern.NonTinyImage", |
| 2848 transaction_pattern_, PATTERN_MAX); | 2862 cache_entry_status_, CacheEntryStatus::MAX); |
| 2849 if (validation_request) { | 2863 if (validation_request) { |
| 2850 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause.NonTinyImage", | 2864 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause.NonTinyImage", |
| 2851 validation_cause_, VALIDATION_CAUSE_MAX); | 2865 validation_cause_, VALIDATION_CAUSE_MAX); |
| 2852 } | 2866 } |
| 2853 if (stale_request) { | 2867 if (stale_request) { |
| 2854 UMA_HISTOGRAM_COUNTS( | 2868 UMA_HISTOGRAM_COUNTS( |
| 2855 "HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed.NonTinyImage", | 2869 "HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed.NonTinyImage", |
| 2856 freshness_periods_since_last_used); | 2870 freshness_periods_since_last_used); |
| 2857 } | 2871 } |
| 2858 } | 2872 } |
| 2859 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern.Image", transaction_pattern_, | 2873 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern.Image", cache_entry_status_, |
| 2860 PATTERN_MAX); | 2874 CacheEntryStatus::MAX); |
| 2861 if (validation_request) { | 2875 if (validation_request) { |
| 2862 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause.Image", | 2876 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause.Image", |
| 2863 validation_cause_, VALIDATION_CAUSE_MAX); | 2877 validation_cause_, VALIDATION_CAUSE_MAX); |
| 2864 } | 2878 } |
| 2865 if (stale_request) { | 2879 if (stale_request) { |
| 2866 UMA_HISTOGRAM_COUNTS( | 2880 UMA_HISTOGRAM_COUNTS( |
| 2867 "HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed.Image", | 2881 "HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed.Image", |
| 2868 freshness_periods_since_last_used); | 2882 freshness_periods_since_last_used); |
| 2869 } | 2883 } |
| 2870 } else if (base::EndsWith(mime_type, "javascript", | 2884 } else if (base::EndsWith(mime_type, "javascript", |
| 2871 base::CompareCase::SENSITIVE) || | 2885 base::CompareCase::SENSITIVE) || |
| 2872 base::EndsWith(mime_type, "ecmascript", | 2886 base::EndsWith(mime_type, "ecmascript", |
| 2873 base::CompareCase::SENSITIVE)) { | 2887 base::CompareCase::SENSITIVE)) { |
| 2874 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern.JavaScript", | 2888 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern.JavaScript", |
| 2875 transaction_pattern_, PATTERN_MAX); | 2889 cache_entry_status_, CacheEntryStatus::MAX); |
| 2876 if (validation_request) { | 2890 if (validation_request) { |
| 2877 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause.JavaScript", | 2891 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause.JavaScript", |
| 2878 validation_cause_, VALIDATION_CAUSE_MAX); | 2892 validation_cause_, VALIDATION_CAUSE_MAX); |
| 2879 } | 2893 } |
| 2880 if (stale_request) { | 2894 if (stale_request) { |
| 2881 UMA_HISTOGRAM_COUNTS( | 2895 UMA_HISTOGRAM_COUNTS( |
| 2882 "HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed.JavaScript", | 2896 "HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed.JavaScript", |
| 2883 freshness_periods_since_last_used); | 2897 freshness_periods_since_last_used); |
| 2884 } | 2898 } |
| 2885 } else if (mime_type.find("font") != std::string::npos) { | 2899 } else if (mime_type.find("font") != std::string::npos) { |
| 2886 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern.Font", transaction_pattern_, | 2900 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern.Font", cache_entry_status_, |
| 2887 PATTERN_MAX); | 2901 CacheEntryStatus::MAX); |
| 2888 if (validation_request) { | 2902 if (validation_request) { |
| 2889 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause.Font", | 2903 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause.Font", |
| 2890 validation_cause_, VALIDATION_CAUSE_MAX); | 2904 validation_cause_, VALIDATION_CAUSE_MAX); |
| 2891 } | 2905 } |
| 2892 if (stale_request) { | 2906 if (stale_request) { |
| 2893 UMA_HISTOGRAM_COUNTS( | 2907 UMA_HISTOGRAM_COUNTS( |
| 2894 "HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed.Font", | 2908 "HttpCache.StaleEntry.FreshnessPeriodsSinceLastUsed.Font", |
| 2895 freshness_periods_since_last_used); | 2909 freshness_periods_since_last_used); |
| 2896 } | 2910 } |
| 2897 } | 2911 } |
| 2898 } | 2912 } |
| 2899 | 2913 |
| 2900 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern", transaction_pattern_, | 2914 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern", cache_entry_status_, |
| 2901 PATTERN_MAX); | 2915 CacheEntryStatus::MAX); |
| 2902 | 2916 |
| 2903 if (validation_request) { | 2917 if (validation_request) { |
| 2904 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause", validation_cause_, | 2918 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause", validation_cause_, |
| 2905 VALIDATION_CAUSE_MAX); | 2919 VALIDATION_CAUSE_MAX); |
| 2906 } | 2920 } |
| 2907 | 2921 |
| 2908 if (transaction_pattern_ == PATTERN_ENTRY_CANT_CONDITIONALIZE) { | 2922 if (cache_entry_status_ == CacheEntryStatus::CANT_CONDITIONALIZE) { |
| 2909 UMA_HISTOGRAM_ENUMERATION("HttpCache.CantConditionalizeCause", | 2923 UMA_HISTOGRAM_ENUMERATION("HttpCache.CantConditionalizeCause", |
| 2910 validation_cause_, VALIDATION_CAUSE_MAX); | 2924 validation_cause_, VALIDATION_CAUSE_MAX); |
| 2911 } | 2925 } |
| 2912 | 2926 |
| 2913 if (transaction_pattern_ == PATTERN_NOT_COVERED) | 2927 if (cache_entry_status_ == CacheEntryStatus::OTHER) |
| 2914 return; | 2928 return; |
| 2915 DCHECK(!range_requested_); | 2929 DCHECK(!range_requested_); |
| 2916 DCHECK(!first_cache_access_since_.is_null()); | 2930 DCHECK(!first_cache_access_since_.is_null()); |
| 2917 | 2931 |
| 2918 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; | 2932 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; |
| 2919 | 2933 |
| 2920 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); | 2934 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); |
| 2921 | 2935 |
| 2922 bool did_send_request = !send_request_since_.is_null(); | 2936 bool did_send_request = !send_request_since_.is_null(); |
| 2923 DCHECK( | 2937 DCHECK((did_send_request && |
| 2924 (did_send_request && | 2938 (cache_entry_status_ == CacheEntryStatus::NOT_IN_CACHE || |
| 2925 (transaction_pattern_ == PATTERN_ENTRY_NOT_CACHED || | 2939 cache_entry_status_ == CacheEntryStatus::VALIDATED || |
| 2926 transaction_pattern_ == PATTERN_ENTRY_VALIDATED || | 2940 cache_entry_status_ == CacheEntryStatus::UPDATED || |
| 2927 transaction_pattern_ == PATTERN_ENTRY_UPDATED || | 2941 cache_entry_status_ == CacheEntryStatus::CANT_CONDITIONALIZE)) || |
| 2928 transaction_pattern_ == PATTERN_ENTRY_CANT_CONDITIONALIZE)) || | 2942 (!did_send_request && cache_entry_status_ == CacheEntryStatus::USED)); |
| 2929 (!did_send_request && transaction_pattern_ == PATTERN_ENTRY_USED)); | |
| 2930 | 2943 |
| 2931 if (!did_send_request) { | 2944 if (!did_send_request) { |
| 2932 DCHECK(transaction_pattern_ == PATTERN_ENTRY_USED); | 2945 DCHECK(cache_entry_status_ == CacheEntryStatus::USED); |
| 2933 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.Used", total_time); | 2946 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.Used", total_time); |
| 2934 return; | 2947 return; |
| 2935 } | 2948 } |
| 2936 | 2949 |
| 2937 TimeDelta before_send_time = send_request_since_ - first_cache_access_since_; | 2950 TimeDelta before_send_time = send_request_since_ - first_cache_access_since_; |
| 2938 int64_t before_send_percent = (total_time.ToInternalValue() == 0) | 2951 int64_t before_send_percent = (total_time.ToInternalValue() == 0) |
| 2939 ? 0 | 2952 ? 0 |
| 2940 : before_send_time * 100 / total_time; | 2953 : before_send_time * 100 / total_time; |
| 2941 DCHECK_GE(before_send_percent, 0); | 2954 DCHECK_GE(before_send_percent, 0); |
| 2942 DCHECK_LE(before_send_percent, 100); | 2955 DCHECK_LE(before_send_percent, 100); |
| 2943 base::HistogramBase::Sample before_send_sample = | 2956 base::HistogramBase::Sample before_send_sample = |
| 2944 static_cast<base::HistogramBase::Sample>(before_send_percent); | 2957 static_cast<base::HistogramBase::Sample>(before_send_percent); |
| 2945 | 2958 |
| 2946 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.SentRequest", total_time); | 2959 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.SentRequest", total_time); |
| 2947 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend", before_send_time); | 2960 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend", before_send_time); |
| 2948 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend", before_send_sample); | 2961 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend", before_send_sample); |
| 2949 | 2962 |
| 2950 // TODO(gavinp): Remove or minimize these histograms, particularly the ones | 2963 // TODO(gavinp): Remove or minimize these histograms, particularly the ones |
| 2951 // below this comment after we have received initial data. | 2964 // below this comment after we have received initial data. |
| 2952 switch (transaction_pattern_) { | 2965 switch (cache_entry_status_) { |
| 2953 case PATTERN_ENTRY_CANT_CONDITIONALIZE: { | 2966 case CacheEntryStatus::CANT_CONDITIONALIZE: { |
| 2954 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.CantConditionalize", | 2967 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.CantConditionalize", |
| 2955 before_send_time); | 2968 before_send_time); |
| 2956 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.CantConditionalize", | 2969 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.CantConditionalize", |
| 2957 before_send_sample); | 2970 before_send_sample); |
| 2958 break; | 2971 break; |
| 2959 } | 2972 } |
| 2960 case PATTERN_ENTRY_NOT_CACHED: { | 2973 case CacheEntryStatus::NOT_IN_CACHE: { |
| 2961 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.NotCached", before_send_time); | 2974 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.NotCached", before_send_time); |
| 2962 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.NotCached", | 2975 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.NotCached", |
| 2963 before_send_sample); | 2976 before_send_sample); |
| 2964 break; | 2977 break; |
| 2965 } | 2978 } |
| 2966 case PATTERN_ENTRY_VALIDATED: { | 2979 case CacheEntryStatus::VALIDATED: { |
| 2967 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Validated", before_send_time); | 2980 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Validated", before_send_time); |
| 2968 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Validated", | 2981 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Validated", |
| 2969 before_send_sample); | 2982 before_send_sample); |
| 2970 break; | 2983 break; |
| 2971 } | 2984 } |
| 2972 case PATTERN_ENTRY_UPDATED: { | 2985 case CacheEntryStatus::UPDATED: { |
| 2973 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Updated", before_send_time); | 2986 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Updated", before_send_time); |
| 2974 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Updated", | 2987 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Updated", |
| 2975 before_send_sample); | 2988 before_send_sample); |
| 2976 break; | 2989 break; |
| 2977 } | 2990 } |
| 2978 default: | 2991 default: |
| 2979 NOTREACHED(); | 2992 NOTREACHED(); |
| 2980 } | 2993 } |
| 2981 } | 2994 } |
| 2982 | 2995 |
| 2983 void HttpCache::Transaction::OnIOComplete(int result) { | 2996 void HttpCache::Transaction::OnIOComplete(int result) { |
| 2984 DoLoop(result); | 2997 DoLoop(result); |
| 2985 } | 2998 } |
| 2986 | 2999 |
| 2987 } // namespace net | 3000 } // namespace net |
| OLD | NEW |