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