| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 <limits.h> | 5 #include <limits.h> |
| 6 #include <ctype.h> | 6 #include <ctype.h> |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/histogram.h" | 10 #include "base/histogram.h" |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 UpdateReadTimes(); | 220 UpdateReadTimes(); |
| 221 | 221 |
| 222 if (WAITING_FOR_DICTIONARY_SELECTION == decoding_status_) { | 222 if (WAITING_FOR_DICTIONARY_SELECTION == decoding_status_) { |
| 223 FilterStatus status = InitializeDictionary(); | 223 FilterStatus status = InitializeDictionary(); |
| 224 if (FILTER_NEED_MORE_DATA == status) | 224 if (FILTER_NEED_MORE_DATA == status) |
| 225 return FILTER_NEED_MORE_DATA; | 225 return FILTER_NEED_MORE_DATA; |
| 226 if (FILTER_ERROR == status) { | 226 if (FILTER_ERROR == status) { |
| 227 DCHECK(DECODING_ERROR == decoding_status_); | 227 DCHECK(DECODING_ERROR == decoding_status_); |
| 228 DCHECK(0 == dest_buffer_excess_index_); | 228 DCHECK(0 == dest_buffer_excess_index_); |
| 229 DCHECK(dest_buffer_excess_.empty()); | 229 DCHECK(dest_buffer_excess_.empty()); |
| 230 if (possible_pass_through_) { | 230 // This is where we try very hard to do error recovery, and make this |
| 231 // protocol robust in teh face of proxies that do many different things. |
| 232 // If we decide that things are looking very bad (too hard to recover), |
| 233 // we may even issue a "meta-refresh" to reload the page without an SDCH |
| 234 // advertisement (so that we are sure we're not hurting anything). First |
| 235 // we try for some light weight recovery, and teh final else clause below |
| 236 // supports the last ditch meta-refresh approach. |
| 237 // |
| 238 // Watch out for an error page inserted by the proxy as part of a 40x |
| 239 // error response. When we see such content molestation, we certainly |
| 240 // need to fall into the meta-refresh case. |
| 241 bool successful_response = filter_context().GetResponseCode() == 200; |
| 242 if (possible_pass_through_ && successful_response) { |
| 243 // This is the most graceful response. There really was no error. We |
| 244 // were just overly cautious. |
| 231 // We added the sdch coding tag, and it should not have been added. | 245 // We added the sdch coding tag, and it should not have been added. |
| 232 // This can happen in server experiments, where the server decides | 246 // This can happen in server experiments, where the server decides |
| 233 // not to use sdch, even though there is a dictionary. To be | 247 // not to use sdch, even though there is a dictionary. To be |
| 234 // conservative, we locally added the tentative sdch (fearing that a | 248 // conservative, we locally added the tentative sdch (fearing that a |
| 235 // proxy stripped it!) and we must now recant (pass through). | 249 // proxy stripped it!) and we must now recant (pass through). |
| 236 SdchManager::SdchErrorRecovery(SdchManager::DISCARD_TENTATIVE_SDCH); | 250 SdchManager::SdchErrorRecovery(SdchManager::DISCARD_TENTATIVE_SDCH); |
| 237 decoding_status_ = PASS_THROUGH; | 251 decoding_status_ = PASS_THROUGH; |
| 238 dest_buffer_excess_ = dictionary_hash_; // Send what we scanned. | 252 dest_buffer_excess_ = dictionary_hash_; // Send what we scanned. |
| 239 } else if (!dictionary_hash_is_plausible_) { | 253 } else if (successful_response && !dictionary_hash_is_plausible_) { |
| 240 // One of the first 9 bytes precluded consideration as a hash. | 254 // One of the first 9 bytes precluded consideration as a hash. |
| 241 // This can't be an SDCH payload, even though the server said it was. | 255 // This can't be an SDCH payload, even though the server said it was. |
| 242 // This is a major error, as the server or proxy tagged this SDCH even | 256 // This is a major error, as the server or proxy tagged this SDCH even |
| 243 // though it is not! | 257 // though it is not! |
| 244 // The good news is that error recovery is clear... | 258 // The good news is that error recovery is clear... |
| 245 SdchManager::SdchErrorRecovery(SdchManager::PASSING_THROUGH_NON_SDCH); | 259 SdchManager::SdchErrorRecovery(SdchManager::PASSING_THROUGH_NON_SDCH); |
| 246 decoding_status_ = PASS_THROUGH; | 260 decoding_status_ = PASS_THROUGH; |
| 247 dest_buffer_excess_ = dictionary_hash_; // Send what we scanned. | 261 dest_buffer_excess_ = dictionary_hash_; // Send what we scanned. |
| 248 } else { | 262 } else { |
| 249 // We don't have the dictionary that was demanded. | 263 // This is where we try to do the expensive meta-refresh. |
| 264 // Either this was an error response (probably an error page inserted |
| 265 // by a proxy, as in bug 8916) or else we don't have the dictionary that |
| 266 // was demanded. |
| 250 // With very low probability, random garbage data looked like a | 267 // With very low probability, random garbage data looked like a |
| 251 // dictionary specifier (8 ASCII characters followed by a null), but | 268 // dictionary specifier (8 ASCII characters followed by a null), but |
| 252 // that is sufficiently unlikely that we ignore it. | 269 // that is sufficiently unlikely that we ignore it. |
| 253 if (std::string::npos == mime_type_.find_first_of("text/html")) { | 270 if (std::string::npos == mime_type_.find("text/html")) { |
| 271 // Since we can't do a meta-refresh (along with an exponential |
| 272 // backoff), we'll just make sure this NEVER happens again. |
| 254 SdchManager::BlacklistDomainForever(url_); | 273 SdchManager::BlacklistDomainForever(url_); |
| 255 if (was_cached_) | 274 if (was_cached_) |
| 256 SdchManager::SdchErrorRecovery( | 275 SdchManager::SdchErrorRecovery( |
| 257 SdchManager::CACHED_META_REFRESH_UNSUPPORTED); | 276 SdchManager::CACHED_META_REFRESH_UNSUPPORTED); |
| 258 else | 277 else |
| 259 SdchManager::SdchErrorRecovery( | 278 SdchManager::SdchErrorRecovery( |
| 260 SdchManager::META_REFRESH_UNSUPPORTED); | 279 SdchManager::META_REFRESH_UNSUPPORTED); |
| 261 return FILTER_ERROR; | 280 return FILTER_ERROR; |
| 262 } | 281 } |
| 263 // HTML content means we can issue a meta-refresh, and get the content | 282 // HTML content means we can issue a meta-refresh, and get the content |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 memcpy(dest_buffer, dest_buffer_excess_.data() + dest_buffer_excess_index_, | 424 memcpy(dest_buffer, dest_buffer_excess_.data() + dest_buffer_excess_index_, |
| 406 amount); | 425 amount); |
| 407 dest_buffer_excess_index_ += amount; | 426 dest_buffer_excess_index_ += amount; |
| 408 if (dest_buffer_excess_.size() <= dest_buffer_excess_index_) { | 427 if (dest_buffer_excess_.size() <= dest_buffer_excess_index_) { |
| 409 DCHECK(dest_buffer_excess_.size() == dest_buffer_excess_index_); | 428 DCHECK(dest_buffer_excess_.size() == dest_buffer_excess_index_); |
| 410 dest_buffer_excess_.clear(); | 429 dest_buffer_excess_.clear(); |
| 411 dest_buffer_excess_index_ = 0; | 430 dest_buffer_excess_index_ = 0; |
| 412 } | 431 } |
| 413 return amount; | 432 return amount; |
| 414 } | 433 } |
| OLD | NEW |