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

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

Issue 266243004: Clang format slam. Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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 | Annotate | Revision Log
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/filter.h" 5 #include "net/filter/filter.h"
6 6
7 #include "base/files/file_path.h" 7 #include "base/files/file_path.h"
8 #include "base/strings/string_util.h" 8 #include "base/strings/string_util.h"
9 #include "net/base/filename_util.h" 9 #include "net/base/filename_util.h"
10 #include "net/base/io_buffer.h" 10 #include "net/base/io_buffer.h"
11 #include "net/base/mime_util.h" 11 #include "net/base/mime_util.h"
12 #include "net/filter/gzip_filter.h" 12 #include "net/filter/gzip_filter.h"
13 #include "net/filter/sdch_filter.h" 13 #include "net/filter/sdch_filter.h"
14 #include "url/gurl.h" 14 #include "url/gurl.h"
15 15
16 namespace { 16 namespace {
17 17
18 // Filter types (using canonical lower case only): 18 // Filter types (using canonical lower case only):
19 const char kDeflate[] = "deflate"; 19 const char kDeflate[] = "deflate";
20 const char kGZip[] = "gzip"; 20 const char kGZip[] = "gzip";
21 const char kXGZip[] = "x-gzip"; 21 const char kXGZip[] = "x-gzip";
22 const char kSdch[] = "sdch"; 22 const char kSdch[] = "sdch";
23 // compress and x-compress are currently not supported. If we decide to support 23 // compress and x-compress are currently not supported. If we decide to support
24 // them, we'll need the same mime type compatibility hack we have for gzip. For 24 // them, we'll need the same mime type compatibility hack we have for gzip. For
25 // more information, see Firefox's nsHttpChannel::ProcessNormal. 25 // more information, see Firefox's nsHttpChannel::ProcessNormal.
26 26
27 // Mime types: 27 // Mime types:
28 const char kApplicationXGzip[] = "application/x-gzip"; 28 const char kApplicationXGzip[] = "application/x-gzip";
29 const char kApplicationGzip[] = "application/gzip"; 29 const char kApplicationGzip[] = "application/gzip";
30 const char kApplicationXGunzip[] = "application/x-gunzip"; 30 const char kApplicationXGunzip[] = "application/x-gunzip";
31 const char kTextHtml[] = "text/html"; 31 const char kTextHtml[] = "text/html";
32 32
33 // Buffer size allocated when de-compressing data. 33 // Buffer size allocated when de-compressing data.
34 const int kFilterBufSize = 32 * 1024; 34 const int kFilterBufSize = 32 * 1024;
35 35
36 } // namespace 36 } // namespace
37 37
38 namespace net { 38 namespace net {
39 39
40 FilterContext::~FilterContext() { 40 FilterContext::~FilterContext() {
41 } 41 }
42 42
43 Filter::~Filter() {} 43 Filter::~Filter() {
44 }
44 45
45 // static 46 // static
46 Filter* Filter::Factory(const std::vector<FilterType>& filter_types, 47 Filter* Filter::Factory(const std::vector<FilterType>& filter_types,
47 const FilterContext& filter_context) { 48 const FilterContext& filter_context) {
48 if (filter_types.empty()) 49 if (filter_types.empty())
49 return NULL; 50 return NULL;
50 51
51 Filter* filter_list = NULL; // Linked list of filters. 52 Filter* filter_list = NULL; // Linked list of filters.
52 for (size_t i = 0; i < filter_types.size(); i++) { 53 for (size_t i = 0; i < filter_types.size(); i++) {
53 filter_list = PrependNewFilter(filter_types[i], filter_context, 54 filter_list = PrependNewFilter(
54 kFilterBufSize, filter_list); 55 filter_types[i], filter_context, kFilterBufSize, filter_list);
55 if (!filter_list) 56 if (!filter_list)
56 return NULL; 57 return NULL;
57 } 58 }
58 return filter_list; 59 return filter_list;
59 } 60 }
60 61
61 // static 62 // static
62 Filter* Filter::GZipFactory() { 63 Filter* Filter::GZipFactory() {
63 return InitGZipFilter(FILTER_TYPE_GZIP, kFilterBufSize); 64 return InitGZipFilter(FILTER_TYPE_GZIP, kFilterBufSize);
64 } 65 }
65 66
66 // static 67 // static
67 Filter* Filter::FactoryForTests(const std::vector<FilterType>& filter_types, 68 Filter* Filter::FactoryForTests(const std::vector<FilterType>& filter_types,
68 const FilterContext& filter_context, 69 const FilterContext& filter_context,
69 int buffer_size) { 70 int buffer_size) {
70 if (filter_types.empty()) 71 if (filter_types.empty())
71 return NULL; 72 return NULL;
72 73
73 Filter* filter_list = NULL; // Linked list of filters. 74 Filter* filter_list = NULL; // Linked list of filters.
74 for (size_t i = 0; i < filter_types.size(); i++) { 75 for (size_t i = 0; i < filter_types.size(); i++) {
75 filter_list = PrependNewFilter(filter_types[i], filter_context, 76 filter_list = PrependNewFilter(
76 buffer_size, filter_list); 77 filter_types[i], filter_context, buffer_size, filter_list);
77 if (!filter_list) 78 if (!filter_list)
78 return NULL; 79 return NULL;
79 } 80 }
80 return filter_list; 81 return filter_list;
81 } 82 }
82 83
83 Filter::FilterStatus Filter::ReadData(char* dest_buffer, int* dest_len) { 84 Filter::FilterStatus Filter::ReadData(char* dest_buffer, int* dest_len) {
84 const int dest_buffer_capacity = *dest_len; 85 const int dest_buffer_capacity = *dest_len;
85 if (last_status_ == FILTER_ERROR) 86 if (last_status_ == FILTER_ERROR)
86 return last_status_; 87 return last_status_;
87 if (!next_filter_.get()) 88 if (!next_filter_.get())
88 return last_status_ = ReadFilteredData(dest_buffer, dest_len); 89 return last_status_ = ReadFilteredData(dest_buffer, dest_len);
89 if (last_status_ == FILTER_NEED_MORE_DATA && !stream_data_len()) 90 if (last_status_ == FILTER_NEED_MORE_DATA && !stream_data_len())
90 return next_filter_->ReadData(dest_buffer, dest_len); 91 return next_filter_->ReadData(dest_buffer, dest_len);
91 92
92 do { 93 do {
93 if (next_filter_->last_status() == FILTER_NEED_MORE_DATA) { 94 if (next_filter_->last_status() == FILTER_NEED_MORE_DATA) {
94 PushDataIntoNextFilter(); 95 PushDataIntoNextFilter();
95 if (FILTER_ERROR == last_status_) 96 if (FILTER_ERROR == last_status_)
96 return FILTER_ERROR; 97 return FILTER_ERROR;
97 } 98 }
98 *dest_len = dest_buffer_capacity; // Reset the input/output parameter. 99 *dest_len = dest_buffer_capacity; // Reset the input/output parameter.
99 next_filter_->ReadData(dest_buffer, dest_len); 100 next_filter_->ReadData(dest_buffer, dest_len);
100 if (FILTER_NEED_MORE_DATA == last_status_) 101 if (FILTER_NEED_MORE_DATA == last_status_)
101 return next_filter_->last_status(); 102 return next_filter_->last_status();
102 103
103 // In the case where this filter has data internally, and is indicating such 104 // In the case where this filter has data internally, and is indicating such
104 // with a last_status_ of FILTER_OK, but at the same time the next filter in 105 // with a last_status_ of FILTER_OK, but at the same time the next filter in
105 // the chain indicated it FILTER_NEED_MORE_DATA, we have to be cautious 106 // the chain indicated it FILTER_NEED_MORE_DATA, we have to be cautious
106 // about confusing the caller. The API confusion can appear if we return 107 // about confusing the caller. The API confusion can appear if we return
107 // FILTER_OK (suggesting we have more data in aggregate), but yet we don't 108 // FILTER_OK (suggesting we have more data in aggregate), but yet we don't
108 // populate our output buffer. When that is the case, we need to 109 // populate our output buffer. When that is the case, we need to
109 // alternately call our filter element, and the next_filter element until we 110 // alternately call our filter element, and the next_filter element until we
110 // get out of this state (by pumping data into the next filter until it 111 // get out of this state (by pumping data into the next filter until it
111 // outputs data, or it runs out of data and reports that it NEED_MORE_DATA.) 112 // outputs data, or it runs out of data and reports that it NEED_MORE_DATA.)
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 type_id = FILTER_TYPE_SDCH; 147 type_id = FILTER_TYPE_SDCH;
147 } else { 148 } else {
148 // Note we also consider "identity" and "uncompressed" UNSUPPORTED as 149 // Note we also consider "identity" and "uncompressed" UNSUPPORTED as
149 // filter should be disabled in such cases. 150 // filter should be disabled in such cases.
150 type_id = FILTER_TYPE_UNSUPPORTED; 151 type_id = FILTER_TYPE_UNSUPPORTED;
151 } 152 }
152 return type_id; 153 return type_id;
153 } 154 }
154 155
155 // static 156 // static
156 void Filter::FixupEncodingTypes( 157 void Filter::FixupEncodingTypes(const FilterContext& filter_context,
157 const FilterContext& filter_context, 158 std::vector<FilterType>* encoding_types) {
158 std::vector<FilterType>* encoding_types) {
159 std::string mime_type; 159 std::string mime_type;
160 bool success = filter_context.GetMimeType(&mime_type); 160 bool success = filter_context.GetMimeType(&mime_type);
161 DCHECK(success || mime_type.empty()); 161 DCHECK(success || mime_type.empty());
162 162
163 if ((1 == encoding_types->size()) && 163 if ((1 == encoding_types->size()) &&
164 (FILTER_TYPE_GZIP == encoding_types->front())) { 164 (FILTER_TYPE_GZIP == encoding_types->front())) {
165 if (LowerCaseEqualsASCII(mime_type, kApplicationXGzip) || 165 if (LowerCaseEqualsASCII(mime_type, kApplicationXGzip) ||
166 LowerCaseEqualsASCII(mime_type, kApplicationGzip) || 166 LowerCaseEqualsASCII(mime_type, kApplicationGzip) ||
167 LowerCaseEqualsASCII(mime_type, kApplicationXGunzip)) 167 LowerCaseEqualsASCII(mime_type, kApplicationXGunzip))
168 // The server has told us that it sent us gziped content with a gzip 168 // The server has told us that it sent us gziped content with a gzip
169 // content encoding. Sadly, Apache mistakenly sets these headers for all 169 // content encoding. Sadly, Apache mistakenly sets these headers for all
170 // .gz files. We match Firefox's nsHttpChannel::ProcessNormal and ignore 170 // .gz files. We match Firefox's nsHttpChannel::ProcessNormal and ignore
171 // the Content-Encoding here. 171 // the Content-Encoding here.
172 encoding_types->clear(); 172 encoding_types->clear();
173 173
174 GURL url; 174 GURL url;
175 std::string disposition; 175 std::string disposition;
176 success = filter_context.GetURL(&url); 176 success = filter_context.GetURL(&url);
177 DCHECK(success); 177 DCHECK(success);
178 filter_context.GetContentDisposition(&disposition); 178 filter_context.GetContentDisposition(&disposition);
179 // Don't supply a MIME type here, since that may cause disk IO. 179 // Don't supply a MIME type here, since that may cause disk IO.
180 base::FilePath filepath = GenerateFileName(url, disposition, "UTF-8", "", 180 base::FilePath filepath =
181 "", ""); 181 GenerateFileName(url, disposition, "UTF-8", "", "", "");
182 base::FilePath::StringType extension = filepath.Extension(); 182 base::FilePath::StringType extension = filepath.Extension();
183 183
184 if (filter_context.IsDownload()) { 184 if (filter_context.IsDownload()) {
185 // We don't want to decompress gzipped files when the user explicitly 185 // We don't want to decompress gzipped files when the user explicitly
186 // asks to download them. 186 // asks to download them.
187 // For the case of svgz files, we use the extension to distinguish 187 // For the case of svgz files, we use the extension to distinguish
188 // between svgz files and svg files compressed with gzip by the server. 188 // between svgz files and svg files compressed with gzip by the server.
189 // When viewing a .svgz file, we need to uncompress it, but we don't 189 // When viewing a .svgz file, we need to uncompress it, but we don't
190 // want to do that when downloading. 190 // want to do that when downloading.
191 // See Firefox's nonDecodableExtensions in nsExternalHelperAppService.cpp 191 // See Firefox's nonDecodableExtensions in nsExternalHelperAppService.cpp
(...skipping 16 matching lines...) Expand all
208 // If the request was for SDCH content, then we might need additional fixups. 208 // If the request was for SDCH content, then we might need additional fixups.
209 if (!filter_context.IsSdchResponse()) { 209 if (!filter_context.IsSdchResponse()) {
210 // It was not an SDCH request, so we'll just record stats. 210 // It was not an SDCH request, so we'll just record stats.
211 if (1 < encoding_types->size()) { 211 if (1 < encoding_types->size()) {
212 // Multiple filters were intended to only be used for SDCH (thus far!) 212 // Multiple filters were intended to only be used for SDCH (thus far!)
213 SdchManager::SdchErrorRecovery( 213 SdchManager::SdchErrorRecovery(
214 SdchManager::MULTIENCODING_FOR_NON_SDCH_REQUEST); 214 SdchManager::MULTIENCODING_FOR_NON_SDCH_REQUEST);
215 } 215 }
216 if ((1 == encoding_types->size()) && 216 if ((1 == encoding_types->size()) &&
217 (FILTER_TYPE_SDCH == encoding_types->front())) { 217 (FILTER_TYPE_SDCH == encoding_types->front())) {
218 SdchManager::SdchErrorRecovery( 218 SdchManager::SdchErrorRecovery(
219 SdchManager::SDCH_CONTENT_ENCODE_FOR_NON_SDCH_REQUEST); 219 SdchManager::SDCH_CONTENT_ENCODE_FOR_NON_SDCH_REQUEST);
220 } 220 }
221 return; 221 return;
222 } 222 }
223 223
224 // The request was tagged as an SDCH request, which means the server supplied 224 // The request was tagged as an SDCH request, which means the server supplied
225 // a dictionary, and we advertised it in the request. Some proxies will do 225 // a dictionary, and we advertised it in the request. Some proxies will do
226 // very strange things to the request, or the response, so we have to handle 226 // very strange things to the request, or the response, so we have to handle
227 // them gracefully. 227 // them gracefully.
228 228
229 // If content encoding included SDCH, then everything is "relatively" fine. 229 // If content encoding included SDCH, then everything is "relatively" fine.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 // The one unresolved failure mode comes when we advertise a dictionary, and 264 // The one unresolved failure mode comes when we advertise a dictionary, and
265 // the server tries to *send* a gzipped file (not gzip encode content), and 265 // the server tries to *send* a gzipped file (not gzip encode content), and
266 // then we could do a gzip decode :-(. Since SDCH is only (currently) 266 // then we could do a gzip decode :-(. Since SDCH is only (currently)
267 // supported server side on paths that only send HTML content, this mode has 267 // supported server side on paths that only send HTML content, this mode has
268 // never surfaced in the wild (and is unlikely to). 268 // never surfaced in the wild (and is unlikely to).
269 // We will gather a lot of stats as we perform the fixups 269 // We will gather a lot of stats as we perform the fixups
270 if (StartsWithASCII(mime_type, kTextHtml, false)) { 270 if (StartsWithASCII(mime_type, kTextHtml, false)) {
271 // Suspicious case: Advertised dictionary, but server didn't use sdch, and 271 // Suspicious case: Advertised dictionary, but server didn't use sdch, and
272 // we're HTML tagged. 272 // we're HTML tagged.
273 if (encoding_types->empty()) { 273 if (encoding_types->empty()) {
274 SdchManager::SdchErrorRecovery( 274 SdchManager::SdchErrorRecovery(SdchManager::ADDED_CONTENT_ENCODING);
275 SdchManager::ADDED_CONTENT_ENCODING);
276 } else if (1 == encoding_types->size()) { 275 } else if (1 == encoding_types->size()) {
277 SdchManager::SdchErrorRecovery( 276 SdchManager::SdchErrorRecovery(SdchManager::FIXED_CONTENT_ENCODING);
278 SdchManager::FIXED_CONTENT_ENCODING);
279 } else { 277 } else {
280 SdchManager::SdchErrorRecovery( 278 SdchManager::SdchErrorRecovery(SdchManager::FIXED_CONTENT_ENCODINGS);
281 SdchManager::FIXED_CONTENT_ENCODINGS);
282 } 279 }
283 } else { 280 } else {
284 // Remarkable case!?! We advertised an SDCH dictionary, content-encoding 281 // Remarkable case!?! We advertised an SDCH dictionary, content-encoding
285 // was not marked for SDCH processing: Why did the server suggest an SDCH 282 // was not marked for SDCH processing: Why did the server suggest an SDCH
286 // dictionary in the first place??. Also, the content isn't 283 // dictionary in the first place??. Also, the content isn't
287 // tagged as HTML, despite the fact that SDCH encoding is mostly likely for 284 // tagged as HTML, despite the fact that SDCH encoding is mostly likely for
288 // HTML: Did some anti-virus system strip this tag (sometimes they strip 285 // HTML: Did some anti-virus system strip this tag (sometimes they strip
289 // accept-encoding headers on the request)?? Does the content encoding not 286 // accept-encoding headers on the request)?? Does the content encoding not
290 // start with "text/html" for some other reason?? We'll report this as a 287 // start with "text/html" for some other reason?? We'll report this as a
291 // fixup to a binary file, but it probably really is text/html (some how). 288 // fixup to a binary file, but it probably really is text/html (some how).
(...skipping 22 matching lines...) Expand all
314 FILTER_TYPE_GZIP_HELPING_SDCH); 311 FILTER_TYPE_GZIP_HELPING_SDCH);
315 encoding_types->insert(encoding_types->begin(), FILTER_TYPE_SDCH_POSSIBLE); 312 encoding_types->insert(encoding_types->begin(), FILTER_TYPE_SDCH_POSSIBLE);
316 return; 313 return;
317 } 314 }
318 315
319 Filter::Filter() 316 Filter::Filter()
320 : stream_buffer_(NULL), 317 : stream_buffer_(NULL),
321 stream_buffer_size_(0), 318 stream_buffer_size_(0),
322 next_stream_data_(NULL), 319 next_stream_data_(NULL),
323 stream_data_len_(0), 320 stream_data_len_(0),
324 last_status_(FILTER_NEED_MORE_DATA) {} 321 last_status_(FILTER_NEED_MORE_DATA) {
322 }
325 323
326 Filter::FilterStatus Filter::CopyOut(char* dest_buffer, int* dest_len) { 324 Filter::FilterStatus Filter::CopyOut(char* dest_buffer, int* dest_len) {
327 int out_len; 325 int out_len;
328 int input_len = *dest_len; 326 int input_len = *dest_len;
329 *dest_len = 0; 327 *dest_len = 0;
330 328
331 if (0 == stream_data_len_) 329 if (0 == stream_data_len_)
332 return Filter::FILTER_NEED_MORE_DATA; 330 return Filter::FILTER_NEED_MORE_DATA;
333 331
334 out_len = std::min(input_len, stream_data_len_); 332 out_len = std::min(input_len, stream_data_len_);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 397
400 void Filter::PushDataIntoNextFilter() { 398 void Filter::PushDataIntoNextFilter() {
401 IOBuffer* next_buffer = next_filter_->stream_buffer(); 399 IOBuffer* next_buffer = next_filter_->stream_buffer();
402 int next_size = next_filter_->stream_buffer_size(); 400 int next_size = next_filter_->stream_buffer_size();
403 last_status_ = ReadFilteredData(next_buffer->data(), &next_size); 401 last_status_ = ReadFilteredData(next_buffer->data(), &next_size);
404 if (FILTER_ERROR != last_status_) 402 if (FILTER_ERROR != last_status_)
405 next_filter_->FlushStreamBuffer(next_size); 403 next_filter_->FlushStreamBuffer(next_size);
406 } 404 }
407 405
408 } // namespace net 406 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698