| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 // This bit is set if the response info has vary header data. | 60 // This bit is set if the response info has vary header data. |
| 61 RESPONSE_INFO_HAS_VARY_DATA = 1 << 11, | 61 RESPONSE_INFO_HAS_VARY_DATA = 1 << 11, |
| 62 | 62 |
| 63 // TODO(darin): Add other bits to indicate alternate request methods and | 63 // TODO(darin): Add other bits to indicate alternate request methods and |
| 64 // whether or not we are storing a partial document. For now, we don't | 64 // whether or not we are storing a partial document. For now, we don't |
| 65 // support storing those. | 65 // support storing those. |
| 66 }; | 66 }; |
| 67 | 67 |
| 68 //----------------------------------------------------------------------------- | 68 //----------------------------------------------------------------------------- |
| 69 | 69 |
| 70 static int kTransactionTimeoutInMillisecond = 5000; |
| 71 |
| 70 struct HeaderNameAndValue { | 72 struct HeaderNameAndValue { |
| 71 const char* name; | 73 const char* name; |
| 72 const char* value; | 74 const char* value; |
| 73 }; | 75 }; |
| 74 | 76 |
| 75 // If the request includes one of these request headers, then avoid caching | 77 // If the request includes one of these request headers, then avoid caching |
| 76 // to avoid getting confused. | 78 // to avoid getting confused. |
| 77 static const HeaderNameAndValue kPassThroughHeaders[] = { | 79 static const HeaderNameAndValue kPassThroughHeaders[] = { |
| 78 { "range", NULL }, // causes unexpected 206s | 80 { "range", NULL }, // causes unexpected 206s |
| 79 { "if-modified-since", NULL }, // causes unexpected 304s | 81 { "if-modified-since", NULL }, // causes unexpected 304s |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 mode_(NONE), | 149 mode_(NONE), |
| 148 read_offset_(0), | 150 read_offset_(0), |
| 149 effective_load_flags_(0), | 151 effective_load_flags_(0), |
| 150 final_upload_progress_(0), | 152 final_upload_progress_(0), |
| 151 ALLOW_THIS_IN_INITIALIZER_LIST( | 153 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 152 network_info_callback_(this, &Transaction::OnNetworkInfoAvailable)), | 154 network_info_callback_(this, &Transaction::OnNetworkInfoAvailable)), |
| 153 ALLOW_THIS_IN_INITIALIZER_LIST( | 155 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 154 network_read_callback_(this, &Transaction::OnNetworkReadCompleted)), | 156 network_read_callback_(this, &Transaction::OnNetworkReadCompleted)), |
| 155 ALLOW_THIS_IN_INITIALIZER_LIST( | 157 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 156 cache_read_callback_(new CancelableCompletionCallback<Transaction>( | 158 cache_read_callback_(new CancelableCompletionCallback<Transaction>( |
| 157 this, &Transaction::OnCacheReadCompleted))) { | 159 this, &Transaction::OnCacheReadCompleted))), |
| 160 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), |
| 161 is_waiting_for_entry_(false) { |
| 158 } | 162 } |
| 159 | 163 |
| 160 // Clean up the transaction. | 164 // Clean up the transaction. |
| 161 virtual ~Transaction(); | 165 virtual ~Transaction(); |
| 162 | 166 |
| 163 // HttpTransaction methods: | 167 // HttpTransaction methods: |
| 164 virtual int Start(const HttpRequestInfo*, CompletionCallback*); | 168 virtual int Start(const HttpRequestInfo*, CompletionCallback*); |
| 165 virtual int RestartIgnoringLastError(CompletionCallback*); | 169 virtual int RestartIgnoringLastError(CompletionCallback*); |
| 166 virtual int RestartWithAuth(const std::wstring& username, | 170 virtual int RestartWithAuth(const std::wstring& username, |
| 167 const std::wstring& password, | 171 const std::wstring& password, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 | 203 |
| 200 const std::string& key() const { return cache_key_; } | 204 const std::string& key() const { return cache_key_; } |
| 201 | 205 |
| 202 // Associates this transaction with a cache entry. | 206 // Associates this transaction with a cache entry. |
| 203 int AddToEntry(); | 207 int AddToEntry(); |
| 204 | 208 |
| 205 // Called by the HttpCache when the given disk cache entry becomes accessible | 209 // Called by the HttpCache when the given disk cache entry becomes accessible |
| 206 // to the transaction. Returns network error code. | 210 // to the transaction. Returns network error code. |
| 207 int EntryAvailable(ActiveEntry* entry); | 211 int EntryAvailable(ActiveEntry* entry); |
| 208 | 212 |
| 213 // Called by the HttpCache when the given disk cache entry is busy. Sets up |
| 214 // a timeout alarm to MessageLoop. |
| 215 void PendOnEntry(ActiveEntry* entry); |
| 216 |
| 209 private: | 217 private: |
| 210 // This is a helper function used to trigger a completion callback. It may | 218 // This is a helper function used to trigger a completion callback. It may |
| 211 // only be called if callback_ is non-null. | 219 // only be called if callback_ is non-null. |
| 212 void DoCallback(int rv); | 220 void DoCallback(int rv); |
| 213 | 221 |
| 214 // This will trigger the completion callback if appropriate. | 222 // This will trigger the completion callback if appropriate. |
| 215 int HandleResult(int rv); | 223 int HandleResult(int rv); |
| 216 | 224 |
| 217 // Set request_ and fields derived from it. | 225 // Set request_ and fields derived from it. |
| 218 void SetRequest(const HttpRequestInfo* request); | 226 void SetRequest(const HttpRequestInfo* request); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 | 279 |
| 272 // Called to signal completion of the network transaction's Start method: | 280 // Called to signal completion of the network transaction's Start method: |
| 273 void OnNetworkInfoAvailable(int result); | 281 void OnNetworkInfoAvailable(int result); |
| 274 | 282 |
| 275 // Called to signal completion of the network transaction's Read method: | 283 // Called to signal completion of the network transaction's Read method: |
| 276 void OnNetworkReadCompleted(int result); | 284 void OnNetworkReadCompleted(int result); |
| 277 | 285 |
| 278 // Called to signal completion of the cache's ReadData method: | 286 // Called to signal completion of the cache's ReadData method: |
| 279 void OnCacheReadCompleted(int result); | 287 void OnCacheReadCompleted(int result); |
| 280 | 288 |
| 289 // Called to bypass cache when it took too much time to get access to cache. |
| 290 void OnAddToEntryTimeout(ActiveEntry* entry); |
| 291 |
| 281 const HttpRequestInfo* request_; | 292 const HttpRequestInfo* request_; |
| 282 scoped_ptr<HttpRequestInfo> custom_request_; | 293 scoped_ptr<HttpRequestInfo> custom_request_; |
| 283 HttpCache* cache_; | 294 HttpCache* cache_; |
| 284 HttpCache::ActiveEntry* entry_; | 295 HttpCache::ActiveEntry* entry_; |
| 285 scoped_ptr<HttpTransaction> network_trans_; | 296 scoped_ptr<HttpTransaction> network_trans_; |
| 286 CompletionCallback* callback_; // consumer's callback | 297 CompletionCallback* callback_; // consumer's callback |
| 287 HttpResponseInfo response_; | 298 HttpResponseInfo response_; |
| 288 HttpResponseInfo auth_response_; | 299 HttpResponseInfo auth_response_; |
| 289 std::string cache_key_; | 300 std::string cache_key_; |
| 290 Mode mode_; | 301 Mode mode_; |
| 291 scoped_refptr<IOBuffer> read_buf_; | 302 scoped_refptr<IOBuffer> read_buf_; |
| 292 int read_offset_; | 303 int read_offset_; |
| 293 int effective_load_flags_; | 304 int effective_load_flags_; |
| 294 uint64 final_upload_progress_; | 305 uint64 final_upload_progress_; |
| 295 CompletionCallbackImpl<Transaction> network_info_callback_; | 306 CompletionCallbackImpl<Transaction> network_info_callback_; |
| 296 CompletionCallbackImpl<Transaction> network_read_callback_; | 307 CompletionCallbackImpl<Transaction> network_read_callback_; |
| 297 scoped_refptr<CancelableCompletionCallback<Transaction> > | 308 scoped_refptr<CancelableCompletionCallback<Transaction> > |
| 298 cache_read_callback_; | 309 cache_read_callback_; |
| 310 |
| 311 ScopedRunnableMethodFactory<Transaction> task_factory_; |
| 312 bool is_waiting_for_entry_; |
| 299 }; | 313 }; |
| 300 | 314 |
| 301 HttpCache::Transaction::~Transaction() { | 315 HttpCache::Transaction::~Transaction() { |
| 302 if (!revoked()) { | 316 if (!revoked()) { |
| 303 if (entry_) { | 317 if (entry_) { |
| 304 cache_->DoneWithEntry(entry_, this); | 318 cache_->DoneWithEntry(entry_, this); |
| 305 } else { | 319 } else { |
| 306 cache_->RemovePendingTransaction(this); | 320 cache_->RemovePendingTransaction(this); |
| 307 } | 321 } |
| 308 } | 322 } |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 // | 545 // |
| 532 // o if we are a reader for the transaction, then we can start reading the | 546 // o if we are a reader for the transaction, then we can start reading the |
| 533 // cache entry. | 547 // cache entry. |
| 534 // | 548 // |
| 535 // o if we can read or write, then we should check if the cache entry needs | 549 // o if we can read or write, then we should check if the cache entry needs |
| 536 // to be validated and then issue a network request if needed or just read | 550 // to be validated and then issue a network request if needed or just read |
| 537 // from the cache if the cache entry is already valid. | 551 // from the cache if the cache entry is already valid. |
| 538 // | 552 // |
| 539 int rv; | 553 int rv; |
| 540 entry_ = entry; | 554 entry_ = entry; |
| 555 is_waiting_for_entry_ = false; |
| 541 switch (mode_) { | 556 switch (mode_) { |
| 542 case READ: | 557 case READ: |
| 543 rv = BeginCacheRead(); | 558 rv = BeginCacheRead(); |
| 544 break; | 559 break; |
| 545 case WRITE: | 560 case WRITE: |
| 546 rv = BeginNetworkRequest(); | 561 rv = BeginNetworkRequest(); |
| 547 break; | 562 break; |
| 548 case READ_WRITE: | 563 case READ_WRITE: |
| 549 rv = BeginCacheValidation(); | 564 rv = BeginCacheValidation(); |
| 550 break; | 565 break; |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 943 | 958 |
| 944 if (result > 0) { | 959 if (result > 0) { |
| 945 read_offset_ += result; | 960 read_offset_ += result; |
| 946 } else if (result == 0) { // end of file | 961 } else if (result == 0) { // end of file |
| 947 cache_->DoneReadingFromEntry(entry_, this); | 962 cache_->DoneReadingFromEntry(entry_, this); |
| 948 entry_ = NULL; | 963 entry_ = NULL; |
| 949 } | 964 } |
| 950 HandleResult(result); | 965 HandleResult(result); |
| 951 } | 966 } |
| 952 | 967 |
| 968 void HttpCache::Transaction::PendOnEntry(ActiveEntry* entry) { |
| 969 if (is_waiting_for_entry_) { |
| 970 // Don't add timeout alarm more than once. |
| 971 return; |
| 972 } |
| 973 |
| 974 is_waiting_for_entry_ = true; |
| 975 |
| 976 MessageLoop::current()->PostDelayedTask( |
| 977 FROM_HERE, |
| 978 task_factory_.NewRunnableMethod(&Transaction::OnAddToEntryTimeout, entry), |
| 979 kTransactionTimeoutInMillisecond); |
| 980 } |
| 981 |
| 982 void HttpCache::Transaction::OnAddToEntryTimeout(ActiveEntry* entry) { |
| 983 if (!is_waiting_for_entry_) { |
| 984 // Already added to entry. |
| 985 return; |
| 986 } |
| 987 |
| 988 if (mode_ == READ) { |
| 989 // We cannot bypass the cache. |
| 990 return; |
| 991 } |
| 992 |
| 993 // Check that the writer is still busy, and then give up accessing cache. |
| 994 if (entry->writer && |
| 995 entry->writer->GetLoadState() == LOAD_STATE_WAITING_FOR_USER_ACTION) { |
| 996 // There is a writer transaction suspended due to some error. Bypass |
| 997 // cache if we can. |
| 998 entry->pending_queue.remove(this); |
| 999 mode_ = NONE; |
| 1000 is_waiting_for_entry_ = false; |
| 1001 BeginNetworkRequest(); |
| 1002 } |
| 1003 } |
| 1004 |
| 953 //----------------------------------------------------------------------------- | 1005 //----------------------------------------------------------------------------- |
| 954 | 1006 |
| 955 HttpCache::HttpCache(ProxyService* proxy_service, | 1007 HttpCache::HttpCache(ProxyService* proxy_service, |
| 956 const std::wstring& cache_dir, | 1008 const std::wstring& cache_dir, |
| 957 int cache_size) | 1009 int cache_size) |
| 958 : disk_cache_dir_(cache_dir), | 1010 : disk_cache_dir_(cache_dir), |
| 959 mode_(NORMAL), | 1011 mode_(NORMAL), |
| 960 type_(DISK_CACHE), | 1012 type_(DISK_CACHE), |
| 961 network_layer_(HttpNetworkLayer::CreateFactory(proxy_service)), | 1013 network_layer_(HttpNetworkLayer::CreateFactory(proxy_service)), |
| 962 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), | 1014 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1310 // We implement a basic reader/writer lock for the disk cache entry. If | 1362 // We implement a basic reader/writer lock for the disk cache entry. If |
| 1311 // there is already a writer, then everyone has to wait for the writer to | 1363 // there is already a writer, then everyone has to wait for the writer to |
| 1312 // finish before they can access the cache entry. There can be multiple | 1364 // finish before they can access the cache entry. There can be multiple |
| 1313 // readers. | 1365 // readers. |
| 1314 // | 1366 // |
| 1315 // NOTE: If the transaction can only write, then the entry should not be in | 1367 // NOTE: If the transaction can only write, then the entry should not be in |
| 1316 // use (since any existing entry should have already been doomed). | 1368 // use (since any existing entry should have already been doomed). |
| 1317 | 1369 |
| 1318 if (entry->writer || entry->will_process_pending_queue) { | 1370 if (entry->writer || entry->will_process_pending_queue) { |
| 1319 entry->pending_queue.push_back(trans); | 1371 entry->pending_queue.push_back(trans); |
| 1372 trans->PendOnEntry(entry); |
| 1373 |
| 1320 return ERR_IO_PENDING; | 1374 return ERR_IO_PENDING; |
| 1321 } | 1375 } |
| 1322 | 1376 |
| 1323 if (trans->mode() & Transaction::WRITE) { | 1377 if (trans->mode() & Transaction::WRITE) { |
| 1324 // transaction needs exclusive access to the entry | 1378 // transaction needs exclusive access to the entry |
| 1325 if (entry->readers.empty()) { | 1379 if (entry->readers.empty()) { |
| 1326 entry->writer = trans; | 1380 entry->writer = trans; |
| 1327 } else { | 1381 } else { |
| 1328 entry->pending_queue.push_back(trans); | 1382 entry->pending_queue.push_back(trans); |
| 1329 return ERR_IO_PENDING; | 1383 return ERR_IO_PENDING; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1457 return; // have to wait | 1511 return; // have to wait |
| 1458 | 1512 |
| 1459 entry->pending_queue.erase(entry->pending_queue.begin()); | 1513 entry->pending_queue.erase(entry->pending_queue.begin()); |
| 1460 | 1514 |
| 1461 AddTransactionToEntry(entry, next); | 1515 AddTransactionToEntry(entry, next); |
| 1462 } | 1516 } |
| 1463 | 1517 |
| 1464 //----------------------------------------------------------------------------- | 1518 //----------------------------------------------------------------------------- |
| 1465 | 1519 |
| 1466 } // namespace net | 1520 } // namespace net |
| OLD | NEW |