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 |