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 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: | |
|
jkarlin
2017/02/07 15:20:31
Ah, I'm not sure that I appreciated just how large
shivanisha
2017/02/07 20:56:48
Yes, there are lots of states and this switch only
| |
| 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 699 // -> CacheToggleUnusedSincePrefetch* -> CacheDispatchValidation -> | 830 // -> CacheToggleUnusedSincePrefetch* -> CacheDispatchValidation -> |
| 700 // BeginPartialCacheValidation() -> BeginCacheValidation() -> | 831 // BeginPartialCacheValidation() -> BeginCacheValidation() -> |
| 701 // SetupEntryForRead() | 832 // SetupEntryForRead() |
| 702 // | 833 // |
| 703 // Read(): | 834 // Read(): |
| 704 // CacheReadData* | 835 // CacheReadData* |
| 705 // | 836 // |
| 706 // 14. Cached entry more than 5 minutes old, unused_since_prefetch is true: | 837 // 14. Cached entry more than 5 minutes old, unused_since_prefetch is true: |
| 707 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between | 838 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between |
| 708 // CacheReadResponse* and CacheDispatchValidation. | 839 // CacheReadResponse* and CacheDispatchValidation. |
| 840 // | |
| 709 int HttpCache::Transaction::DoLoop(int result) { | 841 int HttpCache::Transaction::DoLoop(int result) { |
| 710 DCHECK(next_state_ != STATE_NONE); | 842 DCHECK(next_state_ != STATE_NONE); |
| 711 | 843 |
| 712 int rv = result; | 844 int rv = result; |
| 713 do { | 845 do { |
| 714 State state = next_state_; | 846 State state = next_state_; |
| 715 next_state_ = STATE_NONE; | 847 next_state_ = STATE_NONE; |
| 716 switch (state) { | 848 switch (state) { |
| 717 case STATE_GET_BACKEND: | 849 case STATE_GET_BACKEND: |
| 718 DCHECK_EQ(OK, rv); | 850 DCHECK_EQ(OK, rv); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 866 case STATE_CACHE_WRITE_DATA_COMPLETE: | 998 case STATE_CACHE_WRITE_DATA_COMPLETE: |
| 867 rv = DoCacheWriteDataComplete(rv); | 999 rv = DoCacheWriteDataComplete(rv); |
| 868 break; | 1000 break; |
| 869 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE: | 1001 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE: |
| 870 DCHECK_EQ(OK, rv); | 1002 DCHECK_EQ(OK, rv); |
| 871 rv = DoCacheWriteTruncatedResponse(); | 1003 rv = DoCacheWriteTruncatedResponse(); |
| 872 break; | 1004 break; |
| 873 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE: | 1005 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE: |
| 874 rv = DoCacheWriteTruncatedResponseComplete(rv); | 1006 rv = DoCacheWriteTruncatedResponseComplete(rv); |
| 875 break; | 1007 break; |
| 1008 case STATE_SHARED_NETWORK_READ: | |
| 1009 DCHECK_EQ(OK, rv); | |
| 1010 rv = DoSharedNetworkRead(); | |
| 1011 break; | |
| 1012 case STATE_SHARED_NETWORK_READ_COMPLETE: | |
| 1013 rv = DoSharedNetworkReadComplete(rv); | |
| 1014 break; | |
| 1015 case STATE_SHARED_NETWORK_READ_WAIT_COMPLETE: | |
| 1016 rv = DoSharedNetworkReadWaitComplete(rv); | |
| 1017 break; | |
| 1018 case STATE_SHARED_CACHE_WRITE_DATA: | |
| 1019 rv = DoSharedCacheWriteData(rv); | |
| 1020 break; | |
| 1021 case STATE_SHARED_CACHE_WRITE_DATA_COMPLETE: | |
| 1022 rv = DoSharedCacheWriteDataComplete(rv); | |
| 1023 break; | |
| 1024 case STATE_SHARED_READ_WRITE_FAILED: | |
| 1025 rv = DoSharedReadWriteFailed(); | |
| 1026 break; | |
| 876 default: | 1027 default: |
| 877 NOTREACHED() << "bad state"; | 1028 NOTREACHED() << "bad state"; |
| 878 rv = ERR_FAILED; | 1029 rv = ERR_FAILED; |
| 879 break; | 1030 break; |
| 880 } | 1031 } |
| 881 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 1032 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
| 882 | 1033 |
| 883 if (rv != ERR_IO_PENDING && !callback_.is_null()) { | 1034 if (rv != ERR_IO_PENDING && !callback_.is_null()) { |
| 884 read_buf_ = NULL; // Release the buffer before invoking the callback. | 1035 read_buf_ = NULL; // Release the buffer before invoking the callback. |
| 885 base::ResetAndReturn(&callback_).Run(rv); | 1036 base::ResetAndReturn(&callback_).Run(rv); |
| (...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1503 | 1654 |
| 1504 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); | 1655 RecordNoStoreHeaderHistogram(request_->load_flags, new_response); |
| 1505 | 1656 |
| 1506 if (new_response_->headers->response_code() == 416 && | 1657 if (new_response_->headers->response_code() == 416 && |
| 1507 (request_->method == "GET" || request_->method == "POST")) { | 1658 (request_->method == "GET" || request_->method == "POST")) { |
| 1508 // If there is an active entry it may be destroyed with this transaction. | 1659 // If there is an active entry it may be destroyed with this transaction. |
| 1509 SetResponse(*new_response_); | 1660 SetResponse(*new_response_); |
| 1510 return OK; | 1661 return OK; |
| 1511 } | 1662 } |
| 1512 | 1663 |
| 1664 // If the transaction is shared and it is a 200 or an error response, then | |
| 1665 // doom the entry and let this transaction continue without writing to the | |
| 1666 // cache if shared writers contain more transactions. If not, continue | |
| 1667 // writing to the cache and also transfer the network transaction to shared | |
| 1668 // writers. | |
| 1669 if (shared_ && new_response->headers->response_code() != 304) { | |
| 1670 network_trans_ = entry_->shared_writers->OnValidationNoMatch( | |
| 1671 cache_key_, this, std::move(network_trans_), priority_); | |
| 1672 if (!shared_) { | |
| 1673 DCHECK(network_trans_); | |
| 1674 if (cache_entry_status_ == CacheEntryStatus::ENTRY_UNDEFINED) { | |
| 1675 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING); | |
| 1676 } | |
| 1677 DoneWritingToEntry(false, false); | |
| 1678 return OK; | |
| 1679 } else { | |
| 1680 DCHECK(!network_trans_); | |
| 1681 } | |
| 1682 } | |
| 1683 | |
| 1513 // Are we expecting a response to a conditional query? | 1684 // Are we expecting a response to a conditional query? |
| 1514 if (mode_ == READ_WRITE || mode_ == UPDATE) { | 1685 if (mode_ == READ_WRITE || mode_ == UPDATE) { |
| 1515 if (new_response->headers->response_code() == 304 || handling_206_) { | 1686 if (new_response->headers->response_code() == 304 || handling_206_) { |
| 1516 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED); | 1687 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED); |
| 1517 next_state_ = STATE_UPDATE_CACHED_RESPONSE; | 1688 next_state_ = STATE_UPDATE_CACHED_RESPONSE; |
| 1518 return OK; | 1689 return OK; |
| 1519 } | 1690 } |
| 1520 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_UPDATED); | 1691 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_UPDATED); |
| 1521 mode_ = WRITE; | 1692 mode_ = WRITE; |
| 1522 } | 1693 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1625 SetResponse(*new_response_); | 1796 SetResponse(*new_response_); |
| 1626 | 1797 |
| 1627 if (request_->method == "HEAD") { | 1798 if (request_->method == "HEAD") { |
| 1628 // This response is replacing the cached one. | 1799 // This response is replacing the cached one. |
| 1629 DoneWritingToEntry(false); | 1800 DoneWritingToEntry(false); |
| 1630 mode_ = NONE; | 1801 mode_ = NONE; |
| 1631 new_response_ = NULL; | 1802 new_response_ = NULL; |
| 1632 return OK; | 1803 return OK; |
| 1633 } | 1804 } |
| 1634 | 1805 |
| 1635 if (handling_206_ && !CanResume(false)) { | 1806 if (handling_206_ && |
| 1807 !cache_->CanResumeEntry(false, request_->method, &response_, entry_)) { | |
| 1636 // There is no point in storing this resource because it will never be used. | 1808 // 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. | 1809 // This may change if we support LOAD_ONLY_FROM_CACHE with sparse entries. |
| 1638 DoneWritingToEntry(false); | 1810 DoneWritingToEntry(false); |
| 1639 if (partial_) | 1811 if (partial_) |
| 1640 partial_->FixResponseHeaders(response_.headers.get(), true); | 1812 partial_->FixResponseHeaders(response_.headers.get(), true); |
| 1641 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | 1813 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; |
| 1642 return OK; | 1814 return OK; |
| 1643 } | 1815 } |
| 1644 | 1816 |
| 1645 next_state_ = STATE_CACHE_WRITE_RESPONSE; | 1817 next_state_ = STATE_CACHE_WRITE_RESPONSE; |
| 1646 return OK; | 1818 return OK; |
| 1647 } | 1819 } |
| 1648 | 1820 |
| 1649 int HttpCache::Transaction::DoCacheWriteResponse() { | 1821 int HttpCache::Transaction::DoCacheWriteResponse() { |
| 1650 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse"); | 1822 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse"); |
| 1651 next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE; | 1823 next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE; |
| 1652 return WriteResponseInfoToEntry(truncated_); | 1824 return WriteResponseInfoToEntry(truncated_); |
| 1653 } | 1825 } |
| 1654 | 1826 |
| 1655 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { | 1827 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { |
| 1656 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete"); | 1828 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponseComplete"); |
| 1657 next_state_ = STATE_TRUNCATE_CACHED_DATA; | 1829 next_state_ = STATE_TRUNCATE_CACHED_DATA; |
| 1658 return OnWriteResponseInfoToEntryComplete(result); | 1830 return OnWriteResponseInfoToEntryComplete(result); |
| 1659 } | 1831 } |
| 1660 | 1832 |
| 1833 void HttpCache::Transaction::SetShared() { | |
| 1834 shared_ = true; | |
| 1835 } | |
| 1836 | |
| 1837 void HttpCache::Transaction::ResetShared(bool continue_network_reading, | |
| 1838 bool continue_cache_reading) { | |
| 1839 if (!continue_network_reading) { | |
| 1840 SaveSharedNetworkTransactionInfo(); | |
| 1841 } | |
| 1842 if (continue_cache_reading) { | |
| 1843 mode_ = READ; | |
| 1844 } | |
| 1845 shared_ = false; | |
| 1846 } | |
| 1847 | |
| 1661 int HttpCache::Transaction::DoTruncateCachedData() { | 1848 int HttpCache::Transaction::DoTruncateCachedData() { |
| 1662 TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedData"); | 1849 TRACE_EVENT0("io", "HttpCacheTransaction::DoTruncateCachedData"); |
| 1663 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; | 1850 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; |
| 1664 if (!entry_) | 1851 if (!entry_) |
| 1665 return OK; | 1852 return OK; |
| 1666 if (net_log_.IsCapturing()) | 1853 if (net_log_.IsCapturing()) |
| 1667 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); | 1854 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); |
| 1668 // Truncate the stream. | 1855 // Truncate the stream. |
| 1669 return WriteToEntry(kResponseContentIndex, 0, NULL, 0, io_callback_); | 1856 return WriteToEntry(kResponseContentIndex, 0, NULL, 0, io_callback_); |
| 1670 } | 1857 } |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1699 if (net_log_.IsCapturing()) { | 1886 if (net_log_.IsCapturing()) { |
| 1700 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, | 1887 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, |
| 1701 result); | 1888 result); |
| 1702 } | 1889 } |
| 1703 } | 1890 } |
| 1704 | 1891 |
| 1705 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; | 1892 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; |
| 1706 return OK; | 1893 return OK; |
| 1707 } | 1894 } |
| 1708 | 1895 |
| 1896 void HttpCache::Transaction::ProcessForSharedWriting() { | |
| 1897 // Should not be already reading. | |
| 1898 if (reading_) | |
| 1899 return; | |
| 1900 | |
| 1901 // If not already part of SharedWriters, then check if one should be | |
| 1902 // created. | |
| 1903 if (!shared_ && !IsEligibleForSharedWriting()) | |
| 1904 return; | |
| 1905 | |
| 1906 if (shared_) { | |
| 1907 // Non 304 case is already handled in DoSuccessfulSendRequest. | |
| 1908 if (response_.headers->response_code() != 304) { | |
| 1909 return; | |
| 1910 } | |
| 1911 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING); | |
| 1912 entry_->shared_writers->OnValidationMatch(this, priority_); | |
| 1913 network_trans_.reset(); | |
| 1914 return; | |
| 1915 } | |
| 1916 | |
| 1917 // Do not create a SharedWriters if its a Redirect response. | |
| 1918 if (response_.headers->response_code() != 200) | |
| 1919 return; | |
| 1920 | |
| 1921 // or if its a no-store response. | |
| 1922 if (!entry_) | |
| 1923 return; | |
| 1924 | |
| 1925 DCHECK(cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE || | |
| 1926 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED || | |
| 1927 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE || | |
| 1928 cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER); | |
| 1929 // Measure how many requests out of the total of "not cached" and "updated" | |
| 1930 // are initiating Shared Writing. | |
| 1931 initiate_shared_writing_ = true; | |
| 1932 DCHECK(entry_ && network_trans_); | |
| 1933 | |
| 1934 // An instance of SharedWriters will be created when the first writer has | |
| 1935 // written the new response headers in the cache. Transfer network | |
| 1936 // transaction’s ownership to SharedWriters so it can be used by any of the | |
| 1937 // transactions for subsequent reading from the network. | |
| 1938 cache_->CreateSharedWriters(this, std::move(network_trans_), priority_); | |
| 1939 } | |
| 1940 | |
| 1709 int HttpCache::Transaction::DoPartialHeadersReceived() { | 1941 int HttpCache::Transaction::DoPartialHeadersReceived() { |
| 1710 new_response_ = NULL; | 1942 new_response_ = NULL; |
| 1711 if (entry_ && !partial_ && entry_->disk_entry->GetDataSize(kMetadataIndex)) | 1943 if (entry_ && !partial_ && entry_->disk_entry->GetDataSize(kMetadataIndex)) |
| 1712 next_state_ = STATE_CACHE_READ_METADATA; | 1944 next_state_ = STATE_CACHE_READ_METADATA; |
| 1713 | 1945 |
| 1946 ProcessForSharedWriting(); | |
| 1947 | |
| 1714 if (!partial_) | 1948 if (!partial_) |
| 1715 return OK; | 1949 return OK; |
| 1716 | 1950 |
| 1717 if (reading_) { | 1951 if (reading_) { |
| 1718 if (network_trans_.get()) { | 1952 if (network_trans_.get()) { |
| 1719 next_state_ = STATE_NETWORK_READ; | 1953 next_state_ = STATE_NETWORK_READ; |
| 1720 } else { | 1954 } else { |
| 1721 next_state_ = STATE_CACHE_READ_DATA; | 1955 next_state_ = STATE_CACHE_READ_DATA; |
| 1722 } | 1956 } |
| 1723 } else if (mode_ != NONE) { | 1957 } else if (mode_ != NONE) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1754 } | 1988 } |
| 1755 | 1989 |
| 1756 int HttpCache::Transaction::DoNetworkRead() { | 1990 int HttpCache::Transaction::DoNetworkRead() { |
| 1757 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead"); | 1991 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkRead"); |
| 1758 next_state_ = STATE_NETWORK_READ_COMPLETE; | 1992 next_state_ = STATE_NETWORK_READ_COMPLETE; |
| 1759 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); | 1993 return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_); |
| 1760 } | 1994 } |
| 1761 | 1995 |
| 1762 int HttpCache::Transaction::DoNetworkReadComplete(int result) { | 1996 int HttpCache::Transaction::DoNetworkReadComplete(int result) { |
| 1763 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkReadComplete"); | 1997 TRACE_EVENT0("io", "HttpCacheTransaction::DoNetworkReadComplete"); |
| 1998 if (net_log_.IsCapturing()) | |
| 1999 net_log_.EndEventWithNetErrorCode( | |
| 2000 NetLogEventType::HTTP_CACHE_NETWORK_READ_COMPLETE, result); | |
| 2001 | |
| 1764 DCHECK(mode_ & WRITE || mode_ == NONE); | 2002 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 1765 | 2003 |
| 1766 if (!cache_.get()) | 2004 if (!cache_.get()) |
| 1767 return ERR_UNEXPECTED; | 2005 return ERR_UNEXPECTED; |
| 1768 | 2006 |
| 1769 // If there is an error or we aren't saving the data, we are done; just wait | 2007 // 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. | 2008 // until the destructor runs to see if we can keep the data. |
| 1771 if (mode_ == NONE || result < 0) | 2009 if (mode_ == NONE || result < 0) |
| 1772 return result; | 2010 return result; |
| 1773 | 2011 |
| 1774 next_state_ = STATE_CACHE_WRITE_DATA; | 2012 next_state_ = STATE_CACHE_WRITE_DATA; |
| 1775 return result; | 2013 return result; |
| 1776 } | 2014 } |
| 1777 | 2015 |
| 2016 int HttpCache::Transaction::DoSharedNetworkRead() { | |
| 2017 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedNetworkRead"); | |
| 2018 if (net_log_.IsCapturing()) | |
| 2019 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_SHARED_NETWORK_READ); | |
| 2020 | |
| 2021 next_state_ = STATE_SHARED_NETWORK_READ_COMPLETE; | |
| 2022 bool shared_read_in_progress = false; | |
| 2023 int result = entry_->shared_writers->Read( | |
| 2024 read_buf_, io_buf_len_, io_callback_, this, &shared_read_in_progress); | |
| 2025 if (shared_read_in_progress) { | |
| 2026 next_state_ = STATE_SHARED_NETWORK_READ_WAIT_COMPLETE; | |
| 2027 } | |
| 2028 return result; | |
| 2029 } | |
| 2030 | |
| 2031 int HttpCache::Transaction::DoSharedNetworkReadComplete(int result) { | |
| 2032 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedNetworkReadComplete"); | |
| 2033 if (net_log_.IsCapturing()) | |
| 2034 net_log_.EndEventWithNetErrorCode( | |
| 2035 NetLogEventType::HTTP_CACHE_SHARED_NETWORK_READ_COMPLETE, result); | |
| 2036 | |
| 2037 if (result <= 0) { | |
| 2038 // Set entry as null so that the destructor does not invoke DoneWithEntry | |
| 2039 // again as entry_ is already cleaned up by SharedWriters. | |
| 2040 entry_ = nullptr; | |
| 2041 return result; | |
| 2042 } | |
| 2043 | |
| 2044 read_offset_ += result; | |
| 2045 | |
| 2046 next_state_ = STATE_SHARED_CACHE_WRITE_DATA; | |
| 2047 return result; | |
| 2048 } | |
| 2049 | |
| 2050 int HttpCache::Transaction::DoSharedCacheWriteData(int result) { | |
| 2051 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedCacheWriteData"); | |
| 2052 if (net_log_.IsCapturing()) | |
| 2053 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_SHARED_CACHE_WRITE_DATA); | |
| 2054 | |
| 2055 next_state_ = STATE_SHARED_CACHE_WRITE_DATA_COMPLETE; | |
| 2056 write_len_ = result; | |
| 2057 return entry_->shared_writers->CacheWrite(read_buf_, write_len_, io_callback_, | |
| 2058 this); | |
| 2059 } | |
| 2060 | |
| 2061 int HttpCache::Transaction::DoSharedCacheWriteDataComplete(int result) { | |
| 2062 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedCacheWriteDataComplete"); | |
| 2063 if (net_log_.IsCapturing()) | |
| 2064 net_log_.EndEventWithNetErrorCode( | |
| 2065 NetLogEventType::HTTP_CACHE_SHARED_CACHE_WRITE_DATA_COMPLETE, result); | |
| 2066 | |
| 2067 OnCacheWriteDataComplete(true, &result); | |
| 2068 | |
| 2069 if (result == 0) { | |
| 2070 DoneWritingToEntry(true, false); | |
| 2071 } | |
| 2072 return result; | |
| 2073 } | |
| 2074 | |
| 2075 void HttpCache::Transaction::OnCacheWriteDataComplete(bool was_shared, | |
| 2076 int* result) { | |
| 2077 if (*result != write_len_) { | |
| 2078 DoneWritingToEntry(false, !was_shared); | |
| 2079 // We want to ignore errors writing to disk and just keep reading from | |
| 2080 // the network. | |
| 2081 *result = write_len_; | |
| 2082 } else if (!done_reading_ && entry_ && (!partial_ || truncated_)) { | |
| 2083 done_reading_ = cache_->IsResponseCompleted(entry_, &response_); | |
| 2084 } | |
| 2085 } | |
| 2086 | |
| 2087 int HttpCache::Transaction::DoSharedNetworkReadWaitComplete(int result) { | |
| 2088 TRACE_EVENT0("io", "HttpCacheTransaction::DoSharedNetworkReadWaitComplete"); | |
| 2089 if (net_log_.IsCapturing()) | |
| 2090 net_log_.EndEventWithNetErrorCode( | |
| 2091 NetLogEventType::HTTP_CACHE_SHARED_NETWORK_READ_WAIT_COMPLETE, result); | |
| 2092 | |
| 2093 // If its a network read failure or cache write failure, we just return the | |
| 2094 // result. If its a cache write success, read_buf_ would have been filled | |
| 2095 // with the read data by SharedWriters. | |
| 2096 if (result == 0) { // response is complete. | |
| 2097 DoneWritingToEntry(true, false); // changes the mode_ to NONE. | |
| 2098 } else if (result > 0) { | |
| 2099 read_offset_ += result; | |
| 2100 } else { | |
| 2101 // Set entry as null so that the destructor does not invoke DoneWithEntry | |
| 2102 // again as entry_ is already cleaned up by SharedWriters. | |
| 2103 entry_ = nullptr; | |
| 2104 } | |
| 2105 | |
| 2106 return result; | |
| 2107 } | |
| 2108 | |
| 1778 int HttpCache::Transaction::DoCacheReadData() { | 2109 int HttpCache::Transaction::DoCacheReadData() { |
| 1779 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadData"); | 2110 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadData"); |
| 1780 if (request_->method == "HEAD") | 2111 if (request_->method == "HEAD") |
| 1781 return 0; | 2112 return 0; |
| 1782 | 2113 |
| 1783 DCHECK(entry_); | 2114 DCHECK(entry_); |
| 1784 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; | 2115 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; |
| 1785 | 2116 |
| 1786 if (net_log_.IsCapturing()) | 2117 if (net_log_.IsCapturing()) |
| 1787 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_DATA); | 2118 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; | 2160 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; |
| 1830 write_len_ = num_bytes; | 2161 write_len_ = num_bytes; |
| 1831 if (entry_) { | 2162 if (entry_) { |
| 1832 if (net_log_.IsCapturing()) | 2163 if (net_log_.IsCapturing()) |
| 1833 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); | 2164 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); |
| 1834 } | 2165 } |
| 1835 | 2166 |
| 1836 if (!entry_ || !num_bytes) | 2167 if (!entry_ || !num_bytes) |
| 1837 return num_bytes; | 2168 return num_bytes; |
| 1838 | 2169 |
| 2170 if (partial_) { | |
| 2171 return partial_->CacheWrite(entry_->disk_entry, read_buf_.get(), num_bytes, | |
| 2172 io_callback_); | |
| 2173 } | |
| 2174 | |
| 1839 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 2175 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); |
| 1840 return WriteToEntry(kResponseContentIndex, current_size, read_buf_.get(), | 2176 return entry_->disk_entry->WriteData(kResponseContentIndex, current_size, |
| 1841 num_bytes, io_callback_); | 2177 read_buf_.get(), num_bytes, io_callback_, |
| 2178 true); | |
| 1842 } | 2179 } |
| 1843 | 2180 |
| 1844 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) { | 2181 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) { |
| 1845 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteDataComplete"); | 2182 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteDataComplete"); |
| 1846 if (entry_) { | 2183 if (entry_) { |
| 1847 if (net_log_.IsCapturing()) { | 2184 if (net_log_.IsCapturing()) { |
| 1848 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_DATA, | 2185 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_DATA, |
| 1849 result); | 2186 result); |
| 1850 } | 2187 } |
| 1851 } | 2188 } |
| 1852 if (!cache_.get()) | 2189 if (!cache_.get()) |
| 1853 return ERR_UNEXPECTED; | 2190 return ERR_UNEXPECTED; |
| 1854 | 2191 |
| 1855 if (result != write_len_) { | 2192 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 | 2193 |
| 1869 if (partial_) { | 2194 if (partial_) { |
| 1870 // This may be the last request. | 2195 // This may be the last request. |
| 1871 if (result != 0 || truncated_ || | 2196 if (result != 0 || truncated_ || |
| 1872 !(partial_->IsLastRange() || mode_ == WRITE)) { | 2197 !(partial_->IsLastRange() || mode_ == WRITE)) { |
| 1873 return DoPartialNetworkReadCompleted(result); | 2198 return DoPartialNetworkReadCompleted(result); |
| 1874 } | 2199 } |
| 1875 } | 2200 } |
| 1876 | 2201 |
| 2202 // End of file. This may be the result of a connection problem so see if we | |
| 2203 // have to keep the entry around to be flagged as truncated later on. | |
| 1877 if (result == 0) { | 2204 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_ || | 2205 if (done_reading_ || !entry_ || partial_ || |
| 1881 response_.headers->GetContentLength() <= 0) { | 2206 response_.headers->GetContentLength() <= 0) |
| 1882 DoneWritingToEntry(true); | 2207 DoneWritingToEntry(true); |
| 1883 } | |
| 1884 } | 2208 } |
| 1885 | 2209 |
| 1886 return result; | 2210 return result; |
| 1887 } | 2211 } |
| 1888 | 2212 |
| 1889 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() { | 2213 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() { |
| 1890 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); | 2214 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); |
| 1891 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE; | 2215 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE; |
| 1892 return WriteResponseInfoToEntry(true); | 2216 return WriteResponseInfoToEntry(true); |
| 1893 } | 2217 } |
| 1894 | 2218 |
| 1895 int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) { | 2219 int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) { |
| 1896 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); | 2220 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteTruncatedResponse"); |
| 1897 | 2221 |
| 1898 return OnWriteResponseInfoToEntryComplete(result); | 2222 return OnWriteResponseInfoToEntryComplete(result); |
| 1899 } | 2223 } |
| 1900 | 2224 |
| 2225 int HttpCache::Transaction::DoSharedReadWriteFailed() { | |
| 2226 if (net_log_.IsCapturing()) | |
| 2227 net_log_.EndEventWithNetErrorCode( | |
| 2228 NetLogEventType::HTTP_CACHE_SHARED_READ_WRITE_FAILED, | |
| 2229 shared_read_write_failure_result_); | |
| 2230 | |
| 2231 return shared_read_write_failure_result_; | |
| 2232 } | |
| 2233 | |
| 1901 //----------------------------------------------------------------------------- | 2234 //----------------------------------------------------------------------------- |
| 1902 | 2235 |
| 1903 void HttpCache::Transaction::SetRequest(const NetLogWithSource& net_log, | 2236 void HttpCache::Transaction::SetRequest(const NetLogWithSource& net_log, |
| 1904 const HttpRequestInfo* request) { | 2237 const HttpRequestInfo* request) { |
| 1905 net_log_ = net_log; | 2238 net_log_ = net_log; |
| 1906 request_ = request; | 2239 request_ = request; |
| 1907 effective_load_flags_ = request_->load_flags; | 2240 effective_load_flags_ = request_->load_flags; |
| 1908 | 2241 |
| 1909 if (cache_->mode() == DISABLE) | 2242 if (cache_->mode() == DISABLE) |
| 1910 effective_load_flags_ |= LOAD_DISABLE_CACHE; | 2243 effective_load_flags_ |= LOAD_DISABLE_CACHE; |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2084 | 2417 |
| 2085 if (partial_ && (is_sparse_ || truncated_) && | 2418 if (partial_ && (is_sparse_ || truncated_) && |
| 2086 (!partial_->IsCurrentRangeCached() || invalid_range_)) { | 2419 (!partial_->IsCurrentRangeCached() || invalid_range_)) { |
| 2087 // Force revalidation for sparse or truncated entries. Note that we don't | 2420 // 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 | 2421 // want to ignore the regular validation logic just because a byte range was |
| 2089 // part of the request. | 2422 // part of the request. |
| 2090 skip_validation = false; | 2423 skip_validation = false; |
| 2091 } | 2424 } |
| 2092 | 2425 |
| 2093 if (skip_validation) { | 2426 if (skip_validation) { |
| 2094 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_USED); | 2427 if (shared_) { |
| 2095 return SetupEntryForRead(); | 2428 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING); |
| 2429 entry_->shared_writers->OnValidationMatch(this, priority_); | |
| 2430 } else { | |
| 2431 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_USED); | |
| 2432 return SetupEntryForRead(); | |
| 2433 } | |
| 2096 } else { | 2434 } else { |
| 2097 // Make the network request conditional, to see if we may reuse our cached | 2435 // 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. | 2436 // 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 | 2437 // Our mode remains READ_WRITE for a conditional request. Even if the |
| 2100 // conditionalization fails, we don't switch to WRITE mode until we | 2438 // 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 | 2439 // know we won't be falling back to using the cache entry in the |
| 2102 // LOAD_FROM_CACHE_IF_OFFLINE case. | 2440 // LOAD_FROM_CACHE_IF_OFFLINE case. |
| 2103 if (!ConditionalizeRequest()) { | 2441 if (!ConditionalizeRequest()) { |
| 2104 couldnt_conditionalize_request_ = true; | 2442 couldnt_conditionalize_request_ = true; |
| 2105 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE); | 2443 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)) { | 2942 IsCertStatusError(response_.ssl_info.cert_status)) { |
| 2605 DoneWritingToEntry(false); | 2943 DoneWritingToEntry(false); |
| 2606 if (net_log_.IsCapturing()) | 2944 if (net_log_.IsCapturing()) |
| 2607 net_log_.EndEvent(NetLogEventType::HTTP_CACHE_WRITE_INFO); | 2945 net_log_.EndEvent(NetLogEventType::HTTP_CACHE_WRITE_INFO); |
| 2608 return OK; | 2946 return OK; |
| 2609 } | 2947 } |
| 2610 | 2948 |
| 2611 if (truncated) | 2949 if (truncated) |
| 2612 DCHECK_EQ(200, response_.headers->response_code()); | 2950 DCHECK_EQ(200, response_.headers->response_code()); |
| 2613 | 2951 |
| 2614 // When writing headers, we normally only write the non-transient headers. | 2952 return cache_->WriteResponseInfo(entry_, &response_, io_callback_, truncated, |
| 2615 bool skip_transient_headers = true; | 2953 &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 } | 2954 } |
| 2624 | 2955 |
| 2625 int HttpCache::Transaction::OnWriteResponseInfoToEntryComplete(int result) { | 2956 int HttpCache::Transaction::OnWriteResponseInfoToEntryComplete(int result) { |
| 2626 if (!entry_) | 2957 if (!entry_) |
| 2627 return OK; | 2958 return OK; |
| 2628 if (net_log_.IsCapturing()) { | 2959 if (net_log_.IsCapturing()) { |
| 2629 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, | 2960 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, |
| 2630 result); | 2961 result); |
| 2631 } | 2962 } |
| 2632 | 2963 |
| 2633 if (result != io_buf_len_) { | 2964 if (result != io_buf_len_) { |
| 2634 DLOG(ERROR) << "failed to write response info to cache"; | 2965 DLOG(ERROR) << "failed to write response info to cache"; |
| 2635 DoneWritingToEntry(false); | 2966 DoneWritingToEntry(false); |
| 2636 } | 2967 } |
| 2637 return OK; | 2968 return OK; |
| 2638 } | 2969 } |
| 2639 | 2970 |
| 2640 void HttpCache::Transaction::DoneWritingToEntry(bool success) { | 2971 void HttpCache::Transaction::DoneWritingToEntry(bool success, |
| 2972 bool perform_entry_cleanup) { | |
| 2641 if (!entry_) | 2973 if (!entry_) |
| 2642 return; | 2974 return; |
| 2643 | 2975 |
| 2644 RecordHistograms(); | 2976 RecordHistograms(); |
| 2645 | 2977 |
| 2646 cache_->DoneWritingToEntry(entry_, success); | 2978 if (perform_entry_cleanup) { |
| 2647 entry_ = NULL; | 2979 cache_->DoneWritingToEntry(entry_, success); |
| 2980 } | |
| 2981 entry_ = nullptr; | |
| 2648 mode_ = NONE; // switch to 'pass through' mode | 2982 mode_ = NONE; // switch to 'pass through' mode |
| 2649 } | 2983 } |
| 2650 | 2984 |
| 2985 void HttpCache::Transaction::ContinueWithoutSharedWriting( | |
| 2986 std::unique_ptr<HttpTransaction> network_transaction, | |
| 2987 bool needs_entry) { | |
| 2988 shared_ = false; | |
| 2989 if (!needs_entry) | |
| 2990 entry_ = nullptr; | |
| 2991 mode_ = NONE; | |
| 2992 network_trans_ = std::move(network_transaction); | |
| 2993 } | |
| 2994 | |
| 2651 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { | 2995 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { |
| 2652 DLOG(ERROR) << "ReadData failed: " << result; | 2996 DLOG(ERROR) << "ReadData failed: " << result; |
| 2653 const int result_for_histogram = std::max(0, -result); | 2997 const int result_for_histogram = std::max(0, -result); |
| 2654 if (restart) { | 2998 if (restart) { |
| 2655 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", | 2999 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", |
| 2656 result_for_histogram); | 3000 result_for_histogram); |
| 2657 } else { | 3001 } else { |
| 2658 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable", | 3002 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable", |
| 2659 result_for_histogram); | 3003 result_for_histogram); |
| 2660 } | 3004 } |
| 2661 | 3005 |
| 2662 // Avoid using this entry in the future. | 3006 // Avoid using this entry in the future. |
| 2663 if (cache_.get()) | 3007 if (cache_.get()) |
| 2664 cache_->DoomActiveEntry(cache_key_); | 3008 cache_->DoomActiveEntry(cache_key_); |
| 2665 | 3009 |
| 2666 if (restart) { | 3010 if (restart) { |
| 2667 DCHECK(!reading_); | 3011 DCHECK(!reading_); |
| 2668 DCHECK(!network_trans_.get()); | 3012 DCHECK(!network_trans_.get()); |
| 2669 cache_->DoneWithEntry(entry_, this, false); | 3013 if (shared_) { |
| 3014 entry_->shared_writers->RemoveValidatingTransaction(this); | |
| 3015 } else { | |
| 3016 cache_->DoneWithEntry(entry_, this, false); | |
| 3017 } | |
| 2670 entry_ = NULL; | 3018 entry_ = NULL; |
| 2671 is_sparse_ = false; | 3019 is_sparse_ = false; |
| 2672 partial_.reset(); | 3020 partial_.reset(); |
| 2673 next_state_ = STATE_GET_BACKEND; | 3021 next_state_ = STATE_GET_BACKEND; |
| 2674 return OK; | 3022 return OK; |
| 2675 } | 3023 } |
| 2676 | 3024 |
| 2677 return ERR_CACHE_READ_FAILURE; | 3025 return ERR_CACHE_READ_FAILURE; |
| 2678 } | 3026 } |
| 2679 | 3027 |
| 2680 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { | 3028 void HttpCache::Transaction::OnAddToEntryTimeout(base::TimeTicks start_time) { |
| 2681 if (entry_lock_waiting_since_ != start_time) | 3029 if (entry_lock_waiting_since_ != start_time) |
| 2682 return; | 3030 return; |
| 2683 | 3031 |
| 2684 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); | 3032 DCHECK_EQ(next_state_, STATE_ADD_TO_ENTRY_COMPLETE); |
| 2685 | 3033 |
| 2686 if (!cache_) | 3034 if (!cache_) |
| 2687 return; | 3035 return; |
| 2688 | 3036 |
| 2689 cache_->RemovePendingTransaction(this); | 3037 cache_->RemovePendingTransaction(this); |
| 2690 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); | 3038 OnIOComplete(ERR_CACHE_LOCK_TIMEOUT); |
| 2691 } | 3039 } |
| 2692 | 3040 |
| 2693 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { | 3041 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { |
| 3042 // Partial requests not supported with shared writing as of now. | |
| 3043 DCHECK(!shared_); | |
| 2694 DVLOG(2) << "DoomPartialEntry"; | 3044 DVLOG(2) << "DoomPartialEntry"; |
| 2695 int rv = cache_->DoomEntry(cache_key_, NULL); | 3045 int rv = cache_->DoomEntry(cache_key_, NULL); |
| 2696 DCHECK_EQ(OK, rv); | 3046 DCHECK_EQ(OK, rv); |
| 2697 cache_->DoneWithEntry(entry_, this, false); | 3047 cache_->DoneWithEntry(entry_, this, false); |
| 2698 entry_ = NULL; | 3048 entry_ = NULL; |
| 2699 is_sparse_ = false; | 3049 is_sparse_ = false; |
| 2700 truncated_ = false; | 3050 truncated_ = false; |
| 2701 if (delete_object) | 3051 if (delete_object) |
| 2702 partial_.reset(NULL); | 3052 partial_.reset(NULL); |
| 2703 } | 3053 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2744 if (!delete_object) { | 3094 if (!delete_object) { |
| 2745 // The simplest way to re-initialize partial_ is to create a new object. | 3095 // The simplest way to re-initialize partial_ is to create a new object. |
| 2746 partial_.reset(new PartialData()); | 3096 partial_.reset(new PartialData()); |
| 2747 if (partial_->Init(request_->extra_headers)) | 3097 if (partial_->Init(request_->extra_headers)) |
| 2748 partial_->SetHeaders(custom_request_->extra_headers); | 3098 partial_->SetHeaders(custom_request_->extra_headers); |
| 2749 else | 3099 else |
| 2750 partial_.reset(); | 3100 partial_.reset(); |
| 2751 } | 3101 } |
| 2752 } | 3102 } |
| 2753 | 3103 |
| 2754 void HttpCache::Transaction::ResetNetworkTransaction() { | 3104 void HttpCache::Transaction::SaveNetworkTransactionInfo( |
| 3105 const HttpTransaction* transaction) { | |
| 2755 DCHECK(!old_network_trans_load_timing_); | 3106 DCHECK(!old_network_trans_load_timing_); |
| 2756 DCHECK(network_trans_); | 3107 DCHECK(transaction); |
| 2757 LoadTimingInfo load_timing; | 3108 LoadTimingInfo load_timing; |
| 2758 if (network_trans_->GetLoadTimingInfo(&load_timing)) | 3109 if (transaction->GetLoadTimingInfo(&load_timing)) |
| 2759 old_network_trans_load_timing_.reset(new LoadTimingInfo(load_timing)); | 3110 old_network_trans_load_timing_.reset(new LoadTimingInfo(load_timing)); |
| 2760 total_received_bytes_ += network_trans_->GetTotalReceivedBytes(); | 3111 total_received_bytes_ += transaction->GetTotalReceivedBytes(); |
| 2761 total_sent_bytes_ += network_trans_->GetTotalSentBytes(); | 3112 total_sent_bytes_ += transaction->GetTotalSentBytes(); |
| 2762 ConnectionAttempts attempts; | 3113 ConnectionAttempts attempts; |
| 2763 network_trans_->GetConnectionAttempts(&attempts); | 3114 transaction->GetConnectionAttempts(&attempts); |
| 2764 for (const auto& attempt : attempts) | 3115 for (const auto& attempt : attempts) |
| 2765 old_connection_attempts_.push_back(attempt); | 3116 old_connection_attempts_.push_back(attempt); |
| 2766 old_remote_endpoint_ = IPEndPoint(); | 3117 old_remote_endpoint_ = IPEndPoint(); |
| 2767 network_trans_->GetRemoteEndpoint(&old_remote_endpoint_); | 3118 transaction->GetRemoteEndpoint(&old_remote_endpoint_); |
| 3119 } | |
| 3120 | |
| 3121 void HttpCache::Transaction::SaveSharedNetworkTransactionInfo() { | |
| 3122 // If network_trans_ is still present, this transaction has not started using | |
| 3123 // the "shared" network transaction. | |
| 3124 if (network_trans_) { | |
| 3125 SaveNetworkTransactionInfo(network_trans_.get()); | |
| 3126 return; | |
| 3127 } | |
| 3128 | |
| 3129 DCHECK(!old_network_trans_load_timing_); | |
| 3130 | |
| 3131 // If the transaction is being deleted while still in the waiting queue, | |
| 3132 // entry_ is not yet set, do nothing. | |
| 3133 if (!entry_) | |
| 3134 return; | |
| 3135 DCHECK(entry_->shared_writers); | |
| 3136 HttpTransaction* network_transaction = | |
| 3137 entry_->shared_writers->network_transaction(); | |
| 3138 SaveNetworkTransactionInfo(network_transaction); | |
| 3139 have_full_request_headers_ = | |
| 3140 network_transaction->GetFullRequestHeaders(&full_request_headers_); | |
| 3141 } | |
| 3142 | |
| 3143 void HttpCache::Transaction::ResetNetworkTransaction() { | |
| 3144 SaveNetworkTransactionInfo(network_trans_.get()); | |
| 2768 network_trans_.reset(); | 3145 network_trans_.reset(); |
| 2769 } | 3146 } |
| 2770 | 3147 |
| 2771 // Histogram data from the end of 2010 show the following distribution of | 3148 HttpTransaction* HttpCache::Transaction::GetCurrentNetworkTransaction() const { |
| 2772 // response headers: | 3149 if (network_trans_) |
| 2773 // | 3150 return network_trans_.get(); |
| 2774 // Content-Length............... 87% | 3151 if (shared_ && entry_ && entry_->shared_writers) |
| 2775 // Date......................... 98% | 3152 return entry_->shared_writers->network_transaction(); |
| 2776 // Last-Modified................ 49% | 3153 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 } | 3154 } |
| 2802 | 3155 |
| 2803 void HttpCache::Transaction::SetResponse(const HttpResponseInfo& response) { | 3156 void HttpCache::Transaction::SetResponse(const HttpResponseInfo& response) { |
| 2804 response_ = response; | 3157 response_ = response; |
| 2805 SyncCacheEntryStatusToResponse(); | 3158 SyncCacheEntryStatusToResponse(); |
| 2806 } | 3159 } |
| 2807 | 3160 |
| 2808 void HttpCache::Transaction::SetAuthResponse( | 3161 void HttpCache::Transaction::SetAuthResponse( |
| 2809 const HttpResponseInfo& auth_response) { | 3162 const HttpResponseInfo& auth_response) { |
| 2810 auth_response_ = auth_response; | 3163 auth_response_ = auth_response; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2916 } | 3269 } |
| 2917 } | 3270 } |
| 2918 | 3271 |
| 2919 CACHE_STATUS_HISTOGRAMS(""); | 3272 CACHE_STATUS_HISTOGRAMS(""); |
| 2920 | 3273 |
| 2921 if (cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE) { | 3274 if (cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE) { |
| 2922 UMA_HISTOGRAM_ENUMERATION("HttpCache.CantConditionalizeCause", | 3275 UMA_HISTOGRAM_ENUMERATION("HttpCache.CantConditionalizeCause", |
| 2923 validation_cause_, VALIDATION_CAUSE_MAX); | 3276 validation_cause_, VALIDATION_CAUSE_MAX); |
| 2924 } | 3277 } |
| 2925 | 3278 |
| 3279 // This may also exclude shared writing counts for these cases. | |
| 2926 if (cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER) | 3280 if (cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER) |
| 2927 return; | 3281 return; |
| 3282 | |
| 2928 DCHECK(!range_requested_); | 3283 DCHECK(!range_requested_); |
| 2929 DCHECK(!first_cache_access_since_.is_null()); | 3284 DCHECK(!first_cache_access_since_.is_null()); |
| 2930 | 3285 |
| 2931 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; | 3286 TimeDelta total_time = base::TimeTicks::Now() - first_cache_access_since_; |
| 2932 | 3287 |
| 2933 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); | 3288 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone", total_time); |
| 2934 | 3289 |
| 3290 if (cache_entry_status_ == CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING) { | |
| 3291 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.JoinSharedWriting", total_time); | |
| 3292 } else if (cache_entry_status_ == | |
| 3293 CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING) { | |
| 3294 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.DoomSharedWriting", total_time); | |
| 3295 } else if (initiate_shared_writing_) { | |
| 3296 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.InitiateSharedWriting", | |
| 3297 total_time); | |
| 3298 } | |
| 3299 | |
| 2935 bool did_send_request = !send_request_since_.is_null(); | 3300 bool did_send_request = !send_request_since_.is_null(); |
| 2936 DCHECK( | 3301 DCHECK( |
| 2937 (did_send_request && | 3302 (did_send_request && |
| 2938 (cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE || | 3303 (cache_entry_status_ == CacheEntryStatus::ENTRY_NOT_IN_CACHE || |
| 2939 cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED || | 3304 cache_entry_status_ == CacheEntryStatus::ENTRY_VALIDATED || |
| 2940 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED || | 3305 cache_entry_status_ == CacheEntryStatus::ENTRY_UPDATED || |
| 2941 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE)) || | 3306 cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE || |
| 3307 cache_entry_status_ == CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING || | |
| 3308 cache_entry_status_ == CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING)) || | |
| 2942 (!did_send_request && | 3309 (!did_send_request && |
| 2943 cache_entry_status_ == CacheEntryStatus::ENTRY_USED)); | 3310 (cache_entry_status_ == CacheEntryStatus::ENTRY_USED || |
| 3311 cache_entry_status_ == CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING))); | |
| 2944 | 3312 |
| 2945 if (!did_send_request) { | 3313 if (!did_send_request) { |
| 2946 DCHECK(cache_entry_status_ == CacheEntryStatus::ENTRY_USED); | 3314 if (cache_entry_status_ == CacheEntryStatus::ENTRY_USED) { |
| 2947 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.Used", total_time); | 3315 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.Used", total_time); |
| 3316 } | |
| 2948 return; | 3317 return; |
| 2949 } | 3318 } |
| 2950 | 3319 |
| 2951 TimeDelta before_send_time = send_request_since_ - first_cache_access_since_; | 3320 TimeDelta before_send_time = send_request_since_ - first_cache_access_since_; |
| 2952 int64_t before_send_percent = (total_time.ToInternalValue() == 0) | 3321 int64_t before_send_percent = (total_time.ToInternalValue() == 0) |
| 2953 ? 0 | 3322 ? 0 |
| 2954 : before_send_time * 100 / total_time; | 3323 : before_send_time * 100 / total_time; |
| 2955 DCHECK_GE(before_send_percent, 0); | 3324 DCHECK_GE(before_send_percent, 0); |
| 2956 DCHECK_LE(before_send_percent, 100); | 3325 DCHECK_LE(before_send_percent, 100); |
| 2957 base::HistogramBase::Sample before_send_sample = | 3326 base::HistogramBase::Sample before_send_sample = |
| 2958 static_cast<base::HistogramBase::Sample>(before_send_percent); | 3327 static_cast<base::HistogramBase::Sample>(before_send_percent); |
| 2959 | 3328 |
| 2960 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.SentRequest", total_time); | 3329 UMA_HISTOGRAM_TIMES("HttpCache.AccessToDone.SentRequest", total_time); |
| 2961 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend", before_send_time); | 3330 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend", before_send_time); |
| 2962 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend", before_send_sample); | 3331 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend", before_send_sample); |
| 2963 | 3332 |
| 2964 // TODO(gavinp): Remove or minimize these histograms, particularly the ones | 3333 // TODO(gavinp): Remove or minimize these histograms, particularly the ones |
| 2965 // below this comment after we have received initial data. | 3334 // below this comment after we have received initial data. |
| 2966 switch (cache_entry_status_) { | 3335 switch (cache_entry_status_) { |
| 2967 case CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE: { | 3336 case CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE: { |
| 2968 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.CantConditionalize", | 3337 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.CantConditionalize", |
| 2969 before_send_time); | 3338 before_send_time); |
| 2970 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.CantConditionalize", | 3339 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.CantConditionalize", |
| 2971 before_send_sample); | 3340 before_send_sample); |
| 3341 if (initiate_shared_writing_) { | |
| 3342 UMA_HISTOGRAM_TIMES( | |
| 3343 "HttpCache.BeforeSend.CantConditionalize.InitiateSharedWriting", | |
| 3344 before_send_time); | |
| 3345 UMA_HISTOGRAM_PERCENTAGE( | |
| 3346 "HttpCache.PercentBeforeSend.CantConditionalize." | |
| 3347 "InitiateSharedWriting", | |
| 3348 before_send_sample); | |
| 3349 } | |
| 3350 | |
| 2972 break; | 3351 break; |
| 2973 } | 3352 } |
| 2974 case CacheEntryStatus::ENTRY_NOT_IN_CACHE: { | 3353 case CacheEntryStatus::ENTRY_NOT_IN_CACHE: { |
| 2975 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.NotCached", before_send_time); | 3354 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.NotCached", before_send_time); |
| 2976 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.NotCached", | 3355 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.NotCached", |
| 2977 before_send_sample); | 3356 before_send_sample); |
| 3357 if (initiate_shared_writing_) { | |
| 3358 UMA_HISTOGRAM_TIMES( | |
| 3359 "HttpCache.BeforeSend.NotCached.InitiateSharedWriting", | |
| 3360 before_send_time); | |
| 3361 UMA_HISTOGRAM_PERCENTAGE( | |
| 3362 "HttpCache.PercentBeforeSend.NotCached.InitiateSharedWriting", | |
| 3363 before_send_sample); | |
| 3364 } | |
| 3365 | |
| 2978 break; | 3366 break; |
| 2979 } | 3367 } |
| 2980 case CacheEntryStatus::ENTRY_VALIDATED: { | 3368 case CacheEntryStatus::ENTRY_VALIDATED: { |
| 2981 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Validated", before_send_time); | 3369 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Validated", before_send_time); |
| 2982 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Validated", | 3370 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Validated", |
| 2983 before_send_sample); | 3371 before_send_sample); |
| 2984 break; | 3372 break; |
| 2985 } | 3373 } |
| 2986 case CacheEntryStatus::ENTRY_UPDATED: { | 3374 case CacheEntryStatus::ENTRY_UPDATED: { |
| 2987 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Updated", before_send_time); | 3375 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.Updated", before_send_time); |
| 2988 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Updated", | 3376 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.Updated", |
| 2989 before_send_sample); | 3377 before_send_sample); |
| 3378 if (initiate_shared_writing_) { | |
| 3379 UMA_HISTOGRAM_TIMES( | |
| 3380 "HttpCache.BeforeSend.Updated.InitiateSharedWriting", | |
| 3381 before_send_time); | |
| 3382 UMA_HISTOGRAM_PERCENTAGE( | |
| 3383 "HttpCache.PercentBeforeSend.Updated.InitiateSharedWriting", | |
| 3384 before_send_sample); | |
| 3385 } | |
| 3386 break; | |
| 3387 } | |
| 3388 case CacheEntryStatus::ENTRY_JOIN_SHARED_WRITING: { | |
| 3389 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.JoinSharedWriting", | |
| 3390 before_send_time); | |
| 3391 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.JoinSharedWriting", | |
| 3392 before_send_sample); | |
| 3393 break; | |
| 3394 } | |
| 3395 case CacheEntryStatus::ENTRY_DOOM_SHARED_WRITING: { | |
| 3396 UMA_HISTOGRAM_TIMES("HttpCache.BeforeSend.DoomSharedWriting", | |
| 3397 before_send_time); | |
| 3398 UMA_HISTOGRAM_PERCENTAGE("HttpCache.PercentBeforeSend.DoomSharedWriting", | |
| 3399 before_send_sample); | |
| 2990 break; | 3400 break; |
| 2991 } | 3401 } |
| 2992 default: | 3402 default: |
| 2993 NOTREACHED(); | 3403 NOTREACHED(); |
| 2994 } | 3404 } |
| 2995 } | 3405 } |
| 2996 | 3406 |
| 3407 bool HttpCache::Transaction::IsEligibleForSharedWriting() const { | |
| 3408 if (!(mode_ & WRITE)) | |
| 3409 return false; | |
| 3410 | |
| 3411 DCHECK(request_); | |
| 3412 if (request_->method != "GET") | |
| 3413 return false; | |
| 3414 | |
| 3415 if (partial_ || range_requested_) | |
| 3416 return false; | |
| 3417 | |
| 3418 if (truncated_) | |
| 3419 return false; | |
| 3420 | |
| 3421 return true; | |
| 3422 } | |
| 3423 | |
| 3424 void HttpCache::Transaction::SetSharedWritingFailState(int result) { | |
| 3425 next_state_ = STATE_SHARED_READ_WRITE_FAILED; | |
| 3426 shared_read_write_failure_result_ = result; | |
| 3427 entry_ = nullptr; | |
| 3428 } | |
| 3429 | |
| 2997 void HttpCache::Transaction::OnIOComplete(int result) { | 3430 void HttpCache::Transaction::OnIOComplete(int result) { |
| 2998 DoLoop(result); | 3431 DoLoop(result); |
| 2999 } | 3432 } |
| 3000 | 3433 |
| 3001 } // namespace net | 3434 } // namespace net |
| OLD | NEW |