Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(329)

Side by Side Diff: net/http/http_cache_transaction.cc

Issue 1604011: Use HttpRequestHeaders for extra_headers. (Closed)
Patch Set: Address eroman comments. Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/http/http_cache.h ('k') | net/http/http_cache_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2010 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 "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 8
9 #if defined(OS_POSIX) 9 #if defined(OS_POSIX)
10 #include <unistd.h> 10 #include <unistd.h>
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 { NULL, NULL } 71 { NULL, NULL }
72 }; 72 };
73 73
74 // If the request includes one of these request headers, then force our 74 // If the request includes one of these request headers, then force our
75 // cached copy (if any) to be revalidated before reusing it. 75 // cached copy (if any) to be revalidated before reusing it.
76 static const HeaderNameAndValue kForceValidateHeaders[] = { 76 static const HeaderNameAndValue kForceValidateHeaders[] = {
77 { "cache-control", "max-age=0" }, 77 { "cache-control", "max-age=0" },
78 { NULL, NULL } 78 { NULL, NULL }
79 }; 79 };
80 80
81 static bool HeaderMatches(const HttpUtil::HeadersIterator& h, 81 static bool HeaderMatches(const HttpRequestHeaders& headers,
82 const HeaderNameAndValue* search) { 82 const HeaderNameAndValue* search) {
83 for (; search->name; ++search) { 83 for (; search->name; ++search) {
84 if (!LowerCaseEqualsASCII(h.name_begin(), h.name_end(), search->name)) 84 std::string header_value;
85 if (!headers.GetHeader(search->name, &header_value))
85 continue; 86 continue;
86 87
87 if (!search->value) 88 if (!search->value)
88 return true; 89 return true;
89 90
90 HttpUtil::ValuesIterator v(h.values_begin(), h.values_end(), ','); 91 HttpUtil::ValuesIterator v(header_value.begin(), header_value.end(), ',');
91 while (v.GetNext()) { 92 while (v.GetNext()) {
92 if (LowerCaseEqualsASCII(v.value_begin(), v.value_end(), search->value)) 93 if (LowerCaseEqualsASCII(v.value_begin(), v.value_end(), search->value))
93 return true; 94 return true;
94 } 95 }
95 } 96 }
96 return false; 97 return false;
97 } 98 }
98 99
99 //----------------------------------------------------------------------------- 100 //-----------------------------------------------------------------------------
100 101
(...skipping 1077 matching lines...) Expand 10 before | Expand all | Expand 10 after
1178 // 1179 //
1179 static const struct { 1180 static const struct {
1180 const HeaderNameAndValue* search; 1181 const HeaderNameAndValue* search;
1181 int load_flag; 1182 int load_flag;
1182 } kSpecialHeaders[] = { 1183 } kSpecialHeaders[] = {
1183 { kPassThroughHeaders, LOAD_DISABLE_CACHE }, 1184 { kPassThroughHeaders, LOAD_DISABLE_CACHE },
1184 { kForceFetchHeaders, LOAD_BYPASS_CACHE }, 1185 { kForceFetchHeaders, LOAD_BYPASS_CACHE },
1185 { kForceValidateHeaders, LOAD_VALIDATE_CACHE }, 1186 { kForceValidateHeaders, LOAD_VALIDATE_CACHE },
1186 }; 1187 };
1187 1188
1188 std::string new_extra_headers;
1189 bool range_found = false; 1189 bool range_found = false;
1190 bool external_validation_error = false; 1190 bool external_validation_error = false;
1191 1191
1192 // scan request headers to see if we have any that would impact our load flags 1192 if (request_->extra_headers.HasHeader(HttpRequestHeaders::kRange)) {
1193 HttpUtil::HeadersIterator it(request_->extra_headers.begin(), 1193 if (enable_range_support_) {
1194 request_->extra_headers.end(), 1194 range_found = true;
1195 "\r\n");
1196 while (it.GetNext()) {
1197 if (!LowerCaseEqualsASCII(it.name(), "range")) {
1198 new_extra_headers.append(it.name_begin(), it.values_end());
1199 new_extra_headers.append("\r\n");
1200 } else { 1195 } else {
1201 if (enable_range_support_) { 1196 effective_load_flags_ |= LOAD_DISABLE_CACHE;
1202 range_found = true;
1203 } else {
1204 effective_load_flags_ |= LOAD_DISABLE_CACHE;
1205 continue;
1206 }
1207 }
1208 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kSpecialHeaders); ++i) {
1209 if (HeaderMatches(it, kSpecialHeaders[i].search)) {
1210 effective_load_flags_ |= kSpecialHeaders[i].load_flag;
1211 break;
1212 }
1213 }
1214
1215 // Check for conditionalization headers which may correspond with a
1216 // cache validation request.
1217 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kValidationHeaders); ++i) {
1218 const ValidationHeaderInfo& info = kValidationHeaders[i];
1219 if (LowerCaseEqualsASCII(it.name_begin(), it.name_end(),
1220 info.request_header_name)) {
1221 if (!external_validation_.values[i].empty() || it.values().empty())
1222 external_validation_error = true;
1223 external_validation_.values[i] = it.values();
1224 external_validation_.initialized = true;
1225 break;
1226 }
1227 } 1197 }
1228 } 1198 }
1229 1199
1200 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kSpecialHeaders); ++i) {
1201 if (HeaderMatches(request_->extra_headers, kSpecialHeaders[i].search)) {
1202 effective_load_flags_ |= kSpecialHeaders[i].load_flag;
1203 break;
1204 }
1205 }
1206
1207 // Check for conditionalization headers which may correspond with a
1208 // cache validation request.
1209 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kValidationHeaders); ++i) {
1210 const ValidationHeaderInfo& info = kValidationHeaders[i];
1211 std::string validation_value;
1212 if (request_->extra_headers.GetHeader(
1213 info.request_header_name, &validation_value)) {
1214 if (!external_validation_.values[i].empty() ||
1215 validation_value.empty())
1216 external_validation_error = true;
1217 external_validation_.values[i] = validation_value;
1218 external_validation_.initialized = true;
1219 break;
1220 }
1221 }
1222
1230 // We don't support ranges and validation headers. 1223 // We don't support ranges and validation headers.
1231 if (range_found && external_validation_.initialized) { 1224 if (range_found && external_validation_.initialized) {
1232 LOG(WARNING) << "Byte ranges AND validation headers found."; 1225 LOG(WARNING) << "Byte ranges AND validation headers found.";
1233 effective_load_flags_ |= LOAD_DISABLE_CACHE; 1226 effective_load_flags_ |= LOAD_DISABLE_CACHE;
1234 } 1227 }
1235 1228
1236 // If there is more than one validation header, we can't treat this request as 1229 // If there is more than one validation header, we can't treat this request as
1237 // a cache validation, since we don't know for sure which header the server 1230 // a cache validation, since we don't know for sure which header the server
1238 // will give us a response for (and they could be contradictory). 1231 // will give us a response for (and they could be contradictory).
1239 if (external_validation_error) { 1232 if (external_validation_error) {
1240 LOG(WARNING) << "Multiple or malformed validation headers found."; 1233 LOG(WARNING) << "Multiple or malformed validation headers found.";
1241 effective_load_flags_ |= LOAD_DISABLE_CACHE; 1234 effective_load_flags_ |= LOAD_DISABLE_CACHE;
1242 } 1235 }
1243 1236
1244 if (range_found && !(effective_load_flags_ & LOAD_DISABLE_CACHE)) { 1237 if (range_found && !(effective_load_flags_ & LOAD_DISABLE_CACHE)) {
1245 partial_.reset(new PartialData); 1238 partial_.reset(new PartialData);
1246 if (partial_->Init(request_->extra_headers)) { 1239 if (partial_->Init(request_->extra_headers)) {
1247 // We will be modifying the actual range requested to the server, so 1240 // We will be modifying the actual range requested to the server, so
1248 // let's remove the header here. 1241 // let's remove the header here.
1249 custom_request_.reset(new HttpRequestInfo(*request_)); 1242 custom_request_.reset(new HttpRequestInfo(*request_));
1243 custom_request_->extra_headers.RemoveHeader(HttpRequestHeaders::kRange);
1250 request_ = custom_request_.get(); 1244 request_ = custom_request_.get();
1251 custom_request_->extra_headers = new_extra_headers; 1245 partial_->SetHeaders(custom_request_->extra_headers);
1252 partial_->SetHeaders(new_extra_headers);
1253 } else { 1246 } else {
1254 // The range is invalid or we cannot handle it properly. 1247 // The range is invalid or we cannot handle it properly.
1255 LOG(INFO) << "Invalid byte range found."; 1248 LOG(INFO) << "Invalid byte range found.";
1256 effective_load_flags_ |= LOAD_DISABLE_CACHE; 1249 effective_load_flags_ |= LOAD_DISABLE_CACHE;
1257 partial_.reset(NULL); 1250 partial_.reset(NULL);
1258 } 1251 }
1259 } 1252 }
1260 } 1253 }
1261 1254
1262 bool HttpCache::Transaction::ShouldPassThrough() { 1255 bool HttpCache::Transaction::ShouldPassThrough() {
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 // Need to customize the request, so this forces us to allocate :( 1497 // Need to customize the request, so this forces us to allocate :(
1505 custom_request_.reset(new HttpRequestInfo(*request_)); 1498 custom_request_.reset(new HttpRequestInfo(*request_));
1506 request_ = custom_request_.get(); 1499 request_ = custom_request_.get();
1507 } 1500 }
1508 DCHECK(custom_request_.get()); 1501 DCHECK(custom_request_.get());
1509 1502
1510 if (!etag_value.empty()) { 1503 if (!etag_value.empty()) {
1511 if (partial_.get() && !partial_->IsCurrentRangeCached()) { 1504 if (partial_.get() && !partial_->IsCurrentRangeCached()) {
1512 // We don't want to switch to WRITE mode if we don't have this block of a 1505 // We don't want to switch to WRITE mode if we don't have this block of a
1513 // byte-range request because we may have other parts cached. 1506 // byte-range request because we may have other parts cached.
1514 custom_request_->extra_headers.append("If-Range: "); 1507 custom_request_->extra_headers.SetHeader(
1508 HttpRequestHeaders::kIfRange, etag_value);
1515 } else { 1509 } else {
1516 custom_request_->extra_headers.append("If-None-Match: "); 1510 custom_request_->extra_headers.SetHeader(
1511 HttpRequestHeaders::kIfNoneMatch, etag_value);
1517 } 1512 }
1518 custom_request_->extra_headers.append(etag_value);
1519 custom_request_->extra_headers.append("\r\n");
1520 // For byte-range requests, make sure that we use only one way to validate 1513 // For byte-range requests, make sure that we use only one way to validate
1521 // the request. 1514 // the request.
1522 if (partial_.get() && !partial_->IsCurrentRangeCached()) 1515 if (partial_.get() && !partial_->IsCurrentRangeCached())
1523 return true; 1516 return true;
1524 } 1517 }
1525 1518
1526 if (!last_modified_value.empty()) { 1519 if (!last_modified_value.empty()) {
1527 if (partial_.get() && !partial_->IsCurrentRangeCached()) { 1520 if (partial_.get() && !partial_->IsCurrentRangeCached()) {
1528 custom_request_->extra_headers.append("If-Range: "); 1521 custom_request_->extra_headers.SetHeader(
1522 HttpRequestHeaders::kIfRange, last_modified_value);
1529 } else { 1523 } else {
1530 custom_request_->extra_headers.append("If-Modified-Since: "); 1524 custom_request_->extra_headers.SetHeader(
1525 HttpRequestHeaders::kIfModifiedSince, last_modified_value);
1531 } 1526 }
1532 custom_request_->extra_headers.append(last_modified_value);
1533 custom_request_->extra_headers.append("\r\n");
1534 } 1527 }
1535 1528
1536 return true; 1529 return true;
1537 } 1530 }
1538 1531
1539 // We just received some headers from the server. We may have asked for a range, 1532 // We just received some headers from the server. We may have asked for a range,
1540 // in which case partial_ has an object. This could be the first network request 1533 // in which case partial_ has an object. This could be the first network request
1541 // we make to fulfill the original request, or we may be already reading (from 1534 // we make to fulfill the original request, or we may be already reading (from
1542 // the net and / or the cache). If we are not expecting a certain response, we 1535 // the net and / or the cache). If we are not expecting a certain response, we
1543 // just bypass the cache for this request (but again, maybe we are reading), and 1536 // just bypass the cache for this request (but again, maybe we are reading), and
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
1816 // |value| goes from 0 to 63. Actually, the max value should be 47 (0x2f) 1809 // |value| goes from 0 to 63. Actually, the max value should be 47 (0x2f)
1817 // but we'll see. 1810 // but we'll see.
1818 UMA_HISTOGRAM_ENUMERATION("HttpCache.ResponseHeaders", value, 65); 1811 UMA_HISTOGRAM_ENUMERATION("HttpCache.ResponseHeaders", value, 65);
1819 } 1812 }
1820 1813
1821 void HttpCache::Transaction::OnIOComplete(int result) { 1814 void HttpCache::Transaction::OnIOComplete(int result) {
1822 DoLoop(result); 1815 DoLoop(result);
1823 } 1816 }
1824 1817
1825 } // namespace net 1818 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_cache.h ('k') | net/http/http_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698