Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 // Filter performs filtering on data streams. Sample usage: | 5 // Filter performs filtering on data streams. Sample usage: |
| 6 // | 6 // |
| 7 // IStream* pre_filter_source; | 7 // IStream* pre_filter_source; |
| 8 // ... | 8 // ... |
| 9 // Filter* filter = Filter::Factory(filter_type, size); | 9 // Filter* filter = Filter::Factory(filter_type, size); |
| 10 // int pre_filter_data_len = filter->stream_buffer_size(); | 10 // int pre_filter_data_len = filter->stream_buffer_size(); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 #include <string> | 32 #include <string> |
| 33 #include <vector> | 33 #include <vector> |
| 34 | 34 |
| 35 #include "base/basictypes.h" | 35 #include "base/basictypes.h" |
| 36 #include "base/scoped_ptr.h" | 36 #include "base/scoped_ptr.h" |
| 37 #include "base/time.h" | 37 #include "base/time.h" |
| 38 #include "net/base/io_buffer.h" | 38 #include "net/base/io_buffer.h" |
| 39 #include "googleurl/src/gurl.h" | 39 #include "googleurl/src/gurl.h" |
| 40 #include "testing/gtest/include/gtest/gtest_prod.h" | 40 #include "testing/gtest/include/gtest/gtest_prod.h" |
| 41 | 41 |
| 42 //------------------------------------------------------------------------------ | |
| 43 // Define an interface class that allows access to contextual information | |
| 44 // supplied by the owner of this filter. | |
|
huanr
2009/03/09 17:50:44
Can you also comment on filter chain? If the filte
jar (doing other things)
2009/03/09 19:00:41
Done.
| |
| 45 class FilterContext { | |
| 46 public: | |
| 47 FilterContext() = 0; | |
|
wtc
2009/03/09 17:24:09
We should not need to declare and define (with = 0
huanr
2009/03/09 17:50:44
+1
On 2009/03/09 17:24:09, wtc wrote:
jar (doing other things)
2009/03/09 19:00:41
The problem was apparently that my use of DISALLOW
| |
| 48 virtual ~FilterContext() = 0; | |
| 49 | |
| 50 // What mime type was specified in the header for this data? | |
| 51 virtual bool GetMimeType(std::string* mime_type) const = 0; | |
| 52 | |
| 53 // What URL was used to access this data? | |
| 54 // Return false if gurl is not present. | |
| 55 virtual bool GetURL(GURL* gurl) const = 0; | |
| 56 | |
| 57 // When was this data requested from a server? | |
| 58 virtual base::Time GetRequestTime() const = 0; | |
| 59 | |
| 60 // Is data supplied from cache, or fresh across the net? | |
| 61 virtual bool IsCachedContent() const = 0; | |
| 62 | |
| 63 // TODO(jar): We could use flags, defined by callers, rather than naming a | |
| 64 // protocol here in the base class. | |
| 65 // Was this data flagged as a response to a request with an SDCH dictionary? | |
| 66 virtual bool IsSdchResponse() const = 0; | |
| 67 | |
| 68 // What is the desirable input buffer size for these filters? | |
| 69 virtual int GetInputStreambufferSize() const = 0; | |
| 70 | |
| 71 private: | |
| 72 DISALLOW_COPY_AND_ASSIGN(FilterContext); | |
| 73 }; | |
| 74 | |
| 75 //------------------------------------------------------------------------------ | |
| 42 class Filter { | 76 class Filter { |
| 43 public: | 77 public: |
| 44 // Return values of function ReadFilteredData. | 78 // Return values of function ReadFilteredData. |
| 45 enum FilterStatus { | 79 enum FilterStatus { |
| 46 // Read filtered data successfully | 80 // Read filtered data successfully |
| 47 FILTER_OK, | 81 FILTER_OK, |
| 48 // Read filtered data successfully, and the data in the buffer has been | 82 // Read filtered data successfully, and the data in the buffer has been |
| 49 // consumed by the filter, but more data is needed in order to continue | 83 // consumed by the filter, but more data is needed in order to continue |
| 50 // filtering. At this point, the caller is free to reuse the filter | 84 // filtering. At this point, the caller is free to reuse the filter |
| 51 // buffer to provide more data. | 85 // buffer to provide more data. |
| 52 FILTER_NEED_MORE_DATA, | 86 FILTER_NEED_MORE_DATA, |
| 53 // Read filtered data successfully, and filter reaches the end of the data | 87 // Read filtered data successfully, and filter reaches the end of the data |
| 54 // stream. | 88 // stream. |
| 55 FILTER_DONE, | 89 FILTER_DONE, |
| 56 // There is an error during filtering. | 90 // There is an error during filtering. |
| 57 FILTER_ERROR | 91 FILTER_ERROR |
| 58 }; | 92 }; |
| 59 | 93 |
| 60 // Specifies type of filters that can be created. | 94 // Specifies type of filters that can be created. |
| 61 enum FilterType { | 95 enum FilterType { |
| 62 FILTER_TYPE_DEFLATE, | 96 FILTER_TYPE_DEFLATE, |
| 63 FILTER_TYPE_GZIP, | 97 FILTER_TYPE_GZIP, |
| 64 FILTER_TYPE_BZIP2, | 98 FILTER_TYPE_BZIP2, |
| 65 FILTER_TYPE_GZIP_HELPING_SDCH, // Gzip possible, but pass through allowed. | 99 FILTER_TYPE_GZIP_HELPING_SDCH, // Gzip possible, but pass through allowed. |
| 66 FILTER_TYPE_SDCH, | 100 FILTER_TYPE_SDCH, |
| 67 FILTER_TYPE_SDCH_POSSIBLE, // Sdch possible, but pass through allowed. | 101 FILTER_TYPE_SDCH_POSSIBLE, // Sdch possible, but pass through allowed. |
| 68 FILTER_TYPE_UNSUPPORTED, | 102 FILTER_TYPE_UNSUPPORTED, |
| 69 }; | 103 }; |
| 70 | 104 |
| 71 | |
| 72 virtual ~Filter(); | 105 virtual ~Filter(); |
| 73 | 106 |
| 74 // Creates a Filter object. | 107 // Creates a Filter object. |
| 75 // Parameters: Filter_types specifies the type of filter created; Buffer_size | 108 // Parameters: Filter_types specifies the type of filter created; |
| 76 // specifies the size (in number of chars) of the buffer the filter should | 109 // filter_context allows filters to acquire additional details needed for |
| 77 // allocate to hold pre-filter data. | 110 // construction and operation, such as a specification of requisite input |
| 111 // buffer size. | |
| 78 // If success, the function returns the pointer to the Filter object created. | 112 // If success, the function returns the pointer to the Filter object created. |
| 79 // If failed or a filter is not needed, the function returns NULL. | 113 // If failed or a filter is not needed, the function returns NULL. |
| 80 // | 114 // |
| 81 // Note: filter_types is an array of filter names (content encoding types as | 115 // Note: filter_types is an array of filter names (content encoding types as |
| 82 // provided in an HTTP header), which will be chained together serially do | 116 // provided in an HTTP header), which will be chained together serially to do |
| 83 // successive filtering of data. The names in the vector are ordered based on | 117 // successive filtering of data. The names in the vector are ordered based on |
| 84 // encoding order, and the filters are chained to operate in the reverse | 118 // encoding order, and the filters are chained to operate in the reverse |
| 85 // (decoding) order. For example, types[0] = "sdch", types[1] = "gzip" will | 119 // (decoding) order. For example, types[0] = "sdch", types[1] = "gzip" will |
| 86 // cause data to first be gunizip filtered, and the resulting output from that | 120 // cause data to first be gunizip filtered, and the resulting output from that |
| 87 // filter will be sdch decoded. | 121 // filter will be sdch decoded. |
| 88 static Filter* Factory(const std::vector<FilterType>& filter_types, | 122 static Filter* Factory(const std::vector<FilterType>& filter_types, |
| 89 int buffer_size); | 123 const FilterContext& filter_context); |
| 90 | 124 |
| 91 // External call to obtain data from this filter chain. If ther is no | 125 // External call to obtain data from this filter chain. If ther is no |
| 92 // next_filter_, then it obtains data from this specific filter. | 126 // next_filter_, then it obtains data from this specific filter. |
| 93 FilterStatus ReadData(char* dest_buffer, int* dest_len); | 127 FilterStatus ReadData(char* dest_buffer, int* dest_len); |
| 94 | 128 |
| 95 // Returns a pointer to the stream_buffer_. | 129 // Returns a pointer to the stream_buffer_. |
| 96 net::IOBuffer* stream_buffer() const { return stream_buffer_.get(); } | 130 net::IOBuffer* stream_buffer() const { return stream_buffer_.get(); } |
| 97 | 131 |
| 98 // Returns the maximum size of stream_buffer_ in number of chars. | 132 // Returns the maximum size of stream_buffer_ in number of chars. |
| 99 int stream_buffer_size() const { return stream_buffer_size_; } | 133 int stream_buffer_size() const { return stream_buffer_size_; } |
| 100 | 134 |
| 101 // Returns the total number of chars remaining in stream_buffer_ to be | 135 // Returns the total number of chars remaining in stream_buffer_ to be |
| 102 // filtered. | 136 // filtered. |
| 103 // | 137 // |
| 104 // If the function returns 0 then all data have been filtered and the caller | 138 // If the function returns 0 then all data has been filtered, and the caller |
| 105 // is safe to copy new data into stream_buffer_. | 139 // is safe to copy new data into stream_buffer_. |
| 106 int stream_data_len() const { return stream_data_len_; } | 140 int stream_data_len() const { return stream_data_len_; } |
| 107 | 141 |
| 108 // Flushes stream_buffer_ for next round of filtering. After copying data to | 142 // Flushes stream_buffer_ for next round of filtering. After copying data to |
| 109 // stream_buffer_, the caller should call this function to notify Filter to | 143 // stream_buffer_, the caller should call this function to notify Filter to |
| 110 // start filtering. Then after this function is called, the caller can get | 144 // start filtering. Then after this function is called, the caller can get |
| 111 // post-filtered data using ReadFilteredData. The caller must not write to | 145 // post-filtered data using ReadFilteredData. The caller must not write to |
| 112 // stream_buffer_ and call this function again before stream_buffer_ is empty | 146 // stream_buffer_ and call this function again before stream_buffer_ is |
| 113 // out by ReadFilteredData. | 147 // emptied out by ReadFilteredData. |
| 114 // | 148 // |
| 115 // The input stream_data_len is the length (in number of chars) of valid | 149 // The input stream_data_len is the length (in number of chars) of valid |
| 116 // data in stream_buffer_. It can not be greater than stream_buffer_size_. | 150 // data in stream_buffer_. It can not be greater than stream_buffer_size_. |
| 117 // The function returns true if success, and false otherwise. | 151 // The function returns true if success, and false otherwise. |
| 118 bool FlushStreamBuffer(int stream_data_len); | 152 bool FlushStreamBuffer(int stream_data_len); |
| 119 | 153 |
| 120 void SetURL(const GURL& url); | 154 void SetURL(const GURL& url); |
| 121 const GURL& url() const { return url_; } | 155 const GURL& url() const { return url_; } |
| 122 | 156 |
| 123 void SetMimeType(const std::string& mime_type); | 157 void SetMimeType(const std::string& mime_type); |
| 124 const std::string& mime_type() const { return mime_type_; } | 158 const std::string& mime_type() const { return mime_type_; } |
| 125 | 159 |
| 126 void SetConnectTime(const base::Time& time, bool was_cached); | 160 void SetConnectTime(const base::Time& time, bool was_cached); |
| 127 | 161 |
| 128 // Translate the text of a filter name (from Content-Encoding header) into a | 162 // Translate the text of a filter name (from Content-Encoding header) into a |
| 129 // FilterType. | 163 // FilterType. |
| 130 static FilterType ConvertEncodingToType(const std::string& filter_type); | 164 static FilterType ConvertEncodingToType(const std::string& filter_type); |
| 131 | 165 |
| 132 // Given a array of encoding_types, try to do some error recovery adjustment | 166 // Given a array of encoding_types, try to do some error recovery adjustment |
| 133 // to the list. This includes handling known bugs in the Apache server (where | 167 // to the list. This includes handling known bugs in the Apache server (where |
| 134 // redundant gzip encoding is specified), as well as issues regarding SDCH | 168 // redundant gzip encoding is specified), as well as issues regarding SDCH |
| 135 // encoding, where various proxies and anti-virus products modify or strip the | 169 // encoding, where various proxies and anti-virus products modify or strip the |
| 136 // encodings. These fixups require context, which includes whether this | 170 // encodings. These fixups require context, which includes whether this |
| 137 // response was made to an SDCH request (i.e., an available dictionary was | 171 // response was made to an SDCH request (i.e., an available dictionary was |
| 138 // advertised in the GET), as well as the mime type of the content. | 172 // advertised in the GET), as well as the mime type of the content. |
| 139 static void FixupEncodingTypes(bool is_sdch_response, | 173 static void FixupEncodingTypes(bool is_sdch_response, |
| 140 const std::string& mime_type, | 174 const std::string& mime_type, |
| 141 std::vector<FilterType>* encoding_types); | 175 std::vector<FilterType>* encoding_types); |
| 142 protected: | 176 protected: |
| 143 Filter(); | 177 explicit Filter(const FilterContext& filter_context); |
| 144 | 178 |
| 145 FRIEND_TEST(SdchFilterTest, ContentTypeId); | 179 FRIEND_TEST(SdchFilterTest, ContentTypeId); |
| 146 // Filters the data stored in stream_buffer_ and writes the output into the | 180 // Filters the data stored in stream_buffer_ and writes the output into the |
| 147 // dest_buffer passed in. | 181 // dest_buffer passed in. |
| 148 // | 182 // |
| 149 // Upon entry, *dest_len is the total size (in number of chars) of the | 183 // Upon entry, *dest_len is the total size (in number of chars) of the |
| 150 // destination buffer. Upon exit, *dest_len is the actual number of chars | 184 // destination buffer. Upon exit, *dest_len is the actual number of chars |
| 151 // written into the destination buffer. | 185 // written into the destination buffer. |
| 152 // | 186 // |
| 153 // This function will fail if there is no pre-filter data in the | 187 // This function will fail if there is no pre-filter data in the |
| 154 // stream_buffer_. On the other hand, *dest_len can be 0 upon successful | 188 // stream_buffer_. On the other hand, *dest_len can be 0 upon successful |
| 155 // return. For example, a decoding filter may process some pre-filter data | 189 // return. For example, a decoding filter may process some pre-filter data |
| 156 // but not produce output yet. | 190 // but not produce output yet. |
| 157 virtual FilterStatus ReadFilteredData(char* dest_buffer, int* dest_len); | 191 virtual FilterStatus ReadFilteredData(char* dest_buffer, int* dest_len); |
| 158 | 192 |
| 159 // Copy pre-filter data directly to destination buffer without decoding. | 193 // Copy pre-filter data directly to destination buffer without decoding. |
| 160 FilterStatus CopyOut(char* dest_buffer, int* dest_len); | 194 FilterStatus CopyOut(char* dest_buffer, int* dest_len); |
| 161 | 195 |
| 162 // Allocates and initializes stream_buffer_. | 196 // Allocates and initializes stream_buffer_ based on filter_context_. |
| 163 // Buffer_size is the maximum size of stream_buffer_ in number of chars. | 197 // Establishes a buffer large enough to handle the amount specified in |
| 164 bool InitBuffer(int buffer_size); | 198 // filter_context_.GetInputStreambufferSize(). |
| 199 bool InitBuffer(); | |
| 165 | 200 |
| 166 // A factory helper for creating filters for within a chain of potentially | 201 // A factory helper for creating filters for within a chain of potentially |
| 167 // multiple encodings. If a chain of filters is created, then this may be | 202 // multiple encodings. If a chain of filters is created, then this may be |
| 168 // called multiple times during the filter creation process. In most simple | 203 // called multiple times during the filter creation process. In most simple |
| 169 // cases, this is only called once. Returns NULL and cleans up (deleting | 204 // cases, this is only called once. Returns NULL and cleans up (deleting |
| 170 // filter_list) if a new filter can't be constructed. | 205 // filter_list) if a new filter can't be constructed. |
| 171 static Filter* PrependNewFilter(FilterType type_id, int buffer_size, | 206 static Filter* PrependNewFilter(FilterType type_id, |
| 207 const FilterContext& filter_context, | |
| 172 Filter* filter_list); | 208 Filter* filter_list); |
| 173 | 209 |
| 174 FilterStatus last_status() const { return last_status_; } | 210 FilterStatus last_status() const { return last_status_; } |
| 175 | 211 |
| 176 base::Time connect_time() const { return connect_time_; } | 212 base::Time connect_time() const { return connect_time_; } |
| 177 | 213 |
| 178 bool was_cached() const { return was_cached_; } | 214 bool was_cached() const { return was_cached_; } |
| 179 | 215 |
| 180 // Buffer to hold the data to be filtered. | 216 // Buffer to hold the data to be filtered (the input queue). |
| 181 scoped_refptr<net::IOBuffer> stream_buffer_; | 217 scoped_refptr<net::IOBuffer> stream_buffer_; |
| 182 | 218 |
| 183 // Maximum size of stream_buffer_ in number of chars. | 219 // Maximum size of stream_buffer_ in number of chars. |
| 184 int stream_buffer_size_; | 220 int stream_buffer_size_; |
| 185 | 221 |
| 186 // Pointer to the next data in stream_buffer_ to be filtered. | 222 // Pointer to the next data in stream_buffer_ to be filtered. |
| 187 char* next_stream_data_; | 223 char* next_stream_data_; |
| 188 | 224 |
| 189 // Total number of remaining chars in stream_buffer_ to be filtered. | 225 // Total number of remaining chars in stream_buffer_ to be filtered. |
| 190 int stream_data_len_; | 226 int stream_data_len_; |
| 191 | 227 |
| 228 private: // TODO(jar): Make more data private by moving this up higher. | |
| 192 // The URL that is currently being filtered. | 229 // The URL that is currently being filtered. |
| 193 // This is used by SDCH filters which need to restrict use of a dictionary to | 230 // This is used by SDCH filters which need to restrict use of a dictionary to |
| 194 // a specific URL or path. | 231 // a specific URL or path. |
| 195 GURL url_; | 232 GURL url_; |
| 196 | 233 |
| 197 // To facilitate histogramming by individual filters, we store the connect | 234 // To facilitate histogramming by individual filters, we store the connect |
| 198 // time for the corresponding HTTP transaction, as well as whether this time | 235 // time for the corresponding HTTP transaction, as well as whether this time |
| 199 // was recalled from a cached entry. | 236 // was recalled from a cached entry. |
| 200 base::Time connect_time_; | 237 base::Time connect_time_; |
| 201 bool was_cached_; | 238 bool was_cached_; |
| 202 | 239 |
| 203 private: // TODO(jar): Make more data private by moving this up higher. | |
| 204 // Helper function to empty our output into the next filter's input. | 240 // Helper function to empty our output into the next filter's input. |
| 205 void PushDataIntoNextFilter(); | 241 void PushDataIntoNextFilter(); |
| 206 | 242 |
| 207 // To facilitate error recovery in SDCH filters, allow filter to know if | 243 // To facilitate error recovery in SDCH filters, allow filter to know if |
| 208 // content is text/html by checking within this mime type (SDCH filter may | 244 // content is text/html by checking within this mime type (SDCH filter may |
| 209 // do a meta-refresh via html). | 245 // do a meta-refresh via html). |
| 210 std::string mime_type_; | 246 std::string mime_type_; |
| 211 | 247 |
| 212 // An optional filter to process output from this filter. | 248 // An optional filter to process output from this filter. |
| 213 scoped_ptr<Filter> next_filter_; | 249 scoped_ptr<Filter> next_filter_; |
| 214 // Remember what status or local filter last returned so we can better handle | 250 // Remember what status or local filter last returned so we can better handle |
| 215 // chained filters. | 251 // chained filters. |
| 216 FilterStatus last_status_; | 252 FilterStatus last_status_; |
| 217 | 253 |
| 254 // Context data from the owner of this filter. Some filters need additional | |
| 255 // context information (mime type, etc.) to properly function, and they access | |
| 256 // this data via this reference member. | |
| 257 const FilterContext& filter_context_; | |
| 258 | |
| 218 DISALLOW_COPY_AND_ASSIGN(Filter); | 259 DISALLOW_COPY_AND_ASSIGN(Filter); |
| 219 }; | 260 }; |
| 220 | 261 |
| 221 #endif // NET_BASE_FILTER_H__ | 262 #endif // NET_BASE_FILTER_H__ |
| 222 | 263 |
| OLD | NEW |