| OLD | NEW |
| 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> |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 // is compressed data etc. For now, we do nothing, which gets us into | 237 // is compressed data etc. For now, we do nothing, which gets us into |
| 238 // the meta-refresh result. | 238 // the meta-refresh result. |
| 239 // TODO(jar): Improve robustness by sniffing for valid text that we can | 239 // TODO(jar): Improve robustness by sniffing for valid text that we can |
| 240 // actual use re: decoding_status_ = PASS_THROUGH; | 240 // actual use re: decoding_status_ = PASS_THROUGH; |
| 241 cause = RESPONSE_TENTATIVE_SDCH; | 241 cause = RESPONSE_TENTATIVE_SDCH; |
| 242 } else if (dictionary_hash_is_plausible_) { | 242 } else if (dictionary_hash_is_plausible_) { |
| 243 // We need a meta-refresh since we don't have the dictionary. | 243 // We need a meta-refresh since we don't have the dictionary. |
| 244 // The common cause is a restart of the browser, where we try to render | 244 // The common cause is a restart of the browser, where we try to render |
| 245 // cached content that was saved when we had a dictionary. | 245 // cached content that was saved when we had a dictionary. |
| 246 cause = RESPONSE_NO_DICTIONARY; | 246 cause = RESPONSE_NO_DICTIONARY; |
| 247 } else if (filter_context_.SdchResponseExpected()) { | 247 } else if (filter_context_.SdchDictionariesAdvertised()) { |
| 248 // This is a very corrupt SDCH request response. We can't decode it. | 248 // This is a very corrupt SDCH request response. We can't decode it. |
| 249 // We'll use a meta-refresh, and get content without asking for SDCH. | 249 // We'll use a meta-refresh, and get content without asking for SDCH. |
| 250 // This will also progressively disable SDCH for this domain. | 250 // This will also progressively disable SDCH for this domain. |
| 251 cause = RESPONSE_CORRUPT_SDCH; | 251 cause = RESPONSE_CORRUPT_SDCH; |
| 252 } else { | 252 } else { |
| 253 // One of the first 9 bytes precluded consideration as a hash. | 253 // One of the first 9 bytes precluded consideration as a hash. |
| 254 // This can't be an SDCH payload, even though the server said it was. | 254 // This can't be an SDCH payload, even though the server said it was. |
| 255 // This is a major error, as the server or proxy tagged this SDCH even | 255 // This is a major error, as the server or proxy tagged this SDCH even |
| 256 // though it is not! | 256 // though it is not! |
| 257 // Meta-refresh won't help, as we didn't advertise an SDCH dictionary!! | 257 // Meta-refresh won't help, as we didn't advertise an SDCH dictionary!! |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 } | 384 } |
| 385 dictionary_hash_.append(next_stream_data_, bytes_needed); | 385 dictionary_hash_.append(next_stream_data_, bytes_needed); |
| 386 DCHECK(kServerIdLength == dictionary_hash_.size()); | 386 DCHECK(kServerIdLength == dictionary_hash_.size()); |
| 387 stream_data_len_ -= bytes_needed; | 387 stream_data_len_ -= bytes_needed; |
| 388 DCHECK_LE(0, stream_data_len_); | 388 DCHECK_LE(0, stream_data_len_); |
| 389 if (stream_data_len_ > 0) | 389 if (stream_data_len_ > 0) |
| 390 next_stream_data_ += bytes_needed; | 390 next_stream_data_ += bytes_needed; |
| 391 else | 391 else |
| 392 next_stream_data_ = NULL; | 392 next_stream_data_ = NULL; |
| 393 | 393 |
| 394 DCHECK(!dictionary_.get()); | 394 DCHECK(!dictionary_); |
| 395 dictionary_hash_is_plausible_ = true; // Assume plausible, but check. | 395 dictionary_hash_is_plausible_ = true; // Assume plausible, but check. |
| 396 | 396 |
| 397 if ('\0' == dictionary_hash_[kServerIdLength - 1]) { | 397 if ('\0' == dictionary_hash_[kServerIdLength - 1]) { |
| 398 SdchManager* manager(url_request_context_->sdch_manager()); | 398 std::string server_hash(dictionary_hash_, 0, kServerIdLength - 1); |
| 399 manager->GetVcdiffDictionary( | 399 SdchManager::DictionarySet* handle = |
| 400 std::string(dictionary_hash_, 0, kServerIdLength - 1), | 400 filter_context_.SdchDictionariesAdvertised(); |
| 401 url_, &dictionary_); | 401 if (handle) |
| 402 dictionary_ = handle->Dictionary(server_hash); |
| 403 if (!dictionary_) { |
| 404 // This is a hack. Naively, the dictionaries available for |
| 405 // decoding should be only the ones advertised. However, there are |
| 406 // cases, specifically resources encoded with old dictionaries living |
| 407 // in the cache, that mean the full set of dictionaries should be made |
| 408 // available for decoding. It's not known how often this happens; |
| 409 // if it happens rarely enough, this code can be removed. |
| 410 // |
| 411 // TODO(rdsmith): Long-term, a better solution is necessary, since |
| 412 // an entry in the cache being encoded with the dictionary doesn't |
| 413 // guarantee that the dictionary is present. That solution probably |
| 414 // involves storing unencoded resources in the cache, but might |
| 415 // involve evicting encoded resources on dictionary removal. |
| 416 unexpected_dictionary_handle_ = |
| 417 url_request_context_->sdch_manager()->GetDictionarySetByHash( |
| 418 url_, server_hash); |
| 419 if (unexpected_dictionary_handle_.get()) { |
| 420 dictionary_ = unexpected_dictionary_handle_->Dictionary(server_hash); |
| 421 SdchManager::SdchErrorRecovery( |
| 422 filter_context_.IsCachedContent() ? |
| 423 SdchManager::UNADVERTISED_SDCH_DICTIONARY_USED_CACHED : |
| 424 SdchManager::UNADVERTISED_SDCH_DICTIONARY_USED); |
| 425 } |
| 426 } |
| 402 } else { | 427 } else { |
| 403 dictionary_hash_is_plausible_ = false; | 428 dictionary_hash_is_plausible_ = false; |
| 404 } | 429 } |
| 405 | 430 |
| 406 if (!dictionary_.get()) { | 431 if (!dictionary_) { |
| 407 DCHECK(dictionary_hash_.size() == kServerIdLength); | 432 DCHECK(dictionary_hash_.size() == kServerIdLength); |
| 408 // Since dictionary was not found, check to see if hash was even plausible. | 433 // Since dictionary was not found, check to see if hash was even plausible. |
| 409 for (size_t i = 0; i < kServerIdLength - 1; ++i) { | 434 for (size_t i = 0; i < kServerIdLength - 1; ++i) { |
| 410 char base64_char = dictionary_hash_[i]; | 435 char base64_char = dictionary_hash_[i]; |
| 411 if (!isalnum(base64_char) && '-' != base64_char && '_' != base64_char) { | 436 if (!isalnum(base64_char) && '-' != base64_char && '_' != base64_char) { |
| 412 dictionary_hash_is_plausible_ = false; | 437 dictionary_hash_is_plausible_ = false; |
| 413 break; | 438 break; |
| 414 } | 439 } |
| 415 } | 440 } |
| 416 if (dictionary_hash_is_plausible_) | 441 if (dictionary_hash_is_plausible_) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 440 dest_buffer_excess_index_ += amount; | 465 dest_buffer_excess_index_ += amount; |
| 441 if (dest_buffer_excess_.size() <= dest_buffer_excess_index_) { | 466 if (dest_buffer_excess_.size() <= dest_buffer_excess_index_) { |
| 442 DCHECK(dest_buffer_excess_.size() == dest_buffer_excess_index_); | 467 DCHECK(dest_buffer_excess_.size() == dest_buffer_excess_index_); |
| 443 dest_buffer_excess_.clear(); | 468 dest_buffer_excess_.clear(); |
| 444 dest_buffer_excess_index_ = 0; | 469 dest_buffer_excess_index_ = 0; |
| 445 } | 470 } |
| 446 return amount; | 471 return amount; |
| 447 } | 472 } |
| 448 | 473 |
| 449 } // namespace net | 474 } // namespace net |
| OLD | NEW |