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 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 259 reading_(false), | 259 reading_(false), |
| 260 invalid_range_(false), | 260 invalid_range_(false), |
| 261 truncated_(false), | 261 truncated_(false), |
| 262 is_sparse_(false), | 262 is_sparse_(false), |
| 263 range_requested_(false), | 263 range_requested_(false), |
| 264 handling_206_(false), | 264 handling_206_(false), |
| 265 cache_pending_(false), | 265 cache_pending_(false), |
| 266 done_reading_(false), | 266 done_reading_(false), |
| 267 vary_mismatch_(false), | 267 vary_mismatch_(false), |
| 268 couldnt_conditionalize_request_(false), | 268 couldnt_conditionalize_request_(false), |
| 269 stopped_caching_(false), | |
| 269 bypass_lock_for_test_(false), | 270 bypass_lock_for_test_(false), |
| 270 fail_conditionalization_for_test_(false), | 271 fail_conditionalization_for_test_(false), |
| 272 read_buf_len_(0), | |
| 271 io_buf_len_(0), | 273 io_buf_len_(0), |
| 272 read_offset_(0), | 274 read_offset_(0), |
| 273 effective_load_flags_(0), | 275 effective_load_flags_(0), |
| 274 write_len_(0), | 276 write_len_(0), |
| 275 transaction_pattern_(PATTERN_UNDEFINED), | 277 transaction_pattern_(PATTERN_UNDEFINED), |
| 276 total_received_bytes_(0), | 278 total_received_bytes_(0), |
| 277 websocket_handshake_stream_base_create_helper_(NULL), | 279 websocket_handshake_stream_base_create_helper_(NULL), |
| 278 weak_factory_(this) { | 280 weak_factory_(this) { |
| 279 static_assert(HttpCache::Transaction::kNumValidationHeaders == | 281 static_assert(HttpCache::Transaction::kNumValidationHeaders == |
| 280 arraysize(kValidationHeaders), | 282 arraysize(kValidationHeaders), |
| 281 "invalid number of validation headers"); | 283 "invalid number of validation headers"); |
| 282 | 284 |
| 283 io_callback_ = base::Bind(&Transaction::OnIOComplete, | 285 io_callback_ = base::Bind(&Transaction::OnIOComplete, |
| 284 weak_factory_.GetWeakPtr()); | 286 weak_factory_.GetWeakPtr()); |
| 285 } | 287 } |
| 286 | 288 |
| 287 HttpCache::Transaction::~Transaction() { | 289 HttpCache::Transaction::~Transaction() { |
| 288 // We may have to issue another IO, but we should never invoke the callback_ | 290 // We may have to issue another IO, but we should never invoke the callback_ |
| 289 // after this point. | 291 // after this point. |
| 290 callback_.Reset(); | 292 callback_.Reset(); |
| 291 | 293 |
| 292 if (cache_) { | 294 RecordHistograms(); |
| 293 if (entry_) { | |
| 294 bool cancel_request = reading_ && response_.headers.get(); | |
| 295 if (cancel_request) { | |
| 296 if (partial_) { | |
| 297 entry_->disk_entry->CancelSparseIO(); | |
| 298 } else { | |
| 299 cancel_request &= (response_.headers->response_code() == 200); | |
| 300 } | |
| 301 } | |
| 302 | 295 |
| 303 cache_->DoneWithEntry(entry_, this, cancel_request); | 296 if (!cache_) |
| 304 } else if (cache_pending_) { | 297 return; |
| 298 | |
| 299 if (!entry_) { | |
| 300 if (cache_pending_) | |
| 305 cache_->RemovePendingTransaction(this); | 301 cache_->RemovePendingTransaction(this); |
| 306 } | 302 return; |
| 307 } | 303 } |
| 304 | |
| 305 bool cancel_request = reading_ && response_.headers.get() && | |
| 306 (response_.headers->response_code() == 200 || partial_); | |
| 307 if (cancel_request) { | |
| 308 if (partial_) | |
| 309 entry_->disk_entry->CancelSparseIO(); | |
| 310 | |
| 311 AbandonCacheEntry(CompletionCallback()); | |
| 312 return; | |
| 313 } | |
| 314 | |
| 315 ReleaseCacheEntry(EntryState::DOOMED); | |
| 308 } | 316 } |
| 309 | 317 |
| 310 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len, | 318 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len, |
| 311 const CompletionCallback& callback) { | 319 const CompletionCallback& callback) { |
| 312 DCHECK(buf); | 320 DCHECK(buf); |
| 313 DCHECK_GT(buf_len, 0); | 321 DCHECK_GT(buf_len, 0); |
| 314 DCHECK(!callback.is_null()); | 322 DCHECK(!callback.is_null()); |
| 315 if (!cache_.get() || !entry_) | 323 if (!cache_.get() || !entry_) |
| 316 return ERR_UNEXPECTED; | 324 return ERR_UNEXPECTED; |
| 317 | 325 |
| 318 // We don't need to track this operation for anything. | 326 // We don't need to track this operation for anything. |
| 319 // It could be possible to check if there is something already written and | 327 // It could be possible to check if there is something already written and |
| 320 // avoid writing again (it should be the same, right?), but let's allow the | 328 // avoid writing again (it should be the same, right?), but let's allow the |
| 321 // caller to "update" the contents with something new. | 329 // caller to "update" the contents with something new. |
| 322 return entry_->disk_entry->WriteData(kMetadataIndex, 0, buf, buf_len, | 330 return entry_->disk_entry->WriteData(kMetadataIndex, 0, buf, buf_len, |
| 323 callback, true); | 331 callback, true); |
| 324 } | 332 } |
| 325 | 333 |
| 326 bool HttpCache::Transaction::AddTruncatedFlag() { | |
| 327 DCHECK(mode_ & WRITE || mode_ == NONE); | |
| 328 | |
| 329 // Don't set the flag for sparse entries. | |
| 330 if (partial_ && !truncated_) | |
| 331 return true; | |
| 332 | |
| 333 if (!CanResume(true)) | |
| 334 return false; | |
| 335 | |
| 336 // We may have received the whole resource already. | |
| 337 if (done_reading_) | |
| 338 return true; | |
| 339 | |
| 340 truncated_ = true; | |
| 341 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE; | |
| 342 DoLoop(OK); | |
| 343 return true; | |
| 344 } | |
| 345 | |
| 346 LoadState HttpCache::Transaction::GetWriterLoadState() const { | 334 LoadState HttpCache::Transaction::GetWriterLoadState() const { |
| 347 if (network_trans_.get()) | 335 if (network_trans_.get()) |
| 348 return network_trans_->GetLoadState(); | 336 return network_trans_->GetLoadState(); |
| 349 if (entry_ || !request_) | 337 if (entry_ || !request_) |
| 350 return LOAD_STATE_IDLE; | 338 return LOAD_STATE_IDLE; |
| 351 return LOAD_STATE_WAITING_FOR_CACHE; | 339 return LOAD_STATE_WAITING_FOR_CACHE; |
| 352 } | 340 } |
| 353 | 341 |
| 354 const BoundNetLog& HttpCache::Transaction::net_log() const { | 342 const BoundNetLog& HttpCache::Transaction::net_log() const { |
| 355 return net_log_; | 343 return net_log_; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 450 return false; | 438 return false; |
| 451 return network_trans_->IsReadyToRestartForAuth(); | 439 return network_trans_->IsReadyToRestartForAuth(); |
| 452 } | 440 } |
| 453 | 441 |
| 454 int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len, | 442 int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len, |
| 455 const CompletionCallback& callback) { | 443 const CompletionCallback& callback) { |
| 456 DCHECK_EQ(next_state_, STATE_NONE); | 444 DCHECK_EQ(next_state_, STATE_NONE); |
| 457 DCHECK(buf); | 445 DCHECK(buf); |
| 458 DCHECK_GT(buf_len, 0); | 446 DCHECK_GT(buf_len, 0); |
| 459 DCHECK(!callback.is_null()); | 447 DCHECK(!callback.is_null()); |
| 460 | |
| 461 DCHECK(callback_.is_null()); | 448 DCHECK(callback_.is_null()); |
| 462 | 449 |
| 463 if (!cache_.get()) | 450 if (!cache_.get()) |
| 464 return ERR_UNEXPECTED; | 451 return ERR_UNEXPECTED; |
| 465 | 452 |
| 466 // If we have an intermediate auth response at this point, then it means the | 453 // If we have an intermediate auth response at this point, then it means the |
| 467 // user wishes to read the network response (the error page). If there is a | 454 // user wishes to read the network response (the error page). If there is a |
| 468 // previous response in the cache then we should leave it intact. | 455 // previous response in the cache then we should leave it intact. |
| 469 if (auth_response_.headers.get() && mode_ != NONE) { | 456 if (auth_response_.headers.get() && mode_ != NONE) { |
| 470 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 457 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
| 471 DCHECK(mode_ & WRITE); | 458 DCHECK(mode_ & WRITE); |
| 472 DoneWritingToEntry(mode_ == READ_WRITE); | 459 ReleaseCacheEntry(mode_ == READ_WRITE ? EntryState::SUCCEEDED |
| 473 mode_ = NONE; | 460 : EntryState::DOOMED); |
| 474 } | 461 } |
| 475 | 462 |
| 476 reading_ = true; | 463 reading_ = true; |
| 477 read_buf_ = buf; | 464 read_buf_ = buf; |
| 478 io_buf_len_ = buf_len; | 465 read_buf_len_ = buf_len; |
|
rvargas (doing something else)
2015/09/11 23:56:18
Why do we need another member? (vs io_buf_len_)
asanka
2015/09/17 21:59:41
When we are switching to a single network request,
rvargas (doing something else)
2015/09/21 22:05:59
Acknowledged.
| |
| 479 if (network_trans_) { | 466 if (stopped_caching_ && (mode_ & WRITE) && entry_) { |
|
rvargas (doing something else)
2015/09/11 23:56:18
Shouldn't this look closer to line 1483? (aka, wha
| |
| 467 next_state_ = STATE_SWITCH_TO_NETWORK; | |
| 468 } else if (network_trans_) { | |
| 480 DCHECK(mode_ == WRITE || mode_ == NONE || | 469 DCHECK(mode_ == WRITE || mode_ == NONE || |
| 481 (mode_ == READ_WRITE && partial_)); | 470 (mode_ == READ_WRITE && partial_)); |
| 482 next_state_ = STATE_NETWORK_READ; | 471 next_state_ = STATE_NETWORK_READ; |
| 483 } else { | 472 } else { |
| 484 DCHECK(mode_ == READ || (mode_ == READ_WRITE && partial_)); | 473 DCHECK(mode_ == READ || (mode_ == READ_WRITE && partial_)); |
| 485 next_state_ = STATE_CACHE_READ_DATA; | 474 next_state_ = STATE_CACHE_READ_DATA; |
| 486 } | 475 } |
| 487 | 476 |
| 488 int rv = DoLoop(OK); | 477 int rv = DoLoop(OK); |
| 489 | 478 |
| 490 if (rv == ERR_IO_PENDING) { | 479 if (rv == ERR_IO_PENDING) { |
| 491 DCHECK(callback_.is_null()); | 480 DCHECK(callback_.is_null()); |
| 492 callback_ = callback; | 481 callback_ = callback; |
| 493 } | 482 } |
| 494 return rv; | 483 return rv; |
| 495 } | 484 } |
| 496 | 485 |
| 497 void HttpCache::Transaction::StopCaching() { | 486 void HttpCache::Transaction::StopCaching() { |
| 498 // We really don't know where we are now. Hopefully there is no operation in | 487 DCHECK(callback_.is_null()); |
| 499 // progress, but nothing really prevents this method to be called after we | 488 stopped_caching_ = true; |
| 500 // returned ERR_IO_PENDING. We cannot attempt to truncate the entry at this | |
| 501 // point because we need the state machine for that (and even if we are really | |
| 502 // free, that would be an asynchronous operation). In other words, keep the | |
| 503 // entry how it is (it will be marked as truncated at destruction), and let | |
| 504 // the next piece of code that executes know that we are now reading directly | |
| 505 // from the net. | |
| 506 // TODO(mmenke): This doesn't release the lock on the cache entry, so a | |
| 507 // future request for the resource will be blocked on this one. | |
| 508 // Fix this. | |
| 509 if (cache_.get() && entry_ && (mode_ & WRITE) && network_trans_.get() && | |
| 510 !is_sparse_ && !range_requested_) { | |
| 511 mode_ = NONE; | |
| 512 } | |
| 513 } | 489 } |
| 514 | 490 |
| 515 bool HttpCache::Transaction::GetFullRequestHeaders( | 491 bool HttpCache::Transaction::GetFullRequestHeaders( |
| 516 HttpRequestHeaders* headers) const { | 492 HttpRequestHeaders* headers) const { |
| 517 if (network_trans_) | 493 if (network_trans_) |
| 518 return network_trans_->GetFullRequestHeaders(headers); | 494 return network_trans_->GetFullRequestHeaders(headers); |
| 519 | 495 |
| 520 // TODO(ttuttle): Read headers from cache. | 496 // TODO(ttuttle): Read headers from cache. |
| 521 return false; | 497 return false; |
| 522 } | 498 } |
| 523 | 499 |
| 524 int64 HttpCache::Transaction::GetTotalReceivedBytes() const { | 500 int64 HttpCache::Transaction::GetTotalReceivedBytes() const { |
| 525 int64 total_received_bytes = total_received_bytes_; | 501 int64 total_received_bytes = total_received_bytes_; |
| 526 if (network_trans_) | 502 if (network_trans_) |
| 527 total_received_bytes += network_trans_->GetTotalReceivedBytes(); | 503 total_received_bytes += network_trans_->GetTotalReceivedBytes(); |
| 528 return total_received_bytes; | 504 return total_received_bytes; |
| 529 } | 505 } |
| 530 | 506 |
| 531 void HttpCache::Transaction::DoneReading() { | 507 void HttpCache::Transaction::DoneReading() { |
| 532 if (cache_.get() && entry_) { | 508 DCHECK_NE(mode_, UPDATE); |
| 533 DCHECK_NE(mode_, UPDATE); | 509 if (!cache_ || !entry_) |
| 534 if (mode_ & WRITE) { | 510 return; |
| 535 DoneWritingToEntry(true); | 511 done_reading_ = true; |
| 536 } else if (mode_ & READ) { | 512 ReleaseCacheEntry(EntryState::SUCCEEDED); |
| 537 // It is necessary to check mode_ & READ because it is possible | |
| 538 // for mode_ to be NONE and entry_ non-NULL with a write entry | |
| 539 // if StopCaching was called. | |
| 540 cache_->DoneReadingFromEntry(entry_, this); | |
| 541 entry_ = NULL; | |
| 542 } | |
| 543 } | |
| 544 } | 513 } |
| 545 | 514 |
| 546 const HttpResponseInfo* HttpCache::Transaction::GetResponseInfo() const { | 515 const HttpResponseInfo* HttpCache::Transaction::GetResponseInfo() const { |
| 547 // Null headers means we encountered an error or haven't a response yet | 516 // Null headers means we encountered an error or haven't a response yet |
| 548 if (auth_response_.headers.get()) | 517 if (auth_response_.headers.get()) |
| 549 return &auth_response_; | 518 return &auth_response_; |
| 550 return &response_; | 519 return &response_; |
| 551 } | 520 } |
| 552 | 521 |
| 553 LoadState HttpCache::Transaction::GetLoadState() const { | 522 LoadState HttpCache::Transaction::GetLoadState() const { |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 895 DCHECK_EQ(OK, rv); | 864 DCHECK_EQ(OK, rv); |
| 896 rv = DoPartialHeadersReceived(); | 865 rv = DoPartialHeadersReceived(); |
| 897 break; | 866 break; |
| 898 case STATE_CACHE_READ_METADATA: | 867 case STATE_CACHE_READ_METADATA: |
| 899 DCHECK_EQ(OK, rv); | 868 DCHECK_EQ(OK, rv); |
| 900 rv = DoCacheReadMetadata(); | 869 rv = DoCacheReadMetadata(); |
| 901 break; | 870 break; |
| 902 case STATE_CACHE_READ_METADATA_COMPLETE: | 871 case STATE_CACHE_READ_METADATA_COMPLETE: |
| 903 rv = DoCacheReadMetadataComplete(rv); | 872 rv = DoCacheReadMetadataComplete(rv); |
| 904 break; | 873 break; |
| 874 case STATE_SWITCH_TO_NETWORK: | |
| 875 rv = DoSwitchToNetwork(); | |
| 876 break; | |
| 905 case STATE_NETWORK_READ: | 877 case STATE_NETWORK_READ: |
| 906 DCHECK_EQ(OK, rv); | 878 DCHECK_EQ(OK, rv); |
| 907 rv = DoNetworkRead(); | 879 rv = DoNetworkRead(); |
| 908 break; | 880 break; |
| 909 case STATE_NETWORK_READ_COMPLETE: | 881 case STATE_NETWORK_READ_COMPLETE: |
| 910 rv = DoNetworkReadComplete(rv); | 882 rv = DoNetworkReadComplete(rv); |
| 911 break; | 883 break; |
| 912 case STATE_CACHE_READ_DATA: | 884 case STATE_CACHE_READ_DATA: |
| 913 DCHECK_EQ(OK, rv); | 885 DCHECK_EQ(OK, rv); |
| 914 rv = DoCacheReadData(); | 886 rv = DoCacheReadData(); |
| 915 break; | 887 break; |
| 916 case STATE_CACHE_READ_DATA_COMPLETE: | 888 case STATE_CACHE_READ_DATA_COMPLETE: |
| 917 rv = DoCacheReadDataComplete(rv); | 889 rv = DoCacheReadDataComplete(rv); |
| 918 break; | 890 break; |
| 919 case STATE_CACHE_WRITE_DATA: | 891 case STATE_CACHE_WRITE_DATA: |
| 920 rv = DoCacheWriteData(rv); | 892 rv = DoCacheWriteData(rv); |
| 921 break; | 893 break; |
| 922 case STATE_CACHE_WRITE_DATA_COMPLETE: | 894 case STATE_CACHE_WRITE_DATA_COMPLETE: |
| 923 rv = DoCacheWriteDataComplete(rv); | 895 rv = DoCacheWriteDataComplete(rv); |
| 924 break; | 896 break; |
| 925 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE: | |
| 926 DCHECK_EQ(OK, rv); | |
| 927 rv = DoCacheWriteTruncatedResponse(); | |
| 928 break; | |
| 929 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE: | |
| 930 rv = DoCacheWriteTruncatedResponseComplete(rv); | |
| 931 break; | |
| 932 default: | 897 default: |
| 933 NOTREACHED() << "bad state"; | 898 NOTREACHED() << "bad state"; |
| 934 rv = ERR_FAILED; | 899 rv = ERR_FAILED; |
| 935 break; | 900 break; |
| 936 } | 901 } |
| 937 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 902 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
| 938 | 903 |
| 939 if (rv != ERR_IO_PENDING && !callback_.is_null()) { | 904 if (rv != ERR_IO_PENDING && !callback_.is_null()) { |
| 940 read_buf_ = NULL; // Release the buffer before invoking the callback. | 905 read_buf_ = nullptr; // Release the buffer before invoking the callback. |
| 906 read_buf_len_ = 0; | |
| 941 base::ResetAndReturn(&callback_).Run(rv); | 907 base::ResetAndReturn(&callback_).Run(rv); |
| 942 } | 908 } |
| 943 | 909 |
| 944 return rv; | 910 return rv; |
| 945 } | 911 } |
| 946 | 912 |
| 947 int HttpCache::Transaction::DoGetBackend() { | 913 int HttpCache::Transaction::DoGetBackend() { |
| 948 cache_pending_ = true; | 914 cache_pending_ = true; |
| 949 next_state_ = STATE_GET_BACKEND_COMPLETE; | 915 next_state_ = STATE_GET_BACKEND_COMPLETE; |
| 950 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_GET_BACKEND); | 916 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_GET_BACKEND); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 993 // the cache. If we receive 200, it doesn't matter if there was a validation | 959 // the cache. If we receive 200, it doesn't matter if there was a validation |
| 994 // header or not. | 960 // header or not. |
| 995 if (request_->method == "HEAD" && mode_ == WRITE) | 961 if (request_->method == "HEAD" && mode_ == WRITE) |
| 996 mode_ = NONE; | 962 mode_ = NONE; |
| 997 | 963 |
| 998 // If must use cache, then we must fail. This can happen for back/forward | 964 // If must use cache, then we must fail. This can happen for back/forward |
| 999 // navigations to a page generated via a form post. | 965 // navigations to a page generated via a form post. |
| 1000 if (!(mode_ & READ) && effective_load_flags_ & LOAD_ONLY_FROM_CACHE) | 966 if (!(mode_ & READ) && effective_load_flags_ & LOAD_ONLY_FROM_CACHE) |
| 1001 return ERR_CACHE_MISS; | 967 return ERR_CACHE_MISS; |
| 1002 | 968 |
| 969 // The client may have already decided not to write anything to the cache. | |
| 970 if (stopped_caching_ && mode_ != NONE) { | |
|
rvargas (doing something else)
2015/09/11 23:56:17
Is this for restart? We should not allow StopCachi
| |
| 971 // Avoid touching the cache at all in this case unless the requestor has | |
| 972 // also requested that we prefer the cache entry. The transaction interprets | |
| 973 // the latter case as "Don't write any more response data to the cache." | |
| 974 if (mode_ != READ && !(effective_load_flags_ & LOAD_PREFERRING_CACHE)) | |
| 975 mode_ = NONE; | |
| 976 | |
| 977 // If the WRITE bit is still set, then the transaction has to roll forward | |
| 978 // until the first Read() to decide what to do because it needs to examine | |
| 979 // the cache entry. We could conceivably deal with StopCaching() prior to | |
| 980 // the first Read(), but we are going to wait till the first Read() since | |
| 981 // that allows us to also deal with the case where the requestor calls | |
| 982 // StopCaching() after Start() or Read(). | |
| 983 stopped_caching_ = !!(mode_ & WRITE); | |
|
rvargas (doing something else)
2015/09/11 23:56:18
nit: I hate !!x; How about x != 0 (if we need to k
| |
| 984 DCHECK_IMPLIES(stopped_caching_, | |
| 985 effective_load_flags_ & LOAD_PREFERRING_CACHE); | |
| 986 } | |
| 987 | |
| 1003 if (mode_ == NONE) { | 988 if (mode_ == NONE) { |
| 1004 if (partial_) { | 989 if (partial_) { |
| 1005 partial_->RestoreHeaders(&custom_request_->extra_headers); | 990 partial_->RestoreHeaders(&custom_request_->extra_headers); |
| 1006 partial_.reset(); | 991 partial_.reset(); |
| 1007 } | 992 } |
| 1008 next_state_ = STATE_SEND_REQUEST; | 993 next_state_ = STATE_SEND_REQUEST; |
| 1009 } else { | 994 } else { |
| 1010 next_state_ = STATE_INIT_ENTRY; | 995 next_state_ = STATE_INIT_ENTRY; |
| 1011 } | 996 } |
| 1012 | 997 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1044 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is | 1029 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is |
| 1045 // OK, otherwise the cache will end up with an active entry without any | 1030 // OK, otherwise the cache will end up with an active entry without any |
| 1046 // transaction attached. | 1031 // transaction attached. |
| 1047 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY, result); | 1032 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY, result); |
| 1048 cache_pending_ = false; | 1033 cache_pending_ = false; |
| 1049 if (result == OK) { | 1034 if (result == OK) { |
| 1050 next_state_ = STATE_ADD_TO_ENTRY; | 1035 next_state_ = STATE_ADD_TO_ENTRY; |
| 1051 return OK; | 1036 return OK; |
| 1052 } | 1037 } |
| 1053 | 1038 |
| 1039 // No need to create a cache entry if the transaction has already decided not | |
| 1040 // to write to it. | |
| 1041 if (stopped_caching_) { | |
|
rvargas (doing something else)
2015/09/11 23:56:18
same thing about start.
| |
| 1042 // stopped_caching_ should've been unset in DoGetBackendComplete() if mode_ | |
| 1043 // didn't have the WRITE bit set. | |
| 1044 DCHECK(mode_ & WRITE); | |
| 1045 mode_ = NONE; | |
| 1046 next_state_ = STATE_SEND_REQUEST; | |
| 1047 return OK; | |
| 1048 } | |
| 1049 | |
| 1054 if (result == ERR_CACHE_RACE) { | 1050 if (result == ERR_CACHE_RACE) { |
| 1055 next_state_ = STATE_INIT_ENTRY; | 1051 next_state_ = STATE_INIT_ENTRY; |
| 1056 return OK; | 1052 return OK; |
| 1057 } | 1053 } |
| 1058 | 1054 |
| 1059 if (request_->method == "PUT" || request_->method == "DELETE" || | 1055 if (request_->method == "PUT" || request_->method == "DELETE" || |
| 1060 (request_->method == "HEAD" && mode_ == READ_WRITE)) { | 1056 (request_->method == "HEAD" && mode_ == READ_WRITE)) { |
| 1061 DCHECK(mode_ == READ_WRITE || mode_ == WRITE || request_->method == "HEAD"); | 1057 DCHECK(mode_ == READ_WRITE || mode_ == WRITE || request_->method == "HEAD"); |
| 1062 mode_ = NONE; | 1058 mode_ = NONE; |
| 1063 next_state_ = STATE_SEND_REQUEST; | 1059 next_state_ = STATE_SEND_REQUEST; |
| 1064 return OK; | 1060 return OK; |
| 1065 } | 1061 } |
| 1066 | 1062 |
| 1067 if (mode_ == READ_WRITE) { | 1063 if (mode_ == READ_WRITE) { |
| 1068 mode_ = WRITE; | 1064 mode_ = WRITE; |
| 1069 next_state_ = STATE_CREATE_ENTRY; | 1065 next_state_ = STATE_CREATE_ENTRY; |
| 1070 return OK; | 1066 return OK; |
| 1071 } | 1067 } |
| 1068 | |
| 1072 if (mode_ == UPDATE) { | 1069 if (mode_ == UPDATE) { |
| 1073 // There is no cache entry to update; proceed without caching. | 1070 // There is no cache entry to update; proceed without caching. |
| 1074 mode_ = NONE; | 1071 mode_ = NONE; |
| 1075 next_state_ = STATE_SEND_REQUEST; | 1072 next_state_ = STATE_SEND_REQUEST; |
| 1076 return OK; | 1073 return OK; |
| 1077 } | 1074 } |
| 1078 | 1075 |
| 1079 // The entry does not exist, and we are not permitted to create a new entry, | 1076 // The entry does not exist, and we are not permitted to create a new entry, |
| 1080 // so we must fail. | 1077 // so we must fail. |
| 1081 return ERR_CACHE_MISS; | 1078 return ERR_CACHE_MISS; |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1279 // TODO(jkarlin): If DoUpdateCachedResponse is also called for this | 1276 // TODO(jkarlin): If DoUpdateCachedResponse is also called for this |
| 1280 // transaction then metadata will be written to cache twice. If prefetching | 1277 // transaction then metadata will be written to cache twice. If prefetching |
| 1281 // becomes more common, consider combining the writes. | 1278 // becomes more common, consider combining the writes. |
| 1282 | 1279 |
| 1283 // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed. | 1280 // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 1284 tracked_objects::ScopedTracker tracking_profile( | 1281 tracked_objects::ScopedTracker tracking_profile( |
| 1285 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1282 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1286 "422516 HttpCache::Transaction::DoCacheToggleUnusedSincePrefetch")); | 1283 "422516 HttpCache::Transaction::DoCacheToggleUnusedSincePrefetch")); |
| 1287 | 1284 |
| 1288 next_state_ = STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE; | 1285 next_state_ = STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE; |
| 1289 return WriteResponseInfoToEntry(false); | 1286 return WriteResponseInfoToEntry(false, io_callback_); |
| 1290 } | 1287 } |
| 1291 | 1288 |
| 1292 int HttpCache::Transaction::DoCacheToggleUnusedSincePrefetchComplete( | 1289 int HttpCache::Transaction::DoCacheToggleUnusedSincePrefetchComplete( |
| 1293 int result) { | 1290 int result) { |
| 1294 // Restore the original value for this transaction. | 1291 // Restore the original value for this transaction. |
| 1295 response_.unused_since_prefetch = !response_.unused_since_prefetch; | 1292 response_.unused_since_prefetch = !response_.unused_since_prefetch; |
| 1296 next_state_ = STATE_CACHE_DISPATCH_VALIDATION; | 1293 next_state_ = STATE_CACHE_DISPATCH_VALIDATION; |
| 1297 return OnWriteResponseInfoToEntryComplete(result); | 1294 return OnWriteResponseInfoToEntryComplete(result); |
| 1298 } | 1295 } |
| 1299 | 1296 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1347 int HttpCache::Transaction::DoStartPartialCacheValidation() { | 1344 int HttpCache::Transaction::DoStartPartialCacheValidation() { |
| 1348 if (mode_ == NONE) | 1345 if (mode_ == NONE) |
| 1349 return OK; | 1346 return OK; |
| 1350 | 1347 |
| 1351 next_state_ = STATE_COMPLETE_PARTIAL_CACHE_VALIDATION; | 1348 next_state_ = STATE_COMPLETE_PARTIAL_CACHE_VALIDATION; |
| 1352 return partial_->ShouldValidateCache(entry_->disk_entry, io_callback_); | 1349 return partial_->ShouldValidateCache(entry_->disk_entry, io_callback_); |
| 1353 } | 1350 } |
| 1354 | 1351 |
| 1355 int HttpCache::Transaction::DoCompletePartialCacheValidation(int result) { | 1352 int HttpCache::Transaction::DoCompletePartialCacheValidation(int result) { |
| 1356 if (!result) { | 1353 if (!result) { |
| 1357 // This is the end of the request. | 1354 ReleaseCacheEntry(EntryState::SUCCEEDED); |
| 1358 if (mode_ & WRITE) { | 1355 return 0; |
|
rvargas (doing something else)
2015/09/11 23:56:18
nit: OK (or result).
rvargas (doing something else)
2015/09/21 22:05:59
Missed?
| |
| 1359 DoneWritingToEntry(true); | |
| 1360 } else { | |
| 1361 cache_->DoneReadingFromEntry(entry_, this); | |
| 1362 entry_ = NULL; | |
| 1363 } | |
| 1364 return result; | |
| 1365 } | 1356 } |
| 1366 | 1357 |
| 1367 if (result < 0) | 1358 if (result < 0) |
| 1368 return result; | 1359 return result; |
| 1369 | 1360 |
| 1370 partial_->PrepareCacheValidation(entry_->disk_entry, | 1361 partial_->PrepareCacheValidation(entry_->disk_entry, |
| 1371 &custom_request_->extra_headers); | 1362 &custom_request_->extra_headers); |
| 1372 | 1363 |
| 1373 if (reading_ && partial_->IsCurrentRangeCached()) { | 1364 if (reading_ && partial_->IsCurrentRangeCached()) { |
| 1374 next_state_ = STATE_CACHE_READ_DATA; | 1365 next_state_ = STATE_CACHE_READ_DATA; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1426 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 1417 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
| 1427 if (IsCertificateError(result)) { | 1418 if (IsCertificateError(result)) { |
| 1428 // If we get a certificate error, then there is a certificate in ssl_info, | 1419 // If we get a certificate error, then there is a certificate in ssl_info, |
| 1429 // so GetResponseInfo() should never return NULL here. | 1420 // so GetResponseInfo() should never return NULL here. |
| 1430 DCHECK(response); | 1421 DCHECK(response); |
| 1431 response_.ssl_info = response->ssl_info; | 1422 response_.ssl_info = response->ssl_info; |
| 1432 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 1423 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
| 1433 DCHECK(response); | 1424 DCHECK(response); |
| 1434 response_.cert_request_info = response->cert_request_info; | 1425 response_.cert_request_info = response->cert_request_info; |
| 1435 } else if (response_.was_cached) { | 1426 } else if (response_.was_cached) { |
| 1436 DoneWritingToEntry(true); | 1427 ReleaseCacheEntry(EntryState::SUCCEEDED); |
| 1437 } | 1428 } |
| 1438 | 1429 |
| 1439 return result; | 1430 return result; |
| 1440 } | 1431 } |
| 1441 | 1432 |
| 1442 // We received the response headers and there is no error. | 1433 // We received the response headers and there is no error. |
| 1443 int HttpCache::Transaction::DoSuccessfulSendRequest() { | 1434 int HttpCache::Transaction::DoSuccessfulSendRequest() { |
| 1444 DCHECK(!new_response_); | 1435 DCHECK(!new_response_); |
| 1445 const HttpResponseInfo* new_response = network_trans_->GetResponseInfo(); | 1436 const HttpResponseInfo* new_response = network_trans_->GetResponseInfo(); |
| 1446 | 1437 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1482 // the new response. | 1473 // the new response. |
| 1483 net_log_.AddEvent(NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST); | 1474 net_log_.AddEvent(NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST); |
| 1484 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 1475 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
| 1485 response_ = HttpResponseInfo(); | 1476 response_ = HttpResponseInfo(); |
| 1486 ResetNetworkTransaction(); | 1477 ResetNetworkTransaction(); |
| 1487 new_response_ = NULL; | 1478 new_response_ = NULL; |
| 1488 next_state_ = STATE_SEND_REQUEST; | 1479 next_state_ = STATE_SEND_REQUEST; |
| 1489 return OK; | 1480 return OK; |
| 1490 } | 1481 } |
| 1491 | 1482 |
| 1483 if (handling_206_ && stopped_caching_ && partial_ && | |
| 1484 partial_->IsLastRange() && !partial_->IsCurrentRangeCached() && | |
| 1485 (mode_ & WRITE) && entry_) { | |
| 1486 // The current state of the transaction is: | |
| 1487 // * The client has requested that no addtional data be cached. | |
| 1488 // * The current network transaction spans the entire remainder of the | |
| 1489 // requested range. | |
| 1490 // * A cache entry exists and was being written to or updated. | |
| 1491 // * The current range is not cached. | |
| 1492 // | |
| 1493 // At this point it is safe to abandon the cache entry and proceed with just | |
| 1494 // the network transaction. | |
| 1495 next_state_ = STATE_NETWORK_READ; | |
|
rvargas (doing something else)
2015/09/11 23:56:18
without returning data to the caller?
asanka
2015/09/17 21:59:40
We do. Once AbadonCacheEntry() completes, the SM w
rvargas (doing something else)
2015/09/19 01:09:34
The confusing thing is that we may be doing Start(
| |
| 1496 return AbandonCacheEntry(io_callback_); | |
| 1497 } | |
| 1498 | |
| 1492 if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) { | 1499 if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) { |
| 1493 // We have stored the full entry, but it changed and the server is | 1500 // We have stored the full entry, but it changed and the server is |
| 1494 // sending a range. We have to delete the old entry. | 1501 // sending a range. We have to delete the old entry. |
| 1495 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 1502 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
| 1496 DoneWritingToEntry(false); | 1503 ReleaseCacheEntry(EntryState::DOOMED); |
| 1497 } | 1504 } |
| 1498 | 1505 |
| 1499 if (mode_ == WRITE && | 1506 if (mode_ == WRITE && |
| 1500 transaction_pattern_ != PATTERN_ENTRY_CANT_CONDITIONALIZE) { | 1507 transaction_pattern_ != PATTERN_ENTRY_CANT_CONDITIONALIZE) { |
| 1501 UpdateTransactionPattern(PATTERN_ENTRY_NOT_CACHED); | 1508 UpdateTransactionPattern(PATTERN_ENTRY_NOT_CACHED); |
| 1502 } | 1509 } |
| 1503 | 1510 |
| 1504 // Invalidate any cached GET with a successful PUT or DELETE. | 1511 // Invalidate any cached GET with a successful PUT or DELETE. |
| 1505 if (mode_ == WRITE && | 1512 if (mode_ == WRITE && |
| 1506 (request_->method == "PUT" || request_->method == "DELETE")) { | 1513 (request_->method == "PUT" || request_->method == "DELETE")) { |
| 1507 if (NonErrorResponse(new_response->headers->response_code())) { | 1514 if (NonErrorResponse(new_response->headers->response_code())) { |
| 1508 int ret = cache_->DoomEntry(cache_key_, NULL); | 1515 int ret = cache_->DoomEntry(cache_key_, NULL); |
| 1509 DCHECK_EQ(OK, ret); | 1516 DCHECK_EQ(OK, ret); |
| 1510 } | 1517 } |
| 1511 cache_->DoneWritingToEntry(entry_, true); | 1518 ReleaseCacheEntry(EntryState::SUCCEEDED); |
| 1512 entry_ = NULL; | |
| 1513 mode_ = NONE; | |
| 1514 } | 1519 } |
| 1515 | 1520 |
| 1516 // Invalidate any cached GET with a successful POST. | 1521 // Invalidate any cached GET with a successful POST. |
| 1517 if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) && | 1522 if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) && |
| 1518 request_->method == "POST" && | 1523 request_->method == "POST" && |
| 1519 NonErrorResponse(new_response->headers->response_code())) { | 1524 NonErrorResponse(new_response->headers->response_code())) { |
| 1520 cache_->DoomMainEntryForUrl(request_->url); | 1525 cache_->DoomMainEntryForUrl(request_->url); |
| 1521 } | 1526 } |
| 1522 | 1527 |
| 1523 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); | 1528 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1582 return rv; | 1587 return rv; |
| 1583 } | 1588 } |
| 1584 | 1589 |
| 1585 int HttpCache::Transaction::DoCacheWriteUpdatedResponse() { | 1590 int HttpCache::Transaction::DoCacheWriteUpdatedResponse() { |
| 1586 // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed. | 1591 // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 1587 tracked_objects::ScopedTracker tracking_profile( | 1592 tracked_objects::ScopedTracker tracking_profile( |
| 1588 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1593 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1589 "422516 HttpCache::Transaction::DoCacheWriteUpdatedResponse")); | 1594 "422516 HttpCache::Transaction::DoCacheWriteUpdatedResponse")); |
| 1590 | 1595 |
| 1591 next_state_ = STATE_CACHE_WRITE_UPDATED_RESPONSE_COMPLETE; | 1596 next_state_ = STATE_CACHE_WRITE_UPDATED_RESPONSE_COMPLETE; |
| 1592 return WriteResponseInfoToEntry(false); | 1597 return WriteResponseInfoToEntry(false, io_callback_); |
| 1593 } | 1598 } |
| 1594 | 1599 |
| 1595 int HttpCache::Transaction::DoCacheWriteUpdatedResponseComplete(int result) { | 1600 int HttpCache::Transaction::DoCacheWriteUpdatedResponseComplete(int result) { |
| 1596 next_state_ = STATE_UPDATE_CACHED_RESPONSE_COMPLETE; | 1601 next_state_ = STATE_UPDATE_CACHED_RESPONSE_COMPLETE; |
| 1597 return OnWriteResponseInfoToEntryComplete(result); | 1602 return OnWriteResponseInfoToEntryComplete(result); |
| 1598 } | 1603 } |
| 1599 | 1604 |
| 1600 int HttpCache::Transaction::DoUpdateCachedResponseComplete(int result) { | 1605 int HttpCache::Transaction::DoUpdateCachedResponseComplete(int result) { |
| 1601 if (mode_ == UPDATE) { | 1606 if (mode_ == UPDATE) { |
| 1602 DCHECK(!handling_206_); | 1607 DCHECK(!handling_206_); |
| 1603 // We got a "not modified" response and already updated the corresponding | 1608 // We got a "not modified" response and already updated the corresponding |
| 1604 // cache entry above. | 1609 // cache entry above. |
| 1605 // | 1610 // |
| 1606 // By closing the cached entry now, we make sure that the 304 rather than | 1611 // By closing the cached entry now, we make sure that the 304 rather than |
| 1607 // the cached 200 response, is what will be returned to the user. | 1612 // the cached 200 response, is what will be returned to the user. |
| 1608 DoneWritingToEntry(true); | 1613 ReleaseCacheEntry(EntryState::SUCCEEDED); |
| 1609 } else if (entry_ && !handling_206_) { | 1614 } else if (entry_ && !handling_206_) { |
| 1610 DCHECK_EQ(READ_WRITE, mode_); | 1615 DCHECK_EQ(READ_WRITE, mode_); |
| 1611 if (!partial_ || partial_->IsLastRange()) { | 1616 if (!partial_ || partial_->IsLastRange()) { |
| 1612 cache_->ConvertWriterToReader(entry_); | 1617 cache_->ConvertWriterToReader(entry_); |
| 1613 mode_ = READ; | 1618 mode_ = READ; |
| 1614 } | 1619 } |
| 1615 // We no longer need the network transaction, so destroy it. | 1620 // We no longer need the network transaction, so destroy it. |
| 1616 final_upload_progress_ = network_trans_->GetUploadProgress(); | 1621 final_upload_progress_ = network_trans_->GetUploadProgress(); |
| 1617 ResetNetworkTransaction(); | 1622 ResetNetworkTransaction(); |
| 1618 } else if (entry_ && handling_206_ && truncated_ && | 1623 } else if (entry_ && handling_206_ && truncated_ && |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1637 } | 1642 } |
| 1638 | 1643 |
| 1639 // We change the value of Content-Length for partial content. | 1644 // We change the value of Content-Length for partial content. |
| 1640 if (handling_206_ && partial_) | 1645 if (handling_206_ && partial_) |
| 1641 partial_->FixContentLength(new_response_->headers.get()); | 1646 partial_->FixContentLength(new_response_->headers.get()); |
| 1642 | 1647 |
| 1643 response_ = *new_response_; | 1648 response_ = *new_response_; |
| 1644 | 1649 |
| 1645 if (request_->method == "HEAD") { | 1650 if (request_->method == "HEAD") { |
| 1646 // This response is replacing the cached one. | 1651 // This response is replacing the cached one. |
| 1647 DoneWritingToEntry(false); | 1652 ReleaseCacheEntry(EntryState::DOOMED); |
| 1648 mode_ = NONE; | 1653 new_response_ = nullptr; |
| 1649 new_response_ = NULL; | |
| 1650 return OK; | 1654 return OK; |
| 1651 } | 1655 } |
| 1652 | 1656 |
| 1653 if (handling_206_ && !CanResume(false)) { | 1657 if (handling_206_ && !CanResume(false)) { |
| 1654 // There is no point in storing this resource because it will never be used. | 1658 // There is no point in storing this resource because it will never be used. |
| 1655 // This may change if we support LOAD_ONLY_FROM_CACHE with sparse entries. | 1659 // This may change if we support LOAD_ONLY_FROM_CACHE with sparse entries. |
| 1656 DoneWritingToEntry(false); | 1660 ReleaseCacheEntry(EntryState::DOOMED); |
| 1657 if (partial_) | 1661 if (partial_) |
| 1658 partial_->FixResponseHeaders(response_.headers.get(), true); | 1662 partial_->FixResponseHeaders(response_.headers.get(), true); |
| 1659 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | 1663 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; |
| 1660 return OK; | 1664 return OK; |
| 1661 } | 1665 } |
| 1662 | 1666 |
| 1663 next_state_ = STATE_CACHE_WRITE_RESPONSE; | 1667 next_state_ = STATE_CACHE_WRITE_RESPONSE; |
| 1664 return OK; | 1668 return OK; |
| 1665 } | 1669 } |
| 1666 | 1670 |
| 1667 int HttpCache::Transaction::DoCacheWriteResponse() { | 1671 int HttpCache::Transaction::DoCacheWriteResponse() { |
| 1668 // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed. | 1672 // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 1669 tracked_objects::ScopedTracker tracking_profile( | 1673 tracked_objects::ScopedTracker tracking_profile( |
| 1670 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1674 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1671 "422516 HttpCache::Transaction::DoCacheWriteResponse")); | 1675 "422516 HttpCache::Transaction::DoCacheWriteResponse")); |
| 1672 | 1676 |
| 1673 next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE; | 1677 next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE; |
| 1674 return WriteResponseInfoToEntry(truncated_); | 1678 return WriteResponseInfoToEntry(truncated_, io_callback_); |
| 1675 } | 1679 } |
| 1676 | 1680 |
| 1677 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { | 1681 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { |
| 1678 next_state_ = STATE_TRUNCATE_CACHED_DATA; | 1682 next_state_ = STATE_TRUNCATE_CACHED_DATA; |
| 1679 return OnWriteResponseInfoToEntryComplete(result); | 1683 return OnWriteResponseInfoToEntryComplete(result); |
| 1680 } | 1684 } |
| 1681 | 1685 |
| 1682 int HttpCache::Transaction::DoTruncateCachedData() { | 1686 int HttpCache::Transaction::DoTruncateCachedData() { |
| 1683 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; | 1687 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; |
| 1684 if (!entry_) | 1688 if (!entry_) |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1760 io_callback_); | 1764 io_callback_); |
| 1761 } | 1765 } |
| 1762 | 1766 |
| 1763 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { | 1767 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { |
| 1764 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); | 1768 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result); |
| 1765 if (result != response_.metadata->size()) | 1769 if (result != response_.metadata->size()) |
| 1766 return OnCacheReadError(result, false); | 1770 return OnCacheReadError(result, false); |
| 1767 return OK; | 1771 return OK; |
| 1768 } | 1772 } |
| 1769 | 1773 |
| 1774 int HttpCache::Transaction::DoSwitchToNetwork() { | |
| 1775 // Prerequisites of a switch to network: | |
| 1776 // * A valid cache entry must exist. Otherwise we'd already be exclusively | |
| 1777 // dealing with the network. | |
|
rvargas (doing something else)
2015/09/11 23:56:18
Do we really need this comment (and the next one)?
asanka
2015/09/17 21:59:41
Removed. I suppose those two should be obvious. Al
| |
| 1778 DCHECK(entry_); | |
| 1779 // * Need to be writing to the cache entry. If the transaction was exclusively | |
| 1780 // reading from the cache, then the transaction should continue doing so | |
| 1781 // without trying to switch to the network. | |
| 1782 DCHECK(mode_ & WRITE); | |
| 1783 | |
| 1784 // If the transaction is currently reading from the cache, then it should have | |
| 1785 // a valid partial state. I.e. only part of the requested resource could be | |
| 1786 // fulfiled via the cache. If the entire request was being fulfiled via the | |
| 1787 // cache, the transaction shouldn't be trying to switch to the network at this | |
| 1788 // point, and mode_ should be READ. | |
| 1789 DCHECK_IMPLIES(!network_trans_, partial_); | |
| 1790 | |
| 1791 // The network transaction can be trivially reused if it can promise to | |
| 1792 // deliver all the bits necessary to fulfil the original request. If so, | |
| 1793 // abandon the cache entry and continue with a network read. | |
| 1794 if (network_trans_ && (!partial_ || partial_->IsLastRange())) { | |
| 1795 next_state_ = STATE_NETWORK_READ; | |
| 1796 return AbandonCacheEntry(io_callback_); | |
| 1797 } | |
| 1798 | |
| 1799 if (request_->method != "GET") { | |
|
rvargas (doing something else)
2015/09/11 23:56:18
Isn't it easier to check for this in StopCaching?
asanka
2015/09/17 21:59:41
Check moved there. See earlier confusion about whe
rvargas (doing something else)
2015/09/21 22:05:59
but PS14 still has the if here...
| |
| 1800 // We have a non-GET request that the cache or network can partially fulfil. | |
| 1801 // In other words, at some point the transaction is going to have to issue a | |
| 1802 // partial network request to fulfil this non-GET request. Let's just ignore | |
|
rvargas (doing something else)
2015/09/11 23:56:17
I don't think this ever happens. (partial && !get)
asanka
2015/09/17 21:59:40
Yeah. The condition we check now is:
(!partial_
| |
| 1803 // the StopCaching() directive for now. | |
| 1804 stopped_caching_ = false; | |
| 1805 next_state_ = network_trans_ ? STATE_NETWORK_READ : STATE_CACHE_READ_DATA; | |
| 1806 return OK; | |
| 1807 } | |
| 1808 | |
| 1809 // The existing network transaction doesn't cover the entire range we wanted. | |
| 1810 // Let's discard the network transaction and create a new one that will cover | |
| 1811 // the entire range we need. | |
| 1812 if (network_trans_) | |
| 1813 ResetNetworkTransaction(); | |
| 1814 | |
| 1815 if (!partial_->SkipCacheForRemainder()) { | |
| 1816 // PartialData only refuses to switch to network reads if the entire | |
| 1817 // resource has been accounted for. There's nothing more to do. | |
| 1818 // ** Caveat: This assumes that there's a strict agreement between the | |
| 1819 // server indicated length of the resource and the actual length of the | |
| 1820 // resource. | |
|
rvargas (doing something else)
2015/09/11 23:56:18
This is a pre-requisite for byte range requests
asanka
2015/09/17 21:59:41
Caveat removed.
| |
| 1821 return OK; | |
| 1822 } | |
| 1823 | |
| 1824 // The new network request that's going to be issued has to be validated | |
| 1825 // against the existing cache entry. By extension, this also validates the new | |
| 1826 // request against the portion that has already been sent to our client. | |
| 1827 partial_->PrepareCacheValidation(entry_->disk_entry, | |
| 1828 &custom_request_->extra_headers); | |
| 1829 | |
| 1830 // Since we called SkipCacheForRemainder(), the partial_ state should now | |
| 1831 // assume that the remainder of the resource is not cached. | |
| 1832 DCHECK(!partial_->IsCurrentRangeCached()); | |
| 1833 DCHECK(partial_->IsLastRange()); | |
| 1834 | |
| 1835 // READ shouldn't reach here at all. WRITE/UPDATE require a network_trans_ | |
| 1836 // that spans the entire request range and is handled at the top of this | |
| 1837 // function. At this point we should be left with just READ_WRITE. | |
| 1838 DCHECK_EQ(mode_, READ_WRITE); | |
| 1839 | |
| 1840 // Start validating the cache. DoSuccessfulSendRequest() will now bear the | |
| 1841 // responsibility of abandoning the cache entry if the new network transaction | |
| 1842 // is successfully validated. | |
| 1843 return BeginCacheValidation(); | |
| 1844 } | |
| 1845 | |
| 1770 int HttpCache::Transaction::DoNetworkRead() { | 1846 int HttpCache::Transaction::DoNetworkRead() { |
| 1847 DCHECK_GT(read_buf_len_, 0); | |
| 1848 | |
| 1849 io_buf_len_ = read_buf_len_; | |
| 1771 next_state_ = STATE_NETWORK_READ_COMPLETE; | 1850 next_state_ = STATE_NETWORK_READ_COMPLETE; |
| 1772 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); | 1851 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); |
| 1773 } | 1852 } |
| 1774 | 1853 |
| 1775 int HttpCache::Transaction::DoNetworkReadComplete(int result) { | 1854 int HttpCache::Transaction::DoNetworkReadComplete(int result) { |
| 1776 DCHECK(mode_ & WRITE || mode_ == NONE); | 1855 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 1777 | 1856 |
| 1778 if (!cache_.get()) | 1857 if (!cache_.get()) |
| 1779 return ERR_UNEXPECTED; | 1858 return ERR_UNEXPECTED; |
| 1780 | 1859 |
| 1781 // If there is an error or we aren't saving the data, we are done; just wait | 1860 // If there is an error or we aren't saving the data, we are done; just wait |
| 1782 // until the destructor runs to see if we can keep the data. | 1861 // until the destructor runs to see if we can keep the data. |
| 1783 if (mode_ == NONE || result < 0) | 1862 if (mode_ == NONE || result < 0) |
| 1784 return result; | 1863 return result; |
| 1785 | 1864 |
| 1786 next_state_ = STATE_CACHE_WRITE_DATA; | 1865 next_state_ = STATE_CACHE_WRITE_DATA; |
| 1787 return result; | 1866 return result; |
| 1788 } | 1867 } |
| 1789 | 1868 |
| 1790 int HttpCache::Transaction::DoCacheReadData() { | 1869 int HttpCache::Transaction::DoCacheReadData() { |
| 1870 DCHECK_GT(read_buf_len_, 0); | |
| 1871 | |
| 1791 if (request_->method == "HEAD") | 1872 if (request_->method == "HEAD") |
| 1792 return 0; | 1873 return 0; |
| 1793 | 1874 |
| 1794 DCHECK(entry_); | 1875 DCHECK(entry_); |
| 1795 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; | 1876 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; |
| 1877 io_buf_len_ = read_buf_len_; | |
| 1796 | 1878 |
| 1797 if (net_log_.IsCapturing()) | 1879 if (net_log_.IsCapturing()) |
| 1798 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_DATA); | 1880 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_DATA); |
| 1799 if (partial_) { | 1881 if (partial_) { |
| 1800 return partial_->CacheRead(entry_->disk_entry, read_buf_.get(), io_buf_len_, | 1882 return partial_->CacheRead(entry_->disk_entry, read_buf_.get(), io_buf_len_, |
| 1801 io_callback_); | 1883 io_callback_); |
| 1802 } | 1884 } |
| 1803 | 1885 |
| 1804 return entry_->disk_entry->ReadData(kResponseContentIndex, read_offset_, | 1886 return entry_->disk_entry->ReadData(kResponseContentIndex, read_offset_, |
| 1805 read_buf_.get(), io_buf_len_, | 1887 read_buf_.get(), io_buf_len_, |
| 1806 io_callback_); | 1888 io_callback_); |
| 1807 } | 1889 } |
| 1808 | 1890 |
| 1809 int HttpCache::Transaction::DoCacheReadDataComplete(int result) { | 1891 int HttpCache::Transaction::DoCacheReadDataComplete(int result) { |
| 1810 if (net_log_.IsCapturing()) { | 1892 if (net_log_.IsCapturing()) { |
| 1811 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_DATA, | 1893 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_DATA, |
| 1812 result); | 1894 result); |
| 1813 } | 1895 } |
| 1814 | 1896 |
| 1815 if (!cache_.get()) | 1897 if (!cache_.get()) |
| 1816 return ERR_UNEXPECTED; | 1898 return ERR_UNEXPECTED; |
| 1817 | 1899 |
| 1818 if (partial_) { | 1900 if (partial_) { |
| 1819 // Partial requests are confusing to report in histograms because they may | 1901 // Partial requests are confusing to report in histograms because they may |
| 1820 // have multiple underlying requests. | 1902 // have multiple underlying requests. |
| 1821 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 1903 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
| 1822 return DoPartialCacheReadCompleted(result); | 1904 return DoPartialCacheReadCompleted(result); |
| 1823 } | 1905 } |
| 1824 | 1906 |
| 1825 if (result > 0) { | 1907 if (result < 0) |
| 1826 read_offset_ += result; | |
| 1827 } else if (result == 0) { // End of file. | |
| 1828 RecordHistograms(); | |
| 1829 cache_->DoneReadingFromEntry(entry_, this); | |
| 1830 entry_ = NULL; | |
| 1831 } else { | |
| 1832 return OnCacheReadError(result, false); | 1908 return OnCacheReadError(result, false); |
| 1833 } | 1909 |
| 1910 if (result == 0) | |
| 1911 ReleaseCacheEntry(EntryState::SUCCEEDED); | |
| 1912 | |
| 1913 read_offset_ += result; | |
| 1834 return result; | 1914 return result; |
| 1835 } | 1915 } |
| 1836 | 1916 |
| 1837 int HttpCache::Transaction::DoCacheWriteData(int num_bytes) { | 1917 int HttpCache::Transaction::DoCacheWriteData(int num_bytes) { |
| 1838 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; | 1918 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; |
| 1839 write_len_ = num_bytes; | 1919 write_len_ = num_bytes; |
| 1840 if (entry_) { | 1920 if (entry_) { |
| 1841 if (net_log_.IsCapturing()) | 1921 if (net_log_.IsCapturing()) |
| 1842 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_DATA); | 1922 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_DATA); |
| 1843 } | 1923 } |
| 1844 | 1924 |
| 1845 if (!entry_ || !num_bytes) | 1925 if (!entry_ || !num_bytes) |
| 1846 return num_bytes; | 1926 return num_bytes; |
| 1847 | 1927 |
| 1848 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 1928 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); |
| 1849 return WriteToEntry(kResponseContentIndex, current_size, read_buf_.get(), | 1929 return WriteToEntry(kResponseContentIndex, current_size, read_buf_.get(), |
| 1850 num_bytes, io_callback_); | 1930 num_bytes, io_callback_); |
| 1851 } | 1931 } |
| 1852 | 1932 |
| 1853 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) { | 1933 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) { |
| 1854 if (entry_) { | 1934 if (entry_ && net_log_.IsCapturing()) { |
| 1855 if (net_log_.IsCapturing()) { | 1935 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_WRITE_DATA, |
| 1856 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_WRITE_DATA, | 1936 result); |
| 1857 result); | |
| 1858 } | |
| 1859 } | 1937 } |
| 1938 | |
| 1860 if (!cache_.get()) | 1939 if (!cache_.get()) |
| 1861 return ERR_UNEXPECTED; | 1940 return ERR_UNEXPECTED; |
| 1862 | 1941 |
| 1863 if (result != write_len_) { | 1942 if (result != write_len_) { |
| 1864 DLOG(ERROR) << "failed to write response data to cache"; | 1943 DLOG(ERROR) << "failed to write response data to cache"; |
| 1865 DoneWritingToEntry(false); | 1944 ReleaseCacheEntry(EntryState::DOOMED); |
| 1866 | 1945 |
| 1867 // We want to ignore errors writing to disk and just keep reading from | 1946 // We want to ignore errors writing to disk and just keep reading from |
| 1868 // the network. | 1947 // the network. |
| 1869 result = write_len_; | 1948 result = write_len_; |
| 1949 | |
| 1950 // TODO(asanka): More needs to be done to ignore the error and keep reading | |
| 1951 // from the network. E.g. if the cache entry was sparse, it is possible that | |
| 1952 // the current network_trans_ can't fulfil the entire requested range. | |
| 1953 // Consider setting up state to perform an immediate STATE_SWITCH_TO_NETWORK | |
| 1954 // at the next Read() instead of releasing the entry now. | |
| 1870 } else if (!done_reading_ && entry_) { | 1955 } else if (!done_reading_ && entry_) { |
| 1871 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 1956 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); |
| 1872 int64 body_size = response_.headers->GetContentLength(); | 1957 int64 body_size = response_.headers->GetContentLength(); |
| 1873 if (body_size >= 0 && body_size <= current_size) | 1958 if (body_size >= 0 && body_size <= current_size) |
| 1874 done_reading_ = true; | 1959 done_reading_ = true; |
| 1875 } | 1960 } |
| 1876 | 1961 |
| 1877 if (partial_) { | 1962 if (partial_) { |
| 1878 // This may be the last request. | 1963 // The transaction needs to update partial state under the following |
| 1879 if (result != 0 || truncated_ || | 1964 // circumstances: |
| 1880 !(partial_->IsLastRange() || mode_ == WRITE)) { | 1965 const bool need_to_update_partial_state = |
| 1966 // Still reading. The partial state needs to be updated to account for | |
| 1967 // the data read so far. | |
| 1968 result != 0 || | |
| 1969 | |
| 1970 // Reached the end of one network request, but more transactions may be | |
| 1971 // necessary to fulfil the request. DoPartialNetworkReadCompleted() | |
| 1972 // initiates additional network transactions as needed. | |
| 1973 truncated_ || | |
| 1974 | |
| 1975 // If this isn't the last range, then more network transactions may be | |
| 1976 // necessary. But skip this step for new cache entries (mode_ == WRITE). | |
| 1977 // Range requests with new cache entries will have | |
| 1978 // partial_->IsLastRange() set to false. IsLastRange() is only set to | |
| 1979 // true when validating the last range of an existing cache entry. | |
| 1980 (!partial_->IsLastRange() && mode_ != WRITE); | |
| 1981 | |
| 1982 if (need_to_update_partial_state) | |
| 1881 return DoPartialNetworkReadCompleted(result); | 1983 return DoPartialNetworkReadCompleted(result); |
| 1882 } | |
| 1883 } | 1984 } |
| 1884 | 1985 |
| 1885 if (result == 0) { | 1986 if (result == 0) { |
| 1886 // End of file. This may be the result of a connection problem so see if we | 1987 // If the entire response body was successfully read, then the transaction |
| 1887 // have to keep the entry around to be flagged as truncated later on. | 1988 // should release the cache entry. |
| 1888 if (done_reading_ || !entry_ || partial_ || | 1989 // |
| 1889 response_.headers->GetContentLength() <= 0) { | 1990 // While response == 0 typically indicates EOF, it is possible for that to |
| 1890 DoneWritingToEntry(true); | 1991 // happen due to a connection problem. In the latter case the transaction |
| 1992 // should retain ownership of entry_ until the transaction is destroyed so | |
|
rvargas (doing something else)
2015/09/11 23:56:17
But now AbandonCacheEntry is called from here.
asanka
2015/09/17 21:59:40
Comment updated.
| |
| 1993 // that the resulting AbandonCacheEntry() call would cause the entry to be | |
| 1994 // marked as truncated. | |
| 1995 // | |
| 1996 // A succesful receipt of the response body is considered to be indicated by | |
| 1997 // one of: | |
| 1998 // * done_reading_ : Received response body was of expected size. | |
| 1999 // * Content-Length <= 0 : Response body size was not known. | |
| 2000 // * partial_ : | |
| 2001 if (entry_ && (done_reading_ || partial_ || | |
| 2002 response_.headers->GetContentLength() <= 0)) { | |
| 2003 ReleaseCacheEntry(EntryState::SUCCEEDED); | |
| 2004 } else { | |
| 2005 AbandonCacheEntry(CompletionCallback()); | |
|
rvargas (doing something else)
2015/09/11 23:56:18
This is not doing the same checks that the dtor pe
asanka
2015/09/17 21:59:40
Different circumstances.
When we get here, the net
rvargas (doing something else)
2015/09/21 22:05:59
Poor wording on my part. The destructor ends up lo
| |
| 1891 } | 2006 } |
| 1892 } | 2007 } |
| 1893 | 2008 |
| 1894 return result; | 2009 return result; |
| 1895 } | 2010 } |
| 1896 | 2011 |
| 1897 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() { | |
| 1898 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE; | |
| 1899 return WriteResponseInfoToEntry(true); | |
| 1900 } | |
| 1901 | |
| 1902 int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) { | |
| 1903 return OnWriteResponseInfoToEntryComplete(result); | |
| 1904 } | |
| 1905 | |
| 1906 //----------------------------------------------------------------------------- | 2012 //----------------------------------------------------------------------------- |
| 1907 | 2013 |
| 1908 void HttpCache::Transaction::ReadCertChain() { | 2014 void HttpCache::Transaction::ReadCertChain() { |
| 1909 std::string key = | 2015 std::string key = |
| 1910 GetCacheKeyForCert(response_.ssl_info.cert->os_cert_handle()); | 2016 GetCacheKeyForCert(response_.ssl_info.cert->os_cert_handle()); |
| 1911 const X509Certificate::OSCertHandles& intermediates = | 2017 const X509Certificate::OSCertHandles& intermediates = |
| 1912 response_.ssl_info.cert->GetIntermediateCertificates(); | 2018 response_.ssl_info.cert->GetIntermediateCertificates(); |
| 1913 int dist_from_root = intermediates.size(); | 2019 int dist_from_root = intermediates.size(); |
| 1914 | 2020 |
| 1915 scoped_refptr<SharedChainData> shared_chain_data( | 2021 scoped_refptr<SharedChainData> shared_chain_data( |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2153 UpdateTransactionPattern(PATTERN_ENTRY_USED); | 2259 UpdateTransactionPattern(PATTERN_ENTRY_USED); |
| 2154 return SetupEntryForRead(); | 2260 return SetupEntryForRead(); |
| 2155 } else { | 2261 } else { |
| 2156 // Make the network request conditional, to see if we may reuse our cached | 2262 // Make the network request conditional, to see if we may reuse our cached |
| 2157 // response. If we cannot do so, then we just resort to a normal fetch. | 2263 // response. If we cannot do so, then we just resort to a normal fetch. |
| 2158 // Our mode remains READ_WRITE for a conditional request. Even if the | 2264 // Our mode remains READ_WRITE for a conditional request. Even if the |
| 2159 // conditionalization fails, we don't switch to WRITE mode until we | 2265 // conditionalization fails, we don't switch to WRITE mode until we |
| 2160 // know we won't be falling back to using the cache entry in the | 2266 // know we won't be falling back to using the cache entry in the |
| 2161 // LOAD_FROM_CACHE_IF_OFFLINE case. | 2267 // LOAD_FROM_CACHE_IF_OFFLINE case. |
| 2162 if (!ConditionalizeRequest()) { | 2268 if (!ConditionalizeRequest()) { |
| 2269 // Conditionalization should only depend on the state of the cache prior | |
| 2270 // to starting the request and the request method. Failure is unexpected | |
| 2271 // after the client has started reading the stream. | |
| 2272 DCHECK(!reading_); | |
| 2273 | |
| 2163 couldnt_conditionalize_request_ = true; | 2274 couldnt_conditionalize_request_ = true; |
| 2164 UpdateTransactionPattern(PATTERN_ENTRY_CANT_CONDITIONALIZE); | 2275 UpdateTransactionPattern(PATTERN_ENTRY_CANT_CONDITIONALIZE); |
| 2165 if (partial_) | 2276 if (partial_) |
| 2166 return DoRestartPartialRequest(); | 2277 return DoRestartPartialRequest(); |
| 2167 | 2278 |
| 2168 DCHECK_NE(206, response_.headers->response_code()); | 2279 DCHECK_NE(206, response_.headers->response_code()); |
| 2169 } | 2280 } |
| 2170 next_state_ = STATE_SEND_REQUEST; | 2281 next_state_ = STATE_SEND_REQUEST; |
| 2171 } | 2282 } |
| 2172 return OK; | 2283 return OK; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2231 response_.headers->EnumerateHeader( | 2342 response_.headers->EnumerateHeader( |
| 2232 NULL, | 2343 NULL, |
| 2233 kValidationHeaders[i].related_response_header_name, | 2344 kValidationHeaders[i].related_response_header_name, |
| 2234 &validator); | 2345 &validator); |
| 2235 | 2346 |
| 2236 if (response_.headers->response_code() != 200 || truncated_ || | 2347 if (response_.headers->response_code() != 200 || truncated_ || |
| 2237 validator.empty() || validator != external_validation_.values[i]) { | 2348 validator.empty() || validator != external_validation_.values[i]) { |
| 2238 // The externally conditionalized request is not a validation request | 2349 // The externally conditionalized request is not a validation request |
| 2239 // for our existing cache entry. Proceed with caching disabled. | 2350 // for our existing cache entry. Proceed with caching disabled. |
| 2240 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 2351 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
| 2241 DoneWritingToEntry(true); | 2352 ReleaseCacheEntry(EntryState::SUCCEEDED); |
| 2242 } | 2353 } |
| 2243 } | 2354 } |
| 2244 | 2355 |
| 2245 // TODO(ricea): This calculation is expensive to perform just to collect | 2356 // TODO(ricea): This calculation is expensive to perform just to collect |
| 2246 // statistics. Either remove it or use the result, depending on the result of | 2357 // statistics. Either remove it or use the result, depending on the result of |
| 2247 // the experiment. | 2358 // the experiment. |
| 2248 ExternallyConditionalizedType type = | 2359 ExternallyConditionalizedType type = |
| 2249 EXTERNALLY_CONDITIONALIZED_CACHE_USABLE; | 2360 EXTERNALLY_CONDITIONALIZED_CACHE_USABLE; |
| 2250 if (mode_ == NONE) | 2361 if (mode_ == NONE) |
| 2251 type = EXTERNALLY_CONDITIONALIZED_MISMATCHED_VALIDATORS; | 2362 type = EXTERNALLY_CONDITIONALIZED_MISMATCHED_VALIDATORS; |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2559 IgnoreRangeRequest(); | 2670 IgnoreRangeRequest(); |
| 2560 return true; | 2671 return true; |
| 2561 } | 2672 } |
| 2562 | 2673 |
| 2563 void HttpCache::Transaction::IgnoreRangeRequest() { | 2674 void HttpCache::Transaction::IgnoreRangeRequest() { |
| 2564 // We have a problem. We may or may not be reading already (in which case we | 2675 // We have a problem. We may or may not be reading already (in which case we |
| 2565 // returned the headers), but we'll just pretend that this request is not | 2676 // returned the headers), but we'll just pretend that this request is not |
| 2566 // using the cache and see what happens. Most likely this is the first | 2677 // using the cache and see what happens. Most likely this is the first |
| 2567 // response from the server (it's not changing its mind midway, right?). | 2678 // response from the server (it's not changing its mind midway, right?). |
| 2568 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 2679 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
| 2569 if (mode_ & WRITE) | 2680 ReleaseCacheEntry(mode_ == WRITE ? EntryState::DOOMED |
|
rvargas (doing something else)
2015/09/11 23:56:18
wasn't the argument irrelevant for readers? In whi
asanka
2015/09/17 21:59:41
mode_ == READ_WRITE also keeps the entry.
rvargas (doing something else)
2015/09/21 22:05:59
Acknowledged.
| |
| 2570 DoneWritingToEntry(mode_ != WRITE); | 2681 : EntryState::SUCCEEDED); |
| 2571 else if (mode_ & READ && entry_) | 2682 partial_.reset(); |
| 2572 cache_->DoneReadingFromEntry(entry_, this); | |
| 2573 | |
| 2574 partial_.reset(NULL); | |
| 2575 entry_ = NULL; | |
| 2576 mode_ = NONE; | |
| 2577 } | 2683 } |
| 2578 | 2684 |
| 2579 void HttpCache::Transaction::FixHeadersForHead() { | 2685 void HttpCache::Transaction::FixHeadersForHead() { |
| 2580 if (response_.headers->response_code() == 206) { | 2686 if (response_.headers->response_code() == 206) { |
| 2581 response_.headers->RemoveHeader("Content-Range"); | 2687 response_.headers->RemoveHeader("Content-Range"); |
| 2582 response_.headers->ReplaceStatusLine("HTTP/1.1 200 OK"); | 2688 response_.headers->ReplaceStatusLine("HTTP/1.1 200 OK"); |
| 2583 } | 2689 } |
| 2584 } | 2690 } |
| 2585 | 2691 |
| 2586 int HttpCache::Transaction::SetupEntryForRead() { | 2692 int HttpCache::Transaction::SetupEntryForRead() { |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 2616 int rv = 0; | 2722 int rv = 0; |
| 2617 if (!partial_ || !data_len) { | 2723 if (!partial_ || !data_len) { |
| 2618 rv = entry_->disk_entry->WriteData(index, offset, data, data_len, callback, | 2724 rv = entry_->disk_entry->WriteData(index, offset, data, data_len, callback, |
| 2619 true); | 2725 true); |
| 2620 } else { | 2726 } else { |
| 2621 rv = partial_->CacheWrite(entry_->disk_entry, data, data_len, callback); | 2727 rv = partial_->CacheWrite(entry_->disk_entry, data, data_len, callback); |
| 2622 } | 2728 } |
| 2623 return rv; | 2729 return rv; |
| 2624 } | 2730 } |
| 2625 | 2731 |
| 2626 int HttpCache::Transaction::WriteResponseInfoToEntry(bool truncated) { | 2732 int HttpCache::Transaction::WriteResponseInfoToEntry( |
| 2733 bool truncated, | |
| 2734 const CompletionCallback& callback) { | |
| 2627 if (!entry_) | 2735 if (!entry_) |
| 2628 return OK; | 2736 return OK; |
| 2629 | 2737 |
| 2630 if (net_log_.IsCapturing()) | 2738 if (net_log_.IsCapturing()) |
| 2631 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_INFO); | 2739 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_INFO); |
| 2632 | 2740 |
| 2633 // Do not cache no-store content. Do not cache content with cert errors | 2741 // Do not cache no-store content. Do not cache content with cert errors |
| 2634 // either. This is to prevent not reporting net errors when loading a | 2742 // either. This is to prevent not reporting net errors when loading a |
| 2635 // resource from the cache. When we load a page over HTTPS with a cert error | 2743 // resource from the cache. When we load a page over HTTPS with a cert error |
| 2636 // we show an SSL blocking page. If the user clicks proceed we reload the | 2744 // we show an SSL blocking page. If the user clicks proceed we reload the |
| 2637 // resource ignoring the errors. The loaded resource is then cached. If that | 2745 // resource ignoring the errors. The loaded resource is then cached. If that |
| 2638 // resource is subsequently loaded from the cache, no net error is reported | 2746 // resource is subsequently loaded from the cache, no net error is reported |
| 2639 // (even though the cert status contains the actual errors) and no SSL | 2747 // (even though the cert status contains the actual errors) and no SSL |
| 2640 // blocking page is shown. An alternative would be to reverse-map the cert | 2748 // blocking page is shown. An alternative would be to reverse-map the cert |
| 2641 // status to a net error and replay the net error. | 2749 // status to a net error and replay the net error. |
| 2642 if ((response_.headers->HasHeaderValue("cache-control", "no-store")) || | 2750 if ((response_.headers->HasHeaderValue("cache-control", "no-store")) || |
| 2643 IsCertStatusError(response_.ssl_info.cert_status)) { | 2751 IsCertStatusError(response_.ssl_info.cert_status)) { |
| 2644 DoneWritingToEntry(false); | 2752 ReleaseCacheEntry(EntryState::DOOMED); |
| 2645 if (net_log_.IsCapturing()) | 2753 if (net_log_.IsCapturing()) |
| 2646 net_log_.EndEvent(NetLog::TYPE_HTTP_CACHE_WRITE_INFO); | 2754 net_log_.EndEvent(NetLog::TYPE_HTTP_CACHE_WRITE_INFO); |
| 2647 return OK; | 2755 return OK; |
| 2648 } | 2756 } |
| 2649 | 2757 |
| 2650 // cert_cache() will be null if the CertCacheTrial field trial is disabled. | 2758 // cert_cache() will be null if the CertCacheTrial field trial is disabled. |
| 2651 if (cache_->cert_cache() && response_.ssl_info.is_valid()) | 2759 if (cache_->cert_cache() && response_.ssl_info.is_valid()) |
| 2652 WriteCertChain(); | 2760 WriteCertChain(); |
| 2653 | 2761 |
| 2654 if (truncated) | 2762 if (truncated) |
| 2655 DCHECK_EQ(200, response_.headers->response_code()); | 2763 DCHECK_EQ(200, response_.headers->response_code()); |
| 2656 | 2764 |
| 2657 // When writing headers, we normally only write the non-transient headers. | 2765 // When writing headers, we normally only write the non-transient headers. |
| 2658 bool skip_transient_headers = true; | 2766 bool skip_transient_headers = true; |
| 2659 scoped_refptr<PickledIOBuffer> data(new PickledIOBuffer()); | 2767 scoped_refptr<PickledIOBuffer> data(new PickledIOBuffer()); |
| 2660 response_.Persist(data->pickle(), skip_transient_headers, truncated); | 2768 response_.Persist(data->pickle(), skip_transient_headers, truncated); |
| 2661 data->Done(); | 2769 data->Done(); |
| 2662 | 2770 |
| 2663 io_buf_len_ = data->pickle()->size(); | 2771 io_buf_len_ = data->pickle()->size(); |
| 2664 return entry_->disk_entry->WriteData(kResponseInfoIndex, 0, data.get(), | 2772 return entry_->disk_entry->WriteData(kResponseInfoIndex, 0, data.get(), |
| 2665 io_buf_len_, io_callback_, true); | 2773 io_buf_len_, callback, true); |
| 2666 } | 2774 } |
| 2667 | 2775 |
| 2668 int HttpCache::Transaction::OnWriteResponseInfoToEntryComplete(int result) { | 2776 int HttpCache::Transaction::OnWriteResponseInfoToEntryComplete(int result) { |
| 2669 if (!entry_) | 2777 if (!entry_) |
| 2670 return OK; | 2778 return OK; |
| 2671 if (net_log_.IsCapturing()) { | 2779 if (net_log_.IsCapturing()) { |
| 2672 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_WRITE_INFO, | 2780 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_WRITE_INFO, |
| 2673 result); | 2781 result); |
| 2674 } | 2782 } |
| 2675 | 2783 |
| 2676 if (result != io_buf_len_) { | 2784 if (result != io_buf_len_) { |
| 2677 DLOG(ERROR) << "failed to write response info to cache"; | 2785 DLOG(ERROR) << "failed to write response info to cache"; |
| 2678 DoneWritingToEntry(false); | 2786 ReleaseCacheEntry(EntryState::DOOMED); |
| 2679 } | 2787 } |
| 2680 return OK; | 2788 return OK; |
| 2681 } | 2789 } |
| 2682 | 2790 |
| 2683 void HttpCache::Transaction::DoneWritingToEntry(bool success) { | 2791 void HttpCache::Transaction::ReleaseCacheEntry(EntryState entry_state) { |
| 2684 if (!entry_) | 2792 if (!cache_ || !entry_) |
| 2685 return; | 2793 return; |
| 2686 | 2794 |
| 2687 RecordHistograms(); | 2795 cache_->DoneWithEntry(entry_, this, entry_state); |
| 2688 | 2796 entry_ = nullptr; |
| 2689 cache_->DoneWritingToEntry(entry_, success); | 2797 stopped_caching_ = false; |
| 2690 entry_ = NULL; | 2798 mode_ = NONE; |
| 2691 mode_ = NONE; // switch to 'pass through' mode | 2799 return; |
|
rvargas (doing something else)
2015/09/11 23:56:18
remove
asanka
2015/09/17 21:59:41
Done.
| |
| 2692 } | 2800 } |
| 2693 | 2801 |
| 2694 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { | 2802 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { |
| 2695 DLOG(ERROR) << "ReadData failed: " << result; | 2803 DLOG(ERROR) << "ReadData failed: " << result; |
| 2696 const int result_for_histogram = std::max(0, -result); | 2804 const int result_for_histogram = std::max(0, -result); |
| 2697 if (restart) { | 2805 if (restart) { |
| 2698 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", | 2806 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", |
| 2699 result_for_histogram); | 2807 result_for_histogram); |
| 2700 } else { | 2808 } else { |
| 2701 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable", | 2809 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable", |
| 2702 result_for_histogram); | 2810 result_for_histogram); |
| 2703 } | 2811 } |
| 2704 | 2812 |
| 2705 // Avoid using this entry in the future. | 2813 // Avoid using this entry in the future. |
| 2706 if (cache_.get()) | 2814 if (cache_.get()) |
| 2707 cache_->DoomActiveEntry(cache_key_); | 2815 cache_->DoomActiveEntry(cache_key_); |
| 2708 | 2816 |
| 2709 if (restart) { | 2817 if (restart) { |
| 2710 DCHECK(!reading_); | 2818 DCHECK(!reading_); |
| 2711 DCHECK(!network_trans_.get()); | 2819 DCHECK(!network_trans_.get()); |
| 2712 cache_->DoneWithEntry(entry_, this, false); | 2820 ReleaseCacheEntry(EntryState::DOOMED); |
| 2713 entry_ = NULL; | |
| 2714 is_sparse_ = false; | 2821 is_sparse_ = false; |
| 2715 partial_.reset(); | 2822 partial_.reset(); |
| 2716 next_state_ = STATE_GET_BACKEND; | 2823 next_state_ = STATE_GET_BACKEND; |
| 2717 return OK; | 2824 return OK; |
| 2718 } | 2825 } |
| 2719 | 2826 |
| 2720 return ERR_CACHE_READ_FAILURE; | 2827 return ERR_CACHE_READ_FAILURE; |
| 2721 } | 2828 } |
| 2722 | 2829 |
| 2723 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { | 2830 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { |
| 2724 if (entry_lock_waiting_since_ != start_time) | 2831 if (entry_lock_waiting_since_ != start_time) |
| 2725 return; | 2832 return; |
| 2726 | 2833 |
| 2727 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); | 2834 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); |
| 2728 | 2835 |
| 2729 if (!cache_) | 2836 if (!cache_) |
| 2730 return; | 2837 return; |
| 2731 | 2838 |
| 2732 cache_->RemovePendingTransaction(this); | 2839 cache_->RemovePendingTransaction(this); |
| 2733 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); | 2840 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); |
| 2734 } | 2841 } |
| 2735 | 2842 |
| 2736 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { | 2843 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { |
| 2737 DVLOG(2) << "DoomPartialEntry"; | 2844 DVLOG(2) << "DoomPartialEntry"; |
| 2738 int rv = cache_->DoomEntry(cache_key_, NULL); | 2845 ReleaseCacheEntry(EntryState::DOOMED); |
| 2739 DCHECK_EQ(OK, rv); | |
| 2740 cache_->DoneWithEntry(entry_, this, false); | |
| 2741 entry_ = NULL; | |
| 2742 is_sparse_ = false; | 2846 is_sparse_ = false; |
| 2743 truncated_ = false; | 2847 truncated_ = false; |
| 2744 if (delete_object) | 2848 if (delete_object) |
| 2745 partial_.reset(NULL); | 2849 partial_.reset(); |
| 2746 } | 2850 } |
| 2747 | 2851 |
| 2748 int HttpCache::Transaction::DoPartialNetworkReadCompleted(int result) { | 2852 int HttpCache::Transaction::DoPartialNetworkReadCompleted(int result) { |
| 2749 partial_->OnNetworkReadCompleted(result); | 2853 partial_->OnNetworkReadCompleted(result); |
| 2750 | 2854 |
| 2751 if (result == 0) { | 2855 if (result == 0) { |
| 2752 // We need to move on to the next range. | 2856 // We need to move on to the next range. |
| 2753 ResetNetworkTransaction(); | 2857 ResetNetworkTransaction(); |
| 2754 next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; | 2858 next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; |
| 2755 } | 2859 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 2767 } | 2871 } |
| 2768 return result; | 2872 return result; |
| 2769 } | 2873 } |
| 2770 | 2874 |
| 2771 int HttpCache::Transaction::DoRestartPartialRequest() { | 2875 int HttpCache::Transaction::DoRestartPartialRequest() { |
| 2772 // The stored data cannot be used. Get rid of it and restart this request. | 2876 // The stored data cannot be used. Get rid of it and restart this request. |
| 2773 net_log_.AddEvent(NetLog::TYPE_HTTP_CACHE_RESTART_PARTIAL_REQUEST); | 2877 net_log_.AddEvent(NetLog::TYPE_HTTP_CACHE_RESTART_PARTIAL_REQUEST); |
| 2774 | 2878 |
| 2775 // WRITE + Doom + STATE_INIT_ENTRY == STATE_CREATE_ENTRY (without an attempt | 2879 // WRITE + Doom + STATE_INIT_ENTRY == STATE_CREATE_ENTRY (without an attempt |
| 2776 // to Doom the entry again). | 2880 // to Doom the entry again). |
| 2881 ResetPartialState(!range_requested_); | |
| 2777 mode_ = WRITE; | 2882 mode_ = WRITE; |
| 2778 ResetPartialState(!range_requested_); | |
| 2779 next_state_ = STATE_CREATE_ENTRY; | 2883 next_state_ = STATE_CREATE_ENTRY; |
| 2780 return OK; | 2884 return OK; |
| 2781 } | 2885 } |
| 2782 | 2886 |
| 2783 void HttpCache::Transaction::ResetPartialState(bool delete_object) { | 2887 void HttpCache::Transaction::ResetPartialState(bool delete_object) { |
| 2784 partial_->RestoreHeaders(&custom_request_->extra_headers); | 2888 partial_->RestoreHeaders(&custom_request_->extra_headers); |
| 2785 DoomPartialEntry(delete_object); | 2889 DoomPartialEntry(delete_object); |
| 2786 | 2890 |
| 2787 if (!delete_object) { | 2891 if (!delete_object) { |
| 2788 // The simplest way to re-initialize partial_ is to create a new object. | 2892 // The simplest way to re-initialize partial_ is to create a new object. |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2843 void HttpCache::Transaction::UpdateTransactionPattern( | 2947 void HttpCache::Transaction::UpdateTransactionPattern( |
| 2844 TransactionPattern new_transaction_pattern) { | 2948 TransactionPattern new_transaction_pattern) { |
| 2845 if (transaction_pattern_ == PATTERN_NOT_COVERED) | 2949 if (transaction_pattern_ == PATTERN_NOT_COVERED) |
| 2846 return; | 2950 return; |
| 2847 DCHECK(transaction_pattern_ == PATTERN_UNDEFINED || | 2951 DCHECK(transaction_pattern_ == PATTERN_UNDEFINED || |
| 2848 new_transaction_pattern == PATTERN_NOT_COVERED); | 2952 new_transaction_pattern == PATTERN_NOT_COVERED); |
| 2849 transaction_pattern_ = new_transaction_pattern; | 2953 transaction_pattern_ = new_transaction_pattern; |
| 2850 } | 2954 } |
| 2851 | 2955 |
| 2852 void HttpCache::Transaction::RecordHistograms() { | 2956 void HttpCache::Transaction::RecordHistograms() { |
| 2853 DCHECK_NE(PATTERN_UNDEFINED, transaction_pattern_); | 2957 if (transaction_pattern_ == PATTERN_UNDEFINED || !cache_.get() || |
| 2854 if (!cache_.get() || !cache_->GetCurrentBackend() || | 2958 !cache_->GetCurrentBackend() || |
| 2855 cache_->GetCurrentBackend()->GetCacheType() != DISK_CACHE || | 2959 cache_->GetCurrentBackend()->GetCacheType() != DISK_CACHE || |
| 2856 cache_->mode() != NORMAL || request_->method != "GET") { | 2960 cache_->mode() != NORMAL || request_->method != "GET") { |
| 2857 return; | 2961 return; |
| 2858 } | 2962 } |
| 2859 UMA_HISTOGRAM_ENUMERATION( | 2963 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern", transaction_pattern_, |
| 2860 "HttpCache.Pattern", transaction_pattern_, PATTERN_MAX); | 2964 PATTERN_MAX); |
| 2861 if (transaction_pattern_ == PATTERN_NOT_COVERED) | 2965 if (transaction_pattern_ == PATTERN_NOT_COVERED) |
| 2862 return; | 2966 return; |
| 2863 DCHECK(!range_requested_); | 2967 DCHECK(!range_requested_); |
| 2864 DCHECK(!first_cache_access_since_.is_null()); | 2968 DCHECK(!first_cache_access_since_.is_null()); |
| 2865 | 2969 |
| 2866 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; | 2970 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; |
| 2867 | 2971 |
| 2868 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); | 2972 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); |
| 2869 | 2973 |
| 2870 bool did_send_request = !send_request_since_.is_null(); | 2974 bool did_send_request = !send_request_since_.is_null(); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2924 } | 3028 } |
| 2925 default: | 3029 default: |
| 2926 NOTREACHED(); | 3030 NOTREACHED(); |
| 2927 } | 3031 } |
| 2928 } | 3032 } |
| 2929 | 3033 |
| 2930 void HttpCache::Transaction::OnIOComplete(int result) { | 3034 void HttpCache::Transaction::OnIOComplete(int result) { |
| 2931 DoLoop(result); | 3035 DoLoop(result); |
| 2932 } | 3036 } |
| 2933 | 3037 |
| 3038 int HttpCache::Transaction::AbandonCacheEntry( | |
| 3039 const CompletionCallback& callback) { | |
| 3040 if (is_sparse_ || done_reading_ || !(mode_ & WRITE)) { | |
|
rvargas (doing something else)
2015/09/11 23:56:18
is_sparse != partial_ && !truncated_ (which is wha
asanka
2015/09/17 21:59:40
Condition updated with explanation.
| |
| 3041 ReleaseCacheEntry(EntryState::SUCCEEDED); | |
| 3042 return OK; | |
| 3043 } | |
| 3044 if (!reading_ || !CanResume(true)) { | |
| 3045 ReleaseCacheEntry(EntryState::DOOMED); | |
| 3046 return OK; | |
| 3047 } | |
| 3048 if (stopped_caching_ && ((mode_ == WRITE && !truncated_) || | |
|
rvargas (doing something else)
2015/09/11 23:56:18
why write vs rw? why write && truncated_ is ok?
asanka
2015/09/17 21:59:41
Removed this condition block. This "if" is trying
| |
| 3049 (mode_ == READ_WRITE && truncated_))) { | |
| 3050 ReleaseCacheEntry(EntryState::DOOMED); | |
|
rvargas (doing something else)
2015/09/11 23:56:18
This deserves a comment (what we're after with the
asanka
2015/09/17 21:59:41
(removed)
| |
| 3051 return OK; | |
| 3052 } | |
| 3053 | |
| 3054 truncated_ = true; | |
| 3055 int result = WriteResponseInfoToEntry( | |
| 3056 true, base::Bind(&HttpCache::Transaction::OnAbandonCacheEntryIOComplete, | |
| 3057 weak_factory_.GetWeakPtr())); | |
| 3058 if (result == ERR_IO_PENDING) { | |
| 3059 if (!callback.is_null()) { | |
|
rvargas (doing something else)
2015/09/11 23:56:17
nit: invert the logic
asanka
2015/09/17 21:59:41
Done.
| |
| 3060 abandon_cache_entry_callback_ = callback; | |
| 3061 } else { | |
| 3062 ReleaseCacheEntry(EntryState::SUCCEEDED); | |
| 3063 } | |
| 3064 } | |
| 3065 return result; | |
| 3066 } | |
| 3067 | |
| 3068 void HttpCache::Transaction::OnAbandonCacheEntryIOComplete(int result) { | |
| 3069 OnWriteResponseInfoToEntryComplete(result); | |
| 3070 ReleaseCacheEntry(EntryState::SUCCEEDED); | |
| 3071 if (!abandon_cache_entry_callback_.is_null()) | |
| 3072 base::ResetAndReturn(&abandon_cache_entry_callback_).Run(result); | |
| 3073 } | |
| 3074 | |
| 2934 } // namespace net | 3075 } // namespace net |
| OLD | NEW |