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), |
| 271 io_buf_len_(0), | 272 io_buf_len_(0), |
| 272 read_offset_(0), | 273 read_offset_(0), |
| 273 effective_load_flags_(0), | 274 effective_load_flags_(0), |
| 274 write_len_(0), | 275 write_len_(0), |
| 275 transaction_pattern_(PATTERN_UNDEFINED), | 276 transaction_pattern_(PATTERN_UNDEFINED), |
| 276 total_received_bytes_(0), | 277 total_received_bytes_(0), |
| 277 websocket_handshake_stream_base_create_helper_(NULL), | 278 websocket_handshake_stream_base_create_helper_(NULL), |
| 278 weak_factory_(this) { | 279 weak_factory_(this) { |
| 279 static_assert(HttpCache::Transaction::kNumValidationHeaders == | 280 static_assert(HttpCache::Transaction::kNumValidationHeaders == |
| 280 arraysize(kValidationHeaders), | 281 arraysize(kValidationHeaders), |
| 281 "invalid number of validation headers"); | 282 "invalid number of validation headers"); |
| 282 | 283 |
| 283 io_callback_ = base::Bind(&Transaction::OnIOComplete, | 284 io_callback_ = base::Bind(&Transaction::OnIOComplete, |
| 284 weak_factory_.GetWeakPtr()); | 285 weak_factory_.GetWeakPtr()); |
| 285 } | 286 } |
| 286 | 287 |
| 287 HttpCache::Transaction::~Transaction() { | 288 HttpCache::Transaction::~Transaction() { |
| 288 // We may have to issue another IO, but we should never invoke the callback_ | 289 // We may have to issue another IO, but we should never invoke the callback_ |
| 289 // after this point. | 290 // after this point. |
| 290 callback_.Reset(); | 291 callback_.Reset(); |
| 291 | 292 |
| 292 if (cache_) { | 293 if (cache_) { |
| 293 if (entry_) { | 294 if (entry_) { |
| 294 bool cancel_request = reading_ && response_.headers.get(); | 295 bool cancel_request = reading_ && response_.headers.get(); |
|
rvargas (doing something else)
2015/08/19 23:46:38
nit: rename to preserve_entry ?
| |
| 295 if (cancel_request) { | 296 if (cancel_request) { |
| 296 if (partial_) { | 297 if (partial_) { |
| 297 entry_->disk_entry->CancelSparseIO(); | 298 entry_->disk_entry->CancelSparseIO(); |
| 298 } else { | 299 } else { |
| 299 cancel_request &= (response_.headers->response_code() == 200); | 300 cancel_request &= (response_.headers->response_code() == 200); |
| 300 } | 301 } |
| 301 } | 302 } |
| 302 | 303 |
| 303 cache_->DoneWithEntry(entry_, this, cancel_request); | 304 ReleaseCacheEntry(cancel_request ? CACHE_ENTRY_PRESERVE |
| 305 : CACHE_ENTRY_DOOM); | |
| 304 } else if (cache_pending_) { | 306 } else if (cache_pending_) { |
| 305 cache_->RemovePendingTransaction(this); | 307 cache_->RemovePendingTransaction(this); |
| 306 } | 308 } |
| 307 } | 309 } |
| 308 } | 310 } |
| 309 | 311 |
| 310 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len, | 312 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len, |
| 311 const CompletionCallback& callback) { | 313 const CompletionCallback& callback) { |
| 312 DCHECK(buf); | 314 DCHECK(buf); |
| 313 DCHECK_GT(buf_len, 0); | 315 DCHECK_GT(buf_len, 0); |
| 314 DCHECK(!callback.is_null()); | 316 DCHECK(!callback.is_null()); |
| 315 if (!cache_.get() || !entry_) | 317 if (!cache_.get() || !entry_) |
| 316 return ERR_UNEXPECTED; | 318 return ERR_UNEXPECTED; |
| 317 | 319 |
| 318 // We don't need to track this operation for anything. | 320 // We don't need to track this operation for anything. |
| 319 // It could be possible to check if there is something already written and | 321 // 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 | 322 // avoid writing again (it should be the same, right?), but let's allow the |
| 321 // caller to "update" the contents with something new. | 323 // caller to "update" the contents with something new. |
| 322 return entry_->disk_entry->WriteData(kMetadataIndex, 0, buf, buf_len, | 324 return entry_->disk_entry->WriteData(kMetadataIndex, 0, buf, buf_len, |
| 323 callback, true); | 325 callback, true); |
| 324 } | 326 } |
| 325 | 327 |
| 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 { | 328 LoadState HttpCache::Transaction::GetWriterLoadState() const { |
| 347 if (network_trans_.get()) | 329 if (network_trans_.get()) |
| 348 return network_trans_->GetLoadState(); | 330 return network_trans_->GetLoadState(); |
| 349 if (entry_ || !request_) | 331 if (entry_ || !request_) |
| 350 return LOAD_STATE_IDLE; | 332 return LOAD_STATE_IDLE; |
| 351 return LOAD_STATE_WAITING_FOR_CACHE; | 333 return LOAD_STATE_WAITING_FOR_CACHE; |
| 352 } | 334 } |
| 353 | 335 |
| 354 const BoundNetLog& HttpCache::Transaction::net_log() const { | 336 const BoundNetLog& HttpCache::Transaction::net_log() const { |
| 355 return net_log_; | 337 return net_log_; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 450 return false; | 432 return false; |
| 451 return network_trans_->IsReadyToRestartForAuth(); | 433 return network_trans_->IsReadyToRestartForAuth(); |
| 452 } | 434 } |
| 453 | 435 |
| 454 int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len, | 436 int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len, |
| 455 const CompletionCallback& callback) { | 437 const CompletionCallback& callback) { |
| 456 DCHECK_EQ(next_state_, STATE_NONE); | 438 DCHECK_EQ(next_state_, STATE_NONE); |
| 457 DCHECK(buf); | 439 DCHECK(buf); |
| 458 DCHECK_GT(buf_len, 0); | 440 DCHECK_GT(buf_len, 0); |
| 459 DCHECK(!callback.is_null()); | 441 DCHECK(!callback.is_null()); |
| 460 | |
| 461 DCHECK(callback_.is_null()); | 442 DCHECK(callback_.is_null()); |
| 462 | 443 |
| 463 if (!cache_.get()) | 444 if (!cache_.get()) |
| 464 return ERR_UNEXPECTED; | 445 return ERR_UNEXPECTED; |
| 465 | 446 |
| 466 // If we have an intermediate auth response at this point, then it means the | 447 // 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 | 448 // 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. | 449 // previous response in the cache then we should leave it intact. |
| 469 if (auth_response_.headers.get() && mode_ != NONE) { | 450 if (auth_response_.headers.get() && mode_ != NONE) { |
| 470 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 451 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
| 471 DCHECK(mode_ & WRITE); | 452 DCHECK(mode_ & WRITE); |
| 472 DoneWritingToEntry(mode_ == READ_WRITE); | 453 DoneWritingToEntry(mode_ == READ_WRITE); |
| 473 mode_ = NONE; | 454 mode_ = NONE; |
| 474 } | 455 } |
| 475 | 456 |
| 476 reading_ = true; | 457 reading_ = true; |
| 477 read_buf_ = buf; | 458 read_buf_ = buf; |
| 478 io_buf_len_ = buf_len; | 459 io_buf_len_ = buf_len; |
| 479 if (network_trans_) { | 460 if (stopped_caching_ && (mode_ & WRITE) && |
|
rvargas (doing something else)
2015/08/19 23:46:38
Why do we need to check the mode here? (how can we
asanka
2015/09/04 19:09:04
I removed the mode_ check from StopCaching() and w
rvargas (doing something else)
2015/09/11 23:56:17
hmmm. Related to comments elsewhere.
| |
| 461 !(effective_load_flags_ & LOAD_PREFERRING_CACHE) && entry_) { | |
|
rvargas (doing something else)
2015/08/19 23:46:38
why do we look at load_flags_?
asanka
2015/09/04 19:09:03
Originally did so because LOAD_PREFERRING_CACHE ma
| |
| 462 next_state_ = STATE_RELEASE_CACHE_ENTRY_AND_CONTINUE_USING_NETWORK; | |
| 463 } else if (network_trans_) { | |
| 480 DCHECK(mode_ == WRITE || mode_ == NONE || | 464 DCHECK(mode_ == WRITE || mode_ == NONE || |
| 481 (mode_ == READ_WRITE && partial_)); | 465 (mode_ == READ_WRITE && partial_)); |
| 482 next_state_ = STATE_NETWORK_READ; | 466 next_state_ = STATE_NETWORK_READ; |
| 483 } else { | 467 } else { |
| 484 DCHECK(mode_ == READ || (mode_ == READ_WRITE && partial_)); | 468 DCHECK(mode_ == READ || (mode_ == READ_WRITE && partial_)); |
| 485 next_state_ = STATE_CACHE_READ_DATA; | 469 next_state_ = STATE_CACHE_READ_DATA; |
| 486 } | 470 } |
| 487 | 471 |
| 488 int rv = DoLoop(OK); | 472 int rv = DoLoop(OK); |
| 489 | 473 |
| 490 if (rv == ERR_IO_PENDING) { | 474 if (rv == ERR_IO_PENDING) { |
| 491 DCHECK(callback_.is_null()); | 475 DCHECK(callback_.is_null()); |
| 492 callback_ = callback; | 476 callback_ = callback; |
| 493 } | 477 } |
| 494 return rv; | 478 return rv; |
| 495 } | 479 } |
| 496 | 480 |
| 497 void HttpCache::Transaction::StopCaching() { | 481 void HttpCache::Transaction::StopCaching() { |
| 498 // We really don't know where we are now. Hopefully there is no operation in | 482 DCHECK(!(effective_load_flags_ & LOAD_PREFETCH)); |
|
rvargas (doing something else)
2015/08/19 23:46:38
isn't this outside of the control of this code? Wh
asanka
2015/09/04 19:09:04
Not sure how this crept in. Removed.
| |
| 499 // progress, but nothing really prevents this method to be called after we | 483 DCHECK(callback_.is_null()); |
| 500 // returned ERR_IO_PENDING. We cannot attempt to truncate the entry at this | 484 |
| 501 // point because we need the state machine for that (and even if we are really | 485 // StopCaching() only affects cache writes and is meant to prevent excessively |
| 502 // free, that would be an asynchronous operation). In other words, keep the | 486 // large resources from clogging up the cache. If this entry is being read |
| 503 // entry how it is (it will be marked as truncated at destruction), and let | 487 // exclusively from the cache already, then we are going to ignore the |
|
rvargas (doing something else)
2015/08/19 23:46:38
I'd probably remove the second sentence, as it is
asanka
2015/09/04 19:09:03
Removed the check and comment since we just set th
| |
| 504 // the next piece of code that executes know that we are now reading directly | 488 // StopCaching() request. |
| 505 // from the net. | 489 if (mode_ & WRITE) { |
| 506 // TODO(mmenke): This doesn't release the lock on the cache entry, so a | 490 stopped_caching_ = true; |
| 507 // future request for the resource will be blocked on this one. | 491 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
| 508 // Fix this. | |
| 509 if (cache_.get() && entry_ && (mode_ & WRITE) && network_trans_.get() && | |
| 510 !is_sparse_ && !range_requested_) { | |
| 511 mode_ = NONE; | |
| 512 } | 492 } |
| 513 } | 493 } |
| 514 | 494 |
| 515 bool HttpCache::Transaction::GetFullRequestHeaders( | 495 bool HttpCache::Transaction::GetFullRequestHeaders( |
| 516 HttpRequestHeaders* headers) const { | 496 HttpRequestHeaders* headers) const { |
| 517 if (network_trans_) | 497 if (network_trans_) |
| 518 return network_trans_->GetFullRequestHeaders(headers); | 498 return network_trans_->GetFullRequestHeaders(headers); |
| 519 | 499 |
| 520 // TODO(ttuttle): Read headers from cache. | 500 // TODO(ttuttle): Read headers from cache. |
| 521 return false; | 501 return false; |
| 522 } | 502 } |
| 523 | 503 |
| 524 int64 HttpCache::Transaction::GetTotalReceivedBytes() const { | 504 int64 HttpCache::Transaction::GetTotalReceivedBytes() const { |
| 525 int64 total_received_bytes = total_received_bytes_; | 505 int64 total_received_bytes = total_received_bytes_; |
| 526 if (network_trans_) | 506 if (network_trans_) |
| 527 total_received_bytes += network_trans_->GetTotalReceivedBytes(); | 507 total_received_bytes += network_trans_->GetTotalReceivedBytes(); |
| 528 return total_received_bytes; | 508 return total_received_bytes; |
| 529 } | 509 } |
| 530 | 510 |
| 531 void HttpCache::Transaction::DoneReading() { | 511 void HttpCache::Transaction::DoneReading() { |
| 532 if (cache_.get() && entry_) { | 512 DCHECK_NE(mode_, UPDATE); |
|
rvargas (doing something else)
2015/08/19 23:46:38
We still need this code, otherwise it will crash a
asanka
2015/09/04 19:09:03
Done.
| |
| 533 DCHECK_NE(mode_, UPDATE); | 513 |
| 534 if (mode_ & WRITE) { | 514 if (mode_ & WRITE) { |
| 535 DoneWritingToEntry(true); | 515 DoneWritingToEntry(true); |
| 536 } else if (mode_ & READ) { | 516 } else if (mode_ & READ) { |
| 537 // It is necessary to check mode_ & READ because it is possible | 517 cache_->DoneReadingFromEntry(entry_, this); |
|
rvargas (doing something else)
2015/08/19 23:46:38
We should be able to fix this code now and make th
asanka
2015/09/04 19:09:03
Done.
| |
| 538 // for mode_ to be NONE and entry_ non-NULL with a write entry | 518 entry_ = nullptr; |
| 539 // if StopCaching was called. | |
| 540 cache_->DoneReadingFromEntry(entry_, this); | |
| 541 entry_ = NULL; | |
| 542 } | |
| 543 } | 519 } |
| 544 } | 520 } |
| 545 | 521 |
| 546 const HttpResponseInfo* HttpCache::Transaction::GetResponseInfo() const { | 522 const HttpResponseInfo* HttpCache::Transaction::GetResponseInfo() const { |
| 547 // Null headers means we encountered an error or haven't a response yet | 523 // Null headers means we encountered an error or haven't a response yet |
| 548 if (auth_response_.headers.get()) | 524 if (auth_response_.headers.get()) |
| 549 return &auth_response_; | 525 return &auth_response_; |
| 550 return &response_; | 526 return &response_; |
| 551 } | 527 } |
| 552 | 528 |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 895 DCHECK_EQ(OK, rv); | 871 DCHECK_EQ(OK, rv); |
| 896 rv = DoPartialHeadersReceived(); | 872 rv = DoPartialHeadersReceived(); |
| 897 break; | 873 break; |
| 898 case STATE_CACHE_READ_METADATA: | 874 case STATE_CACHE_READ_METADATA: |
| 899 DCHECK_EQ(OK, rv); | 875 DCHECK_EQ(OK, rv); |
| 900 rv = DoCacheReadMetadata(); | 876 rv = DoCacheReadMetadata(); |
| 901 break; | 877 break; |
| 902 case STATE_CACHE_READ_METADATA_COMPLETE: | 878 case STATE_CACHE_READ_METADATA_COMPLETE: |
| 903 rv = DoCacheReadMetadataComplete(rv); | 879 rv = DoCacheReadMetadataComplete(rv); |
| 904 break; | 880 break; |
| 881 case STATE_RELEASE_CACHE_ENTRY_AND_CONTINUE_USING_NETWORK: | |
| 882 rv = DoReleaseCacheEntryAndContinueUsingNetwork(); | |
| 883 break; | |
| 905 case STATE_NETWORK_READ: | 884 case STATE_NETWORK_READ: |
| 906 DCHECK_EQ(OK, rv); | 885 DCHECK_EQ(OK, rv); |
| 907 rv = DoNetworkRead(); | 886 rv = DoNetworkRead(); |
| 908 break; | 887 break; |
| 909 case STATE_NETWORK_READ_COMPLETE: | 888 case STATE_NETWORK_READ_COMPLETE: |
| 910 rv = DoNetworkReadComplete(rv); | 889 rv = DoNetworkReadComplete(rv); |
| 911 break; | 890 break; |
| 912 case STATE_CACHE_READ_DATA: | 891 case STATE_CACHE_READ_DATA: |
| 913 DCHECK_EQ(OK, rv); | 892 DCHECK_EQ(OK, rv); |
| 914 rv = DoCacheReadData(); | 893 rv = DoCacheReadData(); |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1404 rv = network_trans_->Start(request_, io_callback_, net_log_); | 1383 rv = network_trans_->Start(request_, io_callback_, net_log_); |
| 1405 return rv; | 1384 return rv; |
| 1406 } | 1385 } |
| 1407 | 1386 |
| 1408 int HttpCache::Transaction::DoSendRequestComplete(int result) { | 1387 int HttpCache::Transaction::DoSendRequestComplete(int result) { |
| 1409 if (!cache_.get()) | 1388 if (!cache_.get()) |
| 1410 return ERR_UNEXPECTED; | 1389 return ERR_UNEXPECTED; |
| 1411 | 1390 |
| 1412 // If we tried to conditionalize the request and failed, we know | 1391 // If we tried to conditionalize the request and failed, we know |
| 1413 // we won't be reading from the cache after this point. | 1392 // we won't be reading from the cache after this point. |
| 1414 if (couldnt_conditionalize_request_) | 1393 if (couldnt_conditionalize_request_ && mode_ == READ_WRITE) |
| 1415 mode_ = WRITE; | 1394 mode_ = stopped_caching_ ? NONE : WRITE; |
|
rvargas (doing something else)
2015/08/19 23:46:38
If we switch to NONE, shouldn't we release the cac
asanka
2015/09/04 19:09:03
Removed this logic.
| |
| 1416 | 1395 |
| 1417 if (result == OK) { | 1396 if (result == OK) { |
| 1418 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; | 1397 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; |
| 1419 return OK; | 1398 return OK; |
| 1420 } | 1399 } |
| 1421 | 1400 |
| 1422 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); | 1401 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); |
| 1423 response_.network_accessed = response->network_accessed; | 1402 response_.network_accessed = response->network_accessed; |
| 1424 | 1403 |
| 1425 // Do not record requests that have network errors or restarts. | 1404 // Do not record requests that have network errors or restarts. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1469 if (entry_) | 1448 if (entry_) |
| 1470 DoomPartialEntry(false); | 1449 DoomPartialEntry(false); |
| 1471 mode_ = NONE; | 1450 mode_ = NONE; |
| 1472 partial_.reset(); | 1451 partial_.reset(); |
| 1473 ResetNetworkTransaction(); | 1452 ResetNetworkTransaction(); |
| 1474 return ERR_CACHE_AUTH_FAILURE_AFTER_READ; | 1453 return ERR_CACHE_AUTH_FAILURE_AFTER_READ; |
| 1475 } | 1454 } |
| 1476 | 1455 |
| 1477 new_response_ = new_response; | 1456 new_response_ = new_response; |
| 1478 if (!ValidatePartialResponse() && !auth_response_.headers.get()) { | 1457 if (!ValidatePartialResponse() && !auth_response_.headers.get()) { |
| 1458 if (reading_) { | |
|
rvargas (doing something else)
2015/08/19 23:46:38
Is this block related to this change? can we make
asanka
2015/09/04 19:09:03
Removed.
| |
| 1459 // This transaction has already returned headers and possibly response | |
| 1460 // data to the client on the assumption that future network requests will | |
| 1461 // be validated. If this assumption is false, the transaction can't | |
| 1462 // proceed any further. | |
| 1463 int rv = ReleaseCacheEntry(CACHE_ENTRY_DOOM); | |
| 1464 DCHECK_EQ(rv, OK); | |
| 1465 return ERR_UNEXPECTED; | |
| 1466 } | |
| 1467 | |
| 1479 // Something went wrong with this request and we have to restart it. | 1468 // Something went wrong with this request and we have to restart it. |
| 1480 // If we have an authentication response, we are exposed to weird things | 1469 // If we have an authentication response, we are exposed to weird things |
| 1481 // hapenning if the user cancels the authentication before we receive | 1470 // hapenning if the user cancels the authentication before we receive |
| 1482 // the new response. | 1471 // the new response. |
| 1483 net_log_.AddEvent(NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST); | 1472 net_log_.AddEvent(NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST); |
| 1484 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 1473 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
| 1485 response_ = HttpResponseInfo(); | 1474 response_ = HttpResponseInfo(); |
| 1486 ResetNetworkTransaction(); | 1475 ResetNetworkTransaction(); |
| 1487 new_response_ = NULL; | 1476 new_response_ = NULL; |
| 1488 next_state_ = STATE_SEND_REQUEST; | 1477 next_state_ = STATE_SEND_REQUEST; |
| 1489 return OK; | 1478 return OK; |
| 1490 } | 1479 } |
| 1491 | 1480 |
| 1481 if (handling_206_ && stopped_caching_) { | |
| 1482 // The transaction successfully switched over to streaming exclusively from | |
| 1483 // the network. | |
|
rvargas (doing something else)
2015/08/19 23:46:38
why?. Or what do you mean by "exclusively". This m
asanka
2015/09/04 19:09:03
I expanded the condition here to only include the
| |
| 1484 DCHECK(partial_ && partial_->IsLastRange() && | |
| 1485 !partial_->IsCurrentRangeCached()); | |
| 1486 DCHECK(mode_ & WRITE); | |
| 1487 int rv = ReleaseCacheEntry(CACHE_ENTRY_PRESERVE_PREEXISTING); | |
| 1488 DCHECK_EQ(rv, OK); | |
| 1489 mode_ = NONE; | |
| 1490 stopped_caching_ = false; | |
| 1491 next_state_ = STATE_NETWORK_READ; | |
| 1492 return OK; | |
| 1493 } | |
| 1494 | |
| 1492 if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) { | 1495 if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) { |
| 1493 // We have stored the full entry, but it changed and the server is | 1496 // We have stored the full entry, but it changed and the server is |
| 1494 // sending a range. We have to delete the old entry. | 1497 // sending a range. We have to delete the old entry. |
| 1495 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 1498 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
| 1496 DoneWritingToEntry(false); | 1499 DoneWritingToEntry(false); |
| 1497 } | 1500 } |
| 1498 | 1501 |
| 1499 if (mode_ == WRITE && | 1502 if (mode_ == WRITE && |
| 1500 transaction_pattern_ != PATTERN_ENTRY_CANT_CONDITIONALIZE) { | 1503 transaction_pattern_ != PATTERN_ENTRY_CANT_CONDITIONALIZE) { |
| 1501 UpdateTransactionPattern(PATTERN_ENTRY_NOT_CACHED); | 1504 UpdateTransactionPattern(PATTERN_ENTRY_NOT_CACHED); |
| 1502 } | 1505 } |
| 1503 | 1506 |
| 1504 // Invalidate any cached GET with a successful PUT or DELETE. | 1507 // Invalidate any cached GET with a successful PUT or DELETE. |
| 1505 if (mode_ == WRITE && | 1508 if (mode_ == WRITE && |
| 1506 (request_->method == "PUT" || request_->method == "DELETE")) { | 1509 (request_->method == "PUT" || request_->method == "DELETE")) { |
| 1507 if (NonErrorResponse(new_response->headers->response_code())) { | 1510 if (NonErrorResponse(new_response->headers->response_code())) { |
| 1508 int ret = cache_->DoomEntry(cache_key_, NULL); | 1511 int ret = cache_->DoomEntry(cache_key_, NULL); |
| 1509 DCHECK_EQ(OK, ret); | 1512 DCHECK_EQ(OK, ret); |
| 1510 } | 1513 } |
| 1511 cache_->DoneWritingToEntry(entry_, true); | 1514 DoneWritingToEntry(true); |
| 1512 entry_ = NULL; | |
| 1513 mode_ = NONE; | |
| 1514 } | 1515 } |
| 1515 | 1516 |
| 1516 // Invalidate any cached GET with a successful POST. | 1517 // Invalidate any cached GET with a successful POST. |
| 1517 if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) && | 1518 if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) && |
| 1518 request_->method == "POST" && | 1519 request_->method == "POST" && |
| 1519 NonErrorResponse(new_response->headers->response_code())) { | 1520 NonErrorResponse(new_response->headers->response_code())) { |
| 1520 cache_->DoomMainEntryForUrl(request_->url); | 1521 cache_->DoomMainEntryForUrl(request_->url); |
| 1521 } | 1522 } |
| 1522 | 1523 |
| 1523 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); | 1524 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); |
| 1524 | 1525 |
| 1525 if (new_response_->headers->response_code() == 416 && | 1526 if (new_response_->headers->response_code() == 416 && |
| 1526 (request_->method == "GET" || request_->method == "POST")) { | 1527 (request_->method == "GET" || request_->method == "POST")) { |
| 1527 // If there is an active entry it may be destroyed with this transaction. | 1528 // If there is an active entry it may be destroyed with this transaction. |
| 1528 response_ = *new_response_; | 1529 response_ = *new_response_; |
| 1529 return OK; | 1530 return OK; |
| 1530 } | 1531 } |
| 1531 | 1532 |
| 1533 if (stopped_caching_) { | |
| 1534 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | |
| 1535 return OK; | |
| 1536 } | |
| 1537 | |
| 1532 // Are we expecting a response to a conditional query? | 1538 // Are we expecting a response to a conditional query? |
| 1533 if (mode_ == READ_WRITE || mode_ == UPDATE) { | 1539 if (mode_ == READ_WRITE || mode_ == UPDATE) { |
| 1534 if (new_response->headers->response_code() == 304 || handling_206_) { | 1540 if (new_response->headers->response_code() == 304 || handling_206_) { |
| 1535 UpdateTransactionPattern(PATTERN_ENTRY_VALIDATED); | 1541 UpdateTransactionPattern(PATTERN_ENTRY_VALIDATED); |
| 1536 next_state_ = STATE_UPDATE_CACHED_RESPONSE; | 1542 next_state_ = STATE_UPDATE_CACHED_RESPONSE; |
| 1537 return OK; | 1543 return OK; |
| 1538 } | 1544 } |
| 1539 UpdateTransactionPattern(PATTERN_ENTRY_UPDATED); | 1545 UpdateTransactionPattern(PATTERN_ENTRY_UPDATED); |
| 1540 mode_ = WRITE; | 1546 mode_ = WRITE; |
| 1541 } | 1547 } |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1771 next_state_ = STATE_NETWORK_READ_COMPLETE; | 1777 next_state_ = STATE_NETWORK_READ_COMPLETE; |
| 1772 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); | 1778 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); |
| 1773 } | 1779 } |
| 1774 | 1780 |
| 1775 int HttpCache::Transaction::DoNetworkReadComplete(int result) { | 1781 int HttpCache::Transaction::DoNetworkReadComplete(int result) { |
| 1776 DCHECK(mode_ & WRITE || mode_ == NONE); | 1782 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 1777 | 1783 |
| 1778 if (!cache_.get()) | 1784 if (!cache_.get()) |
| 1779 return ERR_UNEXPECTED; | 1785 return ERR_UNEXPECTED; |
| 1780 | 1786 |
| 1781 // If there is an error or we aren't saving the data, we are done; just wait | |
|
rvargas (doing something else)
2015/08/19 23:46:38
Why remove this?
asanka
2015/09/04 19:09:04
Collateral. In an intermediate stage I experimente
| |
| 1782 // until the destructor runs to see if we can keep the data. | |
| 1783 if (mode_ == NONE || result < 0) | 1787 if (mode_ == NONE || result < 0) |
| 1784 return result; | 1788 return result; |
| 1785 | 1789 |
| 1786 next_state_ = STATE_CACHE_WRITE_DATA; | 1790 next_state_ = STATE_CACHE_WRITE_DATA; |
| 1787 return result; | 1791 return result; |
| 1788 } | 1792 } |
| 1789 | 1793 |
| 1790 int HttpCache::Transaction::DoCacheReadData() { | 1794 int HttpCache::Transaction::DoCacheReadData() { |
| 1791 if (request_->method == "HEAD") | 1795 if (request_->method == "HEAD") |
| 1792 return 0; | 1796 return 0; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1844 | 1848 |
| 1845 if (!entry_ || !num_bytes) | 1849 if (!entry_ || !num_bytes) |
| 1846 return num_bytes; | 1850 return num_bytes; |
| 1847 | 1851 |
| 1848 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 1852 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); |
| 1849 return WriteToEntry(kResponseContentIndex, current_size, read_buf_.get(), | 1853 return WriteToEntry(kResponseContentIndex, current_size, read_buf_.get(), |
| 1850 num_bytes, io_callback_); | 1854 num_bytes, io_callback_); |
| 1851 } | 1855 } |
| 1852 | 1856 |
| 1853 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) { | 1857 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) { |
| 1854 if (entry_) { | 1858 if (entry_ && net_log_.IsCapturing()) { |
| 1855 if (net_log_.IsCapturing()) { | 1859 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_WRITE_DATA, |
| 1856 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_WRITE_DATA, | 1860 result); |
| 1857 result); | |
| 1858 } | |
| 1859 } | 1861 } |
| 1862 | |
| 1860 if (!cache_.get()) | 1863 if (!cache_.get()) |
| 1861 return ERR_UNEXPECTED; | 1864 return ERR_UNEXPECTED; |
| 1862 | 1865 |
| 1863 if (result != write_len_) { | 1866 if (result != write_len_) { |
| 1864 DLOG(ERROR) << "failed to write response data to cache"; | 1867 DLOG(ERROR) << "failed to write response data to cache"; |
| 1865 DoneWritingToEntry(false); | 1868 DoneWritingToEntry(false); |
| 1866 | 1869 |
| 1867 // We want to ignore errors writing to disk and just keep reading from | 1870 // We want to ignore errors writing to disk and just keep reading from |
| 1868 // the network. | 1871 // the network. |
| 1869 result = write_len_; | 1872 result = write_len_; |
| 1870 } else if (!done_reading_ && entry_) { | 1873 } else if (!done_reading_ && entry_) { |
| 1871 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 1874 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); |
| 1872 int64 body_size = response_.headers->GetContentLength(); | 1875 int64 body_size = response_.headers->GetContentLength(); |
| 1873 if (body_size >= 0 && body_size <= current_size) | 1876 if (body_size >= 0 && body_size <= current_size) |
| 1874 done_reading_ = true; | 1877 done_reading_ = true; |
| 1875 } | 1878 } |
| 1876 | 1879 |
| 1877 if (partial_) { | 1880 if (partial_) { |
| 1878 // This may be the last request. | 1881 // This may be the last request. |
| 1879 if (result != 0 || truncated_ || | 1882 if (result != 0 || truncated_ || |
| 1880 !(partial_->IsLastRange() || mode_ == WRITE)) { | 1883 !(partial_->IsLastRange() || mode_ == WRITE)) { |
| 1881 return DoPartialNetworkReadCompleted(result); | 1884 return DoPartialNetworkReadCompleted(result); |
| 1882 } | 1885 } |
| 1883 } | 1886 } |
| 1884 | 1887 |
| 1885 if (result == 0) { | 1888 // End of file. This may be the result of a connection problem so see if we |
| 1886 // End of file. This may be the result of a connection problem so see if we | 1889 // have to keep the entry around to be flagged as truncated later on. |
|
rvargas (doing something else)
2015/08/19 23:46:39
nit: "End of file" is not a given anymore (as it i
asanka
2015/09/17 21:59:40
Comment expanded.
| |
| 1887 // have to keep the entry around to be flagged as truncated later on. | 1890 if (result == 0 && (done_reading_ || !entry_ || partial_ || |
| 1888 if (done_reading_ || !entry_ || partial_ || | 1891 response_.headers->GetContentLength() <= 0)) { |
| 1889 response_.headers->GetContentLength() <= 0) { | 1892 DoneWritingToEntry(true); |
| 1890 DoneWritingToEntry(true); | |
| 1891 } | |
| 1892 } | 1893 } |
| 1893 | 1894 |
| 1894 return result; | 1895 return result; |
| 1895 } | 1896 } |
| 1896 | 1897 |
| 1897 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() { | 1898 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() { |
| 1898 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE; | 1899 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE; |
| 1899 return WriteResponseInfoToEntry(true); | 1900 return WriteResponseInfoToEntry(true); |
| 1900 } | 1901 } |
| 1901 | 1902 |
| 1902 int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) { | 1903 int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) { |
| 1903 return OnWriteResponseInfoToEntryComplete(result); | 1904 OnWriteResponseInfoToEntryComplete(result); |
| 1905 if (entry_) { | |
|
rvargas (doing something else)
2015/08/19 23:46:38
Why can we be here without entry_?
asanka
2015/09/04 19:09:04
OnWriteResponseInfoToEntry() will doom and release
| |
| 1906 cache_->DoneWritingToEntry(entry_, true); | |
| 1907 entry_ = nullptr; | |
| 1908 } | |
| 1909 return OK; | |
| 1910 } | |
| 1911 | |
| 1912 int HttpCache::Transaction::DoReleaseCacheEntryAndContinueUsingNetwork() { | |
| 1913 DCHECK(entry_); | |
| 1914 DCHECK(mode_ & WRITE); | |
| 1915 | |
| 1916 if (request_->method != "GET") { | |
|
rvargas (doing something else)
2015/08/19 23:46:38
look at this on StopCaching?
asanka
2015/09/04 19:09:03
StopCaching() can be called prior to Start() being
rvargas (doing something else)
2015/09/11 23:56:17
Wait, why do we want to support that? That use cas
asanka
2015/09/17 21:59:40
It was done initially on the assumption that calle
| |
| 1917 // Skipping between network and cache reads are only expected to work with | |
| 1918 // GET requests. Ignore stopped_caching_ for everything else. | |
| 1919 stopped_caching_ = false; | |
| 1920 next_state_ = network_trans_ ? STATE_NETWORK_READ : STATE_CACHE_READ_DATA; | |
| 1921 return OK; | |
| 1922 } | |
| 1923 | |
| 1924 // The network transaction can only be trivially reused if it can promise to | |
| 1925 // deliver all the bits necessary to fulfil the original request. | |
| 1926 if (network_trans_ && (!partial_ || partial_->IsLastRange())) { | |
| 1927 // Unless this was a sparse entry or a complete preexiting entry, just get | |
|
rvargas (doing something else)
2015/08/19 23:46:39
typo: preexisting
asanka
2015/09/04 19:09:03
comment changed.
| |
| 1928 // rid of the cache entry entirely. If the requestor isn't going to use the | |
| 1929 // entry, we are going to assume that it's unlikely that anyone will. | |
| 1930 int rv = ReleaseCacheEntry(CACHE_ENTRY_PRESERVE_PREEXISTING); | |
| 1931 DCHECK_EQ(rv, OK); | |
| 1932 | |
| 1933 mode_ = NONE; | |
|
rvargas (doing something else)
2015/08/19 23:46:38
Do this inside Realease?
asanka
2015/09/04 19:09:03
Done.
| |
| 1934 stopped_caching_ = false; | |
|
rvargas (doing something else)
2015/08/19 23:46:38
Do we have to set this to false (and elsewhere)? I
rvargas (doing something else)
2015/09/11 23:56:17
I think you missed this :)
asanka
2015/09/17 21:59:40
Indeed! Done.
| |
| 1935 next_state_ = STATE_NETWORK_READ; | |
| 1936 return OK; | |
| 1937 } | |
| 1938 | |
| 1939 // The existing network transaction doesn't cover the entire range we wanted. | |
| 1940 // Let's discard the network transaction and create a new one that will cover | |
| 1941 // the entire range we need. | |
| 1942 if (network_trans_) | |
| 1943 ResetNetworkTransaction(); | |
| 1944 | |
| 1945 // partial_ == nullptr case was handled above. From here we can assume that | |
| 1946 // this transaction has a valid partial state. | |
| 1947 if (!partial_->SkipCacheForRemainder()) { | |
| 1948 // PartialData only refuses to switch to network reads if the entire | |
| 1949 // resource has been accounted for. There's nothing more to do. | |
| 1950 stopped_caching_ = false; | |
| 1951 return OK; | |
| 1952 } | |
| 1953 | |
| 1954 partial_->PrepareCacheValidation(entry_->disk_entry, | |
| 1955 &custom_request_->extra_headers); | |
| 1956 DCHECK(!partial_->IsCurrentRangeCached()); | |
| 1957 | |
| 1958 // Since we are supposedly switching to network reads from cache reads, we | |
| 1959 // still need to validate the cache entry. Since partial_ is now switched to | |
| 1960 // network reads, it will continue with network reads from here on. | |
| 1961 return BeginCacheValidation(); | |
| 1904 } | 1962 } |
| 1905 | 1963 |
| 1906 //----------------------------------------------------------------------------- | 1964 //----------------------------------------------------------------------------- |
| 1907 | 1965 |
| 1908 void HttpCache::Transaction::ReadCertChain() { | 1966 void HttpCache::Transaction::ReadCertChain() { |
| 1909 std::string key = | 1967 std::string key = |
| 1910 GetCacheKeyForCert(response_.ssl_info.cert->os_cert_handle()); | 1968 GetCacheKeyForCert(response_.ssl_info.cert->os_cert_handle()); |
| 1911 const X509Certificate::OSCertHandles& intermediates = | 1969 const X509Certificate::OSCertHandles& intermediates = |
| 1912 response_.ssl_info.cert->GetIntermediateCertificates(); | 1970 response_.ssl_info.cert->GetIntermediateCertificates(); |
| 1913 int dist_from_root = intermediates.size(); | 1971 int dist_from_root = intermediates.size(); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2146 UpdateTransactionPattern(PATTERN_ENTRY_USED); | 2204 UpdateTransactionPattern(PATTERN_ENTRY_USED); |
| 2147 return SetupEntryForRead(); | 2205 return SetupEntryForRead(); |
| 2148 } else { | 2206 } else { |
| 2149 // Make the network request conditional, to see if we may reuse our cached | 2207 // Make the network request conditional, to see if we may reuse our cached |
| 2150 // response. If we cannot do so, then we just resort to a normal fetch. | 2208 // response. If we cannot do so, then we just resort to a normal fetch. |
| 2151 // Our mode remains READ_WRITE for a conditional request. Even if the | 2209 // Our mode remains READ_WRITE for a conditional request. Even if the |
| 2152 // conditionalization fails, we don't switch to WRITE mode until we | 2210 // conditionalization fails, we don't switch to WRITE mode until we |
| 2153 // know we won't be falling back to using the cache entry in the | 2211 // know we won't be falling back to using the cache entry in the |
| 2154 // LOAD_FROM_CACHE_IF_OFFLINE case. | 2212 // LOAD_FROM_CACHE_IF_OFFLINE case. |
| 2155 if (!ConditionalizeRequest()) { | 2213 if (!ConditionalizeRequest()) { |
| 2214 DCHECK(!reading_); // Conditionalization should only depend on the state | |
|
rvargas (doing something else)
2015/08/19 23:46:38
nit:
// comment
// blah
DCHECK();
asanka
2015/09/04 19:09:03
Done.
| |
| 2215 // of the cache prior to starting the request and the | |
| 2216 // request method. Failure is unexpected after the | |
| 2217 // client has started reading the stream. | |
| 2218 | |
| 2156 couldnt_conditionalize_request_ = true; | 2219 couldnt_conditionalize_request_ = true; |
| 2157 UpdateTransactionPattern(PATTERN_ENTRY_CANT_CONDITIONALIZE); | 2220 UpdateTransactionPattern(PATTERN_ENTRY_CANT_CONDITIONALIZE); |
| 2158 if (partial_) | 2221 if (partial_) |
| 2159 return DoRestartPartialRequest(); | 2222 return DoRestartPartialRequest(); |
| 2160 | 2223 |
| 2161 DCHECK_NE(206, response_.headers->response_code()); | 2224 DCHECK_NE(206, response_.headers->response_code()); |
| 2162 } | 2225 } |
| 2163 next_state_ = STATE_SEND_REQUEST; | 2226 next_state_ = STATE_SEND_REQUEST; |
| 2164 } | 2227 } |
| 2165 return OK; | 2228 return OK; |
| (...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2666 result); | 2729 result); |
| 2667 } | 2730 } |
| 2668 | 2731 |
| 2669 if (result != io_buf_len_) { | 2732 if (result != io_buf_len_) { |
| 2670 DLOG(ERROR) << "failed to write response info to cache"; | 2733 DLOG(ERROR) << "failed to write response info to cache"; |
| 2671 DoneWritingToEntry(false); | 2734 DoneWritingToEntry(false); |
| 2672 } | 2735 } |
| 2673 return OK; | 2736 return OK; |
| 2674 } | 2737 } |
| 2675 | 2738 |
| 2739 int HttpCache::Transaction::ReleaseCacheEntry( | |
| 2740 CacheEntryDisposition entry_disposition) { | |
| 2741 if (!cache_ || !entry_) | |
| 2742 return OK; | |
| 2743 | |
| 2744 if (entry_disposition == CACHE_ENTRY_PRESERVE_PREEXISTING) { | |
| 2745 // The CACHE_ENTRY_PRESERVE_PREEXISTING option is used to indicate that the | |
| 2746 // current client is not interested in keeping the cache entry around. Hence | |
| 2747 // get rid of the cache entry unless it's sparse or it existed in its | |
| 2748 // entirety prior to this transaction. | |
|
rvargas (doing something else)
2015/08/19 23:46:38
Why in its entirety?. If there's a truncated entry
asanka
2015/09/04 19:09:03
The deletion is based on the assumption that most
rvargas (doing something else)
2015/09/11 23:56:17
I suspect the assumption is correct, but I also wo
asanka
2015/09/17 21:59:40
True. It's also not a necessary behavior change fo
| |
| 2749 entry_disposition = is_sparse_ || (mode_ == READ_WRITE && !truncated_) | |
|
rvargas (doing something else)
2015/08/19 23:46:38
is_sparse || mode & read || truncated_ ?.
asanka
2015/09/17 21:59:40
Code removed.
| |
| 2750 ? CACHE_ENTRY_PRESERVE | |
| 2751 : CACHE_ENTRY_DOOM; | |
| 2752 } | |
| 2753 | |
| 2754 // Nothing special needs to happen if this transaction didn't write to the | |
| 2755 // entry. Just leave it as is and ignore |entry_disposition|. | |
| 2756 if (!entry_->writer) { | |
|
rvargas (doing something else)
2015/08/19 23:46:38
We should let the cache decide this part.
asanka
2015/09/04 19:09:03
Done.
| |
| 2757 RecordHistograms(); | |
| 2758 cache_->DoneReadingFromEntry(entry_, this); | |
| 2759 entry_ = nullptr; | |
| 2760 return OK; | |
| 2761 } | |
| 2762 | |
| 2763 // TODO(asanka): This shouldn't be necessary. HttpCache::DoneWritingToEntry | |
| 2764 // should destroy the entry if it's already doomed instead of relying on the | |
| 2765 // |success| parameter to decide to do so. | |
| 2766 if (entry_->doomed) | |
| 2767 entry_disposition = CACHE_ENTRY_DOOM; | |
|
rvargas (doing something else)
2015/08/19 23:46:38
Does this do anything?
asanka
2015/09/04 19:09:04
DoneWithEntry would only destroy the entry and fir
rvargas (doing something else)
2015/09/11 23:56:17
if entry_->doomed is on, the entry will be discard
asanka
2015/09/17 21:59:40
Yes. But if there are pending transactions, then H
rvargas (doing something else)
2015/09/19 01:09:34
I see what you mean. I agree that the cache should
| |
| 2768 | |
| 2769 // The entry should be kept around only if we can use it later. However, the | |
| 2770 // entry should be marked as truncated if the transaction stopped writing to | |
| 2771 // it prematurely. | |
| 2772 if (entry_disposition == CACHE_ENTRY_PRESERVE && !is_sparse_ && reading_ && | |
|
rvargas (doing something else)
2015/08/19 23:46:38
is_sparse != partial_ && !truncated_ (which is wha
asanka
2015/09/17 21:59:40
I moved this condition to AbandonCacheEntry().
| |
| 2773 !done_reading_ && (mode_ & WRITE)) { | |
| 2774 if (CanResume(true)) { | |
| 2775 truncated_ = true; | |
| 2776 return DoCacheWriteTruncatedResponse(); | |
|
rvargas (doing something else)
2015/08/19 23:46:38
I don't believe we call a SM method directly anywh
asanka
2015/09/04 19:09:04
Yeah. Fixed. I moved the logic for abandoning a ca
| |
| 2777 } | |
| 2778 // The entry is incomplete and cannot be resumed. The data we have cannot be | |
| 2779 // used. | |
| 2780 entry_disposition = CACHE_ENTRY_DOOM; | |
| 2781 } | |
| 2782 | |
| 2783 DCHECK_EQ(this, entry_->writer); | |
| 2784 cache_->DoneWritingToEntry(entry_, entry_disposition == CACHE_ENTRY_PRESERVE); | |
| 2785 entry_ = nullptr; | |
| 2786 return OK; | |
| 2787 } | |
| 2788 | |
| 2676 void HttpCache::Transaction::DoneWritingToEntry(bool success) { | 2789 void HttpCache::Transaction::DoneWritingToEntry(bool success) { |
| 2677 if (!entry_) | 2790 if (!entry_) |
| 2678 return; | 2791 return; |
| 2679 | 2792 |
| 2680 RecordHistograms(); | 2793 RecordHistograms(); |
| 2681 | 2794 |
| 2682 cache_->DoneWritingToEntry(entry_, success); | 2795 cache_->DoneWritingToEntry(entry_, success); |
| 2683 entry_ = NULL; | 2796 entry_ = NULL; |
| 2797 stopped_caching_ = false; | |
| 2684 mode_ = NONE; // switch to 'pass through' mode | 2798 mode_ = NONE; // switch to 'pass through' mode |
| 2685 } | 2799 } |
| 2686 | 2800 |
| 2687 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { | 2801 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { |
| 2688 DLOG(ERROR) << "ReadData failed: " << result; | 2802 DLOG(ERROR) << "ReadData failed: " << result; |
| 2689 const int result_for_histogram = std::max(0, -result); | 2803 const int result_for_histogram = std::max(0, -result); |
| 2690 if (restart) { | 2804 if (restart) { |
| 2691 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", | 2805 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", |
| 2692 result_for_histogram); | 2806 result_for_histogram); |
| 2693 } else { | 2807 } else { |
| 2694 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable", | 2808 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable", |
| 2695 result_for_histogram); | 2809 result_for_histogram); |
| 2696 } | 2810 } |
| 2697 | 2811 |
| 2698 // Avoid using this entry in the future. | 2812 // Avoid using this entry in the future. |
| 2699 if (cache_.get()) | 2813 if (cache_.get()) |
| 2700 cache_->DoomActiveEntry(cache_key_); | 2814 cache_->DoomActiveEntry(cache_key_); |
| 2701 | 2815 |
| 2702 if (restart) { | 2816 if (restart) { |
| 2703 DCHECK(!reading_); | 2817 DCHECK(!reading_); |
| 2704 DCHECK(!network_trans_.get()); | 2818 DCHECK(!network_trans_.get()); |
| 2705 cache_->DoneWithEntry(entry_, this, false); | 2819 int rv = ReleaseCacheEntry(CACHE_ENTRY_DOOM); |
| 2706 entry_ = NULL; | 2820 DCHECK_EQ(rv, OK); |
| 2707 is_sparse_ = false; | |
|
rvargas (doing something else)
2015/08/19 23:46:38
We're losing this part (and the transaction will b
asanka
2015/09/04 19:09:04
Reinstated.
| |
| 2708 partial_.reset(); | 2821 partial_.reset(); |
| 2709 next_state_ = STATE_GET_BACKEND; | 2822 next_state_ = STATE_GET_BACKEND; |
| 2710 return OK; | 2823 return OK; |
| 2711 } | 2824 } |
| 2712 | 2825 |
| 2713 return ERR_CACHE_READ_FAILURE; | 2826 return ERR_CACHE_READ_FAILURE; |
| 2714 } | 2827 } |
| 2715 | 2828 |
| 2716 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { | 2829 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { |
| 2717 if (entry_lock_waiting_since_ != start_time) | 2830 if (entry_lock_waiting_since_ != start_time) |
| 2718 return; | 2831 return; |
| 2719 | 2832 |
| 2720 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); | 2833 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); |
| 2721 | 2834 |
| 2722 if (!cache_) | 2835 if (!cache_) |
| 2723 return; | 2836 return; |
| 2724 | 2837 |
| 2725 cache_->RemovePendingTransaction(this); | 2838 cache_->RemovePendingTransaction(this); |
| 2726 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); | 2839 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); |
| 2727 } | 2840 } |
| 2728 | 2841 |
| 2729 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { | 2842 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { |
| 2730 DVLOG(2) << "DoomPartialEntry"; | 2843 DVLOG(2) << "DoomPartialEntry"; |
| 2731 int rv = cache_->DoomEntry(cache_key_, NULL); | 2844 int rv = cache_->DoomEntry(cache_key_, NULL); |
| 2732 DCHECK_EQ(OK, rv); | 2845 DCHECK_EQ(rv, OK); |
| 2733 cache_->DoneWithEntry(entry_, this, false); | 2846 rv = ReleaseCacheEntry(CACHE_ENTRY_DOOM); |
| 2734 entry_ = NULL; | 2847 DCHECK_EQ(rv, OK); |
| 2735 is_sparse_ = false; | 2848 is_sparse_ = false; |
| 2736 truncated_ = false; | 2849 truncated_ = false; |
| 2737 if (delete_object) | 2850 if (delete_object) |
| 2738 partial_.reset(NULL); | 2851 partial_.reset(); |
| 2739 } | 2852 } |
| 2740 | 2853 |
| 2741 int HttpCache::Transaction::DoPartialNetworkReadCompleted(int result) { | 2854 int HttpCache::Transaction::DoPartialNetworkReadCompleted(int result) { |
| 2742 partial_->OnNetworkReadCompleted(result); | 2855 partial_->OnNetworkReadCompleted(result); |
| 2743 | 2856 |
| 2744 if (result == 0) { | 2857 if (result == 0) { |
| 2745 // We need to move on to the next range. | 2858 // We need to move on to the next range. |
| 2746 ResetNetworkTransaction(); | 2859 ResetNetworkTransaction(); |
| 2747 next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; | 2860 next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; |
| 2748 } | 2861 } |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2836 void HttpCache::Transaction::UpdateTransactionPattern( | 2949 void HttpCache::Transaction::UpdateTransactionPattern( |
| 2837 TransactionPattern new_transaction_pattern) { | 2950 TransactionPattern new_transaction_pattern) { |
| 2838 if (transaction_pattern_ == PATTERN_NOT_COVERED) | 2951 if (transaction_pattern_ == PATTERN_NOT_COVERED) |
| 2839 return; | 2952 return; |
| 2840 DCHECK(transaction_pattern_ == PATTERN_UNDEFINED || | 2953 DCHECK(transaction_pattern_ == PATTERN_UNDEFINED || |
| 2841 new_transaction_pattern == PATTERN_NOT_COVERED); | 2954 new_transaction_pattern == PATTERN_NOT_COVERED); |
| 2842 transaction_pattern_ = new_transaction_pattern; | 2955 transaction_pattern_ = new_transaction_pattern; |
| 2843 } | 2956 } |
| 2844 | 2957 |
| 2845 void HttpCache::Transaction::RecordHistograms() { | 2958 void HttpCache::Transaction::RecordHistograms() { |
| 2846 DCHECK_NE(PATTERN_UNDEFINED, transaction_pattern_); | 2959 if (transaction_pattern_ == PATTERN_UNDEFINED) |
|
rvargas (doing something else)
2015/08/19 23:46:38
nit: consolidate with the next line.
rvargas (doing something else)
2015/08/19 23:46:39
Now that we can reach this code without having ins
asanka
2015/09/04 19:09:04
Done. Also consolidated with next line.
| |
| 2960 return; | |
| 2847 if (!cache_.get() || !cache_->GetCurrentBackend() || | 2961 if (!cache_.get() || !cache_->GetCurrentBackend() || |
| 2848 cache_->GetCurrentBackend()->GetCacheType() != DISK_CACHE || | 2962 cache_->GetCurrentBackend()->GetCacheType() != DISK_CACHE || |
| 2849 cache_->mode() != NORMAL || request_->method != "GET") { | 2963 cache_->mode() != NORMAL || request_->method != "GET") { |
| 2850 return; | 2964 return; |
| 2851 } | 2965 } |
| 2852 UMA_HISTOGRAM_ENUMERATION( | 2966 UMA_HISTOGRAM_ENUMERATION( |
| 2853 "HttpCache.Pattern", transaction_pattern_, PATTERN_MAX); | 2967 "HttpCache.Pattern", transaction_pattern_, PATTERN_MAX); |
| 2854 if (transaction_pattern_ == PATTERN_NOT_COVERED) | 2968 if (transaction_pattern_ == PATTERN_NOT_COVERED) |
| 2855 return; | 2969 return; |
| 2856 DCHECK(!range_requested_); | 2970 DCHECK(!range_requested_); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2918 default: | 3032 default: |
| 2919 NOTREACHED(); | 3033 NOTREACHED(); |
| 2920 } | 3034 } |
| 2921 } | 3035 } |
| 2922 | 3036 |
| 2923 void HttpCache::Transaction::OnIOComplete(int result) { | 3037 void HttpCache::Transaction::OnIOComplete(int result) { |
| 2924 DoLoop(result); | 3038 DoLoop(result); |
| 2925 } | 3039 } |
| 2926 | 3040 |
| 2927 } // namespace net | 3041 } // namespace net |
| OLD | NEW |