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

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

Issue 704493002: Revert "Sdch view for net-internals" (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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
« no previous file with comments | « net/filter/sdch_filter.h ('k') | net/filter/sdch_filter_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
15 #include "net/base/sdch_manager.h" 14 #include "net/base/sdch_manager.h"
16 #include "net/base/sdch_net_log_params.h"
17 #include "net/url_request/url_request_context.h" 15 #include "net/url_request/url_request_context.h"
18 16
19 #include "sdch/open-vcdiff/src/google/vcdecoder.h" 17 #include "sdch/open-vcdiff/src/google/vcdecoder.h"
20 18
21 namespace net { 19 namespace net {
22 20
23 namespace { 21 namespace {
24 22
25 // Disambiguate various types of responses that trigger a meta-refresh, 23 // Disambiguate various types of responses that trigger a meta-refresh,
26 // failure, or fallback to pass-through. 24 // failure, or fallback to pass-through.
(...skipping 18 matching lines...) Expand all
45 // Not an SDCH response but should be. 43 // Not an SDCH response but should be.
46 RESPONSE_CORRUPT_SDCH = 6, 44 RESPONSE_CORRUPT_SDCH = 6,
47 45
48 // No dictionary was advertised with the request, the server claims 46 // No dictionary was advertised with the request, the server claims
49 // to have encoded with SDCH anyway, but it isn't an SDCH response. 47 // to have encoded with SDCH anyway, but it isn't an SDCH response.
50 RESPONSE_ENCODING_LIE = 7, 48 RESPONSE_ENCODING_LIE = 7,
51 49
52 RESPONSE_MAX, 50 RESPONSE_MAX,
53 }; 51 };
54 52
55 const char* ResponseCorruptionDetectionCauseToString(
56 ResponseCorruptionDetectionCause cause) {
57 const char* cause_string = "<unknown>";
58 switch (cause) {
59 case RESPONSE_NONE:
60 cause_string = "NONE";
61 case RESPONSE_404:
62 cause_string = "404";
63 case RESPONSE_NOT_200:
64 cause_string = "NOT_200";
65 case RESPONSE_OLD_UNENCODED:
66 cause_string = "OLD_UNENCODED";
67 case RESPONSE_TENTATIVE_SDCH:
68 cause_string = "TENTATIVE_SDCH";
69 case RESPONSE_NO_DICTIONARY:
70 cause_string = "NO_DICTIONARY";
71 case RESPONSE_CORRUPT_SDCH:
72 cause_string = "CORRUPT_SDCH";
73 case RESPONSE_ENCODING_LIE:
74 cause_string = "ENCODING_LIE";
75 case RESPONSE_MAX:
76 cause_string = "<Error: max enum value>";
77 }
78 return cause_string;
79 }
80
81 base::Value* NetLogSdchResponseCorruptionDetectionCallback(
82 ResponseCorruptionDetectionCause cause,
83 bool cached,
84 NetLog::LogLevel log_level) {
85 base::DictionaryValue* dict = new base::DictionaryValue();
86 dict->SetString("cause", ResponseCorruptionDetectionCauseToString(cause));
87 dict->SetBoolean("cached", cached);
88 dict->SetInteger("net_error", ERR_FAILED);
89 return dict;
90 }
91
92 } // namespace 53 } // namespace
93 54
94 SdchFilter::SdchFilter(const FilterContext& filter_context) 55 SdchFilter::SdchFilter(const FilterContext& filter_context)
95 : filter_context_(filter_context), 56 : filter_context_(filter_context),
96 decoding_status_(DECODING_UNINITIALIZED), 57 decoding_status_(DECODING_UNINITIALIZED),
97 dictionary_hash_(), 58 dictionary_hash_(),
98 dictionary_hash_is_plausible_(false), 59 dictionary_hash_is_plausible_(false),
99 dictionary_(NULL), 60 dictionary_(NULL),
100 url_request_context_(filter_context.GetURLRequestContext()), 61 url_request_context_(filter_context.GetURLRequestContext()),
101 dest_buffer_excess_(), 62 dest_buffer_excess_(),
(...skipping 14 matching lines...) Expand all
116 77
117 static int filter_use_count = 0; 78 static int filter_use_count = 0;
118 ++filter_use_count; 79 ++filter_use_count;
119 if (META_REFRESH_RECOVERY == decoding_status_) { 80 if (META_REFRESH_RECOVERY == decoding_status_) {
120 UMA_HISTOGRAM_COUNTS("Sdch3.FilterUseBeforeDisabling", filter_use_count); 81 UMA_HISTOGRAM_COUNTS("Sdch3.FilterUseBeforeDisabling", filter_use_count);
121 } 82 }
122 83
123 if (vcdiff_streaming_decoder_.get()) { 84 if (vcdiff_streaming_decoder_.get()) {
124 if (!vcdiff_streaming_decoder_->FinishDecoding()) { 85 if (!vcdiff_streaming_decoder_->FinishDecoding()) {
125 decoding_status_ = DECODING_ERROR; 86 decoding_status_ = DECODING_ERROR;
126 LogSdchProblem(SDCH_INCOMPLETE_SDCH_CONTENT); 87 SdchManager::SdchErrorRecovery(SdchManager::INCOMPLETE_SDCH_CONTENT);
127 // Make it possible for the user to hit reload, and get non-sdch content. 88 // Make it possible for the user to hit reload, and get non-sdch content.
128 // Note this will "wear off" quickly enough, and is just meant to assure 89 // Note this will "wear off" quickly enough, and is just meant to assure
129 // in some rare case that the user is not stuck. 90 // in some rare case that the user is not stuck.
130 url_request_context_->sdch_manager()->BlacklistDomain( 91 url_request_context_->sdch_manager()->BlacklistDomain(
131 url_, SDCH_INCOMPLETE_SDCH_CONTENT); 92 url_, SdchManager::INCOMPLETE_SDCH_CONTENT);
132 UMA_HISTOGRAM_COUNTS("Sdch3.PartialBytesIn", 93 UMA_HISTOGRAM_COUNTS("Sdch3.PartialBytesIn",
133 static_cast<int>(filter_context_.GetByteReadCount())); 94 static_cast<int>(filter_context_.GetByteReadCount()));
134 UMA_HISTOGRAM_COUNTS("Sdch3.PartialVcdiffIn", source_bytes_); 95 UMA_HISTOGRAM_COUNTS("Sdch3.PartialVcdiffIn", source_bytes_);
135 UMA_HISTOGRAM_COUNTS("Sdch3.PartialVcdiffOut", output_bytes_); 96 UMA_HISTOGRAM_COUNTS("Sdch3.PartialVcdiffOut", output_bytes_);
136 } 97 }
137 } 98 }
138 99
139 if (!dest_buffer_excess_.empty()) { 100 if (!dest_buffer_excess_.empty()) {
140 // Filter chaining error, or premature teardown. 101 // Filter chaining error, or premature teardown.
141 LogSdchProblem(SDCH_UNFLUSHED_CONTENT); 102 SdchManager::SdchErrorRecovery(SdchManager::UNFLUSHED_CONTENT);
142 UMA_HISTOGRAM_COUNTS("Sdch3.UnflushedBytesIn", 103 UMA_HISTOGRAM_COUNTS("Sdch3.UnflushedBytesIn",
143 static_cast<int>(filter_context_.GetByteReadCount())); 104 static_cast<int>(filter_context_.GetByteReadCount()));
144 UMA_HISTOGRAM_COUNTS("Sdch3.UnflushedBufferSize", 105 UMA_HISTOGRAM_COUNTS("Sdch3.UnflushedBufferSize",
145 dest_buffer_excess_.size()); 106 dest_buffer_excess_.size());
146 UMA_HISTOGRAM_COUNTS("Sdch3.UnflushedVcdiffIn", source_bytes_); 107 UMA_HISTOGRAM_COUNTS("Sdch3.UnflushedVcdiffIn", source_bytes_);
147 UMA_HISTOGRAM_COUNTS("Sdch3.UnflushedVcdiffOut", output_bytes_); 108 UMA_HISTOGRAM_COUNTS("Sdch3.UnflushedVcdiffOut", output_bytes_);
148 } 109 }
149 110
150 if (filter_context_.IsCachedContent()) { 111 if (filter_context_.IsCachedContent()) {
151 // Not a real error, but it is useful to have this tally. 112 // Not a real error, but it is useful to have this tally.
152 // TODO(jar): Remove this stat after SDCH stability is validated. 113 // TODO(jar): Remove this stat after SDCH stability is validated.
153 LogSdchProblem(SDCH_CACHE_DECODED); 114 SdchManager::SdchErrorRecovery(SdchManager::CACHE_DECODED);
154 return; // We don't need timing stats, and we aready got ratios. 115 return; // We don't need timing stats, and we aready got ratios.
155 } 116 }
156 117
157 switch (decoding_status_) { 118 switch (decoding_status_) {
158 case DECODING_IN_PROGRESS: { 119 case DECODING_IN_PROGRESS: {
159 if (output_bytes_) 120 if (output_bytes_)
160 UMA_HISTOGRAM_PERCENTAGE("Sdch3.Network_Decode_Ratio_a", 121 UMA_HISTOGRAM_PERCENTAGE("Sdch3.Network_Decode_Ratio_a",
161 static_cast<int>( 122 static_cast<int>(
162 (filter_context_.GetByteReadCount() * 100) / output_bytes_)); 123 (filter_context_.GetByteReadCount() * 100) / output_bytes_));
163 UMA_HISTOGRAM_COUNTS("Sdch3.Network_Decode_Bytes_VcdiffOut_a", 124 UMA_HISTOGRAM_COUNTS("Sdch3.Network_Decode_Bytes_VcdiffOut_a",
164 output_bytes_); 125 output_bytes_);
165 filter_context_.RecordPacketStats(FilterContext::SDCH_DECODE); 126 filter_context_.RecordPacketStats(FilterContext::SDCH_DECODE);
166 127
167 // Allow latency experiments to proceed. 128 // Allow latency experiments to proceed.
168 url_request_context_->sdch_manager()->SetAllowLatencyExperiment( 129 url_request_context_->sdch_manager()->SetAllowLatencyExperiment(
169 url_, true); 130 url_, true);
170 return; 131 return;
171 } 132 }
172 case PASS_THROUGH: { 133 case PASS_THROUGH: {
173 filter_context_.RecordPacketStats(FilterContext::SDCH_PASSTHROUGH); 134 filter_context_.RecordPacketStats(FilterContext::SDCH_PASSTHROUGH);
174 return; 135 return;
175 } 136 }
176 case DECODING_UNINITIALIZED: { 137 case DECODING_UNINITIALIZED: {
177 LogSdchProblem(SDCH_UNINITIALIZED); 138 SdchManager::SdchErrorRecovery(SdchManager::UNINITIALIZED);
178 return; 139 return;
179 } 140 }
180 case WAITING_FOR_DICTIONARY_SELECTION: { 141 case WAITING_FOR_DICTIONARY_SELECTION: {
181 LogSdchProblem(SDCH_PRIOR_TO_DICTIONARY); 142 SdchManager::SdchErrorRecovery(SdchManager::PRIOR_TO_DICTIONARY);
182 return; 143 return;
183 } 144 }
184 case DECODING_ERROR: { 145 case DECODING_ERROR: {
185 LogSdchProblem(SDCH_DECODE_ERROR); 146 SdchManager::SdchErrorRecovery(SdchManager::DECODE_ERROR);
186 return; 147 return;
187 } 148 }
188 case META_REFRESH_RECOVERY: { 149 case META_REFRESH_RECOVERY: {
189 // Already accounted for when set. 150 // Already accounted for when set.
190 return; 151 return;
191 } 152 }
192 } // end of switch. 153 } // end of switch.
193 } 154 }
194 155
195 bool SdchFilter::InitDecoding(Filter::FilterType filter_type) { 156 bool SdchFilter::InitDecoding(Filter::FilterType filter_type) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 // advertisement (so that we are sure we're not hurting anything). 203 // advertisement (so that we are sure we're not hurting anything).
243 // 204 //
244 // Watch out for an error page inserted by the proxy as part of a 40x 205 // Watch out for an error page inserted by the proxy as part of a 40x
245 // error response. When we see such content molestation, we certainly 206 // error response. When we see such content molestation, we certainly
246 // need to fall into the meta-refresh case. 207 // need to fall into the meta-refresh case.
247 ResponseCorruptionDetectionCause cause = RESPONSE_NONE; 208 ResponseCorruptionDetectionCause cause = RESPONSE_NONE;
248 if (filter_context_.GetResponseCode() == 404) { 209 if (filter_context_.GetResponseCode() == 404) {
249 // We could be more generous, but for now, only a "NOT FOUND" code will 210 // We could be more generous, but for now, only a "NOT FOUND" code will
250 // cause a pass through. All other bad codes will fall into a 211 // cause a pass through. All other bad codes will fall into a
251 // meta-refresh. 212 // meta-refresh.
252 LogSdchProblem(SDCH_PASS_THROUGH_404_CODE); 213 SdchManager::SdchErrorRecovery(SdchManager::PASS_THROUGH_404_CODE);
253 cause = RESPONSE_404; 214 cause = RESPONSE_404;
254 decoding_status_ = PASS_THROUGH; 215 decoding_status_ = PASS_THROUGH;
255 } else if (filter_context_.GetResponseCode() != 200) { 216 } else if (filter_context_.GetResponseCode() != 200) {
256 // We need to meta-refresh, with SDCH disabled. 217 // We need to meta-refresh, with SDCH disabled.
257 cause = RESPONSE_NOT_200; 218 cause = RESPONSE_NOT_200;
258 } else if (filter_context_.IsCachedContent() 219 } else if (filter_context_.IsCachedContent()
259 && !dictionary_hash_is_plausible_) { 220 && !dictionary_hash_is_plausible_) {
260 // We must have hit the back button, and gotten content that was fetched 221 // We must have hit the back button, and gotten content that was fetched
261 // before we *really* advertised SDCH and a dictionary. 222 // before we *really* advertised SDCH and a dictionary.
262 LogSdchProblem(SDCH_PASS_THROUGH_OLD_CACHED); 223 SdchManager::SdchErrorRecovery(SdchManager::PASS_THROUGH_OLD_CACHED);
263 decoding_status_ = PASS_THROUGH; 224 decoding_status_ = PASS_THROUGH;
264 cause = RESPONSE_OLD_UNENCODED; 225 cause = RESPONSE_OLD_UNENCODED;
265 } else if (possible_pass_through_) { 226 } else if (possible_pass_through_) {
266 // This is the potentially most graceful response. There really was no 227 // This is the potentially most graceful response. There really was no
267 // error. We were just overly cautious when we added a TENTATIVE_SDCH. 228 // error. We were just overly cautious when we added a TENTATIVE_SDCH.
268 // We added the sdch coding tag, and it should not have been added. 229 // We added the sdch coding tag, and it should not have been added.
269 // This can happen in server experiments, where the server decides 230 // This can happen in server experiments, where the server decides
270 // not to use sdch, even though there is a dictionary. To be 231 // not to use sdch, even though there is a dictionary. To be
271 // conservative, we locally added the tentative sdch (fearing that a 232 // conservative, we locally added the tentative sdch (fearing that a
272 // proxy stripped it!) and we must now recant (pass through). 233 // proxy stripped it!) and we must now recant (pass through).
(...skipping 15 matching lines...) Expand all
288 // 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.
289 // This will also progressively disable SDCH for this domain. 250 // This will also progressively disable SDCH for this domain.
290 cause = RESPONSE_CORRUPT_SDCH; 251 cause = RESPONSE_CORRUPT_SDCH;
291 } else { 252 } else {
292 // One of the first 9 bytes precluded consideration as a hash. 253 // One of the first 9 bytes precluded consideration as a hash.
293 // 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.
294 // 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
295 // though it is not! 256 // though it is not!
296 // 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!!
297 // Worse yet, meta-refresh could lead to an infinite refresh loop. 258 // Worse yet, meta-refresh could lead to an infinite refresh loop.
298 LogSdchProblem(SDCH_PASSING_THROUGH_NON_SDCH); 259 SdchManager::SdchErrorRecovery(SdchManager::PASSING_THROUGH_NON_SDCH);
299 decoding_status_ = PASS_THROUGH; 260 decoding_status_ = PASS_THROUGH;
300 // ... but further back-off on advertising SDCH support. 261 // ... but further back-off on advertising SDCH support.
301 url_request_context_->sdch_manager()->BlacklistDomain( 262 url_request_context_->sdch_manager()->BlacklistDomain(
302 url_, SDCH_PASSING_THROUGH_NON_SDCH); 263 url_, SdchManager::PASSING_THROUGH_NON_SDCH);
303 cause = RESPONSE_ENCODING_LIE; 264 cause = RESPONSE_ENCODING_LIE;
304 } 265 }
305 DCHECK_NE(RESPONSE_NONE, cause); 266 DCHECK_NE(RESPONSE_NONE, cause);
306 267
307 // Use if statement rather than ?: because UMA_HISTOGRAM_ENUMERATION 268 // Use if statement rather than ?: because UMA_HISTOGRAM_ENUMERATION
308 // caches the histogram name based on the call site. 269 // caches the histogram name based on the call site.
309 if (filter_context_.IsCachedContent()) { 270 if (filter_context_.IsCachedContent()) {
310 UMA_HISTOGRAM_ENUMERATION( 271 UMA_HISTOGRAM_ENUMERATION(
311 "Sdch3.ResponseCorruptionDetection.Cached", cause, RESPONSE_MAX); 272 "Sdch3.ResponseCorruptionDetection.Cached", cause, RESPONSE_MAX);
312 } else { 273 } else {
313 UMA_HISTOGRAM_ENUMERATION( 274 UMA_HISTOGRAM_ENUMERATION(
314 "Sdch3.ResponseCorruptionDetection.Uncached", cause, RESPONSE_MAX); 275 "Sdch3.ResponseCorruptionDetection.Uncached", cause, RESPONSE_MAX);
315 } 276 }
316 filter_context_.GetNetLog().AddEvent(
317 NetLog::TYPE_SDCH_RESPONSE_CORRUPTION_DETECTION,
318 base::Bind(&NetLogSdchResponseCorruptionDetectionCallback,
319 cause,
320 filter_context_.IsCachedContent()));
321 277
322 if (decoding_status_ == PASS_THROUGH) { 278 if (decoding_status_ == PASS_THROUGH) {
323 dest_buffer_excess_ = dictionary_hash_; // Send what we scanned. 279 dest_buffer_excess_ = dictionary_hash_; // Send what we scanned.
324 } else { 280 } else {
325 // This is where we try to do the expensive meta-refresh. 281 // This is where we try to do the expensive meta-refresh.
326 if (std::string::npos == mime_type_.find("text/html")) { 282 if (std::string::npos == mime_type_.find("text/html")) {
327 // Since we can't do a meta-refresh (along with an exponential 283 // Since we can't do a meta-refresh (along with an exponential
328 // backoff), we'll just make sure this NEVER happens again. 284 // backoff), we'll just make sure this NEVER happens again.
329 SdchProblemCode problem = (filter_context_.IsCachedContent() 285 SdchManager::ProblemCodes problem =
330 ? SDCH_CACHED_META_REFRESH_UNSUPPORTED 286 (filter_context_.IsCachedContent() ?
331 : SDCH_META_REFRESH_UNSUPPORTED); 287 SdchManager::CACHED_META_REFRESH_UNSUPPORTED :
288 SdchManager::META_REFRESH_UNSUPPORTED);
332 url_request_context_->sdch_manager()->BlacklistDomainForever( 289 url_request_context_->sdch_manager()->BlacklistDomainForever(
333 url_, problem); 290 url_, problem);
334 LogSdchProblem(problem); 291 SdchManager::SdchErrorRecovery(problem);
335 return FILTER_ERROR; 292 return FILTER_ERROR;
336 } 293 }
337 // HTML content means we can issue a meta-refresh, and get the content 294 // HTML content means we can issue a meta-refresh, and get the content
338 // again, perhaps without SDCH (to be safe). 295 // again, perhaps without SDCH (to be safe).
339 if (filter_context_.IsCachedContent()) { 296 if (filter_context_.IsCachedContent()) {
340 // Cached content is probably a startup tab, so we'll just get fresh 297 // Cached content is probably a startup tab, so we'll just get fresh
341 // content and try again, without disabling sdch. 298 // content and try again, without disabling sdch.
342 LogSdchProblem(SDCH_META_REFRESH_CACHED_RECOVERY); 299 SdchManager::SdchErrorRecovery(
300 SdchManager::META_REFRESH_CACHED_RECOVERY);
343 } else { 301 } else {
344 // Since it wasn't in the cache, we definately need at least some 302 // Since it wasn't in the cache, we definately need at least some
345 // period of blacklisting to get the correct content. 303 // period of blacklisting to get the correct content.
346 url_request_context_->sdch_manager()->BlacklistDomain( 304 url_request_context_->sdch_manager()->BlacklistDomain(
347 url_, SDCH_META_REFRESH_RECOVERY); 305 url_, SdchManager::META_REFRESH_RECOVERY);
348 LogSdchProblem(SDCH_META_REFRESH_RECOVERY); 306 SdchManager::SdchErrorRecovery(SdchManager::META_REFRESH_RECOVERY);
349 } 307 }
350 decoding_status_ = META_REFRESH_RECOVERY; 308 decoding_status_ = META_REFRESH_RECOVERY;
351 // Issue a meta redirect with SDCH disabled. 309 // Issue a meta redirect with SDCH disabled.
352 dest_buffer_excess_ = kDecompressionErrorHtml; 310 dest_buffer_excess_ = kDecompressionErrorHtml;
353 } 311 }
354 } else { 312 } else {
355 DCHECK_EQ(DECODING_IN_PROGRESS, decoding_status_); 313 DCHECK_EQ(DECODING_IN_PROGRESS, decoding_status_);
356 } 314 }
357 } 315 }
358 316
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 bool ret = vcdiff_streaming_decoder_->DecodeChunk( 350 bool ret = vcdiff_streaming_decoder_->DecodeChunk(
393 next_stream_data_, stream_data_len_, &dest_buffer_excess_); 351 next_stream_data_, stream_data_len_, &dest_buffer_excess_);
394 // Assume all data was used in decoding. 352 // Assume all data was used in decoding.
395 next_stream_data_ = NULL; 353 next_stream_data_ = NULL;
396 source_bytes_ += stream_data_len_; 354 source_bytes_ += stream_data_len_;
397 stream_data_len_ = 0; 355 stream_data_len_ = 0;
398 output_bytes_ += dest_buffer_excess_.size(); 356 output_bytes_ += dest_buffer_excess_.size();
399 if (!ret) { 357 if (!ret) {
400 vcdiff_streaming_decoder_.reset(NULL); // Don't call it again. 358 vcdiff_streaming_decoder_.reset(NULL); // Don't call it again.
401 decoding_status_ = DECODING_ERROR; 359 decoding_status_ = DECODING_ERROR;
402 LogSdchProblem(SDCH_DECODE_BODY_ERROR); 360 SdchManager::SdchErrorRecovery(SdchManager::DECODE_BODY_ERROR);
403 return FILTER_ERROR; 361 return FILTER_ERROR;
404 } 362 }
405 363
406 amount = OutputBufferExcess(dest_buffer, available_space); 364 amount = OutputBufferExcess(dest_buffer, available_space);
407 *dest_len += amount; 365 *dest_len += amount;
408 dest_buffer += amount; 366 dest_buffer += amount;
409 available_space -= amount; 367 available_space -= amount;
410 if (0 == available_space && !dest_buffer_excess_.empty()) 368 if (0 == available_space && !dest_buffer_excess_.empty())
411 return FILTER_OK; 369 return FILTER_OK;
412 return FILTER_NEED_MORE_DATA; 370 return FILTER_NEED_MORE_DATA;
(...skipping 16 matching lines...) Expand all
429 stream_data_len_ -= bytes_needed; 387 stream_data_len_ -= bytes_needed;
430 DCHECK_LE(0, stream_data_len_); 388 DCHECK_LE(0, stream_data_len_);
431 if (stream_data_len_ > 0) 389 if (stream_data_len_ > 0)
432 next_stream_data_ += bytes_needed; 390 next_stream_data_ += bytes_needed;
433 else 391 else
434 next_stream_data_ = NULL; 392 next_stream_data_ = NULL;
435 393
436 DCHECK(!dictionary_.get()); 394 DCHECK(!dictionary_.get());
437 dictionary_hash_is_plausible_ = true; // Assume plausible, but check. 395 dictionary_hash_is_plausible_ = true; // Assume plausible, but check.
438 396
439 SdchProblemCode rv = SDCH_OK;
440 if ('\0' == dictionary_hash_[kServerIdLength - 1]) { 397 if ('\0' == dictionary_hash_[kServerIdLength - 1]) {
441 SdchManager* manager(url_request_context_->sdch_manager()); 398 SdchManager* manager(url_request_context_->sdch_manager());
442 rv = manager->GetVcdiffDictionary( 399 manager->GetVcdiffDictionary(
443 std::string(dictionary_hash_, 0, kServerIdLength - 1), 400 std::string(dictionary_hash_, 0, kServerIdLength - 1),
444 url_, 401 url_, &dictionary_);
445 &dictionary_); 402 } else {
446 if (rv == SDCH_DICTIONARY_HASH_NOT_FOUND) { 403 dictionary_hash_is_plausible_ = false;
447 DCHECK(dictionary_hash_.size() == kServerIdLength); 404 }
448 // Since dictionary was not found, check to see if hash was even 405
449 // plausible. 406 if (!dictionary_.get()) {
450 for (size_t i = 0; i < kServerIdLength - 1; ++i) { 407 DCHECK(dictionary_hash_.size() == kServerIdLength);
451 char base64_char = dictionary_hash_[i]; 408 // Since dictionary was not found, check to see if hash was even plausible.
452 if (!isalnum(base64_char) && '-' != base64_char && 409 for (size_t i = 0; i < kServerIdLength - 1; ++i) {
453 '_' != base64_char) { 410 char base64_char = dictionary_hash_[i];
454 rv = SDCH_DICTIONARY_HASH_MALFORMED; 411 if (!isalnum(base64_char) && '-' != base64_char && '_' != base64_char) {
455 dictionary_hash_is_plausible_ = false; 412 dictionary_hash_is_plausible_ = false;
456 break; 413 break;
457 }
458 } 414 }
459 } 415 }
460 } else { 416 if (dictionary_hash_is_plausible_)
461 dictionary_hash_is_plausible_ = false; 417 SdchManager::SdchErrorRecovery(SdchManager::DICTIONARY_HASH_NOT_FOUND);
462 rv = SDCH_DICTIONARY_HASH_MALFORMED; 418 else
463 } 419 SdchManager::SdchErrorRecovery(SdchManager::DICTIONARY_HASH_MALFORMED);
464 if (rv != SDCH_OK) {
465 LogSdchProblem(rv);
466 decoding_status_ = DECODING_ERROR; 420 decoding_status_ = DECODING_ERROR;
467 return FILTER_ERROR; 421 return FILTER_ERROR;
468 } 422 }
469 DCHECK(dictionary_.get());
470 vcdiff_streaming_decoder_.reset(new open_vcdiff::VCDiffStreamingDecoder); 423 vcdiff_streaming_decoder_.reset(new open_vcdiff::VCDiffStreamingDecoder);
471 vcdiff_streaming_decoder_->SetAllowVcdTarget(false); 424 vcdiff_streaming_decoder_->SetAllowVcdTarget(false);
472 vcdiff_streaming_decoder_->StartDecoding(dictionary_->text().data(), 425 vcdiff_streaming_decoder_->StartDecoding(dictionary_->text().data(),
473 dictionary_->text().size()); 426 dictionary_->text().size());
474 decoding_status_ = DECODING_IN_PROGRESS; 427 decoding_status_ = DECODING_IN_PROGRESS;
475 return FILTER_OK; 428 return FILTER_OK;
476 } 429 }
477 430
478 int SdchFilter::OutputBufferExcess(char* const dest_buffer, 431 int SdchFilter::OutputBufferExcess(char* const dest_buffer,
479 size_t available_space) { 432 size_t available_space) {
480 if (dest_buffer_excess_.empty()) 433 if (dest_buffer_excess_.empty())
481 return 0; 434 return 0;
482 DCHECK(dest_buffer_excess_.size() > dest_buffer_excess_index_); 435 DCHECK(dest_buffer_excess_.size() > dest_buffer_excess_index_);
483 size_t amount = std::min(available_space, 436 size_t amount = std::min(available_space,
484 dest_buffer_excess_.size() - dest_buffer_excess_index_); 437 dest_buffer_excess_.size() - dest_buffer_excess_index_);
485 memcpy(dest_buffer, dest_buffer_excess_.data() + dest_buffer_excess_index_, 438 memcpy(dest_buffer, dest_buffer_excess_.data() + dest_buffer_excess_index_,
486 amount); 439 amount);
487 dest_buffer_excess_index_ += amount; 440 dest_buffer_excess_index_ += amount;
488 if (dest_buffer_excess_.size() <= dest_buffer_excess_index_) { 441 if (dest_buffer_excess_.size() <= dest_buffer_excess_index_) {
489 DCHECK(dest_buffer_excess_.size() == dest_buffer_excess_index_); 442 DCHECK(dest_buffer_excess_.size() == dest_buffer_excess_index_);
490 dest_buffer_excess_.clear(); 443 dest_buffer_excess_.clear();
491 dest_buffer_excess_index_ = 0; 444 dest_buffer_excess_index_ = 0;
492 } 445 }
493 return amount; 446 return amount;
494 } 447 }
495 448
496 void SdchFilter::LogSdchProblem(SdchProblemCode problem) {
497 SdchManager::SdchErrorRecovery(problem);
498 filter_context_.GetNetLog().AddEvent(
499 NetLog::TYPE_SDCH_DECODING_ERROR,
500 base::Bind(&NetLogSdchResourceProblemCallback, problem));
501 }
502
503 } // namespace net 449 } // namespace net
OLDNEW
« no previous file with comments | « net/filter/sdch_filter.h ('k') | net/filter/sdch_filter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698