| 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 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 | 145 |
| 146 if (WAITING_FOR_DICTIONARY_SELECTION == decoding_status_) { | 146 if (WAITING_FOR_DICTIONARY_SELECTION == decoding_status_) { |
| 147 FilterStatus status = InitializeDictionary(); | 147 FilterStatus status = InitializeDictionary(); |
| 148 if (FILTER_NEED_MORE_DATA == status) | 148 if (FILTER_NEED_MORE_DATA == status) |
| 149 return FILTER_NEED_MORE_DATA; | 149 return FILTER_NEED_MORE_DATA; |
| 150 if (FILTER_ERROR == status) { | 150 if (FILTER_ERROR == status) { |
| 151 DCHECK(DECODING_ERROR == decoding_status_); | 151 DCHECK(DECODING_ERROR == decoding_status_); |
| 152 DCHECK_EQ(0u, dest_buffer_excess_index_); | 152 DCHECK_EQ(0u, dest_buffer_excess_index_); |
| 153 DCHECK(dest_buffer_excess_.empty()); | 153 DCHECK(dest_buffer_excess_.empty()); |
| 154 // This is where we try very hard to do error recovery, and make this | 154 // This is where we try very hard to do error recovery, and make this |
| 155 // protocol robust in teh face of proxies that do many different things. | 155 // protocol robust in the face of proxies that do many different things. |
| 156 // If we decide that things are looking very bad (too hard to recover), | 156 // If we decide that things are looking very bad (too hard to recover), |
| 157 // we may even issue a "meta-refresh" to reload the page without an SDCH | 157 // we may even issue a "meta-refresh" to reload the page without an SDCH |
| 158 // advertisement (so that we are sure we're not hurting anything). First | 158 // advertisement (so that we are sure we're not hurting anything). |
| 159 // we try for some light weight recovery, and teh final else clause below | |
| 160 // supports the last ditch meta-refresh approach. | |
| 161 // | 159 // |
| 162 // Watch out for an error page inserted by the proxy as part of a 40x | 160 // Watch out for an error page inserted by the proxy as part of a 40x |
| 163 // error response. When we see such content molestation, we certainly | 161 // error response. When we see such content molestation, we certainly |
| 164 // need to fall into the meta-refresh case. | 162 // need to fall into the meta-refresh case. |
| 165 bool successful_response = filter_context().GetResponseCode() == 200; | 163 bool successful_response = filter_context().GetResponseCode() == 200; |
| 166 if (possible_pass_through_ && successful_response) { | 164 if (filter_context().GetResponseCode() == 404) { |
| 167 // This is the most graceful response. There really was no error. We | 165 // We could be more generous, but for now, only a "NOT FOUND" code will |
| 168 // were just overly cautious. | 166 // cause a pass through. All other codes will fall into a meta-refresh |
| 167 // attempt. |
| 168 SdchManager::SdchErrorRecovery(SdchManager::PASS_THROUGH_404_CODE); |
| 169 decoding_status_ = PASS_THROUGH; |
| 170 } else if (possible_pass_through_ && successful_response) { |
| 171 // This is the potentially most graceful response. There really was no |
| 172 // error. We were just overly cautious when we added a TENTATIVE_SDCH. |
| 169 // We added the sdch coding tag, and it should not have been added. | 173 // We added the sdch coding tag, and it should not have been added. |
| 170 // This can happen in server experiments, where the server decides | 174 // This can happen in server experiments, where the server decides |
| 171 // not to use sdch, even though there is a dictionary. To be | 175 // not to use sdch, even though there is a dictionary. To be |
| 172 // conservative, we locally added the tentative sdch (fearing that a | 176 // conservative, we locally added the tentative sdch (fearing that a |
| 173 // proxy stripped it!) and we must now recant (pass through). | 177 // proxy stripped it!) and we must now recant (pass through). |
| 174 SdchManager::SdchErrorRecovery(SdchManager::DISCARD_TENTATIVE_SDCH); | 178 SdchManager::SdchErrorRecovery(SdchManager::DISCARD_TENTATIVE_SDCH); |
| 175 decoding_status_ = PASS_THROUGH; | 179 // However.... just to be sure we don't get burned by proxies that |
| 176 dest_buffer_excess_ = dictionary_hash_; // Send what we scanned. | 180 // re-compress with gzip or other system, we can sniff to see if this |
| 181 // is compressed data etc. For now, we do nothing, which gets us into |
| 182 // the meta-refresh result. |
| 183 // TODO(jar): Improve robustness by sniffing for valid text that we can |
| 184 // actual use re: decoding_status_ = PASS_THROUGH; |
| 177 } else if (successful_response && !dictionary_hash_is_plausible_) { | 185 } else if (successful_response && !dictionary_hash_is_plausible_) { |
| 178 // One of the first 9 bytes precluded consideration as a hash. | 186 // One of the first 9 bytes precluded consideration as a hash. |
| 179 // This can't be an SDCH payload, even though the server said it was. | 187 // This can't be an SDCH payload, even though the server said it was. |
| 180 // This is a major error, as the server or proxy tagged this SDCH even | 188 // This is a major error, as the server or proxy tagged this SDCH even |
| 181 // though it is not! | 189 // though it is not! |
| 182 // The good news is that error recovery is clear... | |
| 183 SdchManager::SdchErrorRecovery(SdchManager::PASSING_THROUGH_NON_SDCH); | 190 SdchManager::SdchErrorRecovery(SdchManager::PASSING_THROUGH_NON_SDCH); |
| 191 // Meta-refresh won't help... we didn't advertise an SDCH dictionary!! |
| 184 decoding_status_ = PASS_THROUGH; | 192 decoding_status_ = PASS_THROUGH; |
| 193 } |
| 194 |
| 195 if (decoding_status_ == PASS_THROUGH) { |
| 185 dest_buffer_excess_ = dictionary_hash_; // Send what we scanned. | 196 dest_buffer_excess_ = dictionary_hash_; // Send what we scanned. |
| 186 } else { | 197 } else { |
| 187 // This is where we try to do the expensive meta-refresh. | 198 // This is where we try to do the expensive meta-refresh. |
| 188 // Either this was an error response (probably an error page inserted | |
| 189 // by a proxy, as in bug 8916) or else we don't have the dictionary that | |
| 190 // was demanded. | |
| 191 // With very low probability, random garbage data looked like a | |
| 192 // dictionary specifier (8 ASCII characters followed by a null), but | |
| 193 // that is sufficiently unlikely that we ignore it. | |
| 194 if (std::string::npos == mime_type_.find("text/html")) { | 199 if (std::string::npos == mime_type_.find("text/html")) { |
| 195 // Since we can't do a meta-refresh (along with an exponential | 200 // Since we can't do a meta-refresh (along with an exponential |
| 196 // backoff), we'll just make sure this NEVER happens again. | 201 // backoff), we'll just make sure this NEVER happens again. |
| 197 SdchManager::BlacklistDomainForever(url_); | 202 SdchManager::BlacklistDomainForever(url_); |
| 198 if (filter_context().IsCachedContent()) | 203 if (filter_context().IsCachedContent()) |
| 199 SdchManager::SdchErrorRecovery( | 204 SdchManager::SdchErrorRecovery( |
| 200 SdchManager::CACHED_META_REFRESH_UNSUPPORTED); | 205 SdchManager::CACHED_META_REFRESH_UNSUPPORTED); |
| 201 else | 206 else |
| 202 SdchManager::SdchErrorRecovery( | 207 SdchManager::SdchErrorRecovery( |
| 203 SdchManager::META_REFRESH_UNSUPPORTED); | 208 SdchManager::META_REFRESH_UNSUPPORTED); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 memcpy(dest_buffer, dest_buffer_excess_.data() + dest_buffer_excess_index_, | 354 memcpy(dest_buffer, dest_buffer_excess_.data() + dest_buffer_excess_index_, |
| 350 amount); | 355 amount); |
| 351 dest_buffer_excess_index_ += amount; | 356 dest_buffer_excess_index_ += amount; |
| 352 if (dest_buffer_excess_.size() <= dest_buffer_excess_index_) { | 357 if (dest_buffer_excess_.size() <= dest_buffer_excess_index_) { |
| 353 DCHECK(dest_buffer_excess_.size() == dest_buffer_excess_index_); | 358 DCHECK(dest_buffer_excess_.size() == dest_buffer_excess_index_); |
| 354 dest_buffer_excess_.clear(); | 359 dest_buffer_excess_.clear(); |
| 355 dest_buffer_excess_index_ = 0; | 360 dest_buffer_excess_index_ = 0; |
| 356 } | 361 } |
| 357 return amount; | 362 return amount; |
| 358 } | 363 } |
| OLD | NEW |