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> |
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 "net/base/sdch_manager.h" | 14 #include "net/base/sdch_manager.h" |
15 #include "net/url_request/url_request_context.h" | |
15 | 16 |
16 #include "sdch/open-vcdiff/src/google/vcdecoder.h" | 17 #include "sdch/open-vcdiff/src/google/vcdecoder.h" |
17 | 18 |
18 namespace net { | 19 namespace net { |
19 | 20 |
20 SdchFilter::SdchFilter(const FilterContext& filter_context) | 21 SdchFilter::SdchFilter(const FilterContext& filter_context) |
21 : filter_context_(filter_context), | 22 : filter_context_(filter_context), |
22 decoding_status_(DECODING_UNINITIALIZED), | 23 decoding_status_(DECODING_UNINITIALIZED), |
23 dictionary_hash_(), | 24 dictionary_hash_(), |
24 dictionary_hash_is_plausible_(false), | 25 dictionary_hash_is_plausible_(false), |
25 dictionary_(NULL), | 26 dictionary_(NULL), |
26 dest_buffer_excess_(), | 27 dest_buffer_excess_(), |
27 dest_buffer_excess_index_(0), | 28 dest_buffer_excess_index_(0), |
28 source_bytes_(0), | 29 source_bytes_(0), |
29 output_bytes_(0), | 30 output_bytes_(0), |
30 possible_pass_through_(false) { | 31 possible_pass_through_(false) { |
31 bool success = filter_context.GetMimeType(&mime_type_); | 32 bool success = filter_context.GetMimeType(&mime_type_); |
32 DCHECK(success); | 33 DCHECK(success); |
33 success = filter_context.GetURL(&url_); | 34 success = filter_context.GetURL(&url_); |
34 DCHECK(success); | 35 DCHECK(success); |
36 DCHECK(filter_context_.GetURLRequestContext()->sdch_manager()); | |
35 } | 37 } |
36 | 38 |
37 SdchFilter::~SdchFilter() { | 39 SdchFilter::~SdchFilter() { |
38 // All code here is for gathering stats, and can be removed when SDCH is | 40 // All code here is for gathering stats, and can be removed when SDCH is |
39 // considered stable. | 41 // considered stable. |
40 | 42 |
41 static int filter_use_count = 0; | 43 static int filter_use_count = 0; |
42 ++filter_use_count; | 44 ++filter_use_count; |
43 if (META_REFRESH_RECOVERY == decoding_status_) { | 45 if (META_REFRESH_RECOVERY == decoding_status_) { |
44 UMA_HISTOGRAM_COUNTS("Sdch3.FilterUseBeforeDisabling", filter_use_count); | 46 UMA_HISTOGRAM_COUNTS("Sdch3.FilterUseBeforeDisabling", filter_use_count); |
45 } | 47 } |
46 | 48 |
47 if (vcdiff_streaming_decoder_.get()) { | 49 if (vcdiff_streaming_decoder_.get()) { |
48 if (!vcdiff_streaming_decoder_->FinishDecoding()) { | 50 if (!vcdiff_streaming_decoder_->FinishDecoding()) { |
49 decoding_status_ = DECODING_ERROR; | 51 decoding_status_ = DECODING_ERROR; |
50 SdchManager::SdchErrorRecovery(SdchManager::INCOMPLETE_SDCH_CONTENT); | 52 SdchManager::SdchErrorRecovery(SdchManager::INCOMPLETE_SDCH_CONTENT); |
51 // Make it possible for the user to hit reload, and get non-sdch content. | 53 // Make it possible for the user to hit reload, and get non-sdch content. |
52 // Note this will "wear off" quickly enough, and is just meant to assure | 54 // Note this will "wear off" quickly enough, and is just meant to assure |
53 // in some rare case that the user is not stuck. | 55 // in some rare case that the user is not stuck. |
54 SdchManager::BlacklistDomain(url_); | 56 filter_context_.GetURLRequestContext()->sdch_manager()->BlacklistDomain( |
57 url_); | |
55 UMA_HISTOGRAM_COUNTS("Sdch3.PartialBytesIn", | 58 UMA_HISTOGRAM_COUNTS("Sdch3.PartialBytesIn", |
jar (doing other things)
2014/06/09 23:03:01
nit: I went and looked at these histogtrams. The
Randy Smith (Not in Mondays)
2014/06/10 20:38:41
Will do, but in a separate CL. Confirming: I do t
jar (doing other things)
2014/06/11 20:04:43
+1 with your plan, inluding <owner> field.
On 201
| |
56 static_cast<int>(filter_context_.GetByteReadCount())); | 59 static_cast<int>(filter_context_.GetByteReadCount())); |
57 UMA_HISTOGRAM_COUNTS("Sdch3.PartialVcdiffIn", source_bytes_); | 60 UMA_HISTOGRAM_COUNTS("Sdch3.PartialVcdiffIn", source_bytes_); |
58 UMA_HISTOGRAM_COUNTS("Sdch3.PartialVcdiffOut", output_bytes_); | 61 UMA_HISTOGRAM_COUNTS("Sdch3.PartialVcdiffOut", output_bytes_); |
59 } | 62 } |
60 } | 63 } |
61 | 64 |
62 if (!dest_buffer_excess_.empty()) { | 65 if (!dest_buffer_excess_.empty()) { |
63 // Filter chaining error, or premature teardown. | 66 // Filter chaining error, or premature teardown. |
64 SdchManager::SdchErrorRecovery(SdchManager::UNFLUSHED_CONTENT); | 67 SdchManager::SdchErrorRecovery(SdchManager::UNFLUSHED_CONTENT); |
65 UMA_HISTOGRAM_COUNTS("Sdch3.UnflushedBytesIn", | 68 UMA_HISTOGRAM_COUNTS("Sdch3.UnflushedBytesIn", |
(...skipping 15 matching lines...) Expand all Loading... | |
81 case DECODING_IN_PROGRESS: { | 84 case DECODING_IN_PROGRESS: { |
82 if (output_bytes_) | 85 if (output_bytes_) |
83 UMA_HISTOGRAM_PERCENTAGE("Sdch3.Network_Decode_Ratio_a", | 86 UMA_HISTOGRAM_PERCENTAGE("Sdch3.Network_Decode_Ratio_a", |
84 static_cast<int>( | 87 static_cast<int>( |
85 (filter_context_.GetByteReadCount() * 100) / output_bytes_)); | 88 (filter_context_.GetByteReadCount() * 100) / output_bytes_)); |
86 UMA_HISTOGRAM_COUNTS("Sdch3.Network_Decode_Bytes_VcdiffOut_a", | 89 UMA_HISTOGRAM_COUNTS("Sdch3.Network_Decode_Bytes_VcdiffOut_a", |
87 output_bytes_); | 90 output_bytes_); |
88 filter_context_.RecordPacketStats(FilterContext::SDCH_DECODE); | 91 filter_context_.RecordPacketStats(FilterContext::SDCH_DECODE); |
89 | 92 |
90 // Allow latency experiments to proceed. | 93 // Allow latency experiments to proceed. |
91 SdchManager::Global()->SetAllowLatencyExperiment(url_, true); | 94 filter_context_.GetURLRequestContext()->sdch_manager()-> |
95 SetAllowLatencyExperiment(url_, true); | |
92 return; | 96 return; |
93 } | 97 } |
94 case PASS_THROUGH: { | 98 case PASS_THROUGH: { |
95 filter_context_.RecordPacketStats(FilterContext::SDCH_PASSTHROUGH); | 99 filter_context_.RecordPacketStats(FilterContext::SDCH_PASSTHROUGH); |
96 return; | 100 return; |
97 } | 101 } |
98 case DECODING_UNINITIALIZED: { | 102 case DECODING_UNINITIALIZED: { |
99 SdchManager::SdchErrorRecovery(SdchManager::UNINITIALIZED); | 103 SdchManager::SdchErrorRecovery(SdchManager::UNINITIALIZED); |
100 return; | 104 return; |
101 } | 105 } |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
206 } else { | 210 } else { |
207 // One of the first 9 bytes precluded consideration as a hash. | 211 // One of the first 9 bytes precluded consideration as a hash. |
208 // This can't be an SDCH payload, even though the server said it was. | 212 // This can't be an SDCH payload, even though the server said it was. |
209 // This is a major error, as the server or proxy tagged this SDCH even | 213 // This is a major error, as the server or proxy tagged this SDCH even |
210 // though it is not! | 214 // though it is not! |
211 // Meta-refresh won't help, as we didn't advertise an SDCH dictionary!! | 215 // Meta-refresh won't help, as we didn't advertise an SDCH dictionary!! |
212 // Worse yet, meta-refresh could lead to an infinite refresh loop. | 216 // Worse yet, meta-refresh could lead to an infinite refresh loop. |
213 SdchManager::SdchErrorRecovery(SdchManager::PASSING_THROUGH_NON_SDCH); | 217 SdchManager::SdchErrorRecovery(SdchManager::PASSING_THROUGH_NON_SDCH); |
214 decoding_status_ = PASS_THROUGH; | 218 decoding_status_ = PASS_THROUGH; |
215 // ... but further back-off on advertising SDCH support. | 219 // ... but further back-off on advertising SDCH support. |
216 SdchManager::BlacklistDomain(url_); | 220 filter_context_.GetURLRequestContext()->sdch_manager()->BlacklistDomain( |
221 url_); | |
217 } | 222 } |
218 | 223 |
219 if (decoding_status_ == PASS_THROUGH) { | 224 if (decoding_status_ == PASS_THROUGH) { |
220 dest_buffer_excess_ = dictionary_hash_; // Send what we scanned. | 225 dest_buffer_excess_ = dictionary_hash_; // Send what we scanned. |
221 } else { | 226 } else { |
222 // This is where we try to do the expensive meta-refresh. | 227 // This is where we try to do the expensive meta-refresh. |
223 if (std::string::npos == mime_type_.find("text/html")) { | 228 if (std::string::npos == mime_type_.find("text/html")) { |
224 // Since we can't do a meta-refresh (along with an exponential | 229 // Since we can't do a meta-refresh (along with an exponential |
225 // backoff), we'll just make sure this NEVER happens again. | 230 // backoff), we'll just make sure this NEVER happens again. |
226 SdchManager::BlacklistDomainForever(url_); | 231 filter_context_.GetURLRequestContext()->sdch_manager()-> |
232 BlacklistDomainForever(url_); | |
227 if (filter_context_.IsCachedContent()) | 233 if (filter_context_.IsCachedContent()) |
228 SdchManager::SdchErrorRecovery( | 234 SdchManager::SdchErrorRecovery( |
229 SdchManager::CACHED_META_REFRESH_UNSUPPORTED); | 235 SdchManager::CACHED_META_REFRESH_UNSUPPORTED); |
230 else | 236 else |
231 SdchManager::SdchErrorRecovery( | 237 SdchManager::SdchErrorRecovery( |
232 SdchManager::META_REFRESH_UNSUPPORTED); | 238 SdchManager::META_REFRESH_UNSUPPORTED); |
233 return FILTER_ERROR; | 239 return FILTER_ERROR; |
234 } | 240 } |
235 // HTML content means we can issue a meta-refresh, and get the content | 241 // HTML content means we can issue a meta-refresh, and get the content |
236 // again, perhaps without SDCH (to be safe). | 242 // again, perhaps without SDCH (to be safe). |
237 if (filter_context_.IsCachedContent()) { | 243 if (filter_context_.IsCachedContent()) { |
238 // Cached content is probably a startup tab, so we'll just get fresh | 244 // Cached content is probably a startup tab, so we'll just get fresh |
239 // content and try again, without disabling sdch. | 245 // content and try again, without disabling sdch. |
240 SdchManager::SdchErrorRecovery( | 246 SdchManager::SdchErrorRecovery( |
241 SdchManager::META_REFRESH_CACHED_RECOVERY); | 247 SdchManager::META_REFRESH_CACHED_RECOVERY); |
242 } else { | 248 } else { |
243 // Since it wasn't in the cache, we definately need at least some | 249 // Since it wasn't in the cache, we definately need at least some |
244 // period of blacklisting to get the correct content. | 250 // period of blacklisting to get the correct content. |
245 SdchManager::BlacklistDomain(url_); | 251 filter_context_.GetURLRequestContext()->sdch_manager()-> |
252 BlacklistDomain(url_); | |
246 SdchManager::SdchErrorRecovery(SdchManager::META_REFRESH_RECOVERY); | 253 SdchManager::SdchErrorRecovery(SdchManager::META_REFRESH_RECOVERY); |
247 } | 254 } |
248 decoding_status_ = META_REFRESH_RECOVERY; | 255 decoding_status_ = META_REFRESH_RECOVERY; |
249 // Issue a meta redirect with SDCH disabled. | 256 // Issue a meta redirect with SDCH disabled. |
250 dest_buffer_excess_ = kDecompressionErrorHtml; | 257 dest_buffer_excess_ = kDecompressionErrorHtml; |
251 } | 258 } |
252 } else { | 259 } else { |
253 DCHECK_EQ(DECODING_IN_PROGRESS, decoding_status_); | 260 DCHECK_EQ(DECODING_IN_PROGRESS, decoding_status_); |
254 } | 261 } |
255 } | 262 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
328 DCHECK_LE(0, stream_data_len_); | 335 DCHECK_LE(0, stream_data_len_); |
329 if (stream_data_len_ > 0) | 336 if (stream_data_len_ > 0) |
330 next_stream_data_ += bytes_needed; | 337 next_stream_data_ += bytes_needed; |
331 else | 338 else |
332 next_stream_data_ = NULL; | 339 next_stream_data_ = NULL; |
333 | 340 |
334 DCHECK(!dictionary_.get()); | 341 DCHECK(!dictionary_.get()); |
335 dictionary_hash_is_plausible_ = true; // Assume plausible, but check. | 342 dictionary_hash_is_plausible_ = true; // Assume plausible, but check. |
336 | 343 |
337 SdchManager::Dictionary* dictionary = NULL; | 344 SdchManager::Dictionary* dictionary = NULL; |
338 if ('\0' == dictionary_hash_[kServerIdLength - 1]) | 345 if ('\0' == dictionary_hash_[kServerIdLength - 1]) { |
339 SdchManager::Global()->GetVcdiffDictionary(std::string(dictionary_hash_, 0, | 346 SdchManager* manager( |
340 kServerIdLength - 1), | 347 filter_context_.GetURLRequestContext()->sdch_manager()); |
341 url_, &dictionary); | 348 manager->GetVcdiffDictionary( |
342 else | 349 std::string(dictionary_hash_, 0, kServerIdLength - 1), |
350 url_, &dictionary); | |
351 } else { | |
343 dictionary_hash_is_plausible_ = false; | 352 dictionary_hash_is_plausible_ = false; |
353 } | |
344 | 354 |
345 if (!dictionary) { | 355 if (!dictionary) { |
346 DCHECK(dictionary_hash_.size() == kServerIdLength); | 356 DCHECK(dictionary_hash_.size() == kServerIdLength); |
347 // Since dictionary was not found, check to see if hash was even plausible. | 357 // Since dictionary was not found, check to see if hash was even plausible. |
348 for (size_t i = 0; i < kServerIdLength - 1; ++i) { | 358 for (size_t i = 0; i < kServerIdLength - 1; ++i) { |
349 char base64_char = dictionary_hash_[i]; | 359 char base64_char = dictionary_hash_[i]; |
350 if (!isalnum(base64_char) && '-' != base64_char && '_' != base64_char) { | 360 if (!isalnum(base64_char) && '-' != base64_char && '_' != base64_char) { |
351 dictionary_hash_is_plausible_ = false; | 361 dictionary_hash_is_plausible_ = false; |
352 break; | 362 break; |
353 } | 363 } |
(...skipping 26 matching lines...) Expand all Loading... | |
380 dest_buffer_excess_index_ += amount; | 390 dest_buffer_excess_index_ += amount; |
381 if (dest_buffer_excess_.size() <= dest_buffer_excess_index_) { | 391 if (dest_buffer_excess_.size() <= dest_buffer_excess_index_) { |
382 DCHECK(dest_buffer_excess_.size() == dest_buffer_excess_index_); | 392 DCHECK(dest_buffer_excess_.size() == dest_buffer_excess_index_); |
383 dest_buffer_excess_.clear(); | 393 dest_buffer_excess_.clear(); |
384 dest_buffer_excess_index_ = 0; | 394 dest_buffer_excess_index_ = 0; |
385 } | 395 } |
386 return amount; | 396 return amount; |
387 } | 397 } |
388 | 398 |
389 } // namespace net | 399 } // namespace net |
OLD | NEW |