| 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 switch (next_state_) { |
| 242 case STATE_GET_BACKEND_COMPLETE: |
| 243 case STATE_OPEN_ENTRY_COMPLETE: |
| 244 case STATE_DOOM_ENTRY_COMPLETE: |
| 245 case STATE_CREATE_ENTRY_COMPLETE: |
| 246 case STATE_ADD_TO_ENTRY_COMPLETE: |
| 247 // Pending transaction not yet added to an entry, so entry_ is null, let |
| 248 // cache_ handle the deletion. |
| 249 cache_->RemovePendingTransaction(this); |
| 250 // Set cache_pending_ to false so that more cleanup is not attempted in |
| 251 // the destructor. |
| 252 cache_pending_ = false; |
| 253 break; |
| 254 case STATE_CACHE_READ_RESPONSE_COMPLETE: |
| 255 case STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE: |
| 256 case STATE_CACHE_QUERY_DATA_COMPLETE: |
| 257 case STATE_COMPLETE_PARTIAL_CACHE_VALIDATION: |
| 258 case STATE_SEND_REQUEST_COMPLETE: |
| 259 case STATE_CACHE_WRITE_UPDATED_RESPONSE_COMPLETE: |
| 260 case STATE_UPDATE_CACHED_RESPONSE_COMPLETE: |
| 261 case STATE_CACHE_WRITE_RESPONSE_COMPLETE: |
| 262 case STATE_TRUNCATE_CACHED_DATA_COMPLETE: |
| 263 case STATE_TRUNCATE_CACHED_METADATA_COMPLETE: |
| 264 case STATE_CACHE_READ_METADATA_COMPLETE: |
| 265 entry_->shared_writers->RemoveValidatingTransaction(this); |
| 266 break; |
| 267 case STATE_SHARED_NETWORK_READ_COMPLETE: |
| 268 case STATE_SHARED_CACHE_WRITE_DATA_COMPLETE: |
| 269 // Current shared network transaction's consumer. |
| 270 entry_->shared_writers->RemoveActiveTransaction(this); |
| 271 break; |
| 272 case STATE_SHARED_NETWORK_READ_WAIT_COMPLETE: |
| 273 // Waiting on Read() operation to be completed by another |
| 274 // transaction. |
| 275 entry_->shared_writers->RemoveWaitingForReadTransaction(this); |
| 276 break; |
| 277 case STATE_CACHE_READ_DATA_COMPLETE: |
| 278 case STATE_NONE: |
| 279 entry_->shared_writers->RemoveIdleTransaction(this); |
| 280 break; |
| 281 default: |
| 282 NOTREACHED() << "bad state"; |
| 283 break; |
| 284 } |
| 285 |
| 286 DCHECK(!shared_); |
| 287 |
| 288 // Since any cleanup needed in entry_ and shared_writers is already done, |
| 289 // set entry_ to null. |
| 290 entry_ = nullptr; |
| 291 } |
| 292 |
| 227 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len, | 293 int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len, |
| 228 const CompletionCallback& callback) { | 294 const CompletionCallback& callback) { |
| 229 DCHECK(buf); | 295 DCHECK(buf); |
| 230 DCHECK_GT(buf_len, 0); | 296 DCHECK_GT(buf_len, 0); |
| 231 DCHECK(!callback.is_null()); | 297 DCHECK(!callback.is_null()); |
| 232 if (!cache_.get() || !entry_) | 298 if (!cache_.get() || !entry_) |
| 233 return ERR_UNEXPECTED; | 299 return ERR_UNEXPECTED; |
| 234 | 300 |
| 235 // We don't need to track this operation for anything. | 301 // We don't need to track this operation for anything. |
| 236 // It could be possible to check if there is something already written and | 302 // 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 | 303 // avoid writing again (it should be the same, right?), but let's allow the |
| 238 // caller to "update" the contents with something new. | 304 // caller to "update" the contents with something new. |
| 239 return entry_->disk_entry->WriteData(kMetadataIndex, 0, buf, buf_len, | 305 return entry_->disk_entry->WriteData(kMetadataIndex, 0, buf, buf_len, |
| 240 callback, true); | 306 callback, true); |
| 241 } | 307 } |
| 242 | 308 |
| 243 bool HttpCache::Transaction::AddTruncatedFlag() { | 309 bool HttpCache::Transaction::AddTruncatedFlag() { |
| 244 DCHECK(mode_ & WRITE || mode_ == NONE); | 310 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 245 | 311 |
| 246 // Don't set the flag for sparse entries. | 312 // Don't set the flag for sparse entries. |
| 247 if (partial_ && !truncated_) | 313 if (partial_ && !truncated_) |
| 248 return true; | 314 return true; |
| 249 | 315 |
| 250 if (!CanResume(true)) | 316 if (!cache_->CanResumeEntry(true, request_->method, &response_, entry_)) |
| 251 return false; | 317 return false; |
| 252 | 318 |
| 253 // We may have received the whole resource already. | 319 // We may have received the whole resource already. |
| 254 if (done_reading_) | 320 if (done_reading_) |
| 255 return true; | 321 return true; |
| 256 | 322 |
| 257 truncated_ = true; | 323 truncated_ = true; |
| 258 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE; | 324 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE; |
| 259 DoLoop(OK); | 325 DoLoop(OK); |
| 260 return true; | 326 return true; |
| 261 } | 327 } |
| 262 | 328 |
| 263 LoadState HttpCache::Transaction::GetWriterLoadState() const { | 329 LoadState HttpCache::Transaction::GetWriterLoadState() const { |
| 264 if (network_trans_.get()) | 330 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 265 return network_trans_->GetLoadState(); | 331 if (network_transaction) |
| 332 return network_transaction->GetLoadState(); |
| 266 if (entry_ || !request_) | 333 if (entry_ || !request_) |
| 267 return LOAD_STATE_IDLE; | 334 return LOAD_STATE_IDLE; |
| 268 return LOAD_STATE_WAITING_FOR_CACHE; | 335 return LOAD_STATE_WAITING_FOR_CACHE; |
| 269 } | 336 } |
| 270 | 337 |
| 271 const NetLogWithSource& HttpCache::Transaction::net_log() const { | 338 const NetLogWithSource& HttpCache::Transaction::net_log() const { |
| 272 return net_log_; | 339 return net_log_; |
| 273 } | 340 } |
| 274 | 341 |
| 275 int HttpCache::Transaction::Start(const HttpRequestInfo* request, | 342 int HttpCache::Transaction::Start(const HttpRequestInfo* request, |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 } | 432 } |
| 366 | 433 |
| 367 bool HttpCache::Transaction::IsReadyToRestartForAuth() { | 434 bool HttpCache::Transaction::IsReadyToRestartForAuth() { |
| 368 if (!network_trans_.get()) | 435 if (!network_trans_.get()) |
| 369 return false; | 436 return false; |
| 370 return network_trans_->IsReadyToRestartForAuth(); | 437 return network_trans_->IsReadyToRestartForAuth(); |
| 371 } | 438 } |
| 372 | 439 |
| 373 int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len, | 440 int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len, |
| 374 const CompletionCallback& callback) { | 441 const CompletionCallback& callback) { |
| 442 if (next_state_ == STATE_SHARED_READ_WRITE_FAILED) { |
| 443 if (net_log_.IsCapturing()) |
| 444 net_log_.EndEventWithNetErrorCode( |
| 445 NetLogEventType::HTTP_CACHE_SHARED_READ_WRITE_FAILED, |
| 446 shared_read_write_failure_result_); |
| 447 |
| 448 return shared_read_write_failure_result_; |
| 449 } |
| 450 |
| 375 DCHECK_EQ(next_state_, STATE_NONE); | 451 DCHECK_EQ(next_state_, STATE_NONE); |
| 376 DCHECK(buf); | 452 DCHECK(buf); |
| 377 DCHECK_GT(buf_len, 0); | 453 DCHECK_GT(buf_len, 0); |
| 378 DCHECK(!callback.is_null()); | 454 DCHECK(!callback.is_null()); |
| 379 | 455 |
| 380 DCHECK(callback_.is_null()); | 456 DCHECK(callback_.is_null()); |
| 381 | 457 |
| 382 if (!cache_.get()) | 458 if (!cache_.get()) |
| 383 return ERR_UNEXPECTED; | 459 return ERR_UNEXPECTED; |
| 384 | 460 |
| 385 // If we have an intermediate auth response at this point, then it means the | 461 // 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 | 462 // 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. | 463 // previous response in the cache then we should leave it intact. |
| 388 if (auth_response_.headers.get() && mode_ != NONE) { | 464 if (auth_response_.headers.get() && mode_ != NONE) { |
| 389 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); | 465 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); |
| 390 DCHECK(mode_ & WRITE); | 466 DCHECK(mode_ & WRITE); |
| 391 DoneWritingToEntry(mode_ == READ_WRITE); | 467 DoneWritingToEntry(mode_ == READ_WRITE); |
| 392 mode_ = NONE; | 468 mode_ = NONE; |
| 393 } | 469 } |
| 394 | 470 |
| 395 reading_ = true; | 471 reading_ = true; |
| 396 read_buf_ = buf; | 472 read_buf_ = buf; |
| 397 io_buf_len_ = buf_len; | 473 io_buf_len_ = buf_len; |
| 398 if (network_trans_) { | 474 |
| 399 DCHECK(mode_ == WRITE || mode_ == NONE || | 475 if (shared_) { |
| 400 (mode_ == READ_WRITE && partial_)); | 476 int disk_entry_size = |
| 401 next_state_ = STATE_NETWORK_READ; | 477 entry_->disk_entry->GetDataSize(kResponseContentIndex); |
| 402 } else { | 478 if (read_offset_ == disk_entry_size) { |
| 403 DCHECK(mode_ == READ || (mode_ == READ_WRITE && partial_)); | 479 next_state_ = STATE_SHARED_NETWORK_READ; |
| 404 next_state_ = STATE_CACHE_READ_DATA; | 480 } else { |
| 481 DCHECK_LT(read_offset_, disk_entry_size); |
| 482 next_state_ = STATE_CACHE_READ_DATA; |
| 483 } |
| 484 } else { // not shared. |
| 485 if (network_trans_) { |
| 486 DCHECK(mode_ == WRITE || mode_ == NONE || |
| 487 (mode_ == READ_WRITE && partial_)); |
| 488 next_state_ = STATE_NETWORK_READ; |
| 489 } else { // read-only |
| 490 DCHECK(mode_ == READ || (mode_ == READ_WRITE && partial_)); |
| 491 next_state_ = STATE_CACHE_READ_DATA; |
| 492 } |
| 405 } | 493 } |
| 406 | 494 |
| 407 int rv = DoLoop(OK); | 495 int rv = DoLoop(OK); |
| 408 | 496 |
| 409 if (rv == ERR_IO_PENDING) { | 497 if (rv == ERR_IO_PENDING) { |
| 410 DCHECK(callback_.is_null()); | 498 DCHECK(callback_.is_null()); |
| 411 callback_ = callback; | 499 callback_ = callback; |
| 412 } | 500 } |
| 413 return rv; | 501 return rv; |
| 414 } | 502 } |
| 415 | 503 |
| 416 void HttpCache::Transaction::StopCaching() { | 504 void HttpCache::Transaction::StopCaching() { |
| 417 // We really don't know where we are now. Hopefully there is no operation in | 505 // 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 | 506 // 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 | 507 // 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 | 508 // 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 | 509 // 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 | 510 // 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 | 511 // the next piece of code that executes know that we are now reading directly |
| 424 // from the net. | 512 // from the net. |
| 425 // TODO(mmenke): This doesn't release the lock on the cache entry, so a | 513 // 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. | 514 // future request for the resource will be blocked on this one. |
| 427 // Fix this. | 515 // Fix this. |
| 428 if (cache_.get() && entry_ && (mode_ & WRITE) && network_trans_.get() && | 516 if (shared_) { |
| 429 !is_sparse_ && !range_requested_) { | 517 // This might or might not stop caching based on whether other consumers |
| 518 // exist for this resource or not. If it does, shared_ will be set to false. |
| 519 entry_->shared_writers->StopCaching(this); |
| 520 } |
| 521 if (!shared_ && cache_.get() && entry_ && (mode_ & WRITE) && |
| 522 network_trans_.get() && !is_sparse_ && !range_requested_) { |
| 430 mode_ = NONE; | 523 mode_ = NONE; |
| 431 } | 524 } |
| 432 } | 525 } |
| 433 | 526 |
| 434 bool HttpCache::Transaction::GetFullRequestHeaders( | 527 bool HttpCache::Transaction::GetFullRequestHeaders( |
| 435 HttpRequestHeaders* headers) const { | 528 HttpRequestHeaders* headers) const { |
| 436 if (network_trans_) | 529 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 437 return network_trans_->GetFullRequestHeaders(headers); | 530 if (network_transaction) { |
| 438 | 531 return network_transaction->GetFullRequestHeaders(headers); |
| 532 } else if (have_full_request_headers_) { |
| 533 *headers = full_request_headers_; |
| 534 return true; |
| 535 } |
| 439 // TODO(juliatuttle): Read headers from cache. | 536 // TODO(juliatuttle): Read headers from cache. |
| 440 return false; | 537 return false; |
| 441 } | 538 } |
| 442 | 539 |
| 443 int64_t HttpCache::Transaction::GetTotalReceivedBytes() const { | 540 int64_t HttpCache::Transaction::GetTotalReceivedBytes() const { |
| 444 int64_t total_received_bytes = total_received_bytes_; | 541 int64_t total_received_bytes = total_received_bytes_; |
| 445 if (network_trans_) | 542 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 446 total_received_bytes += network_trans_->GetTotalReceivedBytes(); | 543 if (network_transaction) |
| 544 total_received_bytes += network_transaction->GetTotalReceivedBytes(); |
| 447 return total_received_bytes; | 545 return total_received_bytes; |
| 448 } | 546 } |
| 449 | 547 |
| 450 int64_t HttpCache::Transaction::GetTotalSentBytes() const { | 548 int64_t HttpCache::Transaction::GetTotalSentBytes() const { |
| 451 int64_t total_sent_bytes = total_sent_bytes_; | 549 int64_t total_sent_bytes = total_sent_bytes_; |
| 452 if (network_trans_) | 550 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 453 total_sent_bytes += network_trans_->GetTotalSentBytes(); | 551 if (network_transaction) |
| 552 total_sent_bytes += network_transaction->GetTotalSentBytes(); |
| 454 return total_sent_bytes; | 553 return total_sent_bytes; |
| 455 } | 554 } |
| 456 | 555 |
| 457 void HttpCache::Transaction::DoneReading() { | 556 void HttpCache::Transaction::DoneReading() { |
| 458 if (cache_.get() && entry_) { | 557 if (cache_.get() && entry_) { |
| 459 DCHECK_NE(mode_, UPDATE); | 558 DCHECK_NE(mode_, UPDATE); |
| 559 bool perform_entry_cleanup = true; |
| 560 if (shared_) { |
| 561 entry_->shared_writers->DoneReading(this); |
| 562 |
| 563 // shared_ should have been set to false. |
| 564 DCHECK(!shared_); |
| 565 |
| 566 DoneWritingToEntry(true, false); |
| 567 return; |
| 568 } |
| 569 |
| 460 if (mode_ & WRITE) { | 570 if (mode_ & WRITE) { |
| 461 DoneWritingToEntry(true); | 571 DoneWritingToEntry(true, perform_entry_cleanup); |
| 462 } else if (mode_ & READ) { | 572 } else if (mode_ & READ) { |
| 463 // It is necessary to check mode_ & READ because it is possible | 573 // 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 | 574 // for mode_ to be NONE and entry_ non-NULL with a write entry |
| 465 // if StopCaching was called. | 575 // if StopCaching was called. |
| 466 cache_->DoneReadingFromEntry(entry_, this); | 576 cache_->DoneReadingFromEntry(entry_, this); |
| 467 entry_ = NULL; | 577 entry_ = NULL; |
| 468 } | 578 } |
| 469 } | 579 } |
| 470 } | 580 } |
| 471 | 581 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 490 return cache_->GetLoadStateForPendingTransaction(this); | 600 return cache_->GetLoadStateForPendingTransaction(this); |
| 491 | 601 |
| 492 return LOAD_STATE_IDLE; | 602 return LOAD_STATE_IDLE; |
| 493 } | 603 } |
| 494 | 604 |
| 495 void HttpCache::Transaction::SetQuicServerInfo( | 605 void HttpCache::Transaction::SetQuicServerInfo( |
| 496 QuicServerInfo* quic_server_info) {} | 606 QuicServerInfo* quic_server_info) {} |
| 497 | 607 |
| 498 bool HttpCache::Transaction::GetLoadTimingInfo( | 608 bool HttpCache::Transaction::GetLoadTimingInfo( |
| 499 LoadTimingInfo* load_timing_info) const { | 609 LoadTimingInfo* load_timing_info) const { |
| 500 if (network_trans_) | 610 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 501 return network_trans_->GetLoadTimingInfo(load_timing_info); | 611 if (network_transaction) |
| 612 return network_transaction->GetLoadTimingInfo(load_timing_info); |
| 502 | 613 |
| 503 if (old_network_trans_load_timing_) { | 614 if (old_network_trans_load_timing_) { |
| 504 *load_timing_info = *old_network_trans_load_timing_; | 615 *load_timing_info = *old_network_trans_load_timing_; |
| 505 return true; | 616 return true; |
| 506 } | 617 } |
| 507 | 618 |
| 508 if (first_cache_access_since_.is_null()) | 619 if (first_cache_access_since_.is_null()) |
| 509 return false; | 620 return false; |
| 510 | 621 |
| 511 // If the cache entry was opened, return that time. | 622 // If the cache entry was opened, return that time. |
| 512 load_timing_info->send_start = first_cache_access_since_; | 623 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 | 624 // This time doesn't make much sense when reading from the cache, so just use |
| 514 // the same time as send_start. | 625 // the same time as send_start. |
| 515 load_timing_info->send_end = first_cache_access_since_; | 626 load_timing_info->send_end = first_cache_access_since_; |
| 516 return true; | 627 return true; |
| 517 } | 628 } |
| 518 | 629 |
| 519 bool HttpCache::Transaction::GetRemoteEndpoint(IPEndPoint* endpoint) const { | 630 bool HttpCache::Transaction::GetRemoteEndpoint(IPEndPoint* endpoint) const { |
| 520 if (network_trans_) | 631 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 521 return network_trans_->GetRemoteEndpoint(endpoint); | 632 if (network_transaction) |
| 633 return network_transaction->GetRemoteEndpoint(endpoint); |
| 522 | 634 |
| 523 if (!old_remote_endpoint_.address().empty()) { | 635 if (!old_remote_endpoint_.address().empty()) { |
| 524 *endpoint = old_remote_endpoint_; | 636 *endpoint = old_remote_endpoint_; |
| 525 return true; | 637 return true; |
| 526 } | 638 } |
| 527 | 639 |
| 528 return false; | 640 return false; |
| 529 } | 641 } |
| 530 | 642 |
| 531 void HttpCache::Transaction::PopulateNetErrorDetails( | 643 void HttpCache::Transaction::PopulateNetErrorDetails( |
| 532 NetErrorDetails* details) const { | 644 NetErrorDetails* details) const { |
| 533 if (network_trans_) | 645 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 534 return network_trans_->PopulateNetErrorDetails(details); | 646 if (network_transaction) |
| 647 network_transaction->PopulateNetErrorDetails(details); |
| 535 return; | 648 return; |
| 536 } | 649 } |
| 537 | 650 |
| 538 void HttpCache::Transaction::SetPriority(RequestPriority priority) { | 651 void HttpCache::Transaction::SetPriority(RequestPriority priority) { |
| 539 priority_ = priority; | 652 priority_ = priority; |
| 540 if (network_trans_) | 653 if (network_trans_) |
| 541 network_trans_->SetPriority(priority_); | 654 network_trans_->SetPriority(priority_); |
| 655 else if (shared_ && entry_ && entry_->shared_writers) |
| 656 entry_->shared_writers->PriorityChanged(); |
| 542 } | 657 } |
| 543 | 658 |
| 544 void HttpCache::Transaction::SetWebSocketHandshakeStreamCreateHelper( | 659 void HttpCache::Transaction::SetWebSocketHandshakeStreamCreateHelper( |
| 545 WebSocketHandshakeStreamBase::CreateHelper* create_helper) { | 660 WebSocketHandshakeStreamBase::CreateHelper* create_helper) { |
| 546 websocket_handshake_stream_base_create_helper_ = create_helper; | 661 websocket_handshake_stream_base_create_helper_ = create_helper; |
| 547 if (network_trans_) | 662 if (network_trans_) |
| 548 network_trans_->SetWebSocketHandshakeStreamCreateHelper(create_helper); | 663 network_trans_->SetWebSocketHandshakeStreamCreateHelper(create_helper); |
| 549 } | 664 } |
| 550 | 665 |
| 551 void HttpCache::Transaction::SetBeforeNetworkStartCallback( | 666 void HttpCache::Transaction::SetBeforeNetworkStartCallback( |
| (...skipping 10 matching lines...) Expand all Loading... |
| 562 | 677 |
| 563 int HttpCache::Transaction::ResumeNetworkStart() { | 678 int HttpCache::Transaction::ResumeNetworkStart() { |
| 564 if (network_trans_) | 679 if (network_trans_) |
| 565 return network_trans_->ResumeNetworkStart(); | 680 return network_trans_->ResumeNetworkStart(); |
| 566 return ERR_UNEXPECTED; | 681 return ERR_UNEXPECTED; |
| 567 } | 682 } |
| 568 | 683 |
| 569 void HttpCache::Transaction::GetConnectionAttempts( | 684 void HttpCache::Transaction::GetConnectionAttempts( |
| 570 ConnectionAttempts* out) const { | 685 ConnectionAttempts* out) const { |
| 571 ConnectionAttempts new_connection_attempts; | 686 ConnectionAttempts new_connection_attempts; |
| 572 if (network_trans_) | 687 HttpTransaction* network_transaction = GetCurrentNetworkTransaction(); |
| 573 network_trans_->GetConnectionAttempts(&new_connection_attempts); | 688 if (network_transaction) |
| 689 network_transaction->GetConnectionAttempts(&new_connection_attempts); |
| 574 | 690 |
| 575 out->swap(new_connection_attempts); | 691 out->swap(new_connection_attempts); |
| 576 out->insert(out->begin(), old_connection_attempts_.begin(), | 692 out->insert(out->begin(), old_connection_attempts_.begin(), |
| 577 old_connection_attempts_.end()); | 693 old_connection_attempts_.end()); |
| 578 } | 694 } |
| 579 | 695 |
| 580 //----------------------------------------------------------------------------- | 696 //----------------------------------------------------------------------------- |
| 581 | 697 |
| 582 // A few common patterns: (Foo* means Foo -> FooComplete) | 698 // A few common patterns: (Foo* means Foo -> FooComplete) |
| 583 // | 699 // |
| 584 // 1. Not-cached entry: | 700 // 1. Not-cached entry: |
| 585 // Start(): | 701 // Start(): |
| 586 // GetBackend* -> InitEntry -> OpenEntry* -> CreateEntry* -> AddToEntry* -> | 702 // GetBackend* -> InitEntry -> OpenEntry* -> CreateEntry* -> AddToEntry* -> |
| 587 // SendRequest* -> SuccessfulSendRequest -> OverwriteCachedResponse -> | 703 // SendRequest* -> SuccessfulSendRequest -> OverwriteCachedResponse -> |
| 588 // CacheWriteResponse* -> TruncateCachedData* -> TruncateCachedMetadata* -> | 704 // CacheWriteResponse* -> TruncateCachedData* -> TruncateCachedMetadata* -> |
| 589 // PartialHeadersReceived | 705 // PartialHeadersReceived |
| 590 // | 706 // |
| 591 // Read(): | 707 // Read(): (For transactions that are not eligible for shared writing) |
| 592 // NetworkRead* -> CacheWriteData* | 708 // NetworkRead* -> CacheWriteData* |
| 593 // | 709 // |
| 710 // Read(): (For transactions that are eligible for shared writing) |
| 711 // SharedNetworkRead* -> SharedCacheWriteData* |
| 712 // |
| 713 // Read(): (For a transaction that is shared and another read is already in |
| 714 // progress) |
| 715 // SharedNetworkRead -> SharedNetworkReadWaitComplete |
| 716 // |
| 594 // 2. Cached entry, no validation: | 717 // 2. Cached entry, no validation: |
| 595 // Start(): | 718 // Start(): |
| 596 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* | 719 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* |
| 597 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> | 720 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> |
| 598 // BeginCacheValidation() -> SetupEntryForRead() | 721 // BeginCacheValidation() -> SetupEntryForRead() |
| 599 // | 722 // |
| 600 // Read(): | 723 // Read(): (When response is already written to the cache.) |
| 601 // CacheReadData* | 724 // CacheReadData* |
| 602 // | 725 // |
| 726 // Read(): (When response is currently being written to the cache by shared |
| 727 // writing.) |
| 728 // SharedNetworkRead* -> SharedCacheWriteData* |
| 729 // |
| 603 // 3. Cached entry, validation (304): | 730 // 3. Cached entry, validation (304): |
| 604 // Start(): | 731 // Start(): |
| 605 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* | 732 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* |
| 606 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> | 733 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> |
| 607 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> | 734 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> |
| 608 // UpdateCachedResponse -> CacheWriteUpdatedResponse* -> | 735 // UpdateCachedResponse -> CacheWriteUpdatedResponse* -> |
| 609 // UpdateCachedResponseComplete -> OverwriteCachedResponse -> | 736 // UpdateCachedResponseComplete -> OverwriteCachedResponse -> |
| 610 // PartialHeadersReceived | 737 // PartialHeadersReceived |
| 611 // | 738 // |
| 612 // Read(): | 739 // Read(): () (When response is already written to the cache.) |
| 613 // CacheReadData* | 740 // CacheReadData* |
| 614 // | 741 // |
| 742 // Read(): (When response is currently being written to the cache by shared |
| 743 // writing.) |
| 744 // SharedNetworkRead* -> SharedCacheWriteData* |
| 745 // |
| 615 // 4. Cached entry, validation and replace (200): | 746 // 4. Cached entry, validation and replace (200): |
| 616 // Start(): | 747 // Start(): |
| 617 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* | 748 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* |
| 618 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> | 749 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> |
| 619 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> | 750 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> |
| 620 // OverwriteCachedResponse -> CacheWriteResponse* -> DoTruncateCachedData* -> | 751 // OverwriteCachedResponse -> CacheWriteResponse* -> DoTruncateCachedData* -> |
| 621 // TruncateCachedMetadata* -> PartialHeadersReceived | 752 // TruncateCachedMetadata* -> PartialHeadersReceived |
| 622 // | 753 // |
| 623 // Read(): | 754 // Read(): |
| 624 // NetworkRead* -> CacheWriteData* | 755 // NetworkRead* -> CacheWriteData* |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 866 case STATE_CACHE_WRITE_DATA_COMPLETE: | 997 case STATE_CACHE_WRITE_DATA_COMPLETE: |
| 867 rv = DoCacheWriteDataComplete(rv); | 998 rv = DoCacheWriteDataComplete(rv); |
| 868 break; | 999 break; |
| 869 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE: | 1000 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE: |
| 870 DCHECK_EQ(OK, rv); | 1001 DCHECK_EQ(OK, rv); |
| 871 rv = DoCacheWriteTruncatedResponse(); | 1002 rv = DoCacheWriteTruncatedResponse(); |
| 872 break; | 1003 break; |
| 873 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE: | 1004 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE: |
| 874 rv = DoCacheWriteTruncatedResponseComplete(rv); | 1005 rv = DoCacheWriteTruncatedResponseComplete(rv); |
| 875 break; | 1006 break; |
| 1007 case STATE_SHARED_NETWORK_READ: |
| 1008 DCHECK_EQ(OK, rv); |
| 1009 rv = DoSharedNetworkRead(); |
| 1010 break; |
| 1011 case STATE_SHARED_NETWORK_READ_COMPLETE: |
| 1012 rv = DoSharedNetworkReadComplete(rv); |
| 1013 break; |
| 1014 case STATE_SHARED_NETWORK_READ_WAIT_COMPLETE: |
| 1015 rv = DoSharedNetworkReadWaitComplete(rv); |
| 1016 break; |
| 1017 case STATE_SHARED_CACHE_WRITE_DATA: |
| 1018 rv = DoSharedCacheWriteData(rv); |
| 1019 break; |
| 1020 case STATE_SHARED_CACHE_WRITE_DATA_COMPLETE: |
| 1021 rv = DoSharedCacheWriteDataComplete(rv); |
| 1022 break; |
| 1023 case STATE_SHARED_READ_WRITE_FAILED: |
| 1024 rv = DoSharedReadWriteFailed(); |
| 1025 break; |
| 876 default: | 1026 default: |
| 877 NOTREACHED() << "bad state"; | 1027 NOTREACHED() << "bad state"; |
| 878 rv = ERR_FAILED; | 1028 rv = ERR_FAILED; |
| 879 break; | 1029 break; |
| 880 } | 1030 } |
| 881 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 1031 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
| 882 | 1032 |
| 883 if (rv != ERR_IO_PENDING && !callback_.is_null()) { | 1033 if (rv != ERR_IO_PENDING && !callback_.is_null()) { |
| 884 read_buf_ = NULL; // Release the buffer before invoking the callback. | 1034 read_buf_ = NULL; // Release the buffer before invoking the callback. |
| 885 base::ResetAndReturn(&callback_).Run(rv); | 1035 base::ResetAndReturn(&callback_).Run(rv); |
| (...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1503 | 1653 |
| 1504 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); | 1654 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); |
| 1505 | 1655 |
| 1506 if (new_response_->headers->response_code() == 416 && | 1656 if (new_response_->headers->response_code() == 416 && |
| 1507 (request_->method == "GET" || request_->method == "POST")) { | 1657 (request_->method == "GET" || request_->method == "POST")) { |
| 1508 // If there is an active entry it may be destroyed with this transaction. | 1658 // If there is an active entry it may be destroyed with this transaction. |
| 1509 SetResponse(*new_response_); | 1659 SetResponse(*new_response_); |
| 1510 return OK; | 1660 return OK; |
| 1511 } | 1661 } |
| 1512 | 1662 |
| 1663 // If the transaction is shared and it is a 200 or an error response, then |
| 1664 // doom the entry and let this transaction continue without writing to the |
| 1665 // cache if shared writers contain more transactions. If not, continue |
| 1666 // writing to the cache and also transfer the network transaction to shared |
| 1667 // writers. |
| 1668 if (shared_ && new_response->headers->response_code() != 304) { |
| 1669 network_trans_ = entry_->shared_writers->OnValidationNoMatch( |
| 1670 cache_key_, this, std::move(network_trans_), priority_); |
| 1671 if (!shared_) { |
| 1672 DCHECK(network_trans_); |
| 1673 if (cache_entry_status_ == CacheEntryStatus::ENTRY_UNDEFINED) { |
| 1674 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING); |
| 1675 } |
| 1676 DoneWritingToEntry(false, false); |
| 1677 return OK; |
| 1678 } else { |
| 1679 DCHECK(!network_trans_); |
| 1680 } |
| 1681 } |
| 1682 |
| 1513 // Are we expecting a response to a conditional query? | 1683 // Are we expecting a response to a conditional query? |
| 1514 if (mode_ == READ_WRITE || mode_ == UPDATE) { | 1684 if (mode_ == READ_WRITE || mode_ == UPDATE) { |
| 1515 if (new_response->headers->response_code() == 304 || handling_206_) { | 1685 if (new_response->headers->response_code() == 304 || handling_206_) { |
| 1516 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED); | 1686 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED); |
| 1517 next_state_ = STATE_UPDATE_CACHED_RESPONSE; | 1687 next_state_ = STATE_UPDATE_CACHED_RESPONSE; |
| 1518 return OK; | 1688 return OK; |
| 1519 } | 1689 } |
| 1520 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_UPDATED); | 1690 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_UPDATED); |
| 1521 mode_ = WRITE; | 1691 mode_ = WRITE; |
| 1522 } | 1692 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1625 SetResponse(*new_response_); | 1795 SetResponse(*new_response_); |
| 1626 | 1796 |
| 1627 if (request_->method == "HEAD") { | 1797 if (request_->method == "HEAD") { |
| 1628 // This response is replacing the cached one. | 1798 // This response is replacing the cached one. |
| 1629 DoneWritingToEntry(false); | 1799 DoneWritingToEntry(false); |
| 1630 mode_ = NONE; | 1800 mode_ = NONE; |
| 1631 new_response_ = NULL; | 1801 new_response_ = NULL; |
| 1632 return OK; | 1802 return OK; |
| 1633 } | 1803 } |
| 1634 | 1804 |
| 1635 if (handling_206_ && !CanResume(false)) { | 1805 if (handling_206_ && |
| 1806 !cache_->CanResumeEntry(false, request_->method, &response_, entry_)) { |
| 1636 // There is no point in storing this resource because it will never be used. | 1807 // 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. | 1808 // This may change if we support LOAD_ONLY_FROM_CACHE with sparse entries. |
| 1638 DoneWritingToEntry(false); | 1809 DoneWritingToEntry(false); |
| 1639 if (partial_) | 1810 if (partial_) |
| 1640 partial_->FixResponseHeaders(response_.headers.get(), true); | 1811 partial_->FixResponseHeaders(response_.headers.get(), true); |
| 1641 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | 1812 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; |
| 1642 return OK; | 1813 return OK; |
| 1643 } | 1814 } |
| 1644 | 1815 |
| 1645 next_state_ = STATE_CACHE_WRITE_RESPONSE; | 1816 next_state_ = STATE_CACHE_WRITE_RESPONSE; |
| 1646 return OK; | 1817 return OK; |
| 1647 } | 1818 } |
| 1648 | 1819 |
| 1649 int HttpCache::Transaction::DoCacheWriteResponse() { | 1820 int HttpCache::Transaction::DoCacheWriteResponse() { |
| 1650 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse"); | 1821 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse"); |
| 1651 next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE; | 1822 next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE; |
| 1652 return WriteResponseInfoToEntry(truncated_); | 1823 return WriteResponseInfoToEntry(truncated_); |
| 1653 } | 1824 } |
| 1654 | 1825 |
| 1655 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { | 1826 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { |
| 1656 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete"); | 1827 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete"); |
| 1657 next_state_ = STATE_TRUNCATE_CACHED_DATA; | 1828 next_state_ = STATE_TRUNCATE_CACHED_DATA; |
| 1658 return OnWriteResponseInfoToEntryComplete(result); | 1829 return OnWriteResponseInfoToEntryComplete(result); |
| 1659 } | 1830 } |
| 1660 | 1831 |
| 1832 void HttpCache::Transaction::SetShared() { |
| 1833 shared_ = true; |
| 1834 } |
| 1835 |
| 1836 void HttpCache::Transaction::ResetShared(bool continue_network_reading, |
| 1837 bool continue_cache_reading) { |
| 1838 if (!continue_network_reading) { |
| 1839 SaveSharedNetworkTransactionInfo(); |
| 1840 } |
| 1841 if (continue_cache_reading) { |
| 1842 mode_ = READ; |
| 1843 } |
| 1844 shared_ = false; |
| 1845 } |
| 1846 |
| 1661 int HttpCache::Transaction::DoTruncateCachedData() { | 1847 int HttpCache::Transaction::DoTruncateCachedData() { |
| 1662 TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedData"); | 1848 TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedData"); |
| 1663 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; | 1849 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; |
| 1664 if (!entry_) | 1850 if (!entry_) |
| 1665 return OK; | 1851 return OK; |
| 1666 if (net_log_.IsCapturing()) | 1852 if (net_log_.IsCapturing()) |
| 1667 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); | 1853 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); |
| 1668 // Truncate the stream. | 1854 // Truncate the stream. |
| 1669 return WriteToEntry(kResponseContentIndex, 0, NULL, 0, io_callback_); | 1855 return WriteToEntry(kResponseContentIndex, 0, NULL, 0, io_callback_); |
| 1670 } | 1856 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1699 if (net_log_.IsCapturing()) { | 1885 if (net_log_.IsCapturing()) { |
| 1700 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, | 1886 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, |
| 1701 result); | 1887 result); |
| 1702 } | 1888 } |
| 1703 } | 1889 } |
| 1704 | 1890 |
| 1705 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | 1891 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; |
| 1706 return OK; | 1892 return OK; |
| 1707 } | 1893 } |
| 1708 | 1894 |
| 1895 void HttpCache::Transaction::ProcessForSharedWriting() { |
| 1896 // Should not be already reading. |
| 1897 if (reading_) |
| 1898 return; |
| 1899 |
| 1900 // If not already part of SharedWriters, then check if one should be |
| 1901 // created. |
| 1902 if (!shared_ && !IsEligibleForSharedWriting()) |
| 1903 return; |
| 1904 |
| 1905 if (shared_) { |
| 1906 // Non 304 case is already handled in DoSuccessfulSendRequest. |
| 1907 if (response_.headers->response_code() != 304) { |
| 1908 return; |
| 1909 } |
| 1910 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING); |
| 1911 entry_->shared_writers->OnValidationMatch(this, priority_); |
| 1912 network_trans_.reset(); |
| 1913 return; |
| 1914 } |
| 1915 |
| 1916 // Do not create a SharedWriters if its a Redirect response or if its a |
| 1917 // no-store response. |
| 1918 if (response_.headers->response_code() != 200) |
| 1919 return; |
| 1920 |
| 1921 if (!entry_) |
| 1922 return; |
| 1923 |
| 1924 DCHECK(cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE || |
| 1925 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED || |
| 1926 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE || |
| 1927 cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER); |
| 1928 // Measure how many requests out of the total of "not cached" and "updated" |
| 1929 // are initiating shared writing. |
| 1930 initiate_shared_writing_ = true; |
| 1931 DCHECK(entry_ && network_trans_); |
| 1932 |
| 1933 // An instance of SharedWriters will be created when the first writer has |
| 1934 // written the new response headers in the cache. Transfer network |
| 1935 // transaction’s ownership to SharedWriters so it can be used by any of the |
| 1936 // transactions for subsequent reading from the network. |
| 1937 SharedWriters::Create(this, std::move(network_trans_), cache_, priority_); |
| 1938 } |
| 1939 |
| 1709 int HttpCache::Transaction::DoPartialHeadersReceived() { | 1940 int HttpCache::Transaction::DoPartialHeadersReceived() { |
| 1710 new_response_ = NULL; | 1941 new_response_ = NULL; |
| 1711 if (entry_ && !partial_ && entry_->disk_entry->GetDataSize(kMetadataIndex)) | 1942 if (entry_ && !partial_ && entry_->disk_entry->GetDataSize(kMetadataIndex)) |
| 1712 next_state_ = STATE_CACHE_READ_METADATA; | 1943 next_state_ = STATE_CACHE_READ_METADATA; |
| 1713 | 1944 |
| 1945 ProcessForSharedWriting(); |
| 1946 |
| 1714 if (!partial_) | 1947 if (!partial_) |
| 1715 return OK; | 1948 return OK; |
| 1716 | 1949 |
| 1717 if (reading_) { | 1950 if (reading_) { |
| 1718 if (network_trans_.get()) { | 1951 if (network_trans_.get()) { |
| 1719 next_state_ = STATE_NETWORK_READ; | 1952 next_state_ = STATE_NETWORK_READ; |
| 1720 } else { | 1953 } else { |
| 1721 next_state_ = STATE_CACHE_READ_DATA; | 1954 next_state_ = STATE_CACHE_READ_DATA; |
| 1722 } | 1955 } |
| 1723 } else if (mode_ != NONE) { | 1956 } else if (mode_ != NONE) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1754 } | 1987 } |
| 1755 | 1988 |
| 1756 int HttpCache::Transaction::DoNetworkRead() { | 1989 int HttpCache::Transaction::DoNetworkRead() { |
| 1757 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead"); | 1990 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead"); |
| 1758 next_state_ = STATE_NETWORK_READ_COMPLETE; | 1991 next_state_ = STATE_NETWORK_READ_COMPLETE; |
| 1759 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); | 1992 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); |
| 1760 } | 1993 } |
| 1761 | 1994 |
| 1762 int HttpCache::Transaction::DoNetworkReadComplete(int result) { | 1995 int HttpCache::Transaction::DoNetworkReadComplete(int result) { |
| 1763 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkReadComplete"); | 1996 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkReadComplete"); |
| 1997 if (net_log_.IsCapturing()) |
| 1998 net_log_.EndEventWithNetErrorCode( |
| 1999 NetLogEventType::HTTP_CACHE_NETWORK_READ_COMPLETE, result); |
| 2000 |
| 1764 DCHECK(mode_ & WRITE || mode_ == NONE); | 2001 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 1765 | 2002 |
| 1766 if (!cache_.get()) | 2003 if (!cache_.get()) |
| 1767 return ERR_UNEXPECTED; | 2004 return ERR_UNEXPECTED; |
| 1768 | 2005 |
| 1769 // If there is an error or we aren't saving the data, we are done; just wait | 2006 // 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. | 2007 // until the destructor runs to see if we can keep the data. |
| 1771 if (mode_ == NONE || result < 0) | 2008 if (mode_ == NONE || result < 0) |
| 1772 return result; | 2009 return result; |
| 1773 | 2010 |
| 1774 next_state_ = STATE_CACHE_WRITE_DATA; | 2011 next_state_ = STATE_CACHE_WRITE_DATA; |
| 1775 return result; | 2012 return result; |
| 1776 } | 2013 } |
| 1777 | 2014 |
| 2015 int HttpCache::Transaction::DoSharedNetworkRead() { |
| 2016 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedNetworkRead"); |
| 2017 if (net_log_.IsCapturing()) |
| 2018 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_SHARED_NETWORK_READ); |
| 2019 |
| 2020 next_state_ = STATE_SHARED_NETWORK_READ_COMPLETE; |
| 2021 bool shared_read_in_progress = false; |
| 2022 int result = entry_->shared_writers->Read( |
| 2023 read_buf_, io_buf_len_, io_callback_, this, &shared_read_in_progress); |
| 2024 if (shared_read_in_progress) { |
| 2025 next_state_ = STATE_SHARED_NETWORK_READ_WAIT_COMPLETE; |
| 2026 } |
| 2027 return result; |
| 2028 } |
| 2029 |
| 2030 int HttpCache::Transaction::DoSharedNetworkReadComplete(int result) { |
| 2031 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedNetworkReadComplete"); |
| 2032 if (net_log_.IsCapturing()) |
| 2033 net_log_.EndEventWithNetErrorCode( |
| 2034 NetLogEventType::HTTP_CACHE_SHARED_NETWORK_READ_COMPLETE, result); |
| 2035 |
| 2036 if (result <= 0) { |
| 2037 // Set entry as null so that the destructor does not invoke DoneWithEntry |
| 2038 // again as entry_ is already cleaned up by SharedWriters. |
| 2039 entry_ = nullptr; |
| 2040 return result; |
| 2041 } |
| 2042 |
| 2043 read_offset_ += result; |
| 2044 |
| 2045 next_state_ = STATE_SHARED_CACHE_WRITE_DATA; |
| 2046 return result; |
| 2047 } |
| 2048 |
| 2049 int HttpCache::Transaction::DoSharedCacheWriteData(int result) { |
| 2050 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedCacheWriteData"); |
| 2051 if (net_log_.IsCapturing()) |
| 2052 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_SHARED_CACHE_WRITE_DATA); |
| 2053 |
| 2054 next_state_ = STATE_SHARED_CACHE_WRITE_DATA_COMPLETE; |
| 2055 write_len_ = result; |
| 2056 return entry_->shared_writers->CacheWrite(read_buf_, write_len_, io_callback_, |
| 2057 this); |
| 2058 } |
| 2059 |
| 2060 int HttpCache::Transaction::DoSharedCacheWriteDataComplete(int result) { |
| 2061 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedCacheWriteDataComplete"); |
| 2062 if (net_log_.IsCapturing()) |
| 2063 net_log_.EndEventWithNetErrorCode( |
| 2064 NetLogEventType::HTTP_CACHE_SHARED_CACHE_WRITE_DATA_COMPLETE, result); |
| 2065 |
| 2066 OnCacheWriteDataComplete(true, &result); |
| 2067 |
| 2068 if (result == 0) { |
| 2069 DoneWritingToEntry(true, false); |
| 2070 } |
| 2071 return result; |
| 2072 } |
| 2073 |
| 2074 void HttpCache::Transaction::OnCacheWriteDataComplete(bool was_shared, |
| 2075 int* result) { |
| 2076 if (*result != write_len_) { |
| 2077 DoneWritingToEntry(false, !was_shared); |
| 2078 // We want to ignore errors writing to disk and just keep reading from |
| 2079 // the network. |
| 2080 *result = write_len_; |
| 2081 } else if (!done_reading_ && entry_ && (!partial_ || truncated_)) { |
| 2082 done_reading_ = cache_->IsResponseCompleted(entry_, &response_); |
| 2083 } |
| 2084 } |
| 2085 |
| 2086 int HttpCache::Transaction::DoSharedNetworkReadWaitComplete(int result) { |
| 2087 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedNetworkReadWaitComplete"); |
| 2088 if (net_log_.IsCapturing()) |
| 2089 net_log_.EndEventWithNetErrorCode( |
| 2090 NetLogEventType::HTTP_CACHE_SHARED_NETWORK_READ_WAIT_COMPLETE, result); |
| 2091 |
| 2092 // If its a network read failure or cache write failure, we just return the |
| 2093 // result. If its a cache write success, read_buf_ would have been filled |
| 2094 // with the read data by SharedWriters. |
| 2095 if (result == 0) { // response is complete. |
| 2096 DoneWritingToEntry(true, false); // changes the mode_ to NONE. |
| 2097 } else if (result > 0) { |
| 2098 read_offset_ += result; |
| 2099 } else { |
| 2100 // Set entry as null so that the destructor does not invoke DoneWithEntry |
| 2101 // again as entry_ is already cleaned up by SharedWriters. |
| 2102 entry_ = nullptr; |
| 2103 } |
| 2104 |
| 2105 return result; |
| 2106 } |
| 2107 |
| 1778 int HttpCache::Transaction::DoCacheReadData() { | 2108 int HttpCache::Transaction::DoCacheReadData() { |
| 1779 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadData"); | 2109 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadData"); |
| 1780 if (request_->method == "HEAD") | 2110 if (request_->method == "HEAD") |
| 1781 return 0; | 2111 return 0; |
| 1782 | 2112 |
| 1783 DCHECK(entry_); | 2113 DCHECK(entry_); |
| 1784 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; | 2114 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; |
| 1785 | 2115 |
| 1786 if (net_log_.IsCapturing()) | 2116 if (net_log_.IsCapturing()) |
| 1787 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_DATA); | 2117 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; | 2159 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; |
| 1830 write_len_ = num_bytes; | 2160 write_len_ = num_bytes; |
| 1831 if (entry_) { | 2161 if (entry_) { |
| 1832 if (net_log_.IsCapturing()) | 2162 if (net_log_.IsCapturing()) |
| 1833 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); | 2163 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); |
| 1834 } | 2164 } |
| 1835 | 2165 |
| 1836 if (!entry_ || !num_bytes) | 2166 if (!entry_ || !num_bytes) |
| 1837 return num_bytes; | 2167 return num_bytes; |
| 1838 | 2168 |
| 2169 if (partial_) { |
| 2170 return partial_->CacheWrite(entry_->disk_entry, read_buf_.get(), num_bytes, |
| 2171 io_callback_); |
| 2172 } |
| 2173 |
| 1839 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 2174 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); |
| 1840 return WriteToEntry(kResponseContentIndex, current_size, read_buf_.get(), | 2175 return entry_->disk_entry->WriteData(kResponseContentIndex, current_size, |
| 1841 num_bytes, io_callback_); | 2176 read_buf_.get(), num_bytes, io_callback_, |
| 2177 true); |
| 1842 } | 2178 } |
| 1843 | 2179 |
| 1844 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) { | 2180 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) { |
| 1845 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteDataComplete"); | 2181 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteDataComplete"); |
| 1846 if (entry_) { | 2182 if (entry_) { |
| 1847 if (net_log_.IsCapturing()) { | 2183 if (net_log_.IsCapturing()) { |
| 1848 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_DATA, | 2184 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_DATA, |
| 1849 result); | 2185 result); |
| 1850 } | 2186 } |
| 1851 } | 2187 } |
| 1852 if (!cache_.get()) | 2188 if (!cache_.get()) |
| 1853 return ERR_UNEXPECTED; | 2189 return ERR_UNEXPECTED; |
| 1854 | 2190 |
| 1855 if (result != write_len_) { | 2191 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 | 2192 |
| 1869 if (partial_) { | 2193 if (partial_) { |
| 1870 // This may be the last request. | 2194 // This may be the last request. |
| 1871 if (result != 0 || truncated_ || | 2195 if (result != 0 || truncated_ || |
| 1872 !(partial_->IsLastRange() || mode_ == WRITE)) { | 2196 !(partial_->IsLastRange() || mode_ == WRITE)) { |
| 1873 return DoPartialNetworkReadCompleted(result); | 2197 return DoPartialNetworkReadCompleted(result); |
| 1874 } | 2198 } |
| 1875 } | 2199 } |
| 1876 | 2200 |
| 2201 // End of file. This may be the result of a connection problem so see if we |
| 2202 // have to keep the entry around to be flagged as truncated later on. |
| 1877 if (result == 0) { | 2203 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_ || | 2204 if (done_reading_ || !entry_ || partial_ || |
| 1881 response_.headers->GetContentLength() <= 0) { | 2205 response_.headers->GetContentLength() <= 0) |
| 1882 DoneWritingToEntry(true); | 2206 DoneWritingToEntry(true); |
| 1883 } | |
| 1884 } | 2207 } |
| 1885 | 2208 |
| 1886 return result; | 2209 return result; |
| 1887 } | 2210 } |
| 1888 | 2211 |
| 1889 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() { | 2212 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() { |
| 1890 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); | 2213 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); |
| 1891 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE; | 2214 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE; |
| 1892 return WriteResponseInfoToEntry(true); | 2215 return WriteResponseInfoToEntry(true); |
| 1893 } | 2216 } |
| 1894 | 2217 |
| 1895 int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) { | 2218 int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) { |
| 1896 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); | 2219 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); |
| 1897 | 2220 |
| 1898 return OnWriteResponseInfoToEntryComplete(result); | 2221 return OnWriteResponseInfoToEntryComplete(result); |
| 1899 } | 2222 } |
| 1900 | 2223 |
| 2224 int HttpCache::Transaction::DoSharedReadWriteFailed() { |
| 2225 if (net_log_.IsCapturing()) |
| 2226 net_log_.EndEventWithNetErrorCode( |
| 2227 NetLogEventType::HTTP_CACHE_SHARED_READ_WRITE_FAILED, |
| 2228 shared_read_write_failure_result_); |
| 2229 |
| 2230 return shared_read_write_failure_result_; |
| 2231 } |
| 2232 |
| 1901 //----------------------------------------------------------------------------- | 2233 //----------------------------------------------------------------------------- |
| 1902 | 2234 |
| 1903 void HttpCache::Transaction::SetRequest(const NetLogWithSource& net_log, | 2235 void HttpCache::Transaction::SetRequest(const NetLogWithSource& net_log, |
| 1904 const HttpRequestInfo* request) { | 2236 const HttpRequestInfo* request) { |
| 1905 net_log_ = net_log; | 2237 net_log_ = net_log; |
| 1906 request_ = request; | 2238 request_ = request; |
| 1907 effective_load_flags_ = request_->load_flags; | 2239 effective_load_flags_ = request_->load_flags; |
| 1908 | 2240 |
| 1909 if (cache_->mode() == DISABLE) | 2241 if (cache_->mode() == DISABLE) |
| 1910 effective_load_flags_ |= LOAD_DISABLE_CACHE; | 2242 effective_load_flags_ |= LOAD_DISABLE_CACHE; |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2084 | 2416 |
| 2085 if (partial_ && (is_sparse_ || truncated_) && | 2417 if (partial_ && (is_sparse_ || truncated_) && |
| 2086 (!partial_->IsCurrentRangeCached() || invalid_range_)) { | 2418 (!partial_->IsCurrentRangeCached() || invalid_range_)) { |
| 2087 // Force revalidation for sparse or truncated entries. Note that we don't | 2419 // 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 | 2420 // want to ignore the regular validation logic just because a byte range was |
| 2089 // part of the request. | 2421 // part of the request. |
| 2090 skip_validation = false; | 2422 skip_validation = false; |
| 2091 } | 2423 } |
| 2092 | 2424 |
| 2093 if (skip_validation) { | 2425 if (skip_validation) { |
| 2094 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_USED); | 2426 if (shared_) { |
| 2095 return SetupEntryForRead(); | 2427 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING); |
| 2428 entry_->shared_writers->OnValidationMatch(this, priority_); |
| 2429 } else { |
| 2430 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_USED); |
| 2431 return SetupEntryForRead(); |
| 2432 } |
| 2096 } else { | 2433 } else { |
| 2097 // Make the network request conditional, to see if we may reuse our cached | 2434 // 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. | 2435 // 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 | 2436 // Our mode remains READ_WRITE for a conditional request. Even if the |
| 2100 // conditionalization fails, we don't switch to WRITE mode until we | 2437 // 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 | 2438 // know we won't be falling back to using the cache entry in the |
| 2102 // LOAD_FROM_CACHE_IF_OFFLINE case. | 2439 // LOAD_FROM_CACHE_IF_OFFLINE case. |
| 2103 if (!ConditionalizeRequest()) { | 2440 if (!ConditionalizeRequest()) { |
| 2104 couldnt_conditionalize_request_ = true; | 2441 couldnt_conditionalize_request_ = true; |
| 2105 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE); | 2442 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)) { | 2941 IsCertStatusError(response_.ssl_info.cert_status)) { |
| 2605 DoneWritingToEntry(false); | 2942 DoneWritingToEntry(false); |
| 2606 if (net_log_.IsCapturing()) | 2943 if (net_log_.IsCapturing()) |
| 2607 net_log_.EndEvent(NetLogEventType::HTTP_CACHE_WRITE_INFO); | 2944 net_log_.EndEvent(NetLogEventType::HTTP_CACHE_WRITE_INFO); |
| 2608 return OK; | 2945 return OK; |
| 2609 } | 2946 } |
| 2610 | 2947 |
| 2611 if (truncated) | 2948 if (truncated) |
| 2612 DCHECK_EQ(200, response_.headers->response_code()); | 2949 DCHECK_EQ(200, response_.headers->response_code()); |
| 2613 | 2950 |
| 2614 // When writing headers, we normally only write the non-transient headers. | 2951 return cache_->WriteResponseInfo(entry_, &response_, io_callback_, truncated, |
| 2615 bool skip_transient_headers = true; | 2952 &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 } | 2953 } |
| 2624 | 2954 |
| 2625 int HttpCache::Transaction::OnWriteResponseInfoToEntryComplete(int result) { | 2955 int HttpCache::Transaction::OnWriteResponseInfoToEntryComplete(int result) { |
| 2626 if (!entry_) | 2956 if (!entry_) |
| 2627 return OK; | 2957 return OK; |
| 2628 if (net_log_.IsCapturing()) { | 2958 if (net_log_.IsCapturing()) { |
| 2629 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, | 2959 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, |
| 2630 result); | 2960 result); |
| 2631 } | 2961 } |
| 2632 | 2962 |
| 2633 if (result != io_buf_len_) { | 2963 if (result != io_buf_len_) { |
| 2634 DLOG(ERROR) << "failed to write response info to cache"; | 2964 DLOG(ERROR) << "failed to write response info to cache"; |
| 2635 DoneWritingToEntry(false); | 2965 DoneWritingToEntry(false); |
| 2636 } | 2966 } |
| 2637 return OK; | 2967 return OK; |
| 2638 } | 2968 } |
| 2639 | 2969 |
| 2640 void HttpCache::Transaction::DoneWritingToEntry(bool success) { | 2970 void HttpCache::Transaction::DoneWritingToEntry(bool success, |
| 2971 bool perform_entry_cleanup) { |
| 2641 if (!entry_) | 2972 if (!entry_) |
| 2642 return; | 2973 return; |
| 2643 | 2974 |
| 2644 RecordHistograms(); | 2975 RecordHistograms(); |
| 2645 | 2976 |
| 2646 cache_->DoneWritingToEntry(entry_, success); | 2977 if (perform_entry_cleanup) { |
| 2647 entry_ = NULL; | 2978 cache_->DoneWritingToEntry(entry_, success); |
| 2979 } |
| 2980 entry_ = nullptr; |
| 2648 mode_ = NONE; // switch to 'pass through' mode | 2981 mode_ = NONE; // switch to 'pass through' mode |
| 2649 } | 2982 } |
| 2650 | 2983 |
| 2984 void HttpCache::Transaction::ContinueWithoutSharedWriting( |
| 2985 std::unique_ptr<HttpTransaction> network_transaction, |
| 2986 bool needs_entry) { |
| 2987 shared_ = false; |
| 2988 if (!needs_entry) |
| 2989 entry_ = nullptr; |
| 2990 mode_ = NONE; |
| 2991 network_trans_ = std::move(network_transaction); |
| 2992 } |
| 2993 |
| 2651 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { | 2994 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { |
| 2652 DLOG(ERROR) << "ReadData failed: " << result; | 2995 DLOG(ERROR) << "ReadData failed: " << result; |
| 2653 const int result_for_histogram = std::max(0, -result); | 2996 const int result_for_histogram = std::max(0, -result); |
| 2654 if (restart) { | 2997 if (restart) { |
| 2655 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", | 2998 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", |
| 2656 result_for_histogram); | 2999 result_for_histogram); |
| 2657 } else { | 3000 } else { |
| 2658 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable", | 3001 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable", |
| 2659 result_for_histogram); | 3002 result_for_histogram); |
| 2660 } | 3003 } |
| 2661 | 3004 |
| 2662 // Avoid using this entry in the future. | 3005 // Avoid using this entry in the future. |
| 2663 if (cache_.get()) | 3006 if (cache_.get()) |
| 2664 cache_->DoomActiveEntry(cache_key_); | 3007 cache_->DoomActiveEntry(cache_key_); |
| 2665 | 3008 |
| 2666 if (restart) { | 3009 if (restart) { |
| 2667 DCHECK(!reading_); | 3010 DCHECK(!reading_); |
| 2668 DCHECK(!network_trans_.get()); | 3011 DCHECK(!network_trans_.get()); |
| 2669 cache_->DoneWithEntry(entry_, this, false); | 3012 if (shared_) { |
| 3013 entry_->shared_writers->RemoveValidatingTransaction(this); |
| 3014 } else { |
| 3015 cache_->DoneWithEntry(entry_, this, false); |
| 3016 } |
| 2670 entry_ = NULL; | 3017 entry_ = NULL; |
| 2671 is_sparse_ = false; | 3018 is_sparse_ = false; |
| 2672 partial_.reset(); | 3019 partial_.reset(); |
| 2673 next_state_ = STATE_GET_BACKEND; | 3020 next_state_ = STATE_GET_BACKEND; |
| 2674 return OK; | 3021 return OK; |
| 2675 } | 3022 } |
| 2676 | 3023 |
| 2677 return ERR_CACHE_READ_FAILURE; | 3024 return ERR_CACHE_READ_FAILURE; |
| 2678 } | 3025 } |
| 2679 | 3026 |
| 2680 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { | 3027 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { |
| 2681 if (entry_lock_waiting_since_ != start_time) | 3028 if (entry_lock_waiting_since_ != start_time) |
| 2682 return; | 3029 return; |
| 2683 | 3030 |
| 2684 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); | 3031 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); |
| 2685 | 3032 |
| 2686 if (!cache_) | 3033 if (!cache_) |
| 2687 return; | 3034 return; |
| 2688 | 3035 |
| 2689 cache_->RemovePendingTransaction(this); | 3036 cache_->RemovePendingTransaction(this); |
| 2690 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); | 3037 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); |
| 2691 } | 3038 } |
| 2692 | 3039 |
| 2693 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { | 3040 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { |
| 3041 // Partial requests not supported with shared writing as of now. |
| 3042 DCHECK(!shared_); |
| 2694 DVLOG(2) << "DoomPartialEntry"; | 3043 DVLOG(2) << "DoomPartialEntry"; |
| 2695 int rv = cache_->DoomEntry(cache_key_, NULL); | 3044 int rv = cache_->DoomEntry(cache_key_, NULL); |
| 2696 DCHECK_EQ(OK, rv); | 3045 DCHECK_EQ(OK, rv); |
| 2697 cache_->DoneWithEntry(entry_, this, false); | 3046 cache_->DoneWithEntry(entry_, this, false); |
| 2698 entry_ = NULL; | 3047 entry_ = NULL; |
| 2699 is_sparse_ = false; | 3048 is_sparse_ = false; |
| 2700 truncated_ = false; | 3049 truncated_ = false; |
| 2701 if (delete_object) | 3050 if (delete_object) |
| 2702 partial_.reset(NULL); | 3051 partial_.reset(NULL); |
| 2703 } | 3052 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2744 if (!delete_object) { | 3093 if (!delete_object) { |
| 2745 // The simplest way to re-initialize partial_ is to create a new object. | 3094 // The simplest way to re-initialize partial_ is to create a new object. |
| 2746 partial_.reset(new PartialData()); | 3095 partial_.reset(new PartialData()); |
| 2747 if (partial_->Init(request_->extra_headers)) | 3096 if (partial_->Init(request_->extra_headers)) |
| 2748 partial_->SetHeaders(custom_request_->extra_headers); | 3097 partial_->SetHeaders(custom_request_->extra_headers); |
| 2749 else | 3098 else |
| 2750 partial_.reset(); | 3099 partial_.reset(); |
| 2751 } | 3100 } |
| 2752 } | 3101 } |
| 2753 | 3102 |
| 2754 void HttpCache::Transaction::ResetNetworkTransaction() { | 3103 void HttpCache::Transaction::SaveNetworkTransactionInfo( |
| 3104 const HttpTransaction* transaction) { |
| 2755 DCHECK(!old_network_trans_load_timing_); | 3105 DCHECK(!old_network_trans_load_timing_); |
| 2756 DCHECK(network_trans_); | 3106 DCHECK(transaction); |
| 2757 LoadTimingInfo load_timing; | 3107 LoadTimingInfo load_timing; |
| 2758 if (network_trans_->GetLoadTimingInfo(&load_timing)) | 3108 if (transaction->GetLoadTimingInfo(&load_timing)) |
| 2759 old_network_trans_load_timing_.reset(new LoadTimingInfo(load_timing)); | 3109 old_network_trans_load_timing_.reset(new LoadTimingInfo(load_timing)); |
| 2760 total_received_bytes_ += network_trans_->GetTotalReceivedBytes(); | 3110 total_received_bytes_ += transaction->GetTotalReceivedBytes(); |
| 2761 total_sent_bytes_ += network_trans_->GetTotalSentBytes(); | 3111 total_sent_bytes_ += transaction->GetTotalSentBytes(); |
| 2762 ConnectionAttempts attempts; | 3112 ConnectionAttempts attempts; |
| 2763 network_trans_->GetConnectionAttempts(&attempts); | 3113 transaction->GetConnectionAttempts(&attempts); |
| 2764 for (const auto& attempt : attempts) | 3114 for (const auto& attempt : attempts) |
| 2765 old_connection_attempts_.push_back(attempt); | 3115 old_connection_attempts_.push_back(attempt); |
| 2766 old_remote_endpoint_ = IPEndPoint(); | 3116 old_remote_endpoint_ = IPEndPoint(); |
| 2767 network_trans_->GetRemoteEndpoint(&old_remote_endpoint_); | 3117 transaction->GetRemoteEndpoint(&old_remote_endpoint_); |
| 3118 } |
| 3119 |
| 3120 void HttpCache::Transaction::SaveSharedNetworkTransactionInfo() { |
| 3121 // If network_trans_ is still present, this transaction has not started using |
| 3122 // the "shared" network transaction. |
| 3123 if (network_trans_) { |
| 3124 SaveNetworkTransactionInfo(network_trans_.get()); |
| 3125 return; |
| 3126 } |
| 3127 |
| 3128 DCHECK(!old_network_trans_load_timing_); |
| 3129 |
| 3130 // If the transaction is being deleted while still in the waiting queue, |
| 3131 // entry_ is not yet set, do nothing. |
| 3132 if (!entry_) |
| 3133 return; |
| 3134 DCHECK(entry_->shared_writers); |
| 3135 HttpTransaction* network_transaction = |
| 3136 entry_->shared_writers->network_transaction(); |
| 3137 SaveNetworkTransactionInfo(network_transaction); |
| 3138 have_full_request_headers_ = |
| 3139 network_transaction->GetFullRequestHeaders(&full_request_headers_); |
| 3140 } |
| 3141 |
| 3142 void HttpCache::Transaction::ResetNetworkTransaction() { |
| 3143 SaveNetworkTransactionInfo(network_trans_.get()); |
| 2768 network_trans_.reset(); | 3144 network_trans_.reset(); |
| 2769 } | 3145 } |
| 2770 | 3146 |
| 2771 // Histogram data from the end of 2010 show the following distribution of | 3147 HttpTransaction* HttpCache::Transaction::GetCurrentNetworkTransaction() const { |
| 2772 // response headers: | 3148 if (network_trans_) |
| 2773 // | 3149 return network_trans_.get(); |
| 2774 // Content-Length............... 87% | 3150 if (shared_ && entry_ && entry_->shared_writers) |
| 2775 // Date......................... 98% | 3151 return entry_->shared_writers->network_transaction(); |
| 2776 // Last-Modified................ 49% | 3152 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 } | 3153 } |
| 2802 | 3154 |
| 2803 void HttpCache::Transaction::SetResponse(const HttpResponseInfo& response) { | 3155 void HttpCache::Transaction::SetResponse(const HttpResponseInfo& response) { |
| 2804 response_ = response; | 3156 response_ = response; |
| 2805 SyncCacheEntryStatusToResponse(); | 3157 SyncCacheEntryStatusToResponse(); |
| 2806 } | 3158 } |
| 2807 | 3159 |
| 2808 void HttpCache::Transaction::SetAuthResponse( | 3160 void HttpCache::Transaction::SetAuthResponse( |
| 2809 const HttpResponseInfo& auth_response) { | 3161 const HttpResponseInfo& auth_response) { |
| 2810 auth_response_ = auth_response; | 3162 auth_response_ = auth_response; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2916 } | 3268 } |
| 2917 } | 3269 } |
| 2918 | 3270 |
| 2919 CACHE_STATUS_HISTOGRAMS(""); | 3271 CACHE_STATUS_HISTOGRAMS(""); |
| 2920 | 3272 |
| 2921 if (cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE) { | 3273 if (cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE) { |
| 2922 UMA_HISTOGRAM_ENUMERATION("HttpCache.CantConditionalizeCause", | 3274 UMA_HISTOGRAM_ENUMERATION("HttpCache.CantConditionalizeCause", |
| 2923 validation_cause_, VALIDATION_CAUSE_MAX); | 3275 validation_cause_, VALIDATION_CAUSE_MAX); |
| 2924 } | 3276 } |
| 2925 | 3277 |
| 3278 // This may also exclude shared writing counts for these cases. |
| 2926 if (cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER) | 3279 if (cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER) |
| 2927 return; | 3280 return; |
| 3281 |
| 2928 DCHECK(!range_requested_); | 3282 DCHECK(!range_requested_); |
| 2929 DCHECK(!first_cache_access_since_.is_null()); | 3283 DCHECK(!first_cache_access_since_.is_null()); |
| 2930 | 3284 |
| 2931 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; | 3285 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; |
| 2932 | 3286 |
| 2933 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); | 3287 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); |
| 2934 | 3288 |
| 3289 if (cache_entry_status_ == CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING) { |
| 3290 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.JoinSharedWriting", total_time); |
| 3291 } else if (cache_entry_status_ == |
| 3292 CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING) { |
| 3293 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.DoomSharedWriting", total_time); |
| 3294 } else if (initiate_shared_writing_) { |
| 3295 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.InitiateSharedWriting", |
| 3296 total_time); |
| 3297 } |
| 3298 |
| 2935 bool did_send_request = !send_request_since_.is_null(); | 3299 bool did_send_request = !send_request_since_.is_null(); |
| 2936 DCHECK( | 3300 DCHECK( |
| 2937 (did_send_request && | 3301 (did_send_request && |
| 2938 (cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE || | 3302 (cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE || |
| 2939 cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED || | 3303 cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED || |
| 2940 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED || | 3304 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED || |
| 2941 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE)) || | 3305 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE || |
| 3306 cache_entry_status_ == CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING || |
| 3307 cache_entry_status_ == CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING)) || |
| 2942 (!did_send_request && | 3308 (!did_send_request && |
| 2943 cache_entry_status_ == CacheEntryStatus::ENTRY_USED)); | 3309 (cache_entry_status_ == CacheEntryStatus::ENTRY_USED || |
| 3310 cache_entry_status_ == CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING))); |
| 2944 | 3311 |
| 2945 if (!did_send_request) { | 3312 if (!did_send_request) { |
| 2946 DCHECK(cache_entry_status_ == CacheEntryStatus::ENTRY_USED); | 3313 if (cache_entry_status_ == CacheEntryStatus::ENTRY_USED) { |
| 2947 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.Used", total_time); | 3314 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.Used", total_time); |
| 3315 } |
| 2948 return; | 3316 return; |
| 2949 } | 3317 } |
| 2950 | 3318 |
| 2951 TimeDelta before_send_time = send_request_since_ - first_cache_access_since_; | 3319 TimeDelta before_send_time = send_request_since_ - first_cache_access_since_; |
| 2952 int64_t before_send_percent = (total_time.ToInternalValue() == 0) | 3320 int64_t before_send_percent = (total_time.ToInternalValue() == 0) |
| 2953 ? 0 | 3321 ? 0 |
| 2954 : before_send_time * 100 / total_time; | 3322 : before_send_time * 100 / total_time; |
| 2955 DCHECK_GE(before_send_percent, 0); | 3323 DCHECK_GE(before_send_percent, 0); |
| 2956 DCHECK_LE(before_send_percent, 100); | 3324 DCHECK_LE(before_send_percent, 100); |
| 2957 base::HistogramBase::Sample before_send_sample = | 3325 base::HistogramBase::Sample before_send_sample = |
| 2958 static_cast<base::HistogramBase::Sample>(before_send_percent); | 3326 static_cast<base::HistogramBase::Sample>(before_send_percent); |
| 2959 | 3327 |
| 2960 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.SentRequest", total_time); | 3328 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.SentRequest", total_time); |
| 2961 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend", before_send_time); | 3329 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend", before_send_time); |
| 2962 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend", before_send_sample); | 3330 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend", before_send_sample); |
| 2963 | 3331 |
| 2964 // TODO(gavinp): Remove or minimize these histograms, particularly the ones | 3332 // TODO(gavinp): Remove or minimize these histograms, particularly the ones |
| 2965 // below this comment after we have received initial data. | 3333 // below this comment after we have received initial data. |
| 2966 switch (cache_entry_status_) { | 3334 switch (cache_entry_status_) { |
| 2967 case CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE: { | 3335 case CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE: { |
| 2968 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.CantConditionalize", | 3336 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.CantConditionalize", |
| 2969 before_send_time); | 3337 before_send_time); |
| 2970 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.CantConditionalize", | 3338 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.CantConditionalize", |
| 2971 before_send_sample); | 3339 before_send_sample); |
| 3340 if (initiate_shared_writing_) { |
| 3341 UMA_HISTOGRAM_TIMES( |
| 3342 "HttpCache.BeforeSend.CantConditionalize.InitiateSharedWriting", |
| 3343 before_send_time); |
| 3344 UMA_HISTOGRAM_PERCENTAGE( |
| 3345 "HttpCache.PercentBeforeSend.CantConditionalize." |
| 3346 "InitiateSharedWriting", |
| 3347 before_send_sample); |
| 3348 } |
| 3349 |
| 2972 break; | 3350 break; |
| 2973 } | 3351 } |
| 2974 case CacheEntryStatus::ENTRY_NOT_IN_CACHE: { | 3352 case CacheEntryStatus::ENTRY_NOT_IN_CACHE: { |
| 2975 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.NotCached", before_send_time); | 3353 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.NotCached", before_send_time); |
| 2976 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.NotCached", | 3354 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.NotCached", |
| 2977 before_send_sample); | 3355 before_send_sample); |
| 3356 if (initiate_shared_writing_) { |
| 3357 UMA_HISTOGRAM_TIMES( |
| 3358 "HttpCache.BeforeSend.NotCached.InitiateSharedWriting", |
| 3359 before_send_time); |
| 3360 UMA_HISTOGRAM_PERCENTAGE( |
| 3361 "HttpCache.PercentBeforeSend.NotCached.InitiateSharedWriting", |
| 3362 before_send_sample); |
| 3363 } |
| 3364 |
| 2978 break; | 3365 break; |
| 2979 } | 3366 } |
| 2980 case CacheEntryStatus::ENTRY_VALIDATED: { | 3367 case CacheEntryStatus::ENTRY_VALIDATED: { |
| 2981 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Validated", before_send_time); | 3368 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Validated", before_send_time); |
| 2982 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Validated", | 3369 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Validated", |
| 2983 before_send_sample); | 3370 before_send_sample); |
| 2984 break; | 3371 break; |
| 2985 } | 3372 } |
| 2986 case CacheEntryStatus::ENTRY_UPDATED: { | 3373 case CacheEntryStatus::ENTRY_UPDATED: { |
| 2987 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Updated", before_send_time); | 3374 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Updated", before_send_time); |
| 2988 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Updated", | 3375 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Updated", |
| 2989 before_send_sample); | 3376 before_send_sample); |
| 3377 if (initiate_shared_writing_) { |
| 3378 UMA_HISTOGRAM_TIMES( |
| 3379 "HttpCache.BeforeSend.Updated.InitiateSharedWriting", |
| 3380 before_send_time); |
| 3381 UMA_HISTOGRAM_PERCENTAGE( |
| 3382 "HttpCache.PercentBeforeSend.Updated.InitiateSharedWriting", |
| 3383 before_send_sample); |
| 3384 } |
| 3385 break; |
| 3386 } |
| 3387 case CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING: { |
| 3388 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.JoinSharedWriting", |
| 3389 before_send_time); |
| 3390 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.JoinSharedWriting", |
| 3391 before_send_sample); |
| 3392 break; |
| 3393 } |
| 3394 case CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING: { |
| 3395 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.DoomSharedWriting", |
| 3396 before_send_time); |
| 3397 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.DoomSharedWriting", |
| 3398 before_send_sample); |
| 2990 break; | 3399 break; |
| 2991 } | 3400 } |
| 2992 default: | 3401 default: |
| 2993 NOTREACHED(); | 3402 NOTREACHED(); |
| 2994 } | 3403 } |
| 2995 } | 3404 } |
| 2996 | 3405 |
| 3406 bool HttpCache::Transaction::IsEligibleForSharedWriting() const { |
| 3407 if (!(mode_ & WRITE)) |
| 3408 return false; |
| 3409 |
| 3410 DCHECK(request_); |
| 3411 if (request_->method != "GET") |
| 3412 return false; |
| 3413 |
| 3414 if (partial_ || range_requested_) |
| 3415 return false; |
| 3416 |
| 3417 if (truncated_) |
| 3418 return false; |
| 3419 |
| 3420 return true; |
| 3421 } |
| 3422 |
| 3423 void HttpCache::Transaction::SetSharedWritingFailState(int result) { |
| 3424 next_state_ = STATE_SHARED_READ_WRITE_FAILED; |
| 3425 shared_read_write_failure_result_ = result; |
| 3426 entry_ = nullptr; |
| 3427 } |
| 3428 |
| 2997 void HttpCache::Transaction::OnIOComplete(int result) { | 3429 void HttpCache::Transaction::OnIOComplete(int result) { |
| 2998 DoLoop(result); | 3430 DoLoop(result); |
| 2999 } | 3431 } |
| 3000 | 3432 |
| 3001 } // namespace net | 3433 } // namespace net |
| OLD | NEW |