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" | 7 #include "build/build_config.h" |
8 | 8 |
9 #if defined(OS_POSIX) | 9 #if defined(OS_POSIX) |
10 #include <unistd.h> | 10 #include <unistd.h> |
(...skipping 1555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1566 | 1566 |
1567 int HttpCache::Transaction::BeginCacheValidation() { | 1567 int HttpCache::Transaction::BeginCacheValidation() { |
1568 DCHECK(mode_ == READ_WRITE); | 1568 DCHECK(mode_ == READ_WRITE); |
1569 | 1569 |
1570 bool skip_validation = effective_load_flags_ & LOAD_PREFERRING_CACHE || | 1570 bool skip_validation = effective_load_flags_ & LOAD_PREFERRING_CACHE || |
1571 !RequiresValidation(); | 1571 !RequiresValidation(); |
1572 | 1572 |
1573 if (truncated_) | 1573 if (truncated_) |
1574 skip_validation = !partial_->initial_validation(); | 1574 skip_validation = !partial_->initial_validation(); |
1575 | 1575 |
1576 if ((partial_.get() && !partial_->IsCurrentRangeCached()) || invalid_range_) | 1576 if (partial_.get() && (is_sparse_ || truncated_) && |
| 1577 (!partial_->IsCurrentRangeCached() || invalid_range_)) { |
| 1578 // Force revalidation for sparse or truncated entries. Note that we don't |
| 1579 // want to ignore the regular validation logic just because a byte range was |
| 1580 // part of the request. |
1577 skip_validation = false; | 1581 skip_validation = false; |
| 1582 } |
1578 | 1583 |
1579 if (skip_validation) { | 1584 if (skip_validation) { |
1580 if (partial_.get()) { | 1585 if (partial_.get()) { |
1581 // We are going to return the saved response headers to the caller, so | 1586 if (truncated_ || is_sparse_ || !invalid_range_) { |
1582 // we may need to adjust them first. | 1587 // We are going to return the saved response headers to the caller, so |
1583 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | 1588 // we may need to adjust them first. |
1584 return OK; | 1589 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; |
| 1590 return OK; |
| 1591 } else { |
| 1592 partial_.reset(); |
| 1593 } |
1585 } | 1594 } |
1586 cache_->ConvertWriterToReader(entry_); | 1595 cache_->ConvertWriterToReader(entry_); |
1587 mode_ = READ; | 1596 mode_ = READ; |
1588 | 1597 |
1589 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) | 1598 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) |
1590 next_state_ = STATE_CACHE_READ_METADATA; | 1599 next_state_ = STATE_CACHE_READ_METADATA; |
1591 } else { | 1600 } else { |
1592 // Make the network request conditional, to see if we may reuse our cached | 1601 // Make the network request conditional, to see if we may reuse our cached |
1593 // response. If we cannot do so, then we just resort to a normal fetch. | 1602 // response. If we cannot do so, then we just resort to a normal fetch. |
1594 // Our mode remains READ_WRITE for a conditional request. We'll switch to | 1603 // Our mode remains READ_WRITE for a conditional request. We'll switch to |
1595 // either READ or WRITE mode once we hear back from the server. | 1604 // either READ or WRITE mode once we hear back from the server. |
1596 if (!ConditionalizeRequest()) { | 1605 if (!ConditionalizeRequest()) { |
1597 DCHECK(!partial_.get()); | 1606 if (partial_.get()) |
| 1607 return DoRestartPartialRequest(); |
| 1608 |
1598 DCHECK_NE(206, response_.headers->response_code()); | 1609 DCHECK_NE(206, response_.headers->response_code()); |
1599 mode_ = WRITE; | 1610 mode_ = WRITE; |
1600 } | 1611 } |
1601 next_state_ = STATE_SEND_REQUEST; | 1612 next_state_ = STATE_SEND_REQUEST; |
1602 } | 1613 } |
1603 return OK; | 1614 return OK; |
1604 } | 1615 } |
1605 | 1616 |
1606 int HttpCache::Transaction::BeginPartialCacheValidation() { | 1617 int HttpCache::Transaction::BeginPartialCacheValidation() { |
1607 DCHECK(mode_ == READ_WRITE); | 1618 DCHECK(mode_ == READ_WRITE); |
(...skipping 16 matching lines...) Expand all Loading... |
1624 | 1635 |
1625 return ValidateEntryHeadersAndContinue(); | 1636 return ValidateEntryHeadersAndContinue(); |
1626 } | 1637 } |
1627 | 1638 |
1628 // This should only be called once per request. | 1639 // This should only be called once per request. |
1629 int HttpCache::Transaction::ValidateEntryHeadersAndContinue() { | 1640 int HttpCache::Transaction::ValidateEntryHeadersAndContinue() { |
1630 DCHECK(mode_ == READ_WRITE); | 1641 DCHECK(mode_ == READ_WRITE); |
1631 | 1642 |
1632 if (!partial_->UpdateFromStoredHeaders(response_.headers, entry_->disk_entry, | 1643 if (!partial_->UpdateFromStoredHeaders(response_.headers, entry_->disk_entry, |
1633 truncated_)) { | 1644 truncated_)) { |
1634 // The stored data cannot be used. Get rid of it and restart this request. | 1645 return DoRestartPartialRequest(); |
1635 // We need to also reset the |truncated_| flag as a new entry is created. | |
1636 DoomPartialEntry(!range_requested_); | |
1637 mode_ = WRITE; | |
1638 truncated_ = false; | |
1639 next_state_ = STATE_INIT_ENTRY; | |
1640 return OK; | |
1641 } | 1646 } |
1642 | 1647 |
1643 if (response_.headers->response_code() == 206) | 1648 if (response_.headers->response_code() == 206) |
1644 is_sparse_ = true; | 1649 is_sparse_ = true; |
1645 | 1650 |
1646 if (!partial_->IsRequestedRangeOK()) { | 1651 if (!partial_->IsRequestedRangeOK()) { |
1647 // The stored data is fine, but the request may be invalid. | 1652 // The stored data is fine, but the request may be invalid. |
1648 invalid_range_ = true; | 1653 invalid_range_ = true; |
1649 } | 1654 } |
1650 | 1655 |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1870 | 1875 |
1871 if (response_code == 304 && partial_->ResponseHeadersOK(headers)) | 1876 if (response_code == 304 && partial_->ResponseHeadersOK(headers)) |
1872 return true; | 1877 return true; |
1873 } else { | 1878 } else { |
1874 // We asked for "If-Range: " so a 206 means just another range. | 1879 // We asked for "If-Range: " so a 206 means just another range. |
1875 if (partial_response && partial_->ResponseHeadersOK(headers)) { | 1880 if (partial_response && partial_->ResponseHeadersOK(headers)) { |
1876 handling_206_ = true; | 1881 handling_206_ = true; |
1877 return true; | 1882 return true; |
1878 } | 1883 } |
1879 | 1884 |
1880 if (response_code == 200 && !reading_ && !is_sparse_) { | 1885 if (!reading_ && !is_sparse_ && !partial_response) { |
1881 // The server is sending the whole resource, and we can save it. | 1886 // See if we can ignore the fact that we issued a byte range request. |
1882 DCHECK((truncated_ && !partial_->IsLastRange()) || range_requested_); | 1887 // If the server sends 200, just store it. If it sends an error, redirect |
1883 partial_.reset(); | 1888 // or something else, we may store the response as long as we didn't have |
1884 truncated_ = false; | 1889 // anything already stored. |
1885 return true; | 1890 if (response_code == 200 || |
| 1891 (!truncated_ && response_code != 304 && response_code != 416)) { |
| 1892 // The server is sending something else, and we can save it. |
| 1893 DCHECK((truncated_ && !partial_->IsLastRange()) || range_requested_); |
| 1894 partial_.reset(); |
| 1895 truncated_ = false; |
| 1896 return true; |
| 1897 } |
1886 } | 1898 } |
1887 | 1899 |
1888 // 304 is not expected here, but we'll spare the entry (unless it was | 1900 // 304 is not expected here, but we'll spare the entry (unless it was |
1889 // truncated). | 1901 // truncated). |
1890 if (truncated_) | 1902 if (truncated_) |
1891 failure = true; | 1903 failure = true; |
1892 } | 1904 } |
1893 | 1905 |
1894 if (failure) { | 1906 if (failure) { |
1895 // We cannot truncate this entry, it has to be deleted. | 1907 // We cannot truncate this entry, it has to be deleted. |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2072 | 2084 |
2073 if (result == 0 && mode_ == READ_WRITE) { | 2085 if (result == 0 && mode_ == READ_WRITE) { |
2074 // We need to move on to the next range. | 2086 // We need to move on to the next range. |
2075 next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; | 2087 next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; |
2076 } else if (result < 0) { | 2088 } else if (result < 0) { |
2077 return OnCacheReadError(result, false); | 2089 return OnCacheReadError(result, false); |
2078 } | 2090 } |
2079 return result; | 2091 return result; |
2080 } | 2092 } |
2081 | 2093 |
| 2094 int HttpCache::Transaction::DoRestartPartialRequest() { |
| 2095 // The stored data cannot be used. Get rid of it and restart this request. |
| 2096 // We need to also reset the |truncated_| flag as a new entry is created. |
| 2097 DoomPartialEntry(!range_requested_); |
| 2098 mode_ = WRITE; |
| 2099 truncated_ = false; |
| 2100 next_state_ = STATE_INIT_ENTRY; |
| 2101 return OK; |
| 2102 } |
| 2103 |
2082 // Histogram data from the end of 2010 show the following distribution of | 2104 // Histogram data from the end of 2010 show the following distribution of |
2083 // response headers: | 2105 // response headers: |
2084 // | 2106 // |
2085 // Content-Length............... 87% | 2107 // Content-Length............... 87% |
2086 // Date......................... 98% | 2108 // Date......................... 98% |
2087 // Last-Modified................ 49% | 2109 // Last-Modified................ 49% |
2088 // Etag......................... 19% | 2110 // Etag......................... 19% |
2089 // Accept-Ranges: bytes......... 25% | 2111 // Accept-Ranges: bytes......... 25% |
2090 // Accept-Ranges: none.......... 0.4% | 2112 // Accept-Ranges: none.......... 0.4% |
2091 // Strong Validator............. 50% | 2113 // Strong Validator............. 50% |
(...skipping 14 matching lines...) Expand all Loading... |
2106 return false; | 2128 return false; |
2107 | 2129 |
2108 return true; | 2130 return true; |
2109 } | 2131 } |
2110 | 2132 |
2111 void HttpCache::Transaction::OnIOComplete(int result) { | 2133 void HttpCache::Transaction::OnIOComplete(int result) { |
2112 DoLoop(result); | 2134 DoLoop(result); |
2113 } | 2135 } |
2114 | 2136 |
2115 } // namespace net | 2137 } // namespace net |
OLD | NEW |