1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Filter performs filtering on data streams. Sample usage: 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// IStream* pre_filter_source; 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ... 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Filter* filter = Filter::Factory(filter_type, size); 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// int pre_filter_data_len = filter->stream_buffer_size(); 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// pre_filter_source->read(filter->stream_buffer(), pre_filter_data_len); 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// filter->FlushStreamBuffer(pre_filter_data_len); 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// char post_filter_buf[kBufferSize]; 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// int post_filter_data_len = kBufferSize; 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// filter->ReadFilteredData(post_filter_buf, &post_filter_data_len); 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// To filter a data stream, the caller first gets filter's stream_buffer_ 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// through its accessor and fills in stream_buffer_ with pre-filter data, next 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// calls FlushStreamBuffer to notify Filter, then calls ReadFilteredData 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// repeatedly to get all the filtered data. After all data have been fitlered 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and read out, the caller may fill in stream_buffer_ again. This 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// WriteBuffer-Flush-Read cycle is repeated until reaching the end of data 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// stream. 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The lifetime of a Filter instance is completely controlled by its caller. 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NET_BASE_FILTER_H__ 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_BASE_FILTER_H__ 313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string> 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <vector> 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h" 373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/gtest_prod_util.h" 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h" 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/time.h" 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass GURL; 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass IOBuffer; 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------ 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Define an interface class that allows access to contextual information 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// supplied by the owner of this filter. In the case where there are a chain of 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// filters, there is only one owner of all the chained filters, and that context 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// is passed to the constructor of all those filters. To be clear, the context 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// does NOT reflect the position in a chain, or the fact that there are prior 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// or later filters in a chain. 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass FilterContext { 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Enum to control what histograms are emitted near end-of-life of this 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // instance. 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum StatisticSelector { 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SDCH_DECODE, 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SDCH_PASSTHROUGH, 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SDCH_EXPERIMENT_DECODE, 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SDCH_EXPERIMENT_HOLDBACK, 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~FilterContext(); 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // What mime type was specified in the header for this data? 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Only makes senses for some types of contexts, and returns false 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // when not applicable. 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual bool GetMimeType(std::string* mime_type) const = 0; 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // What URL was used to access this data? 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Return false if gurl is not present. 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual bool GetURL(GURL* gurl) const = 0; 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // When was this data requested from a server? 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual base::Time GetRequestTime() const = 0; 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Is data supplied from cache, or fresh across the net? 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual bool IsCachedContent() const = 0; 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Is this a download? 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual bool IsDownload() const = 0; 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Was this data flagged as a response to a request with an SDCH dictionary? 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual bool IsSdchResponse() const = 0; 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // How many bytes were read from the net or cache so far (and potentially 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // pushed into a filter for processing)? 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual int64 GetByteReadCount() const = 0; 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // What response code was received with the associated network transaction? 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // For example: 200 is ok. 4xx are error codes. etc. 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual int GetResponseCode() const = 0; 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The following method forces the context to emit a specific set of 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // statistics as selected by the argument. 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void RecordPacketStats(StatisticSelector statistic) const = 0; 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------ 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass Filter { 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Return values of function ReadFilteredData. 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum FilterStatus { 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Read filtered data successfully 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FILTER_OK, 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Read filtered data successfully, and the data in the buffer has been 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // consumed by the filter, but more data is needed in order to continue 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // filtering. At this point, the caller is free to reuse the filter 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // buffer to provide more data. 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FILTER_NEED_MORE_DATA, 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Read filtered data successfully, and filter reaches the end of the data 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // stream. 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FILTER_DONE, 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // There is an error during filtering. 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FILTER_ERROR 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Specifies type of filters that can be created. 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum FilterType { 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FILTER_TYPE_DEFLATE, 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FILTER_TYPE_GZIP, 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FILTER_TYPE_GZIP_HELPING_SDCH, // Gzip possible, but pass through allowed. 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FILTER_TYPE_SDCH, 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FILTER_TYPE_SDCH_POSSIBLE, // Sdch possible, but pass through allowed. 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FILTER_TYPE_UNSUPPORTED, 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual ~Filter(); 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Creates a Filter object. 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Parameters: Filter_types specifies the type of filter created; 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // filter_context allows filters to acquire additional details needed for 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // construction and operation, such as a specification of requisite input 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // buffer size. 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If success, the function returns the pointer to the Filter object created. 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If failed or a filter is not needed, the function returns NULL. 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Note: filter_types is an array of filter types (content encoding types as 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // provided in an HTTP header), which will be chained together serially to do 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // successive filtering of data. The types in the vector are ordered based on 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // encoding order, and the filters are chained to operate in the reverse 145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // (decoding) order. For example, types[0] = FILTER_TYPE_SDCH, 146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // types[1] = FILTER_TYPE_GZIP will cause data to first be gunzip filtered, 147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // and the resulting output from that filter will be sdch decoded. 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static Filter* Factory(const std::vector<FilterType>& filter_types, 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const FilterContext& filter_context); 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // A simpler version of Factory() which creates a single, unchained 152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Filter of type FILTER_TYPE_GZIP, or NULL if the filter could not be 153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // initialized. 154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static Filter* GZipFactory(); 155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // External call to obtain data from this filter chain. If ther is no 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // next_filter_, then it obtains data from this specific filter. 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilterStatus ReadData(char* dest_buffer, int* dest_len); 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns a pointer to the stream_buffer_. 161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IOBuffer* stream_buffer() const { return stream_buffer_.get(); } 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns the maximum size of stream_buffer_ in number of chars. 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int stream_buffer_size() const { return stream_buffer_size_; } 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns the total number of chars remaining in stream_buffer_ to be 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // filtered. 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the function returns 0 then all data has been filtered, and the caller 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // is safe to copy new data into stream_buffer_. 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int stream_data_len() const { return stream_data_len_; } 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Flushes stream_buffer_ for next round of filtering. After copying data to 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // stream_buffer_, the caller should call this function to notify Filter to 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // start filtering. Then after this function is called, the caller can get 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // post-filtered data using ReadFilteredData. The caller must not write to 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // stream_buffer_ and call this function again before stream_buffer_ is 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // emptied out by ReadFilteredData. 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The input stream_data_len is the length (in number of chars) of valid 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // data in stream_buffer_. It can not be greater than stream_buffer_size_. 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The function returns true if success, and false otherwise. 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool FlushStreamBuffer(int stream_data_len); 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Translate the text of a filter name (from Content-Encoding header) into a 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // FilterType. 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static FilterType ConvertEncodingToType(const std::string& filter_type); 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Given a array of encoding_types, try to do some error recovery adjustment 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // to the list. This includes handling known bugs in the Apache server (where 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // redundant gzip encoding is specified), as well as issues regarding SDCH 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // encoding, where various proxies and anti-virus products modify or strip the 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // encodings. These fixups require context, which includes whether this 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // response was made to an SDCH request (i.e., an available dictionary was 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // advertised in the GET), as well as the mime type of the content. 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void FixupEncodingTypes(const FilterContext& filter_context, 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::vector<FilterType>* encoding_types); 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen friend class GZipUnitTest; 201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen friend class SdchFilterChainingTest; 20272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Filter(); 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Filters the data stored in stream_buffer_ and writes the output into the 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // dest_buffer passed in. 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Upon entry, *dest_len is the total size (in number of chars) of the 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // destination buffer. Upon exit, *dest_len is the actual number of chars 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // written into the destination buffer. 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This function will fail if there is no pre-filter data in the 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // stream_buffer_. On the other hand, *dest_len can be 0 upon successful 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // return. For example, a decoding filter may process some pre-filter data 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // but not produce output yet. 216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual FilterStatus ReadFilteredData(char* dest_buffer, int* dest_len) = 0; 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Copy pre-filter data directly to destination buffer without decoding. 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilterStatus CopyOut(char* dest_buffer, int* dest_len); 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilterStatus last_status() const { return last_status_; } 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Buffer to hold the data to be filtered (the input queue). 224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_refptr<IOBuffer> stream_buffer_; 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Maximum size of stream_buffer_ in number of chars. 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int stream_buffer_size_; 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Pointer to the next data in stream_buffer_ to be filtered. 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char* next_stream_data_; 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Total number of remaining chars in stream_buffer_ to be filtered. 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int stream_data_len_; 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Allocates and initializes stream_buffer_ and stream_buffer_size_. 237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void InitBuffer(int size); 238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // A factory helper for creating filters for within a chain of potentially 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // multiple encodings. If a chain of filters is created, then this may be 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // called multiple times during the filter creation process. In most simple 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // cases, this is only called once. Returns NULL and cleans up (deleting 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // filter_list) if a new filter can't be constructed. 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static Filter* PrependNewFilter(FilterType type_id, 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const FilterContext& filter_context, 246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int buffer_size, 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Filter* filter_list); 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Helper methods for PrependNewFilter. If initialization is successful, 250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // they return a fully initialized Filter. Otherwise, return NULL. 251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static Filter* InitGZipFilter(FilterType type_id, int buffer_size); 252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static Filter* InitSdchFilter(FilterType type_id, 253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const FilterContext& filter_context, 254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int buffer_size); 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Helper function to empty our output into the next filter's input. 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void PushDataIntoNextFilter(); 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Constructs a filter with an internal buffer of the given size. 260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Only meant to be called by unit tests that need to control the buffer size. 261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static Filter* FactoryForTests(const std::vector<FilterType>& filter_types, 262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const FilterContext& filter_context, 263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int buffer_size); 264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // An optional filter to process output from this filter. 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<Filter> next_filter_; 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Remember what status or local filter last returned so we can better handle 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // chained filters. 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilterStatus last_status_; 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(Filter); 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} // namespace net 275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NET_BASE_FILTER_H__ 277