| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/io_buffer.h" | 10 #include "net/base/io_buffer.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 const char kUncompressed[] = "uncompressed"; | 27 const char kUncompressed[] = "uncompressed"; |
| 28 | 28 |
| 29 // Mime types: | 29 // Mime types: |
| 30 const char kApplicationXGzip[] = "application/x-gzip"; | 30 const char kApplicationXGzip[] = "application/x-gzip"; |
| 31 const char kApplicationGzip[] = "application/gzip"; | 31 const char kApplicationGzip[] = "application/gzip"; |
| 32 const char kApplicationXGunzip[] = "application/x-gunzip"; | 32 const char kApplicationXGunzip[] = "application/x-gunzip"; |
| 33 const char kApplicationXCompress[] = "application/x-compress"; | 33 const char kApplicationXCompress[] = "application/x-compress"; |
| 34 const char kApplicationCompress[] = "application/compress"; | 34 const char kApplicationCompress[] = "application/compress"; |
| 35 const char kTextHtml[] = "text/html"; | 35 const char kTextHtml[] = "text/html"; |
| 36 | 36 |
| 37 // Buffer size allocated when de-compressing data. |
| 38 const int kFilterBufSize = 32 * 1024; |
| 39 |
| 37 } // namespace | 40 } // namespace |
| 38 | 41 |
| 39 FilterContext::~FilterContext() { | 42 FilterContext::~FilterContext() { |
| 40 } | 43 } |
| 41 | 44 |
| 42 Filter::~Filter() {} | 45 Filter::~Filter() {} |
| 43 | 46 |
| 44 Filter* Filter::Factory(const std::vector<FilterType>& filter_types, | 47 Filter* Filter::Factory(const std::vector<FilterType>& filter_types, |
| 45 const FilterContext& filter_context) { | 48 const FilterContext& filter_context) { |
| 46 DCHECK_GT(filter_context.GetInputStreamBufferSize(), 0); | 49 if (filter_types.empty()) |
| 47 if (filter_types.empty() || filter_context.GetInputStreamBufferSize() <= 0) | |
| 48 return NULL; | 50 return NULL; |
| 49 | 51 |
| 50 | |
| 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(filter_types[i], filter_context, |
| 54 filter_list); | 55 kFilterBufSize, filter_list); |
| 55 if (!filter_list) | 56 if (!filter_list) |
| 56 return NULL; | 57 return NULL; |
| 57 } | 58 } |
| 59 return filter_list; |
| 60 } |
| 61 |
| 62 Filter* Filter::FactoryForTests(const std::vector<FilterType>& filter_types, |
| 63 const FilterContext& filter_context, |
| 64 int buffer_size) { |
| 65 if (filter_types.empty()) |
| 66 return NULL; |
| 67 |
| 68 Filter* filter_list = NULL; // Linked list of filters. |
| 69 for (size_t i = 0; i < filter_types.size(); i++) { |
| 70 filter_list = PrependNewFilter(filter_types[i], filter_context, |
| 71 buffer_size, filter_list); |
| 72 if (!filter_list) |
| 73 return NULL; |
| 74 } |
| 58 return filter_list; | 75 return filter_list; |
| 59 } | 76 } |
| 60 | 77 |
| 61 Filter::FilterStatus Filter::ReadData(char* dest_buffer, int* dest_len) { | 78 Filter::FilterStatus Filter::ReadData(char* dest_buffer, int* dest_len) { |
| 62 const int dest_buffer_capacity = *dest_len; | 79 const int dest_buffer_capacity = *dest_len; |
| 63 if (last_status_ == FILTER_ERROR) | 80 if (last_status_ == FILTER_ERROR) |
| 64 return last_status_; | 81 return last_status_; |
| 65 if (!next_filter_.get()) | 82 if (!next_filter_.get()) |
| 66 return last_status_ = ReadFilteredData(dest_buffer, dest_len); | 83 return last_status_ = ReadFilteredData(dest_buffer, dest_len); |
| 67 if (last_status_ == FILTER_NEED_MORE_DATA && !stream_data_len()) | 84 if (last_status_ == FILTER_NEED_MORE_DATA && !stream_data_len()) |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 return Filter::FILTER_NEED_MORE_DATA; | 339 return Filter::FILTER_NEED_MORE_DATA; |
| 323 } else { | 340 } else { |
| 324 next_stream_data_ += out_len; | 341 next_stream_data_ += out_len; |
| 325 return Filter::FILTER_OK; | 342 return Filter::FILTER_OK; |
| 326 } | 343 } |
| 327 } | 344 } |
| 328 | 345 |
| 329 // static | 346 // static |
| 330 Filter* Filter::PrependNewFilter(FilterType type_id, | 347 Filter* Filter::PrependNewFilter(FilterType type_id, |
| 331 const FilterContext& filter_context, | 348 const FilterContext& filter_context, |
| 349 int buffer_size, |
| 332 Filter* filter_list) { | 350 Filter* filter_list) { |
| 333 Filter* first_filter = NULL; // Soon to be start of chain. | 351 Filter* first_filter = NULL; // Soon to be start of chain. |
| 334 switch (type_id) { | 352 switch (type_id) { |
| 335 case FILTER_TYPE_GZIP_HELPING_SDCH: | 353 case FILTER_TYPE_GZIP_HELPING_SDCH: |
| 336 case FILTER_TYPE_DEFLATE: | 354 case FILTER_TYPE_DEFLATE: |
| 337 case FILTER_TYPE_GZIP: { | 355 case FILTER_TYPE_GZIP: { |
| 338 scoped_ptr<net::GZipFilter> gz_filter( | 356 scoped_ptr<net::GZipFilter> gz_filter( |
| 339 new net::GZipFilter(filter_context)); | 357 new net::GZipFilter(filter_context)); |
| 340 if (gz_filter->InitBuffer()) { | 358 gz_filter->InitBuffer(buffer_size); |
| 341 if (gz_filter->InitDecoding(type_id)) { | 359 if (gz_filter->InitDecoding(type_id)) { |
| 342 first_filter = gz_filter.release(); | 360 first_filter = gz_filter.release(); |
| 343 } | |
| 344 } | 361 } |
| 345 break; | 362 break; |
| 346 } | 363 } |
| 347 case FILTER_TYPE_SDCH: | 364 case FILTER_TYPE_SDCH: |
| 348 case FILTER_TYPE_SDCH_POSSIBLE: { | 365 case FILTER_TYPE_SDCH_POSSIBLE: { |
| 349 scoped_ptr<net::SdchFilter> sdch_filter( | 366 scoped_ptr<net::SdchFilter> sdch_filter( |
| 350 new net::SdchFilter(filter_context)); | 367 new net::SdchFilter(filter_context)); |
| 351 if (sdch_filter->InitBuffer()) { | 368 sdch_filter->InitBuffer(buffer_size); |
| 352 if (sdch_filter->InitDecoding(type_id)) { | 369 if (sdch_filter->InitDecoding(type_id)) { |
| 353 first_filter = sdch_filter.release(); | 370 first_filter = sdch_filter.release(); |
| 354 } | |
| 355 } | 371 } |
| 356 break; | 372 break; |
| 357 } | 373 } |
| 358 default: { | 374 default: { |
| 359 break; | 375 break; |
| 360 } | 376 } |
| 361 } | 377 } |
| 362 | 378 |
| 363 if (!first_filter) { | 379 if (!first_filter) { |
| 364 // Cleanup and exit, since we can't construct this filter list. | 380 // Cleanup and exit, since we can't construct this filter list. |
| 365 delete filter_list; | 381 delete filter_list; |
| 366 return NULL; | 382 return NULL; |
| 367 } | 383 } |
| 368 | 384 |
| 369 first_filter->next_filter_.reset(filter_list); | 385 first_filter->next_filter_.reset(filter_list); |
| 370 return first_filter; | 386 return first_filter; |
| 371 } | 387 } |
| 372 | 388 |
| 373 bool Filter::InitBuffer() { | 389 void Filter::InitBuffer(int buffer_size) { |
| 374 int buffer_size = filter_context_.GetInputStreamBufferSize(); | 390 DCHECK(!stream_buffer()); |
| 375 DCHECK_GT(buffer_size, 0); | 391 DCHECK_GT(buffer_size, 0); |
| 376 if (buffer_size <= 0 || stream_buffer()) | |
| 377 return false; | |
| 378 | |
| 379 stream_buffer_ = new net::IOBuffer(buffer_size); | 392 stream_buffer_ = new net::IOBuffer(buffer_size); |
| 380 | 393 stream_buffer_size_ = buffer_size; |
| 381 if (stream_buffer()) { | |
| 382 stream_buffer_size_ = buffer_size; | |
| 383 return true; | |
| 384 } | |
| 385 | |
| 386 return false; | |
| 387 } | 394 } |
| 388 | 395 |
| 389 void Filter::PushDataIntoNextFilter() { | 396 void Filter::PushDataIntoNextFilter() { |
| 390 net::IOBuffer* next_buffer = next_filter_->stream_buffer(); | 397 net::IOBuffer* next_buffer = next_filter_->stream_buffer(); |
| 391 int next_size = next_filter_->stream_buffer_size(); | 398 int next_size = next_filter_->stream_buffer_size(); |
| 392 last_status_ = ReadFilteredData(next_buffer->data(), &next_size); | 399 last_status_ = ReadFilteredData(next_buffer->data(), &next_size); |
| 393 if (FILTER_ERROR != last_status_) | 400 if (FILTER_ERROR != last_status_) |
| 394 next_filter_->FlushStreamBuffer(next_size); | 401 next_filter_->FlushStreamBuffer(next_size); |
| 395 } | 402 } |
| OLD | NEW |