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> |
| 11 #endif | 11 #endif |
| 12 | 12 |
| 13 #include <algorithm> | 13 #include <algorithm> |
| 14 #include <limits> | |
| 14 #include <string> | 15 #include <string> |
| 16 #include <utility> | |
| 15 | 17 |
| 16 #include "base/bind.h" | 18 #include "base/bind.h" |
| 17 #include "base/callback_helpers.h" | 19 #include "base/callback_helpers.h" |
| 18 #include "base/compiler_specific.h" | 20 #include "base/compiler_specific.h" |
| 19 #include "base/format_macros.h" | 21 #include "base/format_macros.h" |
| 20 #include "base/location.h" | 22 #include "base/location.h" |
| 21 #include "base/macros.h" | 23 #include "base/macros.h" |
| 22 #include "base/metrics/histogram_macros.h" | 24 #include "base/metrics/histogram_macros.h" |
| 23 #include "base/metrics/sparse_histogram.h" | 25 #include "base/metrics/sparse_histogram.h" |
| 24 #include "base/single_thread_task_runner.h" | 26 #include "base/single_thread_task_runner.h" |
| 25 #include "base/strings/string_number_conversions.h" // For HexEncode. | 27 #include "base/strings/string_number_conversions.h" // For HexEncode. |
| 26 #include "base/strings/string_piece.h" | 28 #include "base/strings/string_piece.h" |
| 27 #include "base/strings/string_util.h" // For LowerCaseEqualsASCII. | 29 #include "base/strings/string_util.h" // For LowerCaseEqualsASCII. |
| 28 #include "base/strings/stringprintf.h" | 30 #include "base/strings/stringprintf.h" |
| 29 #include "base/threading/thread_task_runner_handle.h" | 31 #include "base/threading/thread_task_runner_handle.h" |
| 30 #include "base/time/clock.h" | 32 #include "base/time/clock.h" |
| 31 #include "base/trace_event/trace_event.h" | 33 #include "base/trace_event/trace_event.h" |
| 32 #include "base/values.h" | 34 #include "base/values.h" |
| 33 #include "net/base/auth.h" | 35 #include "net/base/auth.h" |
| 34 #include "net/base/load_flags.h" | 36 #include "net/base/load_flags.h" |
| 35 #include "net/base/load_timing_info.h" | 37 #include "net/base/load_timing_info.h" |
| 36 #include "net/base/trace_constants.h" | 38 #include "net/base/trace_constants.h" |
| 37 #include "net/base/upload_data_stream.h" | 39 #include "net/base/upload_data_stream.h" |
| 38 #include "net/cert/cert_status_flags.h" | 40 #include "net/cert/cert_status_flags.h" |
| 39 #include "net/cert/x509_certificate.h" | 41 #include "net/cert/x509_certificate.h" |
| 40 #include "net/disk_cache/disk_cache.h" | 42 #include "net/disk_cache/disk_cache.h" |
| 43 #include "net/http/http_cache_shared_writers.h" | |
| 41 #include "net/http/http_network_session.h" | 44 #include "net/http/http_network_session.h" |
| 42 #include "net/http/http_request_info.h" | 45 #include "net/http/http_request_info.h" |
| 43 #include "net/http/http_util.h" | 46 #include "net/http/http_util.h" |
| 44 #include "net/log/net_log_event_type.h" | 47 #include "net/log/net_log_event_type.h" |
| 45 #include "net/ssl/ssl_cert_request_info.h" | 48 #include "net/ssl/ssl_cert_request_info.h" |
| 46 #include "net/ssl/ssl_config_service.h" | 49 #include "net/ssl/ssl_config_service.h" |
| 47 | 50 |
| 48 using base::Time; | 51 using base::Time; |
| 49 using base::TimeDelta; | 52 using base::TimeDelta; |
| 50 using base::TimeTicks; | 53 using base::TimeTicks; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 174 truncated_(false), | 177 truncated_(false), |
| 175 is_sparse_(false), | 178 is_sparse_(false), |
| 176 range_requested_(false), | 179 range_requested_(false), |
| 177 handling_206_(false), | 180 handling_206_(false), |
| 178 cache_pending_(false), | 181 cache_pending_(false), |
| 179 done_reading_(false), | 182 done_reading_(false), |
| 180 vary_mismatch_(false), | 183 vary_mismatch_(false), |
| 181 couldnt_conditionalize_request_(false), | 184 couldnt_conditionalize_request_(false), |
| 182 bypass_lock_for_test_(false), | 185 bypass_lock_for_test_(false), |
| 183 fail_conditionalization_for_test_(false), | 186 fail_conditionalization_for_test_(false), |
| 187 shared_(false), | |
| 188 initiate_shared_writing_(false), | |
| 189 shared_read_write_failure_result_(0), | |
| 184 io_buf_len_(0), | 190 io_buf_len_(0), |
| 185 read_offset_(0), | 191 read_offset_(0), |
| 186 effective_load_flags_(0), | 192 effective_load_flags_(0), |
| 187 write_len_(0), | 193 write_len_(0), |
| 188 cache_entry_status_(CacheEntryStatus::ENTRY_UNDEFINED), | 194 cache_entry_status_(CacheEntryStatus::ENTRY_UNDEFINED), |
| 189 validation_cause_(VALIDATION_CAUSE_UNDEFINED), | 195 validation_cause_(VALIDATION_CAUSE_UNDEFINED), |
| 190 total_received_bytes_(0), | 196 total_received_bytes_(0), |
| 191 total_sent_bytes_(0), | 197 total_sent_bytes_(0), |
| 192 websocket_handshake_stream_base_create_helper_(NULL), | 198 websocket_handshake_stream_base_create_helper_(NULL), |
| 199 have_full_request_headers_(false), | |
| 193 weak_factory_(this) { | 200 weak_factory_(this) { |
| 194 TRACE_EVENT0("io", "HttpCacheTransaction::Transaction"); | 201 TRACE_EVENT0("io", "HttpCacheTransaction::Transaction"); |
| 195 static_assert(HttpCache::Transaction::kNumValidationHeaders == | 202 static_assert(HttpCache::Transaction::kNumValidationHeaders == |
| 196 arraysize(kValidationHeaders), | 203 arraysize(kValidationHeaders), |
| 197 "invalid number of validation headers"); | 204 "invalid number of validation headers"); |
| 198 | 205 |
| 199 io_callback_ = base::Bind(&Transaction::OnIOComplete, | 206 io_callback_ = base::Bind(&Transaction::OnIOComplete, |
| 200 weak_factory_.GetWeakPtr()); | 207 weak_factory_.GetWeakPtr()); |
| 201 } | 208 } |
| 202 | 209 |
| 203 HttpCache::Transaction::~Transaction() { | 210 HttpCache::Transaction::~Transaction() { |
| 204 TRACE_EVENT0("io", "HttpCacheTransaction::~Transaction"); | 211 TRACE_EVENT0("io", "HttpCacheTransaction::~Transaction"); |
| 212 | |
| 205 // We may have to issue another IO, but we should never invoke the callback_ | 213 // We may have to issue another IO, but we should never invoke the callback_ |
| 206 // after this point. | 214 // after this point. |
| 207 callback_.Reset(); | 215 callback_.Reset(); |
| 208 | 216 |
| 217 if (shared_) { | |
| 218 // Remove transaction from shared writers and do any cleanup, if needed, for | |
| 219 // entry_->shared_writers and entry_. | |
| 220 RemoveTransactionFromSharedWriters(); | |
| 221 } | |
| 222 | |
| 209 if (cache_) { | 223 if (cache_) { |
| 210 if (entry_) { | 224 if (entry_) { |
| 211 bool cancel_request = reading_ && response_.headers.get(); | 225 bool cancel_request = reading_ && response_.headers.get(); |
| 212 if (cancel_request) { | 226 if (cancel_request) { |
| 213 if (partial_) { | 227 if (partial_) { |
| 214 entry_->disk_entry->CancelSparseIO(); | 228 entry_->disk_entry->CancelSparseIO(); |
| 215 } else { | 229 } else { |
| 216 cancel_request &= (response_.headers->response_code() == 200); | 230 cancel_request &= (response_.headers->response_code() == 200); |
| 217 } | 231 } |
| 218 } | 232 } |
| 219 | |
| 220 cache_->DoneWithEntry(entry_, this, cancel_request); | 233 cache_->DoneWithEntry(entry_, this, cancel_request); |
| 221 } else if (cache_pending_) { | 234 } else if (cache_pending_) { |
| 222 cache_->RemovePendingTransaction(this); | 235 cache_->RemovePendingTransaction(this); |
| 223 } | 236 } |
| 224 } | 237 } |
| 225 } | 238 } |
| 226 | 239 |
| 240 void HttpCache::Transaction::RemoveTransactionFromSharedWriters() { | |
| 241 // Current shared network transaction's consumer. | |
| 242 if (next_state_ == STATE_SHARED_NETWORK_READ_COMPLETE || | |
| 243 next_state_ == STATE_SHARED_CACHE_WRITE_DATA_COMPLETE) { | |
| 244 entry_->shared_writers->RemoveActiveTransaction(this); | |
| 245 } else if (next_state_ == STATE_SHARED_NETWORK_READ_WAIT_COMPLETE) { | |
| 246 // Waiting on Read() operation to be completed by another | |
| 247 // transaction. | |
| 248 entry_->shared_writers->RemoveWaitingForReadTransaction(this); | |
| 249 } else if (next_state_ != STATE_NONE && | |
| 250 next_state_ <= STATE_ADD_TO_ENTRY_COMPLETE) { | |
|
jkarlin
2017/02/03 18:26:20
Any chance these conditionals could be moved into
shivanisha
2017/02/06 21:14:10
That's true. Changed to switch with only *Complete
| |
| 251 // Pending transaction not yet added to an entry, so entry_ is null, let | |
| 252 // cache_ handle the deletion. | |
| 253 cache_->RemovePendingTransaction(this); | |
| 254 // Set cache_pending_ to false so that more cleanup is not attempted in | |
| 255 // the destructor. | |
| 256 cache_pending_ = false; | |
| 257 } else if (validating_shared()) { | |
| 258 entry_->shared_writers->RemoveValidatingTransaction(this); | |
| 259 } else { | |
| 260 entry_->shared_writers->RemoveIdleTransaction(this); | |
| 261 } | |
| 262 | |
| 263 DCHECK(!shared_); | |
| 264 | |
| 265 // Since any cleanup needed in entry_ and shared_writers is already done, | |
| 266 // set entry_ to null. | |
| 267 entry_ = nullptr; | |
| 268 } | |
| 269 | |
| 227 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len, | 270 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len, |
| 228 const CompletionCallback& callback) { | 271 const CompletionCallback& callback) { |
| 229 DCHECK(buf); | 272 DCHECK(buf); |
| 230 DCHECK_GT(buf_len, 0); | 273 DCHECK_GT(buf_len, 0); |
| 231 DCHECK(!callback.is_null()); | 274 DCHECK(!callback.is_null()); |
| 232 if (!cache_.get() || !entry_) | 275 if (!cache_.get() || !entry_) |
| 233 return ERR_UNEXPECTED; | 276 return ERR_UNEXPECTED; |
| 234 | 277 |
| 235 // We don't need to track this operation for anything. | 278 // We don't need to track this operation for anything. |
| 236 // It could be possible to check if there is something already written and | 279 // It could be possible to check if there is something already written and |
| 237 // avoid writing again (it should be the same, right?), but let's allow the | 280 // avoid writing again (it should be the same, right?), but let's allow the |
| 238 // caller to "update" the contents with something new. | 281 // caller to "update" the contents with something new. |
| 239 return entry_->disk_entry->WriteData(kMetadataIndex, 0, buf, buf_len, | 282 return entry_->disk_entry->WriteData(kMetadataIndex, 0, buf, buf_len, |
| 240 callback, true); | 283 callback, true); |
| 241 } | 284 } |
| 242 | 285 |
| 243 bool HttpCache::Transaction::AddTruncatedFlag() { | 286 bool HttpCache::Transaction::AddTruncatedFlag() { |
| 244 DCHECK(mode_ & WRITE || mode_ == NONE); | 287 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 245 | 288 |
| 246 // Don't set the flag for sparse entries. | 289 // Don't set the flag for sparse entries. |
| 247 if (partial_ && !truncated_) | 290 if (partial_ && !truncated_) |
| 248 return true; | 291 return true; |
| 249 | 292 |
| 250 if (!CanResume(true)) | 293 if (!cache_->CanResumeEntry(true, request_->method, &response_, entry_)) |
| 251 return false; | 294 return false; |
| 252 | 295 |
| 253 // We may have received the whole resource already. | 296 // We may have received the whole resource already. |
| 254 if (done_reading_) | 297 if (done_reading_) |
| 255 return true; | 298 return true; |
| 256 | 299 |
| 257 truncated_ = true; | 300 truncated_ = true; |
| 258 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE; | 301 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE; |
| 259 DoLoop(OK); | 302 DoLoop(OK); |
| 260 return true; | 303 return true; |
| 261 } | 304 } |
| 262 | 305 |
| 263 LoadState HttpCache::Transaction::GetWriterLoadState() const { | 306 LoadState HttpCache::Transaction::GetWriterLoadState() const { |
| 264 if (network_trans_.get()) | 307 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 265 return network_trans_->GetLoadState(); | 308 if (network_transaction) |
| 309 return network_transaction->GetLoadState(); | |
| 266 if (entry_ || !request_) | 310 if (entry_ || !request_) |
| 267 return LOAD_STATE_IDLE; | 311 return LOAD_STATE_IDLE; |
| 268 return LOAD_STATE_WAITING_FOR_CACHE; | 312 return LOAD_STATE_WAITING_FOR_CACHE; |
| 269 } | 313 } |
| 270 | 314 |
| 271 const NetLogWithSource& HttpCache::Transaction::net_log() const { | 315 const NetLogWithSource& HttpCache::Transaction::net_log() const { |
| 272 return net_log_; | 316 return net_log_; |
| 273 } | 317 } |
| 274 | 318 |
| 275 int HttpCache::Transaction::Start(const HttpRequestInfo* request, | 319 int HttpCache::Transaction::Start(const HttpRequestInfo* request, |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 365 } | 409 } |
| 366 | 410 |
| 367 bool HttpCache::Transaction::IsReadyToRestartForAuth() { | 411 bool HttpCache::Transaction::IsReadyToRestartForAuth() { |
| 368 if (!network_trans_.get()) | 412 if (!network_trans_.get()) |
| 369 return false; | 413 return false; |
| 370 return network_trans_->IsReadyToRestartForAuth(); | 414 return network_trans_->IsReadyToRestartForAuth(); |
| 371 } | 415 } |
| 372 | 416 |
| 373 int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len, | 417 int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len, |
| 374 const CompletionCallback& callback) { | 418 const CompletionCallback& callback) { |
| 419 if (next_state_ == STATE_SHARED_READ_WRITE_FAILED) { | |
| 420 if (net_log_.IsCapturing()) | |
| 421 net_log_.EndEventWithNetErrorCode( | |
| 422 NetLogEventType::HTTP_CACHE_SHARED_READ_WRITE_FAILED, | |
| 423 shared_read_write_failure_result_); | |
| 424 | |
| 425 return shared_read_write_failure_result_; | |
| 426 } | |
| 427 | |
| 375 DCHECK_EQ(next_state_, STATE_NONE); | 428 DCHECK_EQ(next_state_, STATE_NONE); |
| 376 DCHECK(buf); | 429 DCHECK(buf); |
| 377 DCHECK_GT(buf_len, 0); | 430 DCHECK_GT(buf_len, 0); |
| 378 DCHECK(!callback.is_null()); | 431 DCHECK(!callback.is_null()); |
| 379 | 432 |
| 380 DCHECK(callback_.is_null()); | 433 DCHECK(callback_.is_null()); |
| 381 | 434 |
| 382 if (!cache_.get()) | 435 if (!cache_.get()) |
| 383 return ERR_UNEXPECTED; | 436 return ERR_UNEXPECTED; |
| 384 | 437 |
| 385 // If we have an intermediate auth response at this point, then it means the | 438 // If we have an intermediate auth response at this point, then it means the |
| 386 // user wishes to read the network response (the error page). If there is a | 439 // user wishes to read the network response (the error page). If there is a |
| 387 // previous response in the cache then we should leave it intact. | 440 // previous response in the cache then we should leave it intact. |
| 388 if (auth_response_.headers.get() && mode_ != NONE) { | 441 if (auth_response_.headers.get() && mode_ != NONE) { |
| 389 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); | 442 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); |
| 390 DCHECK(mode_ & WRITE); | 443 DCHECK(mode_ & WRITE); |
| 391 DoneWritingToEntry(mode_ == READ_WRITE); | 444 DoneWritingToEntry(mode_ == READ_WRITE); |
| 392 mode_ = NONE; | 445 mode_ = NONE; |
| 393 } | 446 } |
| 394 | 447 |
| 395 reading_ = true; | 448 reading_ = true; |
| 396 read_buf_ = buf; | 449 read_buf_ = buf; |
| 397 io_buf_len_ = buf_len; | 450 io_buf_len_ = buf_len; |
| 398 if (network_trans_) { | 451 |
| 399 DCHECK(mode_ == WRITE || mode_ == NONE || | 452 if (shared_) { |
| 400 (mode_ == READ_WRITE && partial_)); | 453 int disk_entry_size = |
| 401 next_state_ = STATE_NETWORK_READ; | 454 entry_->disk_entry->GetDataSize(kResponseContentIndex); |
| 402 } else { | 455 if (read_offset_ == disk_entry_size) { |
| 403 DCHECK(mode_ == READ || (mode_ == READ_WRITE && partial_)); | 456 next_state_ = STATE_SHARED_NETWORK_READ; |
| 404 next_state_ = STATE_CACHE_READ_DATA; | 457 } else { |
| 458 DCHECK_LT(read_offset_, disk_entry_size); | |
| 459 next_state_ = STATE_CACHE_READ_DATA; | |
| 460 } | |
| 461 } else { // not shared. | |
| 462 if (network_trans_) { | |
| 463 DCHECK(mode_ == WRITE || mode_ == NONE || | |
| 464 (mode_ == READ_WRITE && partial_)); | |
| 465 next_state_ = STATE_NETWORK_READ; | |
| 466 } else { // read-only | |
| 467 DCHECK(mode_ == READ || (mode_ == READ_WRITE && partial_)); | |
| 468 next_state_ = STATE_CACHE_READ_DATA; | |
| 469 } | |
| 405 } | 470 } |
| 406 | 471 |
| 407 int rv = DoLoop(OK); | 472 int rv = DoLoop(OK); |
| 408 | 473 |
| 409 if (rv == ERR_IO_PENDING) { | 474 if (rv == ERR_IO_PENDING) { |
| 410 DCHECK(callback_.is_null()); | 475 DCHECK(callback_.is_null()); |
| 411 callback_ = callback; | 476 callback_ = callback; |
| 412 } | 477 } |
| 413 return rv; | 478 return rv; |
| 414 } | 479 } |
| 415 | 480 |
| 416 void HttpCache::Transaction::StopCaching() { | 481 void HttpCache::Transaction::StopCaching() { |
| 417 // We really don't know where we are now. Hopefully there is no operation in | 482 // We really don't know where we are now. Hopefully there is no operation in |
| 418 // progress, but nothing really prevents this method to be called after we | 483 // progress, but nothing really prevents this method to be called after we |
| 419 // returned ERR_IO_PENDING. We cannot attempt to truncate the entry at this | 484 // returned ERR_IO_PENDING. We cannot attempt to truncate the entry at this |
| 420 // point because we need the state machine for that (and even if we are really | 485 // point because we need the state machine for that (and even if we are really |
| 421 // free, that would be an asynchronous operation). In other words, keep the | 486 // free, that would be an asynchronous operation). In other words, keep the |
| 422 // entry how it is (it will be marked as truncated at destruction), and let | 487 // entry how it is (it will be marked as truncated at destruction), and let |
| 423 // the next piece of code that executes know that we are now reading directly | 488 // the next piece of code that executes know that we are now reading directly |
| 424 // from the net. | 489 // from the net. |
| 425 // TODO(mmenke): This doesn't release the lock on the cache entry, so a | 490 // TODO(mmenke): This doesn't release the lock on the cache entry, so a |
| 426 // future request for the resource will be blocked on this one. | 491 // future request for the resource will be blocked on this one. |
| 427 // Fix this. | 492 // Fix this. |
| 428 if (cache_.get() && entry_ && (mode_ & WRITE) && network_trans_.get() && | 493 if (shared_) { |
| 429 !is_sparse_ && !range_requested_) { | 494 // This might or might not stop caching based on whether other consumers |
| 495 // exist for this resource or not. If it does, shared_ will be set to false. | |
| 496 entry_->shared_writers->StopCaching(this); | |
| 497 } | |
| 498 if (!shared_ && cache_.get() && entry_ && (mode_ & WRITE) && | |
| 499 network_trans_.get() && !is_sparse_ && !range_requested_) { | |
| 430 mode_ = NONE; | 500 mode_ = NONE; |
| 431 } | 501 } |
| 432 } | 502 } |
| 433 | 503 |
| 434 bool HttpCache::Transaction::GetFullRequestHeaders( | 504 bool HttpCache::Transaction::GetFullRequestHeaders( |
| 435 HttpRequestHeaders* headers) const { | 505 HttpRequestHeaders* headers) const { |
| 436 if (network_trans_) | 506 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 437 return network_trans_->GetFullRequestHeaders(headers); | 507 if (network_transaction) { |
| 438 | 508 return network_transaction->GetFullRequestHeaders(headers); |
| 509 } else if (have_full_request_headers_) { | |
| 510 *headers = full_request_headers_; | |
| 511 return true; | |
| 512 } | |
| 439 // TODO(juliatuttle): Read headers from cache. | 513 // TODO(juliatuttle): Read headers from cache. |
| 440 return false; | 514 return false; |
| 441 } | 515 } |
| 442 | 516 |
| 443 int64_t HttpCache::Transaction::GetTotalReceivedBytes() const { | 517 int64_t HttpCache::Transaction::GetTotalReceivedBytes() const { |
| 444 int64_t total_received_bytes = total_received_bytes_; | 518 int64_t total_received_bytes = total_received_bytes_; |
| 445 if (network_trans_) | 519 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 446 total_received_bytes += network_trans_->GetTotalReceivedBytes(); | 520 if (network_transaction) |
| 521 total_received_bytes += network_transaction->GetTotalReceivedBytes(); | |
| 447 return total_received_bytes; | 522 return total_received_bytes; |
| 448 } | 523 } |
| 449 | 524 |
| 450 int64_t HttpCache::Transaction::GetTotalSentBytes() const { | 525 int64_t HttpCache::Transaction::GetTotalSentBytes() const { |
| 451 int64_t total_sent_bytes = total_sent_bytes_; | 526 int64_t total_sent_bytes = total_sent_bytes_; |
| 452 if (network_trans_) | 527 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 453 total_sent_bytes += network_trans_->GetTotalSentBytes(); | 528 if (network_transaction) |
| 529 total_sent_bytes += network_transaction->GetTotalSentBytes(); | |
| 454 return total_sent_bytes; | 530 return total_sent_bytes; |
| 455 } | 531 } |
| 456 | 532 |
| 457 void HttpCache::Transaction::DoneReading() { | 533 void HttpCache::Transaction::DoneReading() { |
| 458 if (cache_.get() && entry_) { | 534 if (cache_.get() && entry_) { |
| 459 DCHECK_NE(mode_, UPDATE); | 535 DCHECK_NE(mode_, UPDATE); |
| 536 bool perform_entry_cleanup = true; | |
| 537 if (shared_) { | |
| 538 entry_->shared_writers->DoneReading(this); | |
| 539 | |
| 540 // shared_ should have been set to false. | |
| 541 DCHECK(!shared_); | |
| 542 | |
| 543 DoneWritingToEntry(true, false); | |
| 544 return; | |
| 545 } | |
| 546 | |
| 460 if (mode_ & WRITE) { | 547 if (mode_ & WRITE) { |
| 461 DoneWritingToEntry(true); | 548 DoneWritingToEntry(true, perform_entry_cleanup); |
| 462 } else if (mode_ & READ) { | 549 } else if (mode_ & READ) { |
| 463 // It is necessary to check mode_ & READ because it is possible | 550 // It is necessary to check mode_ & READ because it is possible |
| 464 // for mode_ to be NONE and entry_ non-NULL with a write entry | 551 // for mode_ to be NONE and entry_ non-NULL with a write entry |
| 465 // if StopCaching was called. | 552 // if StopCaching was called. |
| 466 cache_->DoneReadingFromEntry(entry_, this); | 553 cache_->DoneReadingFromEntry(entry_, this); |
| 467 entry_ = NULL; | 554 entry_ = NULL; |
| 468 } | 555 } |
| 469 } | 556 } |
| 470 } | 557 } |
| 471 | 558 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 490 return cache_->GetLoadStateForPendingTransaction(this); | 577 return cache_->GetLoadStateForPendingTransaction(this); |
| 491 | 578 |
| 492 return LOAD_STATE_IDLE; | 579 return LOAD_STATE_IDLE; |
| 493 } | 580 } |
| 494 | 581 |
| 495 void HttpCache::Transaction::SetQuicServerInfo( | 582 void HttpCache::Transaction::SetQuicServerInfo( |
| 496 QuicServerInfo* quic_server_info) {} | 583 QuicServerInfo* quic_server_info) {} |
| 497 | 584 |
| 498 bool HttpCache::Transaction::GetLoadTimingInfo( | 585 bool HttpCache::Transaction::GetLoadTimingInfo( |
| 499 LoadTimingInfo* load_timing_info) const { | 586 LoadTimingInfo* load_timing_info) const { |
| 500 if (network_trans_) | 587 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 501 return network_trans_->GetLoadTimingInfo(load_timing_info); | 588 if (network_transaction) |
| 589 return network_transaction->GetLoadTimingInfo(load_timing_info); | |
| 502 | 590 |
| 503 if (old_network_trans_load_timing_) { | 591 if (old_network_trans_load_timing_) { |
| 504 *load_timing_info = *old_network_trans_load_timing_; | 592 *load_timing_info = *old_network_trans_load_timing_; |
| 505 return true; | 593 return true; |
| 506 } | 594 } |
| 507 | 595 |
| 508 if (first_cache_access_since_.is_null()) | 596 if (first_cache_access_since_.is_null()) |
| 509 return false; | 597 return false; |
| 510 | 598 |
| 511 // If the cache entry was opened, return that time. | 599 // If the cache entry was opened, return that time. |
| 512 load_timing_info->send_start = first_cache_access_since_; | 600 load_timing_info->send_start = first_cache_access_since_; |
| 513 // This time doesn't make much sense when reading from the cache, so just use | 601 // This time doesn't make much sense when reading from the cache, so just use |
| 514 // the same time as send_start. | 602 // the same time as send_start. |
| 515 load_timing_info->send_end = first_cache_access_since_; | 603 load_timing_info->send_end = first_cache_access_since_; |
| 516 return true; | 604 return true; |
| 517 } | 605 } |
| 518 | 606 |
| 519 bool HttpCache::Transaction::GetRemoteEndpoint(IPEndPoint* endpoint) const { | 607 bool HttpCache::Transaction::GetRemoteEndpoint(IPEndPoint* endpoint) const { |
| 520 if (network_trans_) | 608 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 521 return network_trans_->GetRemoteEndpoint(endpoint); | 609 if (network_transaction) |
| 610 return network_transaction->GetRemoteEndpoint(endpoint); | |
| 522 | 611 |
| 523 if (!old_remote_endpoint_.address().empty()) { | 612 if (!old_remote_endpoint_.address().empty()) { |
| 524 *endpoint = old_remote_endpoint_; | 613 *endpoint = old_remote_endpoint_; |
| 525 return true; | 614 return true; |
| 526 } | 615 } |
| 527 | 616 |
| 528 return false; | 617 return false; |
| 529 } | 618 } |
| 530 | 619 |
| 531 void HttpCache::Transaction::PopulateNetErrorDetails( | 620 void HttpCache::Transaction::PopulateNetErrorDetails( |
| 532 NetErrorDetails* details) const { | 621 NetErrorDetails* details) const { |
| 533 if (network_trans_) | 622 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 534 return network_trans_->PopulateNetErrorDetails(details); | 623 if (network_transaction) |
| 624 network_transaction->PopulateNetErrorDetails(details); | |
| 535 return; | 625 return; |
| 536 } | 626 } |
| 537 | 627 |
| 538 void HttpCache::Transaction::SetPriority(RequestPriority priority) { | 628 void HttpCache::Transaction::SetPriority(RequestPriority priority) { |
| 539 priority_ = priority; | 629 priority_ = priority; |
| 540 if (network_trans_) | 630 if (network_trans_) |
| 541 network_trans_->SetPriority(priority_); | 631 network_trans_->SetPriority(priority_); |
| 632 else if (shared_ && entry_ && entry_->shared_writers) | |
| 633 entry_->shared_writers->PriorityChanged(); | |
| 542 } | 634 } |
| 543 | 635 |
| 544 void HttpCache::Transaction::SetWebSocketHandshakeStreamCreateHelper( | 636 void HttpCache::Transaction::SetWebSocketHandshakeStreamCreateHelper( |
| 545 WebSocketHandshakeStreamBase::CreateHelper* create_helper) { | 637 WebSocketHandshakeStreamBase::CreateHelper* create_helper) { |
| 546 websocket_handshake_stream_base_create_helper_ = create_helper; | 638 websocket_handshake_stream_base_create_helper_ = create_helper; |
| 547 if (network_trans_) | 639 if (network_trans_) |
| 548 network_trans_->SetWebSocketHandshakeStreamCreateHelper(create_helper); | 640 network_trans_->SetWebSocketHandshakeStreamCreateHelper(create_helper); |
| 549 } | 641 } |
| 550 | 642 |
| 551 void HttpCache::Transaction::SetBeforeNetworkStartCallback( | 643 void HttpCache::Transaction::SetBeforeNetworkStartCallback( |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 562 | 654 |
| 563 int HttpCache::Transaction::ResumeNetworkStart() { | 655 int HttpCache::Transaction::ResumeNetworkStart() { |
| 564 if (network_trans_) | 656 if (network_trans_) |
| 565 return network_trans_->ResumeNetworkStart(); | 657 return network_trans_->ResumeNetworkStart(); |
| 566 return ERR_UNEXPECTED; | 658 return ERR_UNEXPECTED; |
| 567 } | 659 } |
| 568 | 660 |
| 569 void HttpCache::Transaction::GetConnectionAttempts( | 661 void HttpCache::Transaction::GetConnectionAttempts( |
| 570 ConnectionAttempts* out) const { | 662 ConnectionAttempts* out) const { |
| 571 ConnectionAttempts new_connection_attempts; | 663 ConnectionAttempts new_connection_attempts; |
| 572 if (network_trans_) | 664 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 573 network_trans_->GetConnectionAttempts(&new_connection_attempts); | 665 if (network_transaction) |
| 666 network_transaction->GetConnectionAttempts(&new_connection_attempts); | |
| 574 | 667 |
| 575 out->swap(new_connection_attempts); | 668 out->swap(new_connection_attempts); |
| 576 out->insert(out->begin(), old_connection_attempts_.begin(), | 669 out->insert(out->begin(), old_connection_attempts_.begin(), |
| 577 old_connection_attempts_.end()); | 670 old_connection_attempts_.end()); |
| 578 } | 671 } |
| 579 | 672 |
| 580 //----------------------------------------------------------------------------- | 673 //----------------------------------------------------------------------------- |
| 581 | 674 |
| 582 // A few common patterns: (Foo* means Foo -> FooComplete) | 675 // A few common patterns: (Foo* means Foo -> FooComplete) |
| 583 // | 676 // |
| 584 // 1. Not-cached entry: | 677 // 1. Not-cached entry: |
| 585 // Start(): | 678 // Start(): |
| 586 // GetBackend* -> InitEntry -> OpenEntry* -> CreateEntry* -> AddToEntry* -> | 679 // GetBackend* -> InitEntry -> OpenEntry* -> CreateEntry* -> AddToEntry* -> |
| 587 // SendRequest* -> SuccessfulSendRequest -> OverwriteCachedResponse -> | 680 // SendRequest* -> SuccessfulSendRequest -> OverwriteCachedResponse -> |
| 588 // CacheWriteResponse* -> TruncateCachedData* -> TruncateCachedMetadata* -> | 681 // CacheWriteResponse* -> TruncateCachedData* -> TruncateCachedMetadata* -> |
| 589 // PartialHeadersReceived | 682 // PartialHeadersReceived |
| 590 // | 683 // |
| 591 // Read(): | 684 // Read(): (For transactions that are not eligible for shared writing) |
| 592 // NetworkRead* -> CacheWriteData* | 685 // NetworkRead* -> CacheWriteData* |
| 593 // | 686 // |
| 687 // Read(): (For transactions that are eligible for shared writing) | |
| 688 // SharedNetworkRead* -> SharedCacheWriteData* | |
| 689 // | |
| 690 // Read(): (For a transaction that is shared and another read is already in | |
| 691 // progress) | |
| 692 // SharedNetworkRead -> SharedNetworkReadWaitComplete | |
| 693 // | |
| 594 // 2. Cached entry, no validation: | 694 // 2. Cached entry, no validation: |
| 595 // Start(): | 695 // Start(): |
| 596 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* | 696 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* |
| 597 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> | 697 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> |
| 598 // BeginCacheValidation() -> SetupEntryForRead() | 698 // BeginCacheValidation() -> SetupEntryForRead() |
| 599 // | 699 // |
| 600 // Read(): | 700 // Read(): (When response is already written to the cache.) |
| 601 // CacheReadData* | 701 // CacheReadData* |
| 602 // | 702 // |
| 703 // Read(): (When response is currently being written to the cache by shared | |
| 704 // writing.) | |
| 705 // SharedNetworkRead* -> SharedCacheWriteData* | |
| 706 // | |
| 603 // 3. Cached entry, validation (304): | 707 // 3. Cached entry, validation (304): |
| 604 // Start(): | 708 // Start(): |
| 605 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* | 709 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* |
| 606 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> | 710 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> |
| 607 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> | 711 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> |
| 608 // UpdateCachedResponse -> CacheWriteUpdatedResponse* -> | 712 // UpdateCachedResponse -> CacheWriteUpdatedResponse* -> |
| 609 // UpdateCachedResponseComplete -> OverwriteCachedResponse -> | 713 // UpdateCachedResponseComplete -> OverwriteCachedResponse -> |
| 610 // PartialHeadersReceived | 714 // PartialHeadersReceived |
| 611 // | 715 // |
| 612 // Read(): | 716 // Read(): () (When response is already written to the cache.) |
| 613 // CacheReadData* | 717 // CacheReadData* |
| 614 // | 718 // |
| 719 // Read(): (When response is currently being written to the cache by shared | |
| 720 // writing.) | |
| 721 // SharedNetworkRead* -> SharedCacheWriteData* | |
| 722 // | |
| 615 // 4. Cached entry, validation and replace (200): | 723 // 4. Cached entry, validation and replace (200): |
| 616 // Start(): | 724 // Start(): |
| 617 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* | 725 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* |
| 618 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> | 726 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> |
| 619 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> | 727 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> |
| 620 // OverwriteCachedResponse -> CacheWriteResponse* -> DoTruncateCachedData* -> | 728 // OverwriteCachedResponse -> CacheWriteResponse* -> DoTruncateCachedData* -> |
| 621 // TruncateCachedMetadata* -> PartialHeadersReceived | 729 // TruncateCachedMetadata* -> PartialHeadersReceived |
| 622 // | 730 // |
| 623 // Read(): | 731 // Read(): |
| 624 // NetworkRead* -> CacheWriteData* | 732 // NetworkRead* -> CacheWriteData* |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 699 // -> CacheToggleUnusedSincePrefetch* -> CacheDispatchValidation -> | 807 // -> CacheToggleUnusedSincePrefetch* -> CacheDispatchValidation -> |
| 700 // BeginPartialCacheValidation() -> BeginCacheValidation() -> | 808 // BeginPartialCacheValidation() -> BeginCacheValidation() -> |
| 701 // SetupEntryForRead() | 809 // SetupEntryForRead() |
| 702 // | 810 // |
| 703 // Read(): | 811 // Read(): |
| 704 // CacheReadData* | 812 // CacheReadData* |
| 705 // | 813 // |
| 706 // 14. Cached entry more than 5 minutes old, unused_since_prefetch is true: | 814 // 14. Cached entry more than 5 minutes old, unused_since_prefetch is true: |
| 707 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between | 815 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between |
| 708 // CacheReadResponse* and CacheDispatchValidation. | 816 // CacheReadResponse* and CacheDispatchValidation. |
| 817 // | |
| 709 int HttpCache::Transaction::DoLoop(int result) { | 818 int HttpCache::Transaction::DoLoop(int result) { |
| 710 DCHECK(next_state_ != STATE_NONE); | 819 DCHECK(next_state_ != STATE_NONE); |
| 711 | 820 |
| 712 int rv = result; | 821 int rv = result; |
| 713 do { | 822 do { |
| 714 State state = next_state_; | 823 State state = next_state_; |
| 715 next_state_ = STATE_NONE; | 824 next_state_ = STATE_NONE; |
| 716 switch (state) { | 825 switch (state) { |
| 717 case STATE_GET_BACKEND: | 826 case STATE_GET_BACKEND: |
| 718 DCHECK_EQ(OK, rv); | 827 DCHECK_EQ(OK, rv); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 866 case STATE_CACHE_WRITE_DATA_COMPLETE: | 975 case STATE_CACHE_WRITE_DATA_COMPLETE: |
| 867 rv = DoCacheWriteDataComplete(rv); | 976 rv = DoCacheWriteDataComplete(rv); |
| 868 break; | 977 break; |
| 869 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE: | 978 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE: |
| 870 DCHECK_EQ(OK, rv); | 979 DCHECK_EQ(OK, rv); |
| 871 rv = DoCacheWriteTruncatedResponse(); | 980 rv = DoCacheWriteTruncatedResponse(); |
| 872 break; | 981 break; |
| 873 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE: | 982 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE: |
| 874 rv = DoCacheWriteTruncatedResponseComplete(rv); | 983 rv = DoCacheWriteTruncatedResponseComplete(rv); |
| 875 break; | 984 break; |
| 985 case STATE_SHARED_NETWORK_READ: | |
| 986 DCHECK_EQ(OK, rv); | |
| 987 rv = DoSharedNetworkRead(); | |
| 988 break; | |
| 989 case STATE_SHARED_NETWORK_READ_COMPLETE: | |
| 990 rv = DoSharedNetworkReadComplete(rv); | |
| 991 break; | |
| 992 case STATE_SHARED_NETWORK_READ_WAIT_COMPLETE: | |
| 993 rv = DoSharedNetworkReadWaitComplete(rv); | |
| 994 break; | |
| 995 case STATE_SHARED_CACHE_WRITE_DATA: | |
| 996 rv = DoSharedCacheWriteData(rv); | |
| 997 break; | |
| 998 case STATE_SHARED_CACHE_WRITE_DATA_COMPLETE: | |
| 999 rv = DoSharedCacheWriteDataComplete(rv); | |
| 1000 break; | |
| 1001 case STATE_SHARED_READ_WRITE_FAILED: | |
| 1002 rv = DoSharedReadWriteFailed(); | |
| 1003 break; | |
| 876 default: | 1004 default: |
| 877 NOTREACHED() << "bad state"; | 1005 NOTREACHED() << "bad state"; |
| 878 rv = ERR_FAILED; | 1006 rv = ERR_FAILED; |
| 879 break; | 1007 break; |
| 880 } | 1008 } |
| 881 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 1009 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
| 882 | 1010 |
| 883 if (rv != ERR_IO_PENDING && !callback_.is_null()) { | 1011 if (rv != ERR_IO_PENDING && !callback_.is_null()) { |
| 884 read_buf_ = NULL; // Release the buffer before invoking the callback. | 1012 read_buf_ = NULL; // Release the buffer before invoking the callback. |
| 885 base::ResetAndReturn(&callback_).Run(rv); | 1013 base::ResetAndReturn(&callback_).Run(rv); |
| (...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1503 | 1631 |
| 1504 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); | 1632 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); |
| 1505 | 1633 |
| 1506 if (new_response_->headers->response_code() == 416 && | 1634 if (new_response_->headers->response_code() == 416 && |
| 1507 (request_->method == "GET" || request_->method == "POST")) { | 1635 (request_->method == "GET" || request_->method == "POST")) { |
| 1508 // If there is an active entry it may be destroyed with this transaction. | 1636 // If there is an active entry it may be destroyed with this transaction. |
| 1509 SetResponse(*new_response_); | 1637 SetResponse(*new_response_); |
| 1510 return OK; | 1638 return OK; |
| 1511 } | 1639 } |
| 1512 | 1640 |
| 1641 // If the transaction is shared and it is a 200 or an error response, then | |
| 1642 // doom the entry and let this transaction continue without writing to the | |
| 1643 // cache if shared writers contain more transactions. If not, continue | |
| 1644 // writing to the cache and also transfer the network transaction to shared | |
| 1645 // writers. | |
| 1646 if (shared_ && new_response->headers->response_code() != 304) { | |
| 1647 network_trans_ = entry_->shared_writers->OnValidationNoMatch( | |
| 1648 cache_key_, this, std::move(network_trans_), priority_); | |
| 1649 if (!shared_) { | |
| 1650 DCHECK(network_trans_); | |
| 1651 if (cache_entry_status_ == CacheEntryStatus::ENTRY_UNDEFINED) { | |
| 1652 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING); | |
| 1653 } | |
| 1654 DoneWritingToEntry(false, false); | |
| 1655 return OK; | |
| 1656 } else { | |
| 1657 DCHECK(!network_trans_); | |
| 1658 } | |
| 1659 } | |
| 1660 | |
| 1513 // Are we expecting a response to a conditional query? | 1661 // Are we expecting a response to a conditional query? |
| 1514 if (mode_ == READ_WRITE || mode_ == UPDATE) { | 1662 if (mode_ == READ_WRITE || mode_ == UPDATE) { |
| 1515 if (new_response->headers->response_code() == 304 || handling_206_) { | 1663 if (new_response->headers->response_code() == 304 || handling_206_) { |
| 1516 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED); | 1664 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED); |
| 1517 next_state_ = STATE_UPDATE_CACHED_RESPONSE; | 1665 next_state_ = STATE_UPDATE_CACHED_RESPONSE; |
| 1518 return OK; | 1666 return OK; |
| 1519 } | 1667 } |
| 1520 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_UPDATED); | 1668 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_UPDATED); |
| 1521 mode_ = WRITE; | 1669 mode_ = WRITE; |
| 1522 } | 1670 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1625 SetResponse(*new_response_); | 1773 SetResponse(*new_response_); |
| 1626 | 1774 |
| 1627 if (request_->method == "HEAD") { | 1775 if (request_->method == "HEAD") { |
| 1628 // This response is replacing the cached one. | 1776 // This response is replacing the cached one. |
| 1629 DoneWritingToEntry(false); | 1777 DoneWritingToEntry(false); |
| 1630 mode_ = NONE; | 1778 mode_ = NONE; |
| 1631 new_response_ = NULL; | 1779 new_response_ = NULL; |
| 1632 return OK; | 1780 return OK; |
| 1633 } | 1781 } |
| 1634 | 1782 |
| 1635 if (handling_206_ && !CanResume(false)) { | 1783 if (handling_206_ && |
| 1784 !cache_->CanResumeEntry(false, request_->method, &response_, entry_)) { | |
| 1636 // There is no point in storing this resource because it will never be used. | 1785 // There is no point in storing this resource because it will never be used. |
| 1637 // This may change if we support LOAD_ONLY_FROM_CACHE with sparse entries. | 1786 // This may change if we support LOAD_ONLY_FROM_CACHE with sparse entries. |
| 1638 DoneWritingToEntry(false); | 1787 DoneWritingToEntry(false); |
| 1639 if (partial_) | 1788 if (partial_) |
| 1640 partial_->FixResponseHeaders(response_.headers.get(), true); | 1789 partial_->FixResponseHeaders(response_.headers.get(), true); |
| 1641 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | 1790 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; |
| 1642 return OK; | 1791 return OK; |
| 1643 } | 1792 } |
| 1644 | 1793 |
| 1645 next_state_ = STATE_CACHE_WRITE_RESPONSE; | 1794 next_state_ = STATE_CACHE_WRITE_RESPONSE; |
| 1646 return OK; | 1795 return OK; |
| 1647 } | 1796 } |
| 1648 | 1797 |
| 1649 int HttpCache::Transaction::DoCacheWriteResponse() { | 1798 int HttpCache::Transaction::DoCacheWriteResponse() { |
| 1650 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse"); | 1799 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse"); |
| 1651 next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE; | 1800 next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE; |
| 1652 return WriteResponseInfoToEntry(truncated_); | 1801 return WriteResponseInfoToEntry(truncated_); |
| 1653 } | 1802 } |
| 1654 | 1803 |
| 1655 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { | 1804 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { |
| 1656 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete"); | 1805 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete"); |
| 1657 next_state_ = STATE_TRUNCATE_CACHED_DATA; | 1806 next_state_ = STATE_TRUNCATE_CACHED_DATA; |
| 1658 return OnWriteResponseInfoToEntryComplete(result); | 1807 return OnWriteResponseInfoToEntryComplete(result); |
| 1659 } | 1808 } |
| 1660 | 1809 |
| 1810 void HttpCache::Transaction::ResetShared(bool continue_network_reading, | |
| 1811 bool continue_cache_reading) { | |
| 1812 if (!continue_network_reading) { | |
| 1813 SaveSharedNetworkTransactionInfo(); | |
| 1814 } | |
| 1815 if (continue_cache_reading) { | |
| 1816 mode_ = READ; | |
| 1817 } | |
| 1818 shared_ = false; | |
| 1819 } | |
| 1820 | |
| 1821 void HttpCache::Transaction::SetShared() { | |
| 1822 shared_ = true; | |
| 1823 } | |
| 1824 | |
| 1825 bool HttpCache::Transaction::validating_shared() const { | |
| 1826 return shared_ && next_state_ != STATE_NONE && | |
| 1827 next_state_ <= STATE_START_STATE_MACHINE_FINAL; | |
| 1828 } | |
| 1829 | |
| 1661 int HttpCache::Transaction::DoTruncateCachedData() { | 1830 int HttpCache::Transaction::DoTruncateCachedData() { |
| 1662 TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedData"); | 1831 TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedData"); |
| 1663 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; | 1832 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; |
| 1664 if (!entry_) | 1833 if (!entry_) |
| 1665 return OK; | 1834 return OK; |
| 1666 if (net_log_.IsCapturing()) | 1835 if (net_log_.IsCapturing()) |
| 1667 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); | 1836 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); |
| 1668 // Truncate the stream. | 1837 // Truncate the stream. |
| 1669 return WriteToEntry(kResponseContentIndex, 0, NULL, 0, io_callback_); | 1838 return WriteToEntry(kResponseContentIndex, 0, NULL, 0, io_callback_); |
| 1670 } | 1839 } |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1699 if (net_log_.IsCapturing()) { | 1868 if (net_log_.IsCapturing()) { |
| 1700 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, | 1869 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, |
| 1701 result); | 1870 result); |
| 1702 } | 1871 } |
| 1703 } | 1872 } |
| 1704 | 1873 |
| 1705 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | 1874 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; |
| 1706 return OK; | 1875 return OK; |
| 1707 } | 1876 } |
| 1708 | 1877 |
| 1878 void HttpCache::Transaction::ProcessForSharedWriting() { | |
| 1879 // Should not be already reading. | |
| 1880 if (reading_) | |
| 1881 return; | |
| 1882 | |
| 1883 // If not already part of SharedWriters, then check if one should be | |
| 1884 // created. | |
| 1885 if (!shared_ && !IsEligibleForSharedWriting()) | |
| 1886 return; | |
| 1887 | |
| 1888 if (shared_) { | |
| 1889 // Non 304 case is already handled in DoSuccessfulSendRequest. | |
| 1890 if (response_.headers->response_code() != 304) { | |
| 1891 return; | |
| 1892 } | |
| 1893 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING); | |
| 1894 entry_->shared_writers->OnValidationMatch(this, priority_); | |
| 1895 network_trans_.reset(); | |
| 1896 return; | |
| 1897 } | |
| 1898 | |
| 1899 // Do not create a SharedWriters if its a Redirect response. | |
| 1900 if (response_.headers->response_code() != 200) | |
| 1901 return; | |
| 1902 | |
| 1903 // or if its a no-store response. | |
| 1904 if (!entry_) | |
| 1905 return; | |
| 1906 | |
| 1907 DCHECK(cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE || | |
| 1908 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED || | |
| 1909 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE || | |
| 1910 cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER); | |
| 1911 // Measure how many requests out of the total of "not cached" and "updated" | |
| 1912 // are initiating Shared Writing. | |
| 1913 initiate_shared_writing_ = true; | |
| 1914 DCHECK(entry_ && network_trans_); | |
| 1915 | |
| 1916 // An instance of SharedWriters will be created when the first writer has | |
| 1917 // written the new response headers in the cache. Transfer network | |
| 1918 // transaction’s ownership to SharedWriters so it can be used by any of the | |
| 1919 // transactions for subsequent reading from the network. | |
| 1920 cache_->CreateSharedWriters(this, std::move(network_trans_), priority_); | |
| 1921 } | |
| 1922 | |
| 1709 int HttpCache::Transaction::DoPartialHeadersReceived() { | 1923 int HttpCache::Transaction::DoPartialHeadersReceived() { |
| 1710 new_response_ = NULL; | 1924 new_response_ = NULL; |
| 1711 if (entry_ && !partial_ && entry_->disk_entry->GetDataSize(kMetadataIndex)) | 1925 if (entry_ && !partial_ && entry_->disk_entry->GetDataSize(kMetadataIndex)) |
| 1712 next_state_ = STATE_CACHE_READ_METADATA; | 1926 next_state_ = STATE_CACHE_READ_METADATA; |
| 1713 | 1927 |
| 1928 ProcessForSharedWriting(); | |
| 1929 | |
| 1714 if (!partial_) | 1930 if (!partial_) |
| 1715 return OK; | 1931 return OK; |
| 1716 | 1932 |
| 1717 if (reading_) { | 1933 if (reading_) { |
| 1718 if (network_trans_.get()) { | 1934 if (network_trans_.get()) { |
| 1719 next_state_ = STATE_NETWORK_READ; | 1935 next_state_ = STATE_NETWORK_READ; |
| 1720 } else { | 1936 } else { |
| 1721 next_state_ = STATE_CACHE_READ_DATA; | 1937 next_state_ = STATE_CACHE_READ_DATA; |
| 1722 } | 1938 } |
| 1723 } else if (mode_ != NONE) { | 1939 } else if (mode_ != NONE) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1754 } | 1970 } |
| 1755 | 1971 |
| 1756 int HttpCache::Transaction::DoNetworkRead() { | 1972 int HttpCache::Transaction::DoNetworkRead() { |
| 1757 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead"); | 1973 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead"); |
| 1758 next_state_ = STATE_NETWORK_READ_COMPLETE; | 1974 next_state_ = STATE_NETWORK_READ_COMPLETE; |
| 1759 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); | 1975 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); |
| 1760 } | 1976 } |
| 1761 | 1977 |
| 1762 int HttpCache::Transaction::DoNetworkReadComplete(int result) { | 1978 int HttpCache::Transaction::DoNetworkReadComplete(int result) { |
| 1763 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkReadComplete"); | 1979 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkReadComplete"); |
| 1980 if (net_log_.IsCapturing()) | |
| 1981 net_log_.EndEventWithNetErrorCode( | |
| 1982 NetLogEventType::HTTP_CACHE_NETWORK_READ_COMPLETE, result); | |
| 1983 | |
| 1764 DCHECK(mode_ & WRITE || mode_ == NONE); | 1984 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 1765 | 1985 |
| 1766 if (!cache_.get()) | 1986 if (!cache_.get()) |
| 1767 return ERR_UNEXPECTED; | 1987 return ERR_UNEXPECTED; |
| 1768 | 1988 |
| 1769 // If there is an error or we aren't saving the data, we are done; just wait | 1989 // If there is an error or we aren't saving the data, we are done; just wait |
| 1770 // until the destructor runs to see if we can keep the data. | 1990 // until the destructor runs to see if we can keep the data. |
| 1771 if (mode_ == NONE || result < 0) | 1991 if (mode_ == NONE || result < 0) |
| 1772 return result; | 1992 return result; |
| 1773 | 1993 |
| 1774 next_state_ = STATE_CACHE_WRITE_DATA; | 1994 next_state_ = STATE_CACHE_WRITE_DATA; |
| 1775 return result; | 1995 return result; |
| 1776 } | 1996 } |
| 1777 | 1997 |
| 1998 int HttpCache::Transaction::DoSharedNetworkRead() { | |
| 1999 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedNetworkRead"); | |
| 2000 if (net_log_.IsCapturing()) | |
| 2001 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_SHARED_NETWORK_READ); | |
| 2002 | |
| 2003 next_state_ = STATE_SHARED_NETWORK_READ_COMPLETE; | |
| 2004 bool shared_read_in_progress = false; | |
| 2005 int result = entry_->shared_writers->Read( | |
| 2006 read_buf_, io_buf_len_, io_callback_, this, &shared_read_in_progress); | |
| 2007 if (shared_read_in_progress) { | |
| 2008 next_state_ = STATE_SHARED_NETWORK_READ_WAIT_COMPLETE; | |
| 2009 } | |
| 2010 return result; | |
| 2011 } | |
| 2012 | |
| 2013 int HttpCache::Transaction::DoSharedNetworkReadComplete(int result) { | |
| 2014 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedNetworkReadComplete"); | |
| 2015 if (net_log_.IsCapturing()) | |
| 2016 net_log_.EndEventWithNetErrorCode( | |
| 2017 NetLogEventType::HTTP_CACHE_SHARED_NETWORK_READ_COMPLETE, result); | |
| 2018 | |
| 2019 if (result <= 0) { | |
| 2020 // Set entry as null so that the destructor does not invoke DoneWithEntry | |
| 2021 // again as entry_ is already cleaned up by SharedWriters. | |
| 2022 entry_ = nullptr; | |
| 2023 return result; | |
| 2024 } | |
| 2025 | |
| 2026 read_offset_ += result; | |
| 2027 | |
| 2028 next_state_ = STATE_SHARED_CACHE_WRITE_DATA; | |
| 2029 return result; | |
| 2030 } | |
| 2031 | |
| 2032 int HttpCache::Transaction::DoSharedCacheWriteData(int result) { | |
| 2033 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedCacheWriteData"); | |
| 2034 if (net_log_.IsCapturing()) | |
| 2035 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_SHARED_CACHE_WRITE_DATA); | |
| 2036 | |
| 2037 next_state_ = STATE_SHARED_CACHE_WRITE_DATA_COMPLETE; | |
| 2038 write_len_ = result; | |
| 2039 return entry_->shared_writers->CacheWrite(read_buf_, write_len_, io_callback_, | |
| 2040 this); | |
| 2041 } | |
| 2042 | |
| 2043 int HttpCache::Transaction::DoSharedCacheWriteDataComplete(int result) { | |
| 2044 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedCacheWriteDataComplete"); | |
| 2045 if (net_log_.IsCapturing()) | |
| 2046 net_log_.EndEventWithNetErrorCode( | |
| 2047 NetLogEventType::HTTP_CACHE_SHARED_CACHE_WRITE_DATA_COMPLETE, result); | |
| 2048 | |
| 2049 OnCacheWriteDataComplete(true, &result); | |
| 2050 | |
| 2051 if (result == 0) { | |
| 2052 DoneWritingToEntry(true, false); | |
| 2053 } | |
| 2054 return result; | |
| 2055 } | |
| 2056 | |
| 2057 void HttpCache::Transaction::OnCacheWriteDataComplete(bool was_shared, | |
| 2058 int* result) { | |
| 2059 if (*result != write_len_) { | |
| 2060 DoneWritingToEntry(false, !was_shared); | |
| 2061 // Consumer need not know that it was a failure since this transaction can | |
|
jkarlin
2017/02/03 18:26:20
Not a sentence.
shivanisha
2017/02/06 21:14:10
Restored to the original comment.
| |
| 2062 // continue reading from the network. | |
| 2063 *result = write_len_; | |
| 2064 } else if (!done_reading_ && entry_ && (!partial_ || truncated_)) { | |
| 2065 done_reading_ = cache_->IsResponseCompleted(entry_, &response_); | |
| 2066 } | |
| 2067 } | |
| 2068 | |
| 2069 int HttpCache::Transaction::DoSharedNetworkReadWaitComplete(int result) { | |
| 2070 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedNetworkReadWaitComplete"); | |
| 2071 if (net_log_.IsCapturing()) | |
| 2072 net_log_.EndEventWithNetErrorCode( | |
| 2073 NetLogEventType::HTTP_CACHE_SHARED_NETWORK_READ_WAIT_COMPLETE, result); | |
| 2074 | |
| 2075 // If its a network read failure or cache write failure, we just return the | |
| 2076 // result. | |
| 2077 // If its a cache write success, read_buf_ would have been filled | |
|
jkarlin
2017/02/03 18:26:20
Fix comment formatting
shivanisha
2017/02/06 21:14:10
done
| |
| 2078 // with the read data by SharedWriters. | |
| 2079 if (result == 0) { // response is complete. | |
| 2080 DoneWritingToEntry(true, false); // changes the mode_ to NONE. | |
| 2081 } else if (result > 0) { | |
| 2082 read_offset_ += result; | |
| 2083 } else { | |
| 2084 // Set entry as null so that the destructor does not invoke DoneWithEntry | |
| 2085 // again as entry_ is already cleaned up by SharedWriters. | |
| 2086 entry_ = nullptr; | |
| 2087 } | |
| 2088 | |
| 2089 return result; | |
| 2090 } | |
| 2091 | |
| 1778 int HttpCache::Transaction::DoCacheReadData() { | 2092 int HttpCache::Transaction::DoCacheReadData() { |
| 1779 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadData"); | 2093 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadData"); |
| 1780 if (request_->method == "HEAD") | 2094 if (request_->method == "HEAD") |
| 1781 return 0; | 2095 return 0; |
| 1782 | 2096 |
| 1783 DCHECK(entry_); | 2097 DCHECK(entry_); |
| 1784 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; | 2098 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; |
| 1785 | 2099 |
| 1786 if (net_log_.IsCapturing()) | 2100 if (net_log_.IsCapturing()) |
| 1787 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_DATA); | 2101 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_DATA); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1829 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; | 2143 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; |
| 1830 write_len_ = num_bytes; | 2144 write_len_ = num_bytes; |
| 1831 if (entry_) { | 2145 if (entry_) { |
| 1832 if (net_log_.IsCapturing()) | 2146 if (net_log_.IsCapturing()) |
| 1833 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); | 2147 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); |
| 1834 } | 2148 } |
| 1835 | 2149 |
| 1836 if (!entry_ || !num_bytes) | 2150 if (!entry_ || !num_bytes) |
| 1837 return num_bytes; | 2151 return num_bytes; |
| 1838 | 2152 |
| 2153 if (partial_) { | |
| 2154 return partial_->CacheWrite(entry_->disk_entry, read_buf_.get(), num_bytes, | |
| 2155 io_callback_); | |
| 2156 } | |
| 2157 | |
| 1839 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 2158 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); |
| 1840 return WriteToEntry(kResponseContentIndex, current_size, read_buf_.get(), | 2159 return entry_->disk_entry->WriteData(kResponseContentIndex, current_size, |
| 1841 num_bytes, io_callback_); | 2160 read_buf_.get(), num_bytes, io_callback_, |
| 2161 true); | |
| 1842 } | 2162 } |
| 1843 | 2163 |
| 1844 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) { | 2164 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) { |
| 1845 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteDataComplete"); | 2165 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteDataComplete"); |
| 1846 if (entry_) { | 2166 if (entry_) { |
| 1847 if (net_log_.IsCapturing()) { | 2167 if (net_log_.IsCapturing()) { |
| 1848 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_DATA, | 2168 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_DATA, |
| 1849 result); | 2169 result); |
| 1850 } | 2170 } |
| 1851 } | 2171 } |
| 1852 if (!cache_.get()) | 2172 if (!cache_.get()) |
| 1853 return ERR_UNEXPECTED; | 2173 return ERR_UNEXPECTED; |
| 1854 | 2174 |
| 1855 if (result != write_len_) { | 2175 OnCacheWriteDataComplete(false, &result); |
| 1856 DLOG(ERROR) << "failed to write response data to cache"; | |
| 1857 DoneWritingToEntry(false); | |
| 1858 | |
| 1859 // We want to ignore errors writing to disk and just keep reading from | |
| 1860 // the network. | |
| 1861 result = write_len_; | |
| 1862 } else if (!done_reading_ && entry_ && (!partial_ || truncated_)) { | |
| 1863 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | |
| 1864 int64_t body_size = response_.headers->GetContentLength(); | |
| 1865 if (body_size >= 0 && body_size <= current_size) | |
| 1866 done_reading_ = true; | |
| 1867 } | |
| 1868 | 2176 |
| 1869 if (partial_) { | 2177 if (partial_) { |
| 1870 // This may be the last request. | 2178 // This may be the last request. |
| 1871 if (result != 0 || truncated_ || | 2179 if (result != 0 || truncated_ || |
| 1872 !(partial_->IsLastRange() || mode_ == WRITE)) { | 2180 !(partial_->IsLastRange() || mode_ == WRITE)) { |
| 1873 return DoPartialNetworkReadCompleted(result); | 2181 return DoPartialNetworkReadCompleted(result); |
| 1874 } | 2182 } |
| 1875 } | 2183 } |
| 1876 | 2184 |
| 2185 // End of file. This may be the result of a connection problem so see if we | |
| 2186 // have to keep the entry around to be flagged as truncated later on. | |
| 1877 if (result == 0) { | 2187 if (result == 0) { |
| 1878 // End of file. This may be the result of a connection problem so see if we | |
| 1879 // have to keep the entry around to be flagged as truncated later on. | |
| 1880 if (done_reading_ || !entry_ || partial_ || | 2188 if (done_reading_ || !entry_ || partial_ || |
| 1881 response_.headers->GetContentLength() <= 0) { | 2189 response_.headers->GetContentLength() <= 0) |
| 1882 DoneWritingToEntry(true); | 2190 DoneWritingToEntry(true); |
| 1883 } | |
| 1884 } | 2191 } |
| 1885 | 2192 |
| 1886 return result; | 2193 return result; |
| 1887 } | 2194 } |
| 1888 | 2195 |
| 1889 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() { | 2196 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() { |
| 1890 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); | 2197 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); |
| 1891 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE; | 2198 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE; |
| 1892 return WriteResponseInfoToEntry(true); | 2199 return WriteResponseInfoToEntry(true); |
| 1893 } | 2200 } |
| 1894 | 2201 |
| 1895 int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) { | 2202 int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) { |
| 1896 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); | 2203 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); |
| 1897 | 2204 |
| 1898 return OnWriteResponseInfoToEntryComplete(result); | 2205 return OnWriteResponseInfoToEntryComplete(result); |
| 1899 } | 2206 } |
| 1900 | 2207 |
| 2208 int HttpCache::Transaction::DoSharedReadWriteFailed() { | |
| 2209 if (net_log_.IsCapturing()) | |
| 2210 net_log_.EndEventWithNetErrorCode( | |
| 2211 NetLogEventType::HTTP_CACHE_SHARED_READ_WRITE_FAILED, | |
| 2212 shared_read_write_failure_result_); | |
| 2213 | |
| 2214 return shared_read_write_failure_result_; | |
| 2215 } | |
| 2216 | |
| 1901 //----------------------------------------------------------------------------- | 2217 //----------------------------------------------------------------------------- |
| 1902 | 2218 |
| 1903 void HttpCache::Transaction::SetRequest(const NetLogWithSource& net_log, | 2219 void HttpCache::Transaction::SetRequest(const NetLogWithSource& net_log, |
| 1904 const HttpRequestInfo* request) { | 2220 const HttpRequestInfo* request) { |
| 1905 net_log_ = net_log; | 2221 net_log_ = net_log; |
| 1906 request_ = request; | 2222 request_ = request; |
| 1907 effective_load_flags_ = request_->load_flags; | 2223 effective_load_flags_ = request_->load_flags; |
| 1908 | 2224 |
| 1909 if (cache_->mode() == DISABLE) | 2225 if (cache_->mode() == DISABLE) |
| 1910 effective_load_flags_ |= LOAD_DISABLE_CACHE; | 2226 effective_load_flags_ |= LOAD_DISABLE_CACHE; |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2084 | 2400 |
| 2085 if (partial_ && (is_sparse_ || truncated_) && | 2401 if (partial_ && (is_sparse_ || truncated_) && |
| 2086 (!partial_->IsCurrentRangeCached() || invalid_range_)) { | 2402 (!partial_->IsCurrentRangeCached() || invalid_range_)) { |
| 2087 // Force revalidation for sparse or truncated entries. Note that we don't | 2403 // Force revalidation for sparse or truncated entries. Note that we don't |
| 2088 // want to ignore the regular validation logic just because a byte range was | 2404 // want to ignore the regular validation logic just because a byte range was |
| 2089 // part of the request. | 2405 // part of the request. |
| 2090 skip_validation = false; | 2406 skip_validation = false; |
| 2091 } | 2407 } |
| 2092 | 2408 |
| 2093 if (skip_validation) { | 2409 if (skip_validation) { |
| 2094 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_USED); | 2410 if (shared_) { |
| 2095 return SetupEntryForRead(); | 2411 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING); |
| 2412 entry_->shared_writers->OnValidationMatch(this, priority_); | |
| 2413 } else { | |
| 2414 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_USED); | |
| 2415 return SetupEntryForRead(); | |
| 2416 } | |
| 2096 } else { | 2417 } else { |
| 2097 // Make the network request conditional, to see if we may reuse our cached | 2418 // Make the network request conditional, to see if we may reuse our cached |
| 2098 // response. If we cannot do so, then we just resort to a normal fetch. | 2419 // response. If we cannot do so, then we just resort to a normal fetch. |
| 2099 // Our mode remains READ_WRITE for a conditional request. Even if the | 2420 // Our mode remains READ_WRITE for a conditional request. Even if the |
| 2100 // conditionalization fails, we don't switch to WRITE mode until we | 2421 // conditionalization fails, we don't switch to WRITE mode until we |
| 2101 // know we won't be falling back to using the cache entry in the | 2422 // know we won't be falling back to using the cache entry in the |
| 2102 // LOAD_FROM_CACHE_IF_OFFLINE case. | 2423 // LOAD_FROM_CACHE_IF_OFFLINE case. |
| 2103 if (!ConditionalizeRequest()) { | 2424 if (!ConditionalizeRequest()) { |
| 2104 couldnt_conditionalize_request_ = true; | 2425 couldnt_conditionalize_request_ = true; |
| 2105 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE); | 2426 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE); |
| (...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2604 IsCertStatusError(response_.ssl_info.cert_status)) { | 2925 IsCertStatusError(response_.ssl_info.cert_status)) { |
| 2605 DoneWritingToEntry(false); | 2926 DoneWritingToEntry(false); |
| 2606 if (net_log_.IsCapturing()) | 2927 if (net_log_.IsCapturing()) |
| 2607 net_log_.EndEvent(NetLogEventType::HTTP_CACHE_WRITE_INFO); | 2928 net_log_.EndEvent(NetLogEventType::HTTP_CACHE_WRITE_INFO); |
| 2608 return OK; | 2929 return OK; |
| 2609 } | 2930 } |
| 2610 | 2931 |
| 2611 if (truncated) | 2932 if (truncated) |
| 2612 DCHECK_EQ(200, response_.headers->response_code()); | 2933 DCHECK_EQ(200, response_.headers->response_code()); |
| 2613 | 2934 |
| 2614 // When writing headers, we normally only write the non-transient headers. | 2935 return cache_->WriteResponseInfo(entry_, &response_, io_callback_, truncated, |
| 2615 bool skip_transient_headers = true; | 2936 &io_buf_len_); |
| 2616 scoped_refptr<PickledIOBuffer> data(new PickledIOBuffer()); | |
| 2617 response_.Persist(data->pickle(), skip_transient_headers, truncated); | |
| 2618 data->Done(); | |
| 2619 | |
| 2620 io_buf_len_ = data->pickle()->size(); | |
| 2621 return entry_->disk_entry->WriteData(kResponseInfoIndex, 0, data.get(), | |
| 2622 io_buf_len_, io_callback_, true); | |
| 2623 } | 2937 } |
| 2624 | 2938 |
| 2625 int HttpCache::Transaction::OnWriteResponseInfoToEntryComplete(int result) { | 2939 int HttpCache::Transaction::OnWriteResponseInfoToEntryComplete(int result) { |
| 2626 if (!entry_) | 2940 if (!entry_) |
| 2627 return OK; | 2941 return OK; |
| 2628 if (net_log_.IsCapturing()) { | 2942 if (net_log_.IsCapturing()) { |
| 2629 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, | 2943 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, |
| 2630 result); | 2944 result); |
| 2631 } | 2945 } |
| 2632 | 2946 |
| 2633 if (result != io_buf_len_) { | 2947 if (result != io_buf_len_) { |
| 2634 DLOG(ERROR) << "failed to write response info to cache"; | 2948 DLOG(ERROR) << "failed to write response info to cache"; |
| 2635 DoneWritingToEntry(false); | 2949 DoneWritingToEntry(false); |
| 2636 } | 2950 } |
| 2637 return OK; | 2951 return OK; |
| 2638 } | 2952 } |
| 2639 | 2953 |
| 2640 void HttpCache::Transaction::DoneWritingToEntry(bool success) { | 2954 void HttpCache::Transaction::DoneWritingToEntry(bool success, |
| 2955 bool perform_entry_cleanup) { | |
| 2641 if (!entry_) | 2956 if (!entry_) |
| 2642 return; | 2957 return; |
| 2643 | 2958 |
| 2644 RecordHistograms(); | 2959 RecordHistograms(); |
| 2645 | 2960 |
| 2646 cache_->DoneWritingToEntry(entry_, success); | 2961 if (perform_entry_cleanup) { |
| 2647 entry_ = NULL; | 2962 cache_->DoneWritingToEntry(entry_, success); |
| 2963 } | |
| 2964 entry_ = nullptr; | |
| 2648 mode_ = NONE; // switch to 'pass through' mode | 2965 mode_ = NONE; // switch to 'pass through' mode |
| 2649 } | 2966 } |
| 2650 | 2967 |
| 2968 void HttpCache::Transaction::ContinueWithoutSharedWriting( | |
| 2969 std::unique_ptr<HttpTransaction> network_transaction, | |
| 2970 bool needs_entry) { | |
| 2971 shared_ = false; | |
| 2972 if (!needs_entry) | |
| 2973 entry_ = nullptr; | |
| 2974 mode_ = NONE; | |
| 2975 network_trans_ = std::move(network_transaction); | |
| 2976 } | |
| 2977 | |
| 2651 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { | 2978 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { |
| 2652 DLOG(ERROR) << "ReadData failed: " << result; | 2979 DLOG(ERROR) << "ReadData failed: " << result; |
| 2653 const int result_for_histogram = std::max(0, -result); | 2980 const int result_for_histogram = std::max(0, -result); |
| 2654 if (restart) { | 2981 if (restart) { |
| 2655 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", | 2982 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", |
| 2656 result_for_histogram); | 2983 result_for_histogram); |
| 2657 } else { | 2984 } else { |
| 2658 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable", | 2985 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable", |
| 2659 result_for_histogram); | 2986 result_for_histogram); |
| 2660 } | 2987 } |
| 2661 | 2988 |
| 2662 // Avoid using this entry in the future. | 2989 // Avoid using this entry in the future. |
| 2663 if (cache_.get()) | 2990 if (cache_.get()) |
| 2664 cache_->DoomActiveEntry(cache_key_); | 2991 cache_->DoomActiveEntry(cache_key_); |
| 2665 | 2992 |
| 2666 if (restart) { | 2993 if (restart) { |
| 2667 DCHECK(!reading_); | 2994 DCHECK(!reading_); |
| 2668 DCHECK(!network_trans_.get()); | 2995 DCHECK(!network_trans_.get()); |
| 2669 cache_->DoneWithEntry(entry_, this, false); | 2996 if (shared_) { |
| 2997 entry_->shared_writers->RemoveValidatingTransaction(this); | |
| 2998 } else { | |
| 2999 cache_->DoneWithEntry(entry_, this, false); | |
| 3000 } | |
| 2670 entry_ = NULL; | 3001 entry_ = NULL; |
| 2671 is_sparse_ = false; | 3002 is_sparse_ = false; |
| 2672 partial_.reset(); | 3003 partial_.reset(); |
| 2673 next_state_ = STATE_GET_BACKEND; | 3004 next_state_ = STATE_GET_BACKEND; |
| 2674 return OK; | 3005 return OK; |
| 2675 } | 3006 } |
| 2676 | 3007 |
| 2677 return ERR_CACHE_READ_FAILURE; | 3008 return ERR_CACHE_READ_FAILURE; |
| 2678 } | 3009 } |
| 2679 | 3010 |
| 2680 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { | 3011 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { |
| 2681 if (entry_lock_waiting_since_ != start_time) | 3012 if (entry_lock_waiting_since_ != start_time) |
| 2682 return; | 3013 return; |
| 2683 | 3014 |
| 2684 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); | 3015 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); |
| 2685 | 3016 |
| 2686 if (!cache_) | 3017 if (!cache_) |
| 2687 return; | 3018 return; |
| 2688 | 3019 |
| 2689 cache_->RemovePendingTransaction(this); | 3020 cache_->RemovePendingTransaction(this); |
| 2690 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); | 3021 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); |
| 2691 } | 3022 } |
| 2692 | 3023 |
| 2693 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { | 3024 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { |
| 3025 // Partial requests not supported with shared writing as of now. | |
| 3026 DCHECK(!shared_); | |
| 2694 DVLOG(2) << "DoomPartialEntry"; | 3027 DVLOG(2) << "DoomPartialEntry"; |
| 2695 int rv = cache_->DoomEntry(cache_key_, NULL); | 3028 int rv = cache_->DoomEntry(cache_key_, NULL); |
| 2696 DCHECK_EQ(OK, rv); | 3029 DCHECK_EQ(OK, rv); |
| 2697 cache_->DoneWithEntry(entry_, this, false); | 3030 cache_->DoneWithEntry(entry_, this, false); |
| 2698 entry_ = NULL; | 3031 entry_ = NULL; |
| 2699 is_sparse_ = false; | 3032 is_sparse_ = false; |
| 2700 truncated_ = false; | 3033 truncated_ = false; |
| 2701 if (delete_object) | 3034 if (delete_object) |
| 2702 partial_.reset(NULL); | 3035 partial_.reset(NULL); |
| 2703 } | 3036 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2744 if (!delete_object) { | 3077 if (!delete_object) { |
| 2745 // The simplest way to re-initialize partial_ is to create a new object. | 3078 // The simplest way to re-initialize partial_ is to create a new object. |
| 2746 partial_.reset(new PartialData()); | 3079 partial_.reset(new PartialData()); |
| 2747 if (partial_->Init(request_->extra_headers)) | 3080 if (partial_->Init(request_->extra_headers)) |
| 2748 partial_->SetHeaders(custom_request_->extra_headers); | 3081 partial_->SetHeaders(custom_request_->extra_headers); |
| 2749 else | 3082 else |
| 2750 partial_.reset(); | 3083 partial_.reset(); |
| 2751 } | 3084 } |
| 2752 } | 3085 } |
| 2753 | 3086 |
| 2754 void HttpCache::Transaction::ResetNetworkTransaction() { | 3087 void HttpCache::Transaction::SaveNetworkTransactionInfo( |
| 3088 const HttpTransaction* transaction) { | |
| 2755 DCHECK(!old_network_trans_load_timing_); | 3089 DCHECK(!old_network_trans_load_timing_); |
| 2756 DCHECK(network_trans_); | 3090 DCHECK(transaction); |
| 2757 LoadTimingInfo load_timing; | 3091 LoadTimingInfo load_timing; |
| 2758 if (network_trans_->GetLoadTimingInfo(&load_timing)) | 3092 if (transaction->GetLoadTimingInfo(&load_timing)) |
| 2759 old_network_trans_load_timing_.reset(new LoadTimingInfo(load_timing)); | 3093 old_network_trans_load_timing_.reset(new LoadTimingInfo(load_timing)); |
| 2760 total_received_bytes_ += network_trans_->GetTotalReceivedBytes(); | 3094 total_received_bytes_ += transaction->GetTotalReceivedBytes(); |
| 2761 total_sent_bytes_ += network_trans_->GetTotalSentBytes(); | 3095 total_sent_bytes_ += transaction->GetTotalSentBytes(); |
| 2762 ConnectionAttempts attempts; | 3096 ConnectionAttempts attempts; |
| 2763 network_trans_->GetConnectionAttempts(&attempts); | 3097 transaction->GetConnectionAttempts(&attempts); |
| 2764 for (const auto& attempt : attempts) | 3098 for (const auto& attempt : attempts) |
| 2765 old_connection_attempts_.push_back(attempt); | 3099 old_connection_attempts_.push_back(attempt); |
| 2766 old_remote_endpoint_ = IPEndPoint(); | 3100 old_remote_endpoint_ = IPEndPoint(); |
| 2767 network_trans_->GetRemoteEndpoint(&old_remote_endpoint_); | 3101 transaction->GetRemoteEndpoint(&old_remote_endpoint_); |
| 3102 } | |
| 3103 | |
| 3104 void HttpCache::Transaction::SaveSharedNetworkTransactionInfo() { | |
| 3105 // If network_trans_ is still present, this transaction has not started using | |
| 3106 // the "shared" network transaction. | |
| 3107 if (network_trans_) { | |
| 3108 SaveNetworkTransactionInfo(network_trans_.get()); | |
| 3109 return; | |
| 3110 } | |
| 3111 | |
| 3112 DCHECK(!old_network_trans_load_timing_); | |
| 3113 | |
| 3114 // If the transaction is being deleted while still in the waiting queue, | |
| 3115 // entry_ is not yet set, do nothing. | |
| 3116 if (!entry_) | |
| 3117 return; | |
| 3118 DCHECK(entry_->shared_writers); | |
| 3119 HttpTransaction* network_transaction = | |
| 3120 entry_->shared_writers->network_transaction(); | |
| 3121 SaveNetworkTransactionInfo(network_transaction); | |
| 3122 have_full_request_headers_ = | |
| 3123 network_transaction->GetFullRequestHeaders(&full_request_headers_); | |
| 3124 } | |
| 3125 | |
| 3126 void HttpCache::Transaction::ResetNetworkTransaction() { | |
| 3127 SaveNetworkTransactionInfo(network_trans_.get()); | |
| 2768 network_trans_.reset(); | 3128 network_trans_.reset(); |
| 2769 } | 3129 } |
| 2770 | 3130 |
| 2771 // Histogram data from the end of 2010 show the following distribution of | 3131 HttpTransaction* HttpCache::Transaction::GetCurrentNetworkTransaction() const { |
| 2772 // response headers: | 3132 if (network_trans_) |
| 2773 // | 3133 return network_trans_.get(); |
| 2774 // Content-Length............... 87% | 3134 if (shared_ && entry_ && entry_->shared_writers) |
| 2775 // Date......................... 98% | 3135 return entry_->shared_writers->network_transaction(); |
| 2776 // Last-Modified................ 49% | 3136 return nullptr; |
| 2777 // Etag......................... 19% | |
| 2778 // Accept-Ranges: bytes......... 25% | |
| 2779 // Accept-Ranges: none.......... 0.4% | |
| 2780 // Strong Validator............. 50% | |
| 2781 // Strong Validator + ranges.... 24% | |
| 2782 // Strong Validator + CL........ 49% | |
| 2783 // | |
| 2784 bool HttpCache::Transaction::CanResume(bool has_data) { | |
| 2785 // Double check that there is something worth keeping. | |
| 2786 if (has_data && !entry_->disk_entry->GetDataSize(kResponseContentIndex)) | |
| 2787 return false; | |
| 2788 | |
| 2789 if (request_->method != "GET") | |
| 2790 return false; | |
| 2791 | |
| 2792 // Note that if this is a 206, content-length was already fixed after calling | |
| 2793 // PartialData::ResponseHeadersOK(). | |
| 2794 if (response_.headers->GetContentLength() <= 0 || | |
| 2795 response_.headers->HasHeaderValue("Accept-Ranges", "none") || | |
| 2796 !response_.headers->HasStrongValidators()) { | |
| 2797 return false; | |
| 2798 } | |
| 2799 | |
| 2800 return true; | |
| 2801 } | 3137 } |
| 2802 | 3138 |
| 2803 void HttpCache::Transaction::SetResponse(const HttpResponseInfo& response) { | 3139 void HttpCache::Transaction::SetResponse(const HttpResponseInfo& response) { |
| 2804 response_ = response; | 3140 response_ = response; |
| 2805 SyncCacheEntryStatusToResponse(); | 3141 SyncCacheEntryStatusToResponse(); |
| 2806 } | 3142 } |
| 2807 | 3143 |
| 2808 void HttpCache::Transaction::SetAuthResponse( | 3144 void HttpCache::Transaction::SetAuthResponse( |
| 2809 const HttpResponseInfo& auth_response) { | 3145 const HttpResponseInfo& auth_response) { |
| 2810 auth_response_ = auth_response; | 3146 auth_response_ = auth_response; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2916 } | 3252 } |
| 2917 } | 3253 } |
| 2918 | 3254 |
| 2919 CACHE_STATUS_HISTOGRAMS(""); | 3255 CACHE_STATUS_HISTOGRAMS(""); |
| 2920 | 3256 |
| 2921 if (cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE) { | 3257 if (cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE) { |
| 2922 UMA_HISTOGRAM_ENUMERATION("HttpCache.CantConditionalizeCause", | 3258 UMA_HISTOGRAM_ENUMERATION("HttpCache.CantConditionalizeCause", |
| 2923 validation_cause_, VALIDATION_CAUSE_MAX); | 3259 validation_cause_, VALIDATION_CAUSE_MAX); |
| 2924 } | 3260 } |
| 2925 | 3261 |
| 3262 // This may also exclude shared writing counts for these cases. | |
| 2926 if (cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER) | 3263 if (cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER) |
| 2927 return; | 3264 return; |
| 3265 | |
| 2928 DCHECK(!range_requested_); | 3266 DCHECK(!range_requested_); |
| 2929 DCHECK(!first_cache_access_since_.is_null()); | 3267 DCHECK(!first_cache_access_since_.is_null()); |
| 2930 | 3268 |
| 2931 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; | 3269 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; |
| 2932 | 3270 |
| 2933 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); | 3271 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); |
| 2934 | 3272 |
| 3273 if (cache_entry_status_ == CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING) { | |
| 3274 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.JoinSharedWriting", total_time); | |
| 3275 } else if (cache_entry_status_ == | |
| 3276 CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING) { | |
| 3277 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.DoomSharedWriting", total_time); | |
| 3278 } else if (initiate_shared_writing_) { | |
| 3279 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.InitiateSharedWriting", | |
| 3280 total_time); | |
| 3281 } | |
| 3282 | |
| 2935 bool did_send_request = !send_request_since_.is_null(); | 3283 bool did_send_request = !send_request_since_.is_null(); |
| 2936 DCHECK( | 3284 DCHECK( |
| 2937 (did_send_request && | 3285 (did_send_request && |
| 2938 (cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE || | 3286 (cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE || |
| 2939 cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED || | 3287 cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED || |
| 2940 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED || | 3288 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED || |
| 2941 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE)) || | 3289 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE || |
| 3290 cache_entry_status_ == CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING || | |
| 3291 cache_entry_status_ == CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING)) || | |
| 2942 (!did_send_request && | 3292 (!did_send_request && |
| 2943 cache_entry_status_ == CacheEntryStatus::ENTRY_USED)); | 3293 (cache_entry_status_ == CacheEntryStatus::ENTRY_USED || |
| 3294 cache_entry_status_ == CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING))); | |
| 2944 | 3295 |
| 2945 if (!did_send_request) { | 3296 if (!did_send_request) { |
| 2946 DCHECK(cache_entry_status_ == CacheEntryStatus::ENTRY_USED); | 3297 if (cache_entry_status_ == CacheEntryStatus::ENTRY_USED) { |
| 2947 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.Used", total_time); | 3298 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.Used", total_time); |
| 3299 } | |
| 2948 return; | 3300 return; |
| 2949 } | 3301 } |
| 2950 | 3302 |
| 2951 TimeDelta before_send_time = send_request_since_ - first_cache_access_since_; | 3303 TimeDelta before_send_time = send_request_since_ - first_cache_access_since_; |
| 2952 int64_t before_send_percent = (total_time.ToInternalValue() == 0) | 3304 int64_t before_send_percent = (total_time.ToInternalValue() == 0) |
| 2953 ? 0 | 3305 ? 0 |
| 2954 : before_send_time * 100 / total_time; | 3306 : before_send_time * 100 / total_time; |
| 2955 DCHECK_GE(before_send_percent, 0); | 3307 DCHECK_GE(before_send_percent, 0); |
| 2956 DCHECK_LE(before_send_percent, 100); | 3308 DCHECK_LE(before_send_percent, 100); |
| 2957 base::HistogramBase::Sample before_send_sample = | 3309 base::HistogramBase::Sample before_send_sample = |
| 2958 static_cast<base::HistogramBase::Sample>(before_send_percent); | 3310 static_cast<base::HistogramBase::Sample>(before_send_percent); |
| 2959 | 3311 |
| 2960 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.SentRequest", total_time); | 3312 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.SentRequest", total_time); |
| 2961 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend", before_send_time); | 3313 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend", before_send_time); |
| 2962 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend", before_send_sample); | 3314 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend", before_send_sample); |
| 2963 | 3315 |
| 2964 // TODO(gavinp): Remove or minimize these histograms, particularly the ones | 3316 // TODO(gavinp): Remove or minimize these histograms, particularly the ones |
| 2965 // below this comment after we have received initial data. | 3317 // below this comment after we have received initial data. |
| 2966 switch (cache_entry_status_) { | 3318 switch (cache_entry_status_) { |
| 2967 case CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE: { | 3319 case CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE: { |
| 2968 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.CantConditionalize", | 3320 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.CantConditionalize", |
| 2969 before_send_time); | 3321 before_send_time); |
| 2970 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.CantConditionalize", | 3322 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.CantConditionalize", |
| 2971 before_send_sample); | 3323 before_send_sample); |
| 3324 if (initiate_shared_writing_) { | |
| 3325 UMA_HISTOGRAM_TIMES( | |
| 3326 "HttpCache.BeforeSend.CantConditionalize.InitiateSharedWriting", | |
| 3327 before_send_time); | |
| 3328 UMA_HISTOGRAM_PERCENTAGE( | |
| 3329 "HttpCache.PercentBeforeSend.CantConditionalize." | |
| 3330 "InitiateSharedWriting", | |
| 3331 before_send_sample); | |
| 3332 } | |
| 3333 | |
| 2972 break; | 3334 break; |
| 2973 } | 3335 } |
| 2974 case CacheEntryStatus::ENTRY_NOT_IN_CACHE: { | 3336 case CacheEntryStatus::ENTRY_NOT_IN_CACHE: { |
| 2975 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.NotCached", before_send_time); | 3337 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.NotCached", before_send_time); |
| 2976 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.NotCached", | 3338 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.NotCached", |
| 2977 before_send_sample); | 3339 before_send_sample); |
| 3340 if (initiate_shared_writing_) { | |
| 3341 UMA_HISTOGRAM_TIMES( | |
| 3342 "HttpCache.BeforeSend.NotCached.InitiateSharedWriting", | |
| 3343 before_send_time); | |
| 3344 UMA_HISTOGRAM_PERCENTAGE( | |
| 3345 "HttpCache.PercentBeforeSend.NotCached.InitiateSharedWriting", | |
| 3346 before_send_sample); | |
| 3347 } | |
| 3348 | |
| 2978 break; | 3349 break; |
| 2979 } | 3350 } |
| 2980 case CacheEntryStatus::ENTRY_VALIDATED: { | 3351 case CacheEntryStatus::ENTRY_VALIDATED: { |
| 2981 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Validated", before_send_time); | 3352 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Validated", before_send_time); |
| 2982 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Validated", | 3353 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Validated", |
| 2983 before_send_sample); | 3354 before_send_sample); |
| 2984 break; | 3355 break; |
| 2985 } | 3356 } |
| 2986 case CacheEntryStatus::ENTRY_UPDATED: { | 3357 case CacheEntryStatus::ENTRY_UPDATED: { |
| 2987 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Updated", before_send_time); | 3358 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Updated", before_send_time); |
| 2988 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Updated", | 3359 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Updated", |
| 2989 before_send_sample); | 3360 before_send_sample); |
| 3361 if (initiate_shared_writing_) { | |
| 3362 UMA_HISTOGRAM_TIMES( | |
| 3363 "HttpCache.BeforeSend.Updated.InitiateSharedWriting", | |
| 3364 before_send_time); | |
| 3365 UMA_HISTOGRAM_PERCENTAGE( | |
| 3366 "HttpCache.PercentBeforeSend.Updated.InitiateSharedWriting", | |
| 3367 before_send_sample); | |
| 3368 } | |
| 3369 break; | |
| 3370 } | |
| 3371 case CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING: { | |
| 3372 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.JoinSharedWriting", | |
| 3373 before_send_time); | |
| 3374 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.JoinSharedWriting", | |
| 3375 before_send_sample); | |
| 3376 break; | |
| 3377 } | |
| 3378 case CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING: { | |
| 3379 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.DoomSharedWriting", | |
| 3380 before_send_time); | |
| 3381 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.DoomSharedWriting", | |
| 3382 before_send_sample); | |
| 2990 break; | 3383 break; |
| 2991 } | 3384 } |
| 2992 default: | 3385 default: |
| 2993 NOTREACHED(); | 3386 NOTREACHED(); |
| 2994 } | 3387 } |
| 2995 } | 3388 } |
| 2996 | 3389 |
| 3390 bool HttpCache::Transaction::IsEligibleForSharedWriting() const { | |
| 3391 if (!(mode_ & WRITE)) | |
| 3392 return false; | |
| 3393 | |
| 3394 DCHECK(request_); | |
| 3395 if (request_->method != "GET") | |
| 3396 return false; | |
| 3397 | |
| 3398 if (partial_ || range_requested_) | |
| 3399 return false; | |
| 3400 | |
| 3401 if (truncated_) | |
| 3402 return false; | |
| 3403 | |
| 3404 return true; | |
| 3405 } | |
| 3406 | |
| 3407 void HttpCache::Transaction::SetSharedWritingFailState(int result) { | |
| 3408 next_state_ = STATE_SHARED_READ_WRITE_FAILED; | |
| 3409 shared_read_write_failure_result_ = result; | |
| 3410 entry_ = nullptr; | |
| 3411 } | |
| 3412 | |
| 2997 void HttpCache::Transaction::OnIOComplete(int result) { | 3413 void HttpCache::Transaction::OnIOComplete(int result) { |
| 2998 DoLoop(result); | 3414 DoLoop(result); |
| 2999 } | 3415 } |
| 3000 | 3416 |
| 3001 } // namespace net | 3417 } // namespace net |
| OLD | NEW |