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

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

Issue 155064: Merge r18936.... (Closed) Base URL: svn://chrome-svn.corp.google.com/chrome/branches/172/src/
Patch Set: Created 11 years, 5 months 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 | « no previous file | net/base/gzip_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 (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 "net/base/filter.h" 5 #include "net/base/filter.h"
6 6
7 #include "base/file_path.h" 7 #include "base/file_path.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "net/base/gzip_filter.h" 9 #include "net/base/gzip_filter.h"
10 #include "net/base/bzip2_filter.h" 10 #include "net/base/bzip2_filter.h"
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 // When viewing a .svgz file, we need to uncompress it, but we don't 109 // When viewing a .svgz file, we need to uncompress it, but we don't
110 // want to do that when downloading. 110 // want to do that when downloading.
111 if (0 == extension.compare(FILE_PATH_LITERAL(".gz")) || 111 if (0 == extension.compare(FILE_PATH_LITERAL(".gz")) ||
112 0 == extension.compare(FILE_PATH_LITERAL(".tgz")) || 112 0 == extension.compare(FILE_PATH_LITERAL(".tgz")) ||
113 (0 == extension.compare(FILE_PATH_LITERAL(".svgz")) && 113 (0 == extension.compare(FILE_PATH_LITERAL(".svgz")) &&
114 filter_context.IsDownload())) { 114 filter_context.IsDownload())) {
115 encoding_types->clear(); 115 encoding_types->clear();
116 } 116 }
117 } 117 }
118 118
119 // If the request was for SDCH content, then we might need additional fixups.
119 if (!filter_context.IsSdchResponse()) { 120 if (!filter_context.IsSdchResponse()) {
121 // It was not an SDCH request, so we'll just record stats.
120 if (1 < encoding_types->size()) { 122 if (1 < encoding_types->size()) {
121 // Multiple filters were intended to only be used for SDCH (thus far!) 123 // Multiple filters were intended to only be used for SDCH (thus far!)
122 SdchManager::SdchErrorRecovery( 124 SdchManager::SdchErrorRecovery(
123 SdchManager::MULTIENCODING_FOR_NON_SDCH_REQUEST); 125 SdchManager::MULTIENCODING_FOR_NON_SDCH_REQUEST);
124 } 126 }
125 if ((1 == encoding_types->size()) && 127 if ((1 == encoding_types->size()) &&
126 (FILTER_TYPE_SDCH == encoding_types->front())) { 128 (FILTER_TYPE_SDCH == encoding_types->front())) {
127 SdchManager::SdchErrorRecovery( 129 SdchManager::SdchErrorRecovery(
128 SdchManager::SDCH_CONTENT_ENCODE_FOR_NON_SDCH_REQUEST); 130 SdchManager::SDCH_CONTENT_ENCODE_FOR_NON_SDCH_REQUEST);
129 } 131 }
130 return; 132 return;
131 } 133 }
132 134
133 // If content encoding included SDCH, then everything is fine. 135 // The request was tagged as an SDCH request, which means the server supplied
136 // a dictionary, and we advertised it in the request. Some proxies will do
137 // very strange things to the request, or the response, so we have to handle
138 // them gracefully.
139
140 // If content encoding included SDCH, then everything is "relatively" fine.
134 if (!encoding_types->empty() && 141 if (!encoding_types->empty() &&
135 (FILTER_TYPE_SDCH == encoding_types->front())) { 142 (FILTER_TYPE_SDCH == encoding_types->front())) {
136 // Some proxies (found currently in Argentina) strip the Content-Encoding 143 // Some proxies (found currently in Argentina) strip the Content-Encoding
137 // text from "sdch,gzip" to a mere "sdch" without modifying the compressed 144 // text from "sdch,gzip" to a mere "sdch" without modifying the compressed
138 // payload. To handle this gracefully, we simulate the "probably" deleted 145 // payload. To handle this gracefully, we simulate the "probably" deleted
139 // ",gzip" by appending a tentative gzip decode, which will default to a 146 // ",gzip" by appending a tentative gzip decode, which will default to a
140 // no-op pass through filter if it doesn't get gzip headers where expected. 147 // no-op pass through filter if it doesn't get gzip headers where expected.
141 if (1 == encoding_types->size()) { 148 if (1 == encoding_types->size()) {
142 encoding_types->push_back(FILTER_TYPE_GZIP_HELPING_SDCH); 149 encoding_types->push_back(FILTER_TYPE_GZIP_HELPING_SDCH);
143 SdchManager::SdchErrorRecovery( 150 SdchManager::SdchErrorRecovery(
144 SdchManager::OPTIONAL_GUNZIP_ENCODING_ADDED); 151 SdchManager::OPTIONAL_GUNZIP_ENCODING_ADDED);
145 } 152 }
146 return; 153 return;
147 } 154 }
148 155
149 // SDCH "search results" protective hack: To make sure we don't break the only 156 // There are now several cases to handle for an SDCH request. Foremost, if
150 // currently deployed SDCH enabled server! Be VERY cautious about proxies that 157 // the outbound request was stripped so as not to advertise support for
151 // strip all content-encoding to not include sdch. IF we don't see content 158 // encodings, we might get back content with no encoding, or (for example)
152 // encodings that seem to match what we'd expect from a server that asked us 159 // just gzip. We have to be sure that any changes we make allow for such
153 // to use a dictionary (and we advertised said dictionary in the GET), then 160 // minimal coding to work. That issue is why we use TENTATIVE filters if we
154 // we set the encoding to (try to) use SDCH to decode. Note that SDCH will 161 // add any, as those filters sniff the content, and act as pass-through
155 // degrade into a pass-through filter if it doesn't have a viable dictionary 162 // filters if headers are not found.
156 // hash in its header. Also note that a solo "sdch" will implicitly create 163
157 // a "sdch,gzip" decoding filter, where the gzip portion will degrade to a 164 // If the outbound GET is not modified, then the server will generally try to
158 // pass through if a gzip header is not encountered. Hence we can replace 165 // send us SDCH encoded content. As that content returns, there are several
159 // "gzip" with "sdch" and "everything will work." 166 // corruptions of the header "content-encoding" that proxies may perform (and
160 // The one failure mode comes when we advertise a dictionary, and the server 167 // have been detected in the wild). We already dealt with the a honest
161 // tries to *send* a gzipped file (not gzip encode content), and then we could 168 // content encoding of "sdch,gzip" being corrupted into "sdch" with on change
162 // do a gzip decode :-(. Since current server support does not ever see such 169 // of the actual content. Another common corruption is to either disscard
163 // a transfer, we are safe (for now). 170 // the accurate content encoding, or to replace it with gzip only (again, with
171 // no change in actual content). The last observed corruption it to actually
172 // change the content, such as by re-gzipping it, and that may happen along
173 // with corruption of the stated content encoding (wow!).
174
175 // The one unresolved failure mode comes when we advertise a dictionary, and
176 // the server tries to *send* a gzipped file (not gzip encode content), and
177 // then we could do a gzip decode :-(. Since SDCH is only (currently)
178 // supported server side on paths that only send HTML content, this mode has
179 // never surfaced in the wild (and is unlikely to).
180 // We will gather a lot of stats as we perform the fixups
164 if (StartsWithASCII(mime_type, kTextHtml, false)) { 181 if (StartsWithASCII(mime_type, kTextHtml, false)) {
165 // Suspicious case: Advertised dictionary, but server didn't use sdch, and 182 // Suspicious case: Advertised dictionary, but server didn't use sdch, and
166 // we're HTML tagged. 183 // we're HTML tagged.
167 if (encoding_types->empty()) { 184 if (encoding_types->empty()) {
168 SdchManager::SdchErrorRecovery(SdchManager::ADDED_CONTENT_ENCODING); 185 SdchManager::SdchErrorRecovery(SdchManager::ADDED_CONTENT_ENCODING);
169 } else if (1 == encoding_types->size()) { 186 } else if (1 == encoding_types->size()) {
170 SdchManager::SdchErrorRecovery(SdchManager::FIXED_CONTENT_ENCODING); 187 SdchManager::SdchErrorRecovery(SdchManager::FIXED_CONTENT_ENCODING);
171 } else { 188 } else {
172 SdchManager::SdchErrorRecovery(SdchManager::FIXED_CONTENT_ENCODINGS); 189 SdchManager::SdchErrorRecovery(SdchManager::FIXED_CONTENT_ENCODINGS);
173 } 190 }
(...skipping 11 matching lines...) Expand all
185 SdchManager::BINARY_ADDED_CONTENT_ENCODING); 202 SdchManager::BINARY_ADDED_CONTENT_ENCODING);
186 } else if (1 == encoding_types->size()) { 203 } else if (1 == encoding_types->size()) {
187 SdchManager::SdchErrorRecovery( 204 SdchManager::SdchErrorRecovery(
188 SdchManager::BINARY_FIXED_CONTENT_ENCODING); 205 SdchManager::BINARY_FIXED_CONTENT_ENCODING);
189 } else { 206 } else {
190 SdchManager::SdchErrorRecovery( 207 SdchManager::SdchErrorRecovery(
191 SdchManager::BINARY_FIXED_CONTENT_ENCODINGS); 208 SdchManager::BINARY_FIXED_CONTENT_ENCODINGS);
192 } 209 }
193 } 210 }
194 211
195 encoding_types->clear(); 212 // Leave the existing encoding type to be processed first, and add our
196 encoding_types->push_back(FILTER_TYPE_SDCH_POSSIBLE); 213 // tentative decodings to be done afterwards. Vodaphone UK reportedyl will
197 encoding_types->push_back(FILTER_TYPE_GZIP_HELPING_SDCH); 214 // perform a second layer of gzip encoding atop the server's sdch,gzip
215 // encoding, and then claim that the content encoding is a mere gzip. As a
216 // result we'll need (in that case) to do the gunzip, plus our tentative
217 // gunzip and tentative SDCH decoding.
218 // This approach nicely handles the empty() list as well, and should work with
219 // other (as yet undiscovered) proxies the choose to re-compressed with some
220 // other encoding (such as bzip2, etc.).
221 encoding_types->insert(encoding_types->begin(),
222 FILTER_TYPE_GZIP_HELPING_SDCH);
223 encoding_types->insert(encoding_types->begin(), FILTER_TYPE_SDCH_POSSIBLE);
198 return; 224 return;
199 } 225 }
200 226
201 // static 227 // static
202 Filter* Filter::PrependNewFilter(FilterType type_id, 228 Filter* Filter::PrependNewFilter(FilterType type_id,
203 const FilterContext& filter_context, 229 const FilterContext& filter_context,
204 Filter* filter_list) { 230 Filter* filter_list) {
205 Filter* first_filter = NULL; // Soon to be start of chain. 231 Filter* first_filter = NULL; // Soon to be start of chain.
206 switch (type_id) { 232 switch (type_id) {
207 case FILTER_TYPE_GZIP_HELPING_SDCH: 233 case FILTER_TYPE_GZIP_HELPING_SDCH:
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 385
360 DCHECK(stream_buffer()); 386 DCHECK(stream_buffer());
361 // Bail out if there is more data in the stream buffer to be filtered. 387 // Bail out if there is more data in the stream buffer to be filtered.
362 if (!stream_buffer() || stream_data_len_) 388 if (!stream_buffer() || stream_data_len_)
363 return false; 389 return false;
364 390
365 next_stream_data_ = stream_buffer()->data(); 391 next_stream_data_ = stream_buffer()->data();
366 stream_data_len_ = stream_data_len; 392 stream_data_len_ = stream_data_len;
367 return true; 393 return true;
368 } 394 }
OLDNEW
« no previous file with comments | « no previous file | net/base/gzip_filter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698