Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: net/filter/sdch_filter.cc

Issue 711753003: Pin dictionaries from being deleted while request is outstanding. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Incorporated comments. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/filter/sdch_filter.h" 5 #include "net/filter/sdch_filter.h"
6 6
7 #include <ctype.h> 7 #include <ctype.h>
8 #include <limits.h> 8 #include <limits.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
11 11
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
14 #include "base/values.h" 14 #include "base/values.h"
15 #include "net/base/sdch_manager.h" 15 #include "net/base/sdch_manager.h"
16 #include "net/base/sdch_net_log_params.h" 16 #include "net/base/sdch_net_log_params.h"
17 #include "net/base/sdch_problem_codes.h"
17 #include "net/url_request/url_request_context.h" 18 #include "net/url_request/url_request_context.h"
18 19
19 #include "sdch/open-vcdiff/src/google/vcdecoder.h" 20 #include "sdch/open-vcdiff/src/google/vcdecoder.h"
20 21
21 namespace net { 22 namespace net {
22 23
23 namespace { 24 namespace {
24 25
25 // Disambiguate various types of responses that trigger a meta-refresh, 26 // Disambiguate various types of responses that trigger a meta-refresh,
26 // failure, or fallback to pass-through. 27 // failure, or fallback to pass-through.
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 // is compressed data etc. For now, we do nothing, which gets us into 285 // is compressed data etc. For now, we do nothing, which gets us into
285 // the meta-refresh result. 286 // the meta-refresh result.
286 // TODO(jar): Improve robustness by sniffing for valid text that we can 287 // TODO(jar): Improve robustness by sniffing for valid text that we can
287 // actual use re: decoding_status_ = PASS_THROUGH; 288 // actual use re: decoding_status_ = PASS_THROUGH;
288 cause = RESPONSE_TENTATIVE_SDCH; 289 cause = RESPONSE_TENTATIVE_SDCH;
289 } else if (dictionary_hash_is_plausible_) { 290 } else if (dictionary_hash_is_plausible_) {
290 // We need a meta-refresh since we don't have the dictionary. 291 // We need a meta-refresh since we don't have the dictionary.
291 // The common cause is a restart of the browser, where we try to render 292 // The common cause is a restart of the browser, where we try to render
292 // cached content that was saved when we had a dictionary. 293 // cached content that was saved when we had a dictionary.
293 cause = RESPONSE_NO_DICTIONARY; 294 cause = RESPONSE_NO_DICTIONARY;
294 } else if (filter_context_.SdchResponseExpected()) { 295 } else if (filter_context_.SdchDictionariesAdvertised()) {
295 // This is a very corrupt SDCH request response. We can't decode it. 296 // This is a very corrupt SDCH request response. We can't decode it.
296 // We'll use a meta-refresh, and get content without asking for SDCH. 297 // We'll use a meta-refresh, and get content without asking for SDCH.
297 // This will also progressively disable SDCH for this domain. 298 // This will also progressively disable SDCH for this domain.
298 cause = RESPONSE_CORRUPT_SDCH; 299 cause = RESPONSE_CORRUPT_SDCH;
299 } else { 300 } else {
300 // One of the first 9 bytes precluded consideration as a hash. 301 // One of the first 9 bytes precluded consideration as a hash.
301 // This can't be an SDCH payload, even though the server said it was. 302 // This can't be an SDCH payload, even though the server said it was.
302 // This is a major error, as the server or proxy tagged this SDCH even 303 // This is a major error, as the server or proxy tagged this SDCH even
303 // though it is not! 304 // though it is not!
304 // Meta-refresh won't help, as we didn't advertise an SDCH dictionary!! 305 // Meta-refresh won't help, as we didn't advertise an SDCH dictionary!!
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 } 434 }
434 dictionary_hash_.append(next_stream_data_, bytes_needed); 435 dictionary_hash_.append(next_stream_data_, bytes_needed);
435 DCHECK(kServerIdLength == dictionary_hash_.size()); 436 DCHECK(kServerIdLength == dictionary_hash_.size());
436 stream_data_len_ -= bytes_needed; 437 stream_data_len_ -= bytes_needed;
437 DCHECK_LE(0, stream_data_len_); 438 DCHECK_LE(0, stream_data_len_);
438 if (stream_data_len_ > 0) 439 if (stream_data_len_ > 0)
439 next_stream_data_ += bytes_needed; 440 next_stream_data_ += bytes_needed;
440 else 441 else
441 next_stream_data_ = NULL; 442 next_stream_data_ = NULL;
442 443
443 DCHECK(!dictionary_.get()); 444 DCHECK(!dictionary_);
444 dictionary_hash_is_plausible_ = true; // Assume plausible, but check. 445 dictionary_hash_is_plausible_ = true; // Assume plausible, but check.
445 446
446 SdchProblemCode rv = SDCH_OK; 447 SdchProblemCode rv = SDCH_OK;
447 if ('\0' == dictionary_hash_[kServerIdLength - 1]) { 448 if ('\0' == dictionary_hash_[kServerIdLength - 1]) {
448 SdchManager* manager(url_request_context_->sdch_manager()); 449 std::string server_hash(dictionary_hash_, 0, kServerIdLength - 1);
449 rv = manager->GetVcdiffDictionary( 450 SdchManager::DictionarySet* handle =
450 std::string(dictionary_hash_, 0, kServerIdLength - 1), url_, 451 filter_context_.SdchDictionariesAdvertised();
451 &dictionary_); 452 if (handle)
452 if (rv == SDCH_DICTIONARY_HASH_NOT_FOUND) { 453 dictionary_ = handle->Dictionary(server_hash);
453 DCHECK(dictionary_hash_.size() == kServerIdLength); 454 if (!dictionary_) {
454 // Since dictionary was not found, check to see if hash was even 455 // This is a hack. Naively, the dictionaries available for
455 // plausible. 456 // decoding should be only the ones advertised. However, there are
456 for (size_t i = 0; i < kServerIdLength - 1; ++i) { 457 // cases, specifically resources encoded with old dictionaries living
457 char base64_char = dictionary_hash_[i]; 458 // in the cache, that mean the full set of dictionaries should be made
458 if (!isalnum(base64_char) && '-' != base64_char && '_' != base64_char) { 459 // available for decoding. It's not known how often this happens;
459 rv = SDCH_DICTIONARY_HASH_MALFORMED; 460 // if it happens rarely enough, this code can be removed.
460 dictionary_hash_is_plausible_ = false; 461 //
461 break; 462 // TODO(rdsmith): Long-term, a better solution is necessary, since
463 // an entry in the cache being encoded with the dictionary doesn't
464 // guarantee that the dictionary is present. That solution probably
465 // involves storing unencoded resources in the cache, but might
466 // involve evicting encoded resources on dictionary removal.
467 // See http://crbug.com/383405.
468 unexpected_dictionary_handle_ =
469 url_request_context_->sdch_manager()->GetDictionarySetByHash(
470 url_, server_hash, &rv);
471 if (unexpected_dictionary_handle_.get()) {
472 dictionary_ = unexpected_dictionary_handle_->Dictionary(server_hash);
473 // Override SDCH_OK rv; this is still worth logging.
474 rv = (filter_context_.IsCachedContent() ?
475 SDCH_UNADVERTISED_DICTIONARY_USED_CACHED :
476 SDCH_UNADVERTISED_DICTIONARY_USED);
477 } else {
478 // Since dictionary was not found, check to see if hash was
479 // even plausible.
480 DCHECK(dictionary_hash_.size() == kServerIdLength);
481 rv = SDCH_DICTIONARY_HASH_NOT_FOUND;
482 for (size_t i = 0; i < kServerIdLength - 1; ++i) {
483 char base64_char = dictionary_hash_[i];
484 if (!isalnum(base64_char) &&
485 '-' != base64_char && '_' != base64_char) {
486 dictionary_hash_is_plausible_ = false;
487 rv = SDCH_DICTIONARY_HASH_MALFORMED;
488 break;
489 }
462 } 490 }
463 } 491 }
464 } 492 }
465 } else { 493 } else {
466 dictionary_hash_is_plausible_ = false; 494 dictionary_hash_is_plausible_ = false;
467 rv = SDCH_DICTIONARY_HASH_MALFORMED; 495 rv = SDCH_DICTIONARY_HASH_MALFORMED;
468 } 496 }
469 if (rv != SDCH_OK) { 497
498 if (rv != SDCH_OK)
470 LogSdchProblem(rv); 499 LogSdchProblem(rv);
500
501 if (!dictionary_) {
471 decoding_status_ = DECODING_ERROR; 502 decoding_status_ = DECODING_ERROR;
472 return FILTER_ERROR; 503 return FILTER_ERROR;
473 } 504 }
474 DCHECK(dictionary_.get()); 505
475 vcdiff_streaming_decoder_.reset(new open_vcdiff::VCDiffStreamingDecoder); 506 vcdiff_streaming_decoder_.reset(new open_vcdiff::VCDiffStreamingDecoder);
476 vcdiff_streaming_decoder_->SetAllowVcdTarget(false); 507 vcdiff_streaming_decoder_->SetAllowVcdTarget(false);
477 vcdiff_streaming_decoder_->StartDecoding(dictionary_->text().data(), 508 vcdiff_streaming_decoder_->StartDecoding(dictionary_->text().data(),
478 dictionary_->text().size()); 509 dictionary_->text().size());
479 decoding_status_ = DECODING_IN_PROGRESS; 510 decoding_status_ = DECODING_IN_PROGRESS;
480 return FILTER_OK; 511 return FILTER_OK;
481 } 512 }
482 513
483 int SdchFilter::OutputBufferExcess(char* const dest_buffer, 514 int SdchFilter::OutputBufferExcess(char* const dest_buffer,
484 size_t available_space) { 515 size_t available_space) {
(...skipping 14 matching lines...) Expand all
499 } 530 }
500 531
501 void SdchFilter::LogSdchProblem(SdchProblemCode problem) { 532 void SdchFilter::LogSdchProblem(SdchProblemCode problem) {
502 SdchManager::SdchErrorRecovery(problem); 533 SdchManager::SdchErrorRecovery(problem);
503 filter_context_.GetNetLog().AddEvent( 534 filter_context_.GetNetLog().AddEvent(
504 NetLog::TYPE_SDCH_DECODING_ERROR, 535 NetLog::TYPE_SDCH_DECODING_ERROR,
505 base::Bind(&NetLogSdchResourceProblemCallback, problem)); 536 base::Bind(&NetLogSdchResourceProblemCallback, problem));
506 } 537 }
507 538
508 } // namespace net 539 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698