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 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 |