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

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

Issue 164304: Http cache: Extend support for byte range requests.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | 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-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2009 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.h" 5 #include "net/http/http_cache.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 10
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 int RestartNetworkRequestWithAuth(const std::wstring& username, 302 int RestartNetworkRequestWithAuth(const std::wstring& username,
303 const std::wstring& password); 303 const std::wstring& password);
304 304
305 // Called to determine if we need to validate the cache entry before using it. 305 // Called to determine if we need to validate the cache entry before using it.
306 bool RequiresValidation(); 306 bool RequiresValidation();
307 307
308 // Called to make the request conditional (to ask the server if the cached 308 // Called to make the request conditional (to ask the server if the cached
309 // copy is valid). Returns true if able to make the request conditional. 309 // copy is valid). Returns true if able to make the request conditional.
310 bool ConditionalizeRequest(); 310 bool ConditionalizeRequest();
311 311
312 // Makes sure that a 206 response is expected. Returns a network error code.
313 bool ValidatePartialResponse(const HttpResponseHeaders* headers);
314
312 // Reads data from the network. 315 // Reads data from the network.
313 int ReadFromNetwork(IOBuffer* data, int data_len); 316 int ReadFromNetwork(IOBuffer* data, int data_len);
314 317
315 // Reads data from the cache entry. 318 // Reads data from the cache entry.
316 int ReadFromEntry(IOBuffer* data, int data_len); 319 int ReadFromEntry(IOBuffer* data, int data_len);
317 320
318 // Called to populate response_ from the cache entry. 321 // Called to populate response_ from the cache entry.
319 int ReadResponseInfoFromEntry(); 322 int ReadResponseInfoFromEntry();
320 323
321 // Called to write data to the cache entry. If the write fails, then the 324 // Called to write data to the cache entry. If the write fails, then the
322 // cache entry is destroyed. Future calls to this function will just do 325 // cache entry is destroyed. Future calls to this function will just do
323 // nothing without side-effect. 326 // nothing without side-effect.
324 void WriteToEntry(int index, int offset, IOBuffer* data, int data_len); 327 void WriteToEntry(int index, int offset, IOBuffer* data, int data_len);
325 328
326 // Called to write response_ to the cache entry. 329 // Called to write response_ to the cache entry.
327 void WriteResponseInfoToEntry(); 330 void WriteResponseInfoToEntry();
328 331
329 // Called to truncate response content in the entry. 332 // Called to truncate response content in the entry.
330 void TruncateResponseData(); 333 void TruncateResponseData();
331 334
332 // Called to append response data to the cache entry. 335 // Called to append response data to the cache entry.
333 void AppendResponseDataToEntry(IOBuffer* data, int data_len); 336 void AppendResponseDataToEntry(IOBuffer* data, int data_len);
334 337
335 // Called when we are done writing to the cache entry. 338 // Called when we are done writing to the cache entry.
336 void DoneWritingToEntry(bool success); 339 void DoneWritingToEntry(bool success);
337 340
341 // Deletes the current partial cache entry (sparse), and optionally removes
342 // the control object (partial_).
343 void DoomPartialEntry(bool delete_object);
344
338 // Performs the needed work after receiving data from the network. 345 // Performs the needed work after receiving data from the network.
339 int DoNetworkReadCompleted(int result); 346 int DoNetworkReadCompleted(int result);
340 347
341 // Performs the needed work after receiving data from the network, when 348 // Performs the needed work after receiving data from the network, when
342 // working with range requests. 349 // working with range requests.
343 int DoPartialNetworkReadCompleted(int result); 350 int DoPartialNetworkReadCompleted(int result);
344 351
345 // Performs the needed work after receiving data from the cache. 352 // Performs the needed work after receiving data from the cache.
346 int DoCacheReadCompleted(int result); 353 int DoCacheReadCompleted(int result);
347 354
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 partial_.reset(new PartialData); 798 partial_.reset(new PartialData);
792 if (partial_->Init(request_->extra_headers, new_extra_headers)) { 799 if (partial_->Init(request_->extra_headers, new_extra_headers)) {
793 // We will be modifying the actual range requested to the server, so 800 // We will be modifying the actual range requested to the server, so
794 // let's remove the header here. 801 // let's remove the header here.
795 custom_request_.reset(new HttpRequestInfo(*request_)); 802 custom_request_.reset(new HttpRequestInfo(*request_));
796 request_ = custom_request_.get(); 803 request_ = custom_request_.get();
797 custom_request_->extra_headers = new_extra_headers; 804 custom_request_->extra_headers = new_extra_headers;
798 } else { 805 } else {
799 // The range is invalid or we cannot handle it properly. 806 // The range is invalid or we cannot handle it properly.
800 effective_load_flags_ |= LOAD_DISABLE_CACHE; 807 effective_load_flags_ |= LOAD_DISABLE_CACHE;
808 partial_.reset(NULL);
801 } 809 }
802 } 810 }
803 811
804 // If there is more than one validation header, we can't treat this request as 812 // If there is more than one validation header, we can't treat this request as
805 // a cache validation, since we don't know for sure which header the server 813 // a cache validation, since we don't know for sure which header the server
806 // will give us a response for (and they could be contradictory). 814 // will give us a response for (and they could be contradictory).
807 if (num_validation_headers > 1) { 815 if (num_validation_headers > 1) {
808 LOG(WARNING) << "Multiple validation headers found."; 816 LOG(WARNING) << "Multiple validation headers found.";
809 effective_load_flags_ |= LOAD_DISABLE_CACHE; 817 effective_load_flags_ |= LOAD_DISABLE_CACHE;
810 } 818 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 return HandleResult(rv); 884 return HandleResult(rv);
877 } 885 }
878 886
879 if (response_.headers->response_code() != 206) 887 if (response_.headers->response_code() != 206)
880 return BeginCacheValidation(); 888 return BeginCacheValidation();
881 889
882 #if !defined(ENABLE_RANGE_SUPPORT) 890 #if !defined(ENABLE_RANGE_SUPPORT)
883 return BeginCacheValidation(); 891 return BeginCacheValidation();
884 #endif 892 #endif
885 893
886 if (!partial_.get()) { 894 bool byte_range_requested = partial_.get() != NULL;
895 if (!byte_range_requested) {
887 // The request is not for a range, but we have stored just ranges. 896 // The request is not for a range, but we have stored just ranges.
888 // TODO(rvargas): Add support for this case. 897 partial_.reset(new PartialData());
889 NOTREACHED(); 898 if (!custom_request_.get()) {
899 custom_request_.reset(new HttpRequestInfo(*request_));
900 request_ = custom_request_.get();
901 DCHECK(custom_request_->extra_headers.empty());
902 }
890 } 903 }
891 904
892 if (!partial_->UpdateFromStoredHeaders(response_.headers)) { 905 if (!partial_->UpdateFromStoredHeaders(response_.headers,
893 // TODO(rvargas): Handle this error. 906 entry_->disk_entry)) {
894 NOTREACHED(); 907 // The stored data cannot be used. Get rid of it and restart this request.
908 DoomPartialEntry(!byte_range_requested);
909 mode_ = WRITE;
910 return AddToEntry();
895 } 911 }
896 912
897 return ContinuePartialCacheValidation(); 913 return ContinuePartialCacheValidation();
898 } 914 }
899 915
900 int HttpCache::Transaction::ContinuePartialCacheValidation() { 916 int HttpCache::Transaction::ContinuePartialCacheValidation() {
901 DCHECK(mode_ == READ_WRITE); 917 DCHECK(mode_ == READ_WRITE);
902 // TODO(rvargas): Avoid re-validation of each cached piece.
903
904 int rv = partial_->PrepareCacheValidation(entry_->disk_entry, 918 int rv = partial_->PrepareCacheValidation(entry_->disk_entry,
905 &custom_request_->extra_headers); 919 &custom_request_->extra_headers);
906 920
907 if (!rv) { 921 if (!rv) {
908 // Don't invoke the callback before telling the cache we're done. 922 // Don't invoke the callback before telling the cache we're done.
909 return rv; 923 return rv;
910 } 924 }
911 925
912 if (rv < 0) { 926 if (rv < 0) {
913 DCHECK(rv != ERR_IO_PENDING); 927 DCHECK(rv != ERR_IO_PENDING);
914 return HandleResult(rv); 928 return HandleResult(rv);
915 } 929 }
916 930
931 if (reading_ && partial_->IsCurrentRangeCached()) {
932 rv = ReadFromEntry(read_buf_, read_buf_len_);
933
934 // We are supposed to hanlde errors here.
935 if (rv < 0 && rv != ERR_IO_PENDING)
936 HandleResult(rv);
937 return rv;
938 }
939
917 return BeginCacheValidation(); 940 return BeginCacheValidation();
918 } 941 }
919 942
920 int HttpCache::Transaction::BeginExternallyConditionalizedRequest() { 943 int HttpCache::Transaction::BeginExternallyConditionalizedRequest() {
921 DCHECK_EQ(UPDATE, mode_); 944 DCHECK_EQ(UPDATE, mode_);
922 DCHECK(external_validation_.initialized()); 945 DCHECK(external_validation_.initialized());
923 946
924 // Read the cached response. 947 // Read the cached response.
925 int rv = ReadResponseInfoFromEntry(); 948 int rv = ReadResponseInfoFromEntry();
926 if (rv != OK) { 949 if (rv != OK) {
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 } else { 1096 } else {
1074 custom_request_->extra_headers.append("If-Modified-Since: "); 1097 custom_request_->extra_headers.append("If-Modified-Since: ");
1075 } 1098 }
1076 custom_request_->extra_headers.append(last_modified_value); 1099 custom_request_->extra_headers.append(last_modified_value);
1077 custom_request_->extra_headers.append("\r\n"); 1100 custom_request_->extra_headers.append("\r\n");
1078 } 1101 }
1079 1102
1080 return true; 1103 return true;
1081 } 1104 }
1082 1105
1106 bool HttpCache::Transaction::ValidatePartialResponse(
1107 const HttpResponseHeaders* headers) {
1108 #ifdef ENABLE_RANGE_SUPPORT
1109 bool partial_content = headers->response_code() == 206;
1110 #else
1111 bool partial_content = false;
1112 #endif
1113
1114 bool failure = false;
1115 if (!partial_content) {
1116 if (!partial_.get())
1117 return false;
1118
1119 // TODO(rvargas): Do we need to consider other results here?.
1120 if (headers->response_code() == 200 || headers->response_code() == 416)
1121 failure = true;
1122
1123 if (!reading_ && failure) {
1124 // We are expecting 206 or 304 because we asked for a range. Given that
1125 // the server is refusing the request we'll remove the sparse entry.
1126 DoomPartialEntry(true);
1127 mode_ = NONE;
1128 return false;
1129 }
1130 }
1131
1132 if (!failure && partial_.get() && partial_->ResponseHeadersOK(headers))
1133 return true;
1134
1135 // We have a problem. We may or may not be reading already (in which case we
1136 // returned the headers), but we'll just pretend that this request is not
1137 // using the cache and see what happens. Most likely this is the first
1138 // response from the server (it's not changing its mind midway, right?).
1139 if (mode_ & WRITE) {
1140 DoneWritingToEntry(mode_ != WRITE);
1141 } else if (mode_ & READ && entry_) {
1142 cache_->DoneReadingFromEntry(entry_, this);
1143 }
1144
1145 entry_ = NULL;
1146 mode_ = NONE;
1147 return false;
1148 }
1149
1083 int HttpCache::Transaction::ReadFromNetwork(IOBuffer* data, int data_len) { 1150 int HttpCache::Transaction::ReadFromNetwork(IOBuffer* data, int data_len) {
1084 int rv = network_trans_->Read(data, data_len, &network_read_callback_); 1151 int rv = network_trans_->Read(data, data_len, &network_read_callback_);
1085 read_buf_ = data; 1152 read_buf_ = data;
1086 read_buf_len_ = data_len; 1153 read_buf_len_ = data_len;
1087 if (rv >= 0) 1154 if (rv >= 0)
1088 rv = DoNetworkReadCompleted(rv); 1155 rv = DoNetworkReadCompleted(rv);
1089 return rv; 1156 return rv;
1090 } 1157 }
1091 1158
1092 int HttpCache::Transaction::ReadFromEntry(IOBuffer* data, int data_len) { 1159 int HttpCache::Transaction::ReadFromEntry(IOBuffer* data, int data_len) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1190 1257
1191 if (cache_->mode() == RECORD) 1258 if (cache_->mode() == RECORD)
1192 DLOG(INFO) << "Recorded: " << request_->method << request_->url 1259 DLOG(INFO) << "Recorded: " << request_->method << request_->url
1193 << " status: " << response_.headers->response_code(); 1260 << " status: " << response_.headers->response_code();
1194 1261
1195 cache_->DoneWritingToEntry(entry_, success); 1262 cache_->DoneWritingToEntry(entry_, success);
1196 entry_ = NULL; 1263 entry_ = NULL;
1197 mode_ = NONE; // switch to 'pass through' mode 1264 mode_ = NONE; // switch to 'pass through' mode
1198 } 1265 }
1199 1266
1267 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) {
1268 cache_->DoneWithEntry(entry_, this);
1269 cache_->DoomEntry(cache_key_);
1270 entry_ = NULL;
1271 if (delete_object)
1272 partial_.reset(NULL);
1273 }
1274
1200 void HttpCache::Transaction::OnNetworkInfoAvailable(int result) { 1275 void HttpCache::Transaction::OnNetworkInfoAvailable(int result) {
1201 DCHECK(result != ERR_IO_PENDING); 1276 DCHECK(result != ERR_IO_PENDING);
1202 1277
1203 if (revoked()) { 1278 if (revoked()) {
1204 HandleResult(ERR_UNEXPECTED); 1279 HandleResult(ERR_UNEXPECTED);
1205 return; 1280 return;
1206 } 1281 }
1207 1282
1208 if (result == OK) { 1283 if (result == OK) {
1209 const HttpResponseInfo* new_response = network_trans_->GetResponseInfo(); 1284 const HttpResponseInfo* new_response = network_trans_->GetResponseInfo();
1210 if (new_response->headers->response_code() == 401 || 1285 if (new_response->headers->response_code() == 401 ||
1211 new_response->headers->response_code() == 407) { 1286 new_response->headers->response_code() == 407) {
1212 auth_response_ = *new_response; 1287 auth_response_ = *new_response;
1213 } else { 1288 } else {
1214 #ifdef ENABLE_RANGE_SUPPORT 1289 bool partial_content = ValidatePartialResponse(new_response->headers);
1215 bool partial_content = new_response->headers->response_code() == 206; 1290
1216 #else
1217 bool partial_content = false;
1218 #endif
1219 // TODO(rvargas): Validate partial_content vs partial_ and mode_
1220 if (partial_content) {
1221 DCHECK(partial_.get());
1222 if (!partial_->ResponseHeadersOK(new_response->headers)) {
1223 // TODO(rvargas): Handle this error.
1224 NOTREACHED();
1225 }
1226 }
1227 // Are we expecting a response to a conditional query? 1291 // Are we expecting a response to a conditional query?
1228 if (mode_ == READ_WRITE || mode_ == UPDATE) { 1292 if (mode_ == READ_WRITE || mode_ == UPDATE) {
1229 if (new_response->headers->response_code() == 304 || partial_content) { 1293 if (new_response->headers->response_code() == 304 || partial_content) {
1230 // Update cached response based on headers in new_response. 1294 // Update cached response based on headers in new_response.
1231 // TODO(wtc): should we update cached certificate 1295 // TODO(wtc): should we update cached certificate
1232 // (response_.ssl_info), too? 1296 // (response_.ssl_info), too?
1233 response_.headers->Update(*new_response->headers); 1297 response_.headers->Update(*new_response->headers);
1234 if (response_.headers->HasHeaderValue("cache-control", "no-store")) { 1298 if (response_.headers->HasHeaderValue("cache-control", "no-store")) {
1235 cache_->DoomEntry(cache_key_); 1299 cache_->DoomEntry(cache_key_);
1236 } else { 1300 } else {
(...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after
1961 static_cast<net::HttpNetworkLayer*>(network_layer_.get()); 2025 static_cast<net::HttpNetworkLayer*>(network_layer_.get());
1962 HttpNetworkSession* session = network->GetSession(); 2026 HttpNetworkSession* session = network->GetSession();
1963 if (session) { 2027 if (session) {
1964 session->connection_pool()->CloseIdleSockets(); 2028 session->connection_pool()->CloseIdleSockets();
1965 } 2029 }
1966 } 2030 }
1967 2031
1968 //----------------------------------------------------------------------------- 2032 //-----------------------------------------------------------------------------
1969 2033
1970 } // namespace net 2034 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/http/http_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698