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

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

Issue 1230113012: [net] Better StopCaching() handling for HttpCache::Transaction. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Release cache lock early and request open range if it's the final range. Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 new_entry_(NULL), 256 new_entry_(NULL),
257 new_response_(NULL), 257 new_response_(NULL),
258 mode_(NONE), 258 mode_(NONE),
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_writing_(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) {
(...skipping 14 matching lines...) Expand all
293 if (entry_) { 294 if (entry_) {
294 bool cancel_request = reading_ && response_.headers.get(); 295 bool cancel_request = reading_ && response_.headers.get();
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 DoneWithEntry(cancel_request);
304 } else if (cache_pending_) { 305 } else if (cache_pending_) {
305 cache_->RemovePendingTransaction(this); 306 cache_->RemovePendingTransaction(this);
306 } 307 }
307 } 308 }
308 } 309 }
309 310
310 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len, 311 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len,
311 const CompletionCallback& callback) { 312 const CompletionCallback& callback) {
312 DCHECK(buf); 313 DCHECK(buf);
313 DCHECK_GT(buf_len, 0); 314 DCHECK_GT(buf_len, 0);
(...skipping 13 matching lines...) Expand all
327 DCHECK(mode_ & WRITE || mode_ == NONE); 328 DCHECK(mode_ & WRITE || mode_ == NONE);
328 329
329 // Don't set the flag for sparse entries. 330 // Don't set the flag for sparse entries.
330 if (is_sparse_) 331 if (is_sparse_)
331 return true; 332 return true;
332 333
333 if (!CanResume(true)) 334 if (!CanResume(true))
334 return false; 335 return false;
335 336
336 // We may have received the whole resource already. 337 // We may have received the whole resource already.
337 if (done_reading_) 338 if (done_writing_)
338 return true; 339 return true;
339 340
340 truncated_ = true; 341 truncated_ = true;
341 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE; 342 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE;
342 DoLoop(OK); 343 DoLoop(OK);
343 return true; 344 return true;
344 } 345 }
345 346
346 LoadState HttpCache::Transaction::GetWriterLoadState() const { 347 LoadState HttpCache::Transaction::GetWriterLoadState() const {
347 if (network_trans_.get()) 348 if (network_trans_.get())
(...skipping 11 matching lines...) Expand all
359 const CompletionCallback& callback, 360 const CompletionCallback& callback,
360 const BoundNetLog& net_log) { 361 const BoundNetLog& net_log) {
361 DCHECK(request); 362 DCHECK(request);
362 DCHECK(!callback.is_null()); 363 DCHECK(!callback.is_null());
363 364
364 // Ensure that we only have one asynchronous call at a time. 365 // Ensure that we only have one asynchronous call at a time.
365 DCHECK(callback_.is_null()); 366 DCHECK(callback_.is_null());
366 DCHECK(!reading_); 367 DCHECK(!reading_);
367 DCHECK(!network_trans_.get()); 368 DCHECK(!network_trans_.get());
368 DCHECK(!entry_); 369 DCHECK(!entry_);
369 DCHECK_EQ(next_state_, STATE_NONE); 370 DCHECK_EQ(STATE_NONE, next_state_);
rvargas (doing something else) 2015/07/27 22:25:12 Don't invert the arguments. DCHECKs should read li
asanka 2015/08/18 22:46:59 Done.
370 371
371 if (!cache_.get()) 372 if (!cache_.get())
372 return ERR_UNEXPECTED; 373 return ERR_UNEXPECTED;
373 374
374 SetRequest(net_log, request); 375 SetRequest(net_log, request);
375 376
376 // We have to wait until the backend is initialized so we start the SM. 377 // We have to wait until the backend is initialized so we start the SM.
377 next_state_ = STATE_GET_BACKEND; 378 next_state_ = STATE_GET_BACKEND;
378 int rv = DoLoop(OK); 379 int rv = DoLoop(OK);
379 380
380 // Setting this here allows us to check for the existence of a callback_ to 381 // Setting this here allows us to check for the existence of a callback_ to
381 // determine if we are still inside Start. 382 // determine if we are still inside Start.
382 if (rv == ERR_IO_PENDING) 383 if (rv == ERR_IO_PENDING)
383 callback_ = callback; 384 callback_ = callback;
384 385
385 return rv; 386 return rv;
386 } 387 }
387 388
388 int HttpCache::Transaction::RestartIgnoringLastError( 389 int HttpCache::Transaction::RestartIgnoringLastError(
389 const CompletionCallback& callback) { 390 const CompletionCallback& callback) {
390 DCHECK(!callback.is_null()); 391 DCHECK(!callback.is_null());
391 392
392 // Ensure that we only have one asynchronous call at a time. 393 // Ensure that we only have one asynchronous call at a time.
393 DCHECK(callback_.is_null()); 394 DCHECK(callback_.is_null());
395 DCHECK_EQ(STATE_NONE, next_state_);
394 396
395 if (!cache_.get()) 397 if (!cache_.get())
396 return ERR_UNEXPECTED; 398 return ERR_UNEXPECTED;
397 399
398 int rv = RestartNetworkRequest(); 400 int rv = RestartNetworkRequest();
399 401
400 if (rv == ERR_IO_PENDING) 402 if (rv == ERR_IO_PENDING)
401 callback_ = callback; 403 callback_ = callback;
402 404
403 return rv; 405 return rv;
404 } 406 }
405 407
406 int HttpCache::Transaction::RestartWithCertificate( 408 int HttpCache::Transaction::RestartWithCertificate(
407 X509Certificate* client_cert, 409 X509Certificate* client_cert,
408 const CompletionCallback& callback) { 410 const CompletionCallback& callback) {
409 DCHECK(!callback.is_null()); 411 DCHECK(!callback.is_null());
410 412
411 // Ensure that we only have one asynchronous call at a time. 413 // Ensure that we only have one asynchronous call at a time.
412 DCHECK(callback_.is_null()); 414 DCHECK(callback_.is_null());
415 DCHECK_EQ(STATE_NONE, next_state_);
413 416
414 if (!cache_.get()) 417 if (!cache_.get())
415 return ERR_UNEXPECTED; 418 return ERR_UNEXPECTED;
416 419
417 int rv = RestartNetworkRequestWithCertificate(client_cert); 420 int rv = RestartNetworkRequestWithCertificate(client_cert);
418 421
419 if (rv == ERR_IO_PENDING) 422 if (rv == ERR_IO_PENDING)
420 callback_ = callback; 423 callback_ = callback;
421 424
422 return rv; 425 return rv;
423 } 426 }
424 427
425 int HttpCache::Transaction::RestartWithAuth( 428 int HttpCache::Transaction::RestartWithAuth(
426 const AuthCredentials& credentials, 429 const AuthCredentials& credentials,
427 const CompletionCallback& callback) { 430 const CompletionCallback& callback) {
428 DCHECK(auth_response_.headers.get()); 431 DCHECK(auth_response_.headers.get());
429 DCHECK(!callback.is_null()); 432 DCHECK(!callback.is_null());
430 433
431 // Ensure that we only have one asynchronous call at a time. 434 // Ensure that we only have one asynchronous call at a time.
432 DCHECK(callback_.is_null()); 435 DCHECK(callback_.is_null());
436 DCHECK_EQ(STATE_NONE, next_state_);
433 437
434 if (!cache_.get()) 438 if (!cache_.get())
435 return ERR_UNEXPECTED; 439 return ERR_UNEXPECTED;
436 440
437 // Clear the intermediate response since we are going to start over. 441 // Clear the intermediate response since we are going to start over.
438 auth_response_ = HttpResponseInfo(); 442 auth_response_ = HttpResponseInfo();
439 443
440 int rv = RestartNetworkRequestWithAuth(credentials); 444 int rv = RestartNetworkRequestWithAuth(credentials);
441 445
442 if (rv == ERR_IO_PENDING) 446 if (rv == ERR_IO_PENDING)
443 callback_ = callback; 447 callback_ = callback;
444 448
445 return rv; 449 return rv;
446 } 450 }
447 451
448 bool HttpCache::Transaction::IsReadyToRestartForAuth() { 452 bool HttpCache::Transaction::IsReadyToRestartForAuth() {
449 if (!network_trans_.get()) 453 if (!network_trans_.get())
450 return false; 454 return false;
451 return network_trans_->IsReadyToRestartForAuth(); 455 return network_trans_->IsReadyToRestartForAuth();
452 } 456 }
453 457
454 int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len, 458 int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len,
455 const CompletionCallback& callback) { 459 const CompletionCallback& callback) {
456 DCHECK_EQ(next_state_, STATE_NONE);
457 DCHECK(buf); 460 DCHECK(buf);
458 DCHECK_GT(buf_len, 0); 461 DCHECK_GT(buf_len, 0);
459 DCHECK(!callback.is_null()); 462 DCHECK(!callback.is_null());
460 463
464 // Ensure that we only have one asynchronous call at a time.
461 DCHECK(callback_.is_null()); 465 DCHECK(callback_.is_null());
466 DCHECK_EQ(next_state_, STATE_NONE);
462 467
463 if (!cache_.get()) 468 if (!cache_.get())
464 return ERR_UNEXPECTED; 469 return ERR_UNEXPECTED;
465 470
466 // If we have an intermediate auth response at this point, then it means the 471 // 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 472 // 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. 473 // previous response in the cache then we should leave it intact.
469 if (auth_response_.headers.get() && mode_ != NONE) { 474 if (auth_response_.headers.get() && mode_ != NONE) {
470 UpdateTransactionPattern(PATTERN_NOT_COVERED); 475 UpdateTransactionPattern(PATTERN_NOT_COVERED);
471 DCHECK(mode_ & WRITE); 476 DCHECK(mode_ & WRITE);
(...skipping 16 matching lines...) Expand all
488 int rv = DoLoop(OK); 493 int rv = DoLoop(OK);
489 494
490 if (rv == ERR_IO_PENDING) { 495 if (rv == ERR_IO_PENDING) {
491 DCHECK(callback_.is_null()); 496 DCHECK(callback_.is_null());
492 callback_ = callback; 497 callback_ = callback;
493 } 498 }
494 return rv; 499 return rv;
495 } 500 }
496 501
497 void HttpCache::Transaction::StopCaching() { 502 void HttpCache::Transaction::StopCaching() {
498 // We really don't know where we are now. Hopefully there is no operation in 503 stopped_caching_ = true;
499 // progress, but nothing really prevents this method to be called after we 504 UpdateTransactionPattern(PATTERN_NOT_COVERED);
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 } 505 }
514 506
515 bool HttpCache::Transaction::GetFullRequestHeaders( 507 bool HttpCache::Transaction::GetFullRequestHeaders(
516 HttpRequestHeaders* headers) const { 508 HttpRequestHeaders* headers) const {
517 if (network_trans_) 509 if (network_trans_)
518 return network_trans_->GetFullRequestHeaders(headers); 510 return network_trans_->GetFullRequestHeaders(headers);
519 511
520 // TODO(ttuttle): Read headers from cache. 512 // TODO(ttuttle): Read headers from cache.
521 return false; 513 return false;
522 } 514 }
523 515
524 int64 HttpCache::Transaction::GetTotalReceivedBytes() const { 516 int64 HttpCache::Transaction::GetTotalReceivedBytes() const {
525 int64 total_received_bytes = total_received_bytes_; 517 int64 total_received_bytes = total_received_bytes_;
526 if (network_trans_) 518 if (network_trans_)
527 total_received_bytes += network_trans_->GetTotalReceivedBytes(); 519 total_received_bytes += network_trans_->GetTotalReceivedBytes();
528 return total_received_bytes; 520 return total_received_bytes;
529 } 521 }
530 522
531 void HttpCache::Transaction::DoneReading() { 523 void HttpCache::Transaction::DoneReading() {
532 if (cache_.get() && entry_) { 524 DCHECK_NE(mode_, UPDATE);
533 DCHECK_NE(mode_, UPDATE); 525 DoneWithRequest();
534 if (mode_ & WRITE) {
535 DoneWritingToEntry(true);
536 } else if (mode_ & READ) {
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 } 526 }
545 527
546 const HttpResponseInfo* HttpCache::Transaction::GetResponseInfo() const { 528 const HttpResponseInfo* HttpCache::Transaction::GetResponseInfo() const {
547 // Null headers means we encountered an error or haven't a response yet 529 // Null headers means we encountered an error or haven't a response yet
548 if (auth_response_.headers.get()) 530 if (auth_response_.headers.get())
549 return &auth_response_; 531 return &auth_response_;
550 return &response_; 532 return &response_;
551 } 533 }
552 534
553 LoadState HttpCache::Transaction::GetLoadState() const { 535 LoadState HttpCache::Transaction::GetLoadState() const {
(...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 // We may end up here multiple times for a given request. 1328 // We may end up here multiple times for a given request.
1347 int HttpCache::Transaction::DoStartPartialCacheValidation() { 1329 int HttpCache::Transaction::DoStartPartialCacheValidation() {
1348 if (mode_ == NONE) 1330 if (mode_ == NONE)
1349 return OK; 1331 return OK;
1350 1332
1351 next_state_ = STATE_COMPLETE_PARTIAL_CACHE_VALIDATION; 1333 next_state_ = STATE_COMPLETE_PARTIAL_CACHE_VALIDATION;
1352 return partial_->ShouldValidateCache(entry_->disk_entry, io_callback_); 1334 return partial_->ShouldValidateCache(entry_->disk_entry, io_callback_);
1353 } 1335 }
1354 1336
1355 int HttpCache::Transaction::DoCompletePartialCacheValidation(int result) { 1337 int HttpCache::Transaction::DoCompletePartialCacheValidation(int result) {
1356 if (!result) { 1338 // This is the end of the request.
1357 // This is the end of the request. 1339 if (!result)
1358 if (mode_ & WRITE) { 1340 return DoneWithRequest();
1359 DoneWritingToEntry(true);
1360 } else {
1361 cache_->DoneReadingFromEntry(entry_, this);
1362 entry_ = NULL;
1363 }
1364 return result;
1365 }
1366 1341
1367 if (result < 0) 1342 if (result < 0)
1368 return result; 1343 return result;
1369 1344
1370 partial_->PrepareCacheValidation(entry_->disk_entry, 1345 partial_->PrepareCacheValidation(entry_->disk_entry,
1371 &custom_request_->extra_headers); 1346 &custom_request_->extra_headers);
1372 1347
1373 if (reading_ && partial_->IsCurrentRangeCached()) { 1348 if (reading_ && partial_->IsCurrentRangeCached()) {
1374 next_state_ = STATE_CACHE_READ_DATA; 1349 next_state_ = STATE_CACHE_READ_DATA;
1375 return OK; 1350 return OK;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1501 UpdateTransactionPattern(PATTERN_ENTRY_NOT_CACHED); 1476 UpdateTransactionPattern(PATTERN_ENTRY_NOT_CACHED);
1502 } 1477 }
1503 1478
1504 // Invalidate any cached GET with a successful PUT or DELETE. 1479 // Invalidate any cached GET with a successful PUT or DELETE.
1505 if (mode_ == WRITE && 1480 if (mode_ == WRITE &&
1506 (request_->method == "PUT" || request_->method == "DELETE")) { 1481 (request_->method == "PUT" || request_->method == "DELETE")) {
1507 if (NonErrorResponse(new_response->headers->response_code())) { 1482 if (NonErrorResponse(new_response->headers->response_code())) {
1508 int ret = cache_->DoomEntry(cache_key_, NULL); 1483 int ret = cache_->DoomEntry(cache_key_, NULL);
1509 DCHECK_EQ(OK, ret); 1484 DCHECK_EQ(OK, ret);
1510 } 1485 }
1511 cache_->DoneWritingToEntry(entry_, true); 1486 DoneWritingToEntry(true);
1512 entry_ = NULL;
1513 mode_ = NONE;
1514 } 1487 }
1515 1488
1516 // Invalidate any cached GET with a successful POST. 1489 // Invalidate any cached GET with a successful POST.
1517 if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) && 1490 if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) &&
1518 request_->method == "POST" && 1491 request_->method == "POST" &&
1519 NonErrorResponse(new_response->headers->response_code())) { 1492 NonErrorResponse(new_response->headers->response_code())) {
1520 cache_->DoomMainEntryForUrl(request_->url); 1493 cache_->DoomMainEntryForUrl(request_->url);
1521 } 1494 }
1522 1495
1523 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); 1496 RecordNoStoreHeaderHistogram(request_->load_flags, new_response);
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1638 1611
1639 // We change the value of Content-Length for partial content. 1612 // We change the value of Content-Length for partial content.
1640 if (handling_206_ && partial_) 1613 if (handling_206_ && partial_)
1641 partial_->FixContentLength(new_response_->headers.get()); 1614 partial_->FixContentLength(new_response_->headers.get());
1642 1615
1643 response_ = *new_response_; 1616 response_ = *new_response_;
1644 1617
1645 if (request_->method == "HEAD") { 1618 if (request_->method == "HEAD") {
1646 // This response is replacing the cached one. 1619 // This response is replacing the cached one.
1647 DoneWritingToEntry(false); 1620 DoneWritingToEntry(false);
1648 mode_ = NONE;
1649 new_response_ = NULL; 1621 new_response_ = NULL;
1650 return OK; 1622 return OK;
1651 } 1623 }
1652 1624
1653 if (handling_206_ && !CanResume(false)) { 1625 if (handling_206_ && !CanResume(false)) {
1654 // There is no point in storing this resource because it will never be used. 1626 // 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. 1627 // This may change if we support LOAD_ONLY_FROM_CACHE with sparse entries.
1656 DoneWritingToEntry(false); 1628 DoneWritingToEntry(false);
1657 if (partial_) 1629 if (partial_)
1658 partial_->FixResponseHeaders(response_.headers.get(), true); 1630 partial_->FixResponseHeaders(response_.headers.get(), true);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1771 next_state_ = STATE_NETWORK_READ_COMPLETE; 1743 next_state_ = STATE_NETWORK_READ_COMPLETE;
1772 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); 1744 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_);
1773 } 1745 }
1774 1746
1775 int HttpCache::Transaction::DoNetworkReadComplete(int result) { 1747 int HttpCache::Transaction::DoNetworkReadComplete(int result) {
1776 DCHECK(mode_ & WRITE || mode_ == NONE); 1748 DCHECK(mode_ & WRITE || mode_ == NONE);
1777 1749
1778 if (!cache_.get()) 1750 if (!cache_.get())
1779 return ERR_UNEXPECTED; 1751 return ERR_UNEXPECTED;
1780 1752
1781 // If there is an error or we aren't saving the data, we are done; just wait 1753 if (result < 0)
1782 // until the destructor runs to see if we can keep the data.
1783 if (mode_ == NONE || result < 0)
1784 return result; 1754 return result;
1785 1755
1756 // Skip writing if StopCaching() has been called.
1757 //
1758 // For partial requests the transaction still needs to update its state. If
1759 // the network transaction being read was conditionalized, the cache
1760 // transaction may need to issue additional network or cache reads to fulfil
1761 // the original request.
1762 if (stopped_caching_ && partial_)
1763 return DoPartialNetworkReadCompleted(result);
1764
1765 if (mode_ == NONE || stopped_caching_)
1766 return DoReadComplete(result);
1767
1786 next_state_ = STATE_CACHE_WRITE_DATA; 1768 next_state_ = STATE_CACHE_WRITE_DATA;
1787 return result; 1769 return result;
1788 } 1770 }
1789 1771
1790 int HttpCache::Transaction::DoCacheReadData() { 1772 int HttpCache::Transaction::DoCacheReadData() {
1791 if (request_->method == "HEAD") 1773 if (request_->method == "HEAD")
1792 return 0; 1774 return 0;
1793 1775
1794 DCHECK(entry_); 1776 DCHECK(entry_);
1795 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; 1777 next_state_ = STATE_CACHE_READ_DATA_COMPLETE;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1844 1826
1845 if (!entry_ || !num_bytes) 1827 if (!entry_ || !num_bytes)
1846 return num_bytes; 1828 return num_bytes;
1847 1829
1848 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); 1830 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex);
1849 return WriteToEntry(kResponseContentIndex, current_size, read_buf_.get(), 1831 return WriteToEntry(kResponseContentIndex, current_size, read_buf_.get(),
1850 num_bytes, io_callback_); 1832 num_bytes, io_callback_);
1851 } 1833 }
1852 1834
1853 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) { 1835 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) {
1854 if (entry_) { 1836 if (entry_ && net_log_.IsCapturing())
rvargas (doing something else) 2015/07/27 22:25:12 needs {}
asanka 2015/08/18 22:46:59 Done.
1855 if (net_log_.IsCapturing()) { 1837 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_WRITE_DATA,
1856 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_WRITE_DATA, 1838 result);
1857 result);
1858 }
1859 }
1860 if (!cache_.get()) 1839 if (!cache_.get())
1861 return ERR_UNEXPECTED; 1840 return ERR_UNEXPECTED;
1862 1841
1863 if (result != write_len_) { 1842 if (result != write_len_) {
1864 DLOG(ERROR) << "failed to write response data to cache"; 1843 DLOG(ERROR) << "failed to write response data to cache";
1865 DoneWritingToEntry(false); 1844 DoneWritingToEntry(false);
1866 1845
1867 // We want to ignore errors writing to disk and just keep reading from 1846 // We want to ignore errors writing to disk and just keep reading from
1868 // the network. 1847 // the network.
1869 result = write_len_; 1848 result = write_len_;
1870 } else if (!done_reading_ && entry_) { 1849 } else if (!done_writing_ && entry_) {
1871 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); 1850 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex);
1872 int64 body_size = response_.headers->GetContentLength(); 1851 int64 body_size = response_.headers->GetContentLength();
1873 if (body_size >= 0 && body_size <= current_size) 1852 if (body_size >= 0 && body_size <= current_size)
1874 done_reading_ = true; 1853 done_writing_ = true;
rvargas (doing something else) 2015/07/27 22:25:12 We should probably keep the old name. So far, it s
asanka 2015/08/18 22:46:59 Changed to the old name.
1875 } 1854 }
1876 1855
1877 if (partial_) { 1856 if (partial_) {
1878 // This may be the last request. 1857 // This may be the last request.
1879 if (result != 0 || truncated_ || 1858 if (result != 0 || truncated_ ||
1880 !(partial_->IsLastRange() || mode_ == WRITE)) { 1859 !(partial_->IsLastRange() || mode_ == WRITE)) {
1881 return DoPartialNetworkReadCompleted(result); 1860 return DoPartialNetworkReadCompleted(result);
1882 } 1861 }
1883 } 1862 }
1884 1863
1885 if (result == 0) { 1864 if (result == 0) {
1886 // End of file. This may be the result of a connection problem so see if we 1865 // End of file. This may be the result of a connection problem so see if we
1887 // have to keep the entry around to be flagged as truncated later on. 1866 // have to keep the entry around to be flagged as truncated later on.
1888 if (done_reading_ || !entry_ || partial_ || 1867 if (done_writing_ || !entry_ || partial_ ||
1889 response_.headers->GetContentLength() <= 0) { 1868 response_.headers->GetContentLength() <= 0)
rvargas (doing something else) 2015/07/27 22:25:12 needs {}
asanka 2015/08/18 22:46:59 Done.
1890 DoneWritingToEntry(true); 1869 DoneWritingToEntry(true);
1891 }
1892 } 1870 }
1893 1871
1894 return result; 1872 return result;
1895 } 1873 }
1896 1874
1897 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() { 1875 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() {
1898 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE; 1876 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE;
1899 return WriteResponseInfoToEntry(true); 1877 return WriteResponseInfoToEntry(true);
1900 } 1878 }
1901 1879
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after
2666 result); 2644 result);
2667 } 2645 }
2668 2646
2669 if (result != io_buf_len_) { 2647 if (result != io_buf_len_) {
2670 DLOG(ERROR) << "failed to write response info to cache"; 2648 DLOG(ERROR) << "failed to write response info to cache";
2671 DoneWritingToEntry(false); 2649 DoneWritingToEntry(false);
2672 } 2650 }
2673 return OK; 2651 return OK;
2674 } 2652 }
2675 2653
2654 int HttpCache::Transaction::DoneWithRequest() {
2655 DCHECK_EQ(STATE_NONE, next_state_);
2656
2657 if (!cache_ || !entry_)
2658 return OK;
2659
2660 if (!(mode_ & WRITE)) {
2661 cache_->DoneReadingFromEntry(entry_, this);
2662 entry_ = nullptr;
2663 return OK;
2664 }
2665
2666 if (stopped_caching_ && !is_sparse_ && !done_writing_ && !entry_->doomed) {
2667 if (CanResume(true)) {
2668 truncated_ = true;
2669 return DoCacheWriteTruncatedResponse();
rvargas (doing something else) 2015/07/27 22:25:12 This may return pending and that is not expected b
asanka 2015/08/18 22:46:59 This code was removed in the latest patch set.
2670 }
2671 int ret = cache_->DoomEntry(cache_key_, nullptr);
2672 DCHECK_EQ(OK, ret);
2673 }
2674
2675 DoneWritingToEntry(true);
2676 return OK;
2677 }
2678
2676 void HttpCache::Transaction::DoneWritingToEntry(bool success) { 2679 void HttpCache::Transaction::DoneWritingToEntry(bool success) {
2677 if (!entry_) 2680 if (!entry_)
2678 return; 2681 return;
2679 2682
2680 RecordHistograms(); 2683 RecordHistograms();
2681 2684
2682 cache_->DoneWritingToEntry(entry_, success); 2685 cache_->DoneWritingToEntry(entry_, success);
2683 entry_ = NULL; 2686 entry_ = NULL;
2684 mode_ = NONE; // switch to 'pass through' mode 2687 mode_ = NONE; // switch to 'pass through' mode
2685 } 2688 }
2686 2689
2690 void HttpCache::Transaction::DoneWithEntry(bool cancel) {
2691 cache_->DoneWithEntry(entry_, this, cancel);
2692 entry_ = nullptr;
2693 is_sparse_ = false;
2694 truncated_ = false;
2695 }
2696
2687 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { 2697 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) {
2688 DLOG(ERROR) << "ReadData failed: " << result; 2698 DLOG(ERROR) << "ReadData failed: " << result;
2689 const int result_for_histogram = std::max(0, -result); 2699 const int result_for_histogram = std::max(0, -result);
2690 if (restart) { 2700 if (restart) {
2691 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", 2701 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable",
2692 result_for_histogram); 2702 result_for_histogram);
2693 } else { 2703 } else {
2694 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable", 2704 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable",
2695 result_for_histogram); 2705 result_for_histogram);
2696 } 2706 }
2697 2707
2698 // Avoid using this entry in the future. 2708 // Avoid using this entry in the future.
2699 if (cache_.get()) 2709 if (cache_.get())
2700 cache_->DoomActiveEntry(cache_key_); 2710 cache_->DoomActiveEntry(cache_key_);
2701 2711
2702 if (restart) { 2712 if (restart) {
2703 DCHECK(!reading_); 2713 DCHECK(!reading_);
2704 DCHECK(!network_trans_.get()); 2714 DCHECK(!network_trans_.get());
2705 cache_->DoneWithEntry(entry_, this, false); 2715 DoneWithEntry(false);
2706 entry_ = NULL;
2707 is_sparse_ = false;
2708 partial_.reset(); 2716 partial_.reset();
2709 next_state_ = STATE_GET_BACKEND; 2717 next_state_ = STATE_GET_BACKEND;
2710 return OK; 2718 return OK;
2711 } 2719 }
2712 2720
2713 return ERR_CACHE_READ_FAILURE; 2721 return ERR_CACHE_READ_FAILURE;
2714 } 2722 }
2715 2723
2716 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { 2724 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) {
2717 if (entry_lock_waiting_since_ != start_time) 2725 if (entry_lock_waiting_since_ != start_time)
2718 return; 2726 return;
2719 2727
2720 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); 2728 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE);
2721 2729
2722 if (!cache_) 2730 if (!cache_)
2723 return; 2731 return;
2724 2732
2725 cache_->RemovePendingTransaction(this); 2733 cache_->RemovePendingTransaction(this);
2726 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); 2734 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT);
2727 } 2735 }
2728 2736
2729 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { 2737 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) {
2730 DVLOG(2) << "DoomPartialEntry"; 2738 DVLOG(2) << "DoomPartialEntry";
2731 int rv = cache_->DoomEntry(cache_key_, NULL); 2739 int rv = cache_->DoomEntry(cache_key_, NULL);
2732 DCHECK_EQ(OK, rv); 2740 DCHECK_EQ(OK, rv);
2733 cache_->DoneWithEntry(entry_, this, false); 2741 DoneWithEntry(false);
2734 entry_ = NULL;
2735 is_sparse_ = false;
2736 truncated_ = false;
2737 if (delete_object) 2742 if (delete_object)
2738 partial_.reset(NULL); 2743 partial_.reset();
2739 } 2744 }
2740 2745
2741 int HttpCache::Transaction::DoPartialNetworkReadCompleted(int result) { 2746 int HttpCache::Transaction::DoPartialNetworkReadCompleted(int result) {
2742 partial_->OnNetworkReadCompleted(result); 2747 partial_->OnNetworkReadCompleted(result);
2743 2748
2744 if (result == 0) { 2749 if (result == 0) {
2745 // We need to move on to the next range. 2750 // We need to move on to the next range.
2746 ResetNetworkTransaction(); 2751 ResetNetworkTransaction();
2747 next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; 2752 next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION;
2753 return OK;
2748 } 2754 }
2749 return result; 2755 return DoReadComplete(result);
2750 } 2756 }
2751 2757
2752 int HttpCache::Transaction::DoPartialCacheReadCompleted(int result) { 2758 int HttpCache::Transaction::DoPartialCacheReadCompleted(int result) {
2753 partial_->OnCacheReadCompleted(result); 2759 partial_->OnCacheReadCompleted(result);
2754 2760
2755 if (result == 0 && mode_ == READ_WRITE) { 2761 if (result == 0 && mode_ == READ_WRITE) {
2756 // We need to move on to the next range. 2762 // We need to move on to the next range.
2757 next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION; 2763 next_state_ = STATE_START_PARTIAL_CACHE_VALIDATION;
2758 } else if (result < 0) { 2764 } else if (result < 0) {
2759 return OnCacheReadError(result, false); 2765 return OnCacheReadError(result, false);
2760 } 2766 }
2761 return result; 2767 return result;
2762 } 2768 }
2763 2769
2764 int HttpCache::Transaction::DoRestartPartialRequest() { 2770 int HttpCache::Transaction::DoRestartPartialRequest() {
2765 // The stored data cannot be used. Get rid of it and restart this request. 2771 // The stored data cannot be used. Get rid of it and restart this request.
2766 net_log_.AddEvent(NetLog::TYPE_HTTP_CACHE_RESTART_PARTIAL_REQUEST); 2772 net_log_.AddEvent(NetLog::TYPE_HTTP_CACHE_RESTART_PARTIAL_REQUEST);
2767 2773
2768 // WRITE + Doom + STATE_INIT_ENTRY == STATE_CREATE_ENTRY (without an attempt 2774 // WRITE + Doom + STATE_INIT_ENTRY == STATE_CREATE_ENTRY (without an attempt
2769 // to Doom the entry again). 2775 // to Doom the entry again).
2770 mode_ = WRITE; 2776 mode_ = WRITE;
2771 ResetPartialState(!range_requested_); 2777 ResetPartialState(!range_requested_);
2772 next_state_ = STATE_CREATE_ENTRY; 2778 next_state_ = STATE_CREATE_ENTRY;
2773 return OK; 2779 return OK;
2774 } 2780 }
2775 2781
2782 int HttpCache::Transaction::DoReadComplete(int result) {
2783 DCHECK(mode_ & WRITE || mode_ == NONE);
2784 DCHECK(cache_);
2785 DCHECK_LE(0, result);
2786 DCHECK(reading_);
2787
2788 // If there is no partial data, or if this is the last range of, then all the
2789 // remaining bytes of the response are going to be coming from the network.
2790 // Hence we can release the cache entry and switch to passthrough mode.
2791 if ((mode_ & WRITE) && stopped_caching_ &&
2792 (!partial_ || partial_->IsLastRange()))
rvargas (doing something else) 2015/07/27 22:25:12 needs {}
asanka 2015/08/18 22:46:59 Done.
2793 return BeginCacheEntryRelease(result);
2794 return result;
2795 }
2796
2797 int HttpCache::Transaction::BeginCacheEntryRelease(int result_to_forward) {
2798 DCHECK_EQ(STATE_NONE, next_state_);
2799 DCHECK(stopped_caching_);
2800
2801 // Any errors from the cache truncation operation is going to be ignored.
2802 // There's not much the caller can do about it.
2803 callback_ = base::Bind(&Transaction::OnCacheReleaseComplete,
rvargas (doing something else) 2015/07/27 22:25:12 This is surprising. So far callback_ is always a c
asanka 2015/08/18 22:46:59 Yeah. This was removed.
2804 weak_factory_.GetWeakPtr(),
2805 base::Bind(callback_, result_to_forward));
2806 return DoneWithRequest();
2807 }
2808
2809 void HttpCache::Transaction::OnCacheReleaseComplete(
rvargas (doing something else) 2015/07/27 22:25:12 Why is this not part of the state machine?
asanka 2015/08/18 22:46:59 Point taken, but this code was removed.
2810 const base::Closure& closure,
2811 int result) {
2812 // TODO(asanka): Clean this up.
2813 if (entry_) {
2814 DCHECK(mode_ & WRITE);
2815 DoneWritingToEntry(true);
2816 }
2817 mode_ = NONE;
2818 stopped_caching_ = false;
2819 if (!closure.is_null())
2820 closure.Run();
2821 }
2822
2776 void HttpCache::Transaction::ResetPartialState(bool delete_object) { 2823 void HttpCache::Transaction::ResetPartialState(bool delete_object) {
2777 partial_->RestoreHeaders(&custom_request_->extra_headers); 2824 partial_->RestoreHeaders(&custom_request_->extra_headers);
2778 DoomPartialEntry(delete_object); 2825 DoomPartialEntry(delete_object);
2779 2826
2780 if (!delete_object) { 2827 if (!delete_object) {
2781 // The simplest way to re-initialize partial_ is to create a new object. 2828 // The simplest way to re-initialize partial_ is to create a new object.
2782 partial_.reset(new PartialData()); 2829 partial_.reset(new PartialData());
2783 if (partial_->Init(request_->extra_headers)) 2830 if (partial_->Init(request_->extra_headers))
2784 partial_->SetHeaders(custom_request_->extra_headers); 2831 partial_->SetHeaders(custom_request_->extra_headers);
2785 else 2832 else
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
2918 default: 2965 default:
2919 NOTREACHED(); 2966 NOTREACHED();
2920 } 2967 }
2921 } 2968 }
2922 2969
2923 void HttpCache::Transaction::OnIOComplete(int result) { 2970 void HttpCache::Transaction::OnIOComplete(int result) {
2924 DoLoop(result); 2971 DoLoop(result);
2925 } 2972 }
2926 2973
2927 } // namespace net 2974 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698