OLD | NEW |
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 // The basic usage of the Filter interface is described in the comment at | 5 // The basic usage of the Filter interface is described in the comment at |
6 // the beginning of filter.h. If Filter::Factory is passed a vector of | 6 // the beginning of filter.h. If Filter::Factory is passed a vector of |
7 // size greater than 1, that interface is implemented by a series of filters | 7 // size greater than 1, that interface is implemented by a series of filters |
8 // connected in a chain. In such a case the first filter | 8 // connected in a chain. In such a case the first filter |
9 // in the chain proxies calls to ReadData() so that its return values | 9 // in the chain proxies calls to ReadData() so that its return values |
10 // apply to the entire chain. | 10 // apply to the entire chain. |
(...skipping 10 matching lines...) Expand all Loading... |
21 // next filter needs it, a return value of FILTER_NEED_MORE_DATA from the | 21 // next filter needs it, a return value of FILTER_NEED_MORE_DATA from the |
22 // final filter will apply to the entire chain. | 22 // final filter will apply to the entire chain. |
23 | 23 |
24 #include "net/filter/filter.h" | 24 #include "net/filter/filter.h" |
25 | 25 |
26 #include "base/files/file_path.h" | 26 #include "base/files/file_path.h" |
27 #include "base/strings/string_util.h" | 27 #include "base/strings/string_util.h" |
28 #include "base/values.h" | 28 #include "base/values.h" |
29 #include "net/base/io_buffer.h" | 29 #include "net/base/io_buffer.h" |
30 #include "net/base/sdch_net_log_params.h" | 30 #include "net/base/sdch_net_log_params.h" |
| 31 #if !defined(DISABLE_BROTLI_SUPPORT) |
| 32 #include "net/filter/brotli_filter.h" |
| 33 #endif |
31 #include "net/filter/gzip_filter.h" | 34 #include "net/filter/gzip_filter.h" |
32 #include "net/filter/sdch_filter.h" | 35 #include "net/filter/sdch_filter.h" |
33 #include "net/url_request/url_request_context.h" | 36 #include "net/url_request/url_request_context.h" |
34 #include "url/gurl.h" | 37 #include "url/gurl.h" |
35 | 38 |
36 namespace net { | 39 namespace net { |
37 | 40 |
38 namespace { | 41 namespace { |
39 | 42 |
40 // Filter types (using canonical lower case only): | 43 // Filter types (using canonical lower case only): |
| 44 const char kBrotli[] = "br"; |
41 const char kDeflate[] = "deflate"; | 45 const char kDeflate[] = "deflate"; |
42 const char kGZip[] = "gzip"; | 46 const char kGZip[] = "gzip"; |
43 const char kXGZip[] = "x-gzip"; | 47 const char kXGZip[] = "x-gzip"; |
44 const char kSdch[] = "sdch"; | 48 const char kSdch[] = "sdch"; |
45 // compress and x-compress are currently not supported. If we decide to support | 49 // compress and x-compress are currently not supported. If we decide to support |
46 // them, we'll need the same mime type compatibility hack we have for gzip. For | 50 // them, we'll need the same mime type compatibility hack we have for gzip. For |
47 // more information, see Firefox's nsHttpChannel::ProcessNormal. | 51 // more information, see Firefox's nsHttpChannel::ProcessNormal. |
48 | 52 |
49 // Mime types: | 53 // Mime types: |
50 const char kTextHtml[] = "text/html"; | 54 const char kTextHtml[] = "text/html"; |
51 | 55 |
52 // Buffer size allocated when de-compressing data. | 56 // Buffer size allocated when de-compressing data. |
53 const int kFilterBufSize = 32 * 1024; | 57 const int kFilterBufSize = 32 * 1024; |
54 | 58 |
55 void LogSdchProblem(const FilterContext& filter_context, | 59 void LogSdchProblem(const FilterContext& filter_context, |
56 SdchProblemCode problem) { | 60 SdchProblemCode problem) { |
57 SdchManager::SdchErrorRecovery(problem); | 61 SdchManager::SdchErrorRecovery(problem); |
58 filter_context.GetNetLog().AddEvent( | 62 filter_context.GetNetLog().AddEvent( |
59 NetLog::TYPE_SDCH_DECODING_ERROR, | 63 NetLog::TYPE_SDCH_DECODING_ERROR, |
60 base::Bind(&NetLogSdchResourceProblemCallback, problem)); | 64 base::Bind(&NetLogSdchResourceProblemCallback, problem)); |
61 } | 65 } |
62 | 66 |
63 std::string FilterTypeAsString(Filter::FilterType type_id) { | 67 std::string FilterTypeAsString(Filter::FilterType type_id) { |
64 switch (type_id) { | 68 switch (type_id) { |
| 69 case Filter::FILTER_TYPE_BROTLI: |
| 70 return "FILTER_TYPE_BROTLI"; |
65 case Filter::FILTER_TYPE_DEFLATE: | 71 case Filter::FILTER_TYPE_DEFLATE: |
66 return "FILTER_TYPE_DEFLATE"; | 72 return "FILTER_TYPE_DEFLATE"; |
67 case Filter::FILTER_TYPE_GZIP: | 73 case Filter::FILTER_TYPE_GZIP: |
68 return "FILTER_TYPE_GZIP"; | 74 return "FILTER_TYPE_GZIP"; |
69 case Filter::FILTER_TYPE_GZIP_HELPING_SDCH: | 75 case Filter::FILTER_TYPE_GZIP_HELPING_SDCH: |
70 return "FILTER_TYPE_GZIP_HELPING_SDCH"; | 76 return "FILTER_TYPE_GZIP_HELPING_SDCH"; |
71 case Filter::FILTER_TYPE_SDCH: | 77 case Filter::FILTER_TYPE_SDCH: |
72 return "FILTER_TYPE_SDCH"; | 78 return "FILTER_TYPE_SDCH"; |
73 case Filter::FILTER_TYPE_SDCH_POSSIBLE : | 79 case Filter::FILTER_TYPE_SDCH_POSSIBLE : |
74 return "FILTER_TYPE_SDCH_POSSIBLE "; | 80 return "FILTER_TYPE_SDCH_POSSIBLE "; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 next_stream_data_ = stream_buffer()->data(); | 183 next_stream_data_ = stream_buffer()->data(); |
178 stream_data_len_ = stream_data_len; | 184 stream_data_len_ = stream_data_len; |
179 last_status_ = FILTER_OK; | 185 last_status_ = FILTER_OK; |
180 return true; | 186 return true; |
181 } | 187 } |
182 | 188 |
183 // static | 189 // static |
184 Filter::FilterType Filter::ConvertEncodingToType( | 190 Filter::FilterType Filter::ConvertEncodingToType( |
185 const std::string& filter_type) { | 191 const std::string& filter_type) { |
186 FilterType type_id; | 192 FilterType type_id; |
187 if (base::LowerCaseEqualsASCII(filter_type, kDeflate)) { | 193 if (base::LowerCaseEqualsASCII(filter_type, kBrotli)) { |
| 194 type_id = FILTER_TYPE_BROTLI; |
| 195 } else if (base::LowerCaseEqualsASCII(filter_type, kDeflate)) { |
188 type_id = FILTER_TYPE_DEFLATE; | 196 type_id = FILTER_TYPE_DEFLATE; |
189 } else if (base::LowerCaseEqualsASCII(filter_type, kGZip) || | 197 } else if (base::LowerCaseEqualsASCII(filter_type, kGZip) || |
190 base::LowerCaseEqualsASCII(filter_type, kXGZip)) { | 198 base::LowerCaseEqualsASCII(filter_type, kXGZip)) { |
191 type_id = FILTER_TYPE_GZIP; | 199 type_id = FILTER_TYPE_GZIP; |
192 } else if (base::LowerCaseEqualsASCII(filter_type, kSdch)) { | 200 } else if (base::LowerCaseEqualsASCII(filter_type, kSdch)) { |
193 type_id = FILTER_TYPE_SDCH; | 201 type_id = FILTER_TYPE_SDCH; |
194 } else { | 202 } else { |
195 // Note we also consider "identity" and "uncompressed" UNSUPPORTED as | 203 // Note we also consider "identity" and "uncompressed" UNSUPPORTED as |
196 // filter should be disabled in such cases. | 204 // filter should be disabled in such cases. |
197 type_id = FILTER_TYPE_UNSUPPORTED; | 205 type_id = FILTER_TYPE_UNSUPPORTED; |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 if (0 == stream_data_len_) { | 351 if (0 == stream_data_len_) { |
344 next_stream_data_ = NULL; | 352 next_stream_data_ = NULL; |
345 return Filter::FILTER_NEED_MORE_DATA; | 353 return Filter::FILTER_NEED_MORE_DATA; |
346 } else { | 354 } else { |
347 next_stream_data_ += out_len; | 355 next_stream_data_ += out_len; |
348 return Filter::FILTER_OK; | 356 return Filter::FILTER_OK; |
349 } | 357 } |
350 } | 358 } |
351 | 359 |
352 // static | 360 // static |
| 361 Filter* Filter::InitBrotliFilter(FilterType type_id, int buffer_size) { |
| 362 #if !defined(DISABLE_BROTLI_SUPPORT) |
| 363 scoped_ptr<BrotliFilter> brotli_filter(new BrotliFilter(type_id)); |
| 364 brotli_filter->InitBuffer(buffer_size); |
| 365 return brotli_filter->InitDecoding() ? brotli_filter.release() : NULL; |
| 366 #else |
| 367 return NULL; |
| 368 #endif |
| 369 } |
| 370 |
| 371 // static |
353 Filter* Filter::InitGZipFilter(FilterType type_id, int buffer_size) { | 372 Filter* Filter::InitGZipFilter(FilterType type_id, int buffer_size) { |
354 scoped_ptr<GZipFilter> gz_filter(new GZipFilter(type_id)); | 373 scoped_ptr<GZipFilter> gz_filter(new GZipFilter(type_id)); |
355 gz_filter->InitBuffer(buffer_size); | 374 gz_filter->InitBuffer(buffer_size); |
356 return gz_filter->InitDecoding(type_id) ? gz_filter.release() : NULL; | 375 return gz_filter->InitDecoding(type_id) ? gz_filter.release() : NULL; |
357 } | 376 } |
358 | 377 |
359 // static | 378 // static |
360 Filter* Filter::InitSdchFilter(FilterType type_id, | 379 Filter* Filter::InitSdchFilter(FilterType type_id, |
361 const FilterContext& filter_context, | 380 const FilterContext& filter_context, |
362 int buffer_size) { | 381 int buffer_size) { |
363 scoped_ptr<SdchFilter> sdch_filter(new SdchFilter(type_id, filter_context)); | 382 scoped_ptr<SdchFilter> sdch_filter(new SdchFilter(type_id, filter_context)); |
364 sdch_filter->InitBuffer(buffer_size); | 383 sdch_filter->InitBuffer(buffer_size); |
365 return sdch_filter->InitDecoding(type_id) ? sdch_filter.release() : NULL; | 384 return sdch_filter->InitDecoding(type_id) ? sdch_filter.release() : NULL; |
366 } | 385 } |
367 | 386 |
368 // static | 387 // static |
369 Filter* Filter::PrependNewFilter(FilterType type_id, | 388 Filter* Filter::PrependNewFilter(FilterType type_id, |
370 const FilterContext& filter_context, | 389 const FilterContext& filter_context, |
371 int buffer_size, | 390 int buffer_size, |
372 Filter* filter_list) { | 391 Filter* filter_list) { |
373 scoped_ptr<Filter> first_filter; // Soon to be start of chain. | 392 scoped_ptr<Filter> first_filter; // Soon to be start of chain. |
374 switch (type_id) { | 393 switch (type_id) { |
| 394 case FILTER_TYPE_BROTLI: |
| 395 if (filter_context.IsBrotliEnabled()) |
| 396 first_filter.reset(InitBrotliFilter(type_id, buffer_size)); |
| 397 break; |
375 case FILTER_TYPE_GZIP_HELPING_SDCH: | 398 case FILTER_TYPE_GZIP_HELPING_SDCH: |
376 case FILTER_TYPE_DEFLATE: | 399 case FILTER_TYPE_DEFLATE: |
377 case FILTER_TYPE_GZIP: | 400 case FILTER_TYPE_GZIP: |
378 first_filter.reset(InitGZipFilter(type_id, buffer_size)); | 401 first_filter.reset(InitGZipFilter(type_id, buffer_size)); |
379 break; | 402 break; |
380 case FILTER_TYPE_SDCH: | 403 case FILTER_TYPE_SDCH: |
381 case FILTER_TYPE_SDCH_POSSIBLE: | 404 case FILTER_TYPE_SDCH_POSSIBLE: |
382 if (filter_context.GetURLRequestContext()->sdch_manager()) { | 405 if (filter_context.GetURLRequestContext()->sdch_manager()) { |
383 first_filter.reset( | 406 first_filter.reset( |
384 InitSdchFilter(type_id, filter_context, buffer_size)); | 407 InitSdchFilter(type_id, filter_context, buffer_size)); |
(...skipping 19 matching lines...) Expand all Loading... |
404 | 427 |
405 void Filter::PushDataIntoNextFilter() { | 428 void Filter::PushDataIntoNextFilter() { |
406 IOBuffer* next_buffer = next_filter_->stream_buffer(); | 429 IOBuffer* next_buffer = next_filter_->stream_buffer(); |
407 int next_size = next_filter_->stream_buffer_size(); | 430 int next_size = next_filter_->stream_buffer_size(); |
408 last_status_ = ReadFilteredData(next_buffer->data(), &next_size); | 431 last_status_ = ReadFilteredData(next_buffer->data(), &next_size); |
409 if (FILTER_ERROR != last_status_) | 432 if (FILTER_ERROR != last_status_) |
410 next_filter_->FlushStreamBuffer(next_size); | 433 next_filter_->FlushStreamBuffer(next_size); |
411 } | 434 } |
412 | 435 |
413 } // namespace net | 436 } // namespace net |
OLD | NEW |