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 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |