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 23 matching lines...) Expand all Loading... |
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 //------------------------------------------------------------------------------ | 42 //------------------------------------------------------------------------------ |
43 // Define an interface class that allows access to contextual information | 43 // Define an interface class that allows access to contextual information |
44 // supplied by the owner of this filter. | 44 // supplied by the owner of this filter. In the case where there are a chain of |
| 45 // filters, there is only one owner of all the chained filters, and that context |
| 46 // is passed to the constructor of all those filters. To be clear, the context |
| 47 // does NOT reflect the position in a chain, or the fact that there are prior |
| 48 // or later filters in a chain. |
45 class FilterContext { | 49 class FilterContext { |
46 public: | 50 public: |
47 FilterContext() {}; | 51 virtual ~FilterContext() {} |
48 virtual ~FilterContext() {}; | |
49 | 52 |
50 // What mime type was specified in the header for this data? | 53 // What mime type was specified in the header for this data? |
| 54 // Only makes senses for some types of contexts, and returns false |
| 55 // when not applicable. |
51 virtual bool GetMimeType(std::string* mime_type) const = 0; | 56 virtual bool GetMimeType(std::string* mime_type) const = 0; |
52 | 57 |
53 // What URL was used to access this data? | 58 // What URL was used to access this data? |
54 // Return false if gurl is not present. | 59 // Return false if gurl is not present. |
55 virtual bool GetURL(GURL* gurl) const = 0; | 60 virtual bool GetURL(GURL* gurl) const = 0; |
56 | 61 |
57 // When was this data requested from a server? | 62 // When was this data requested from a server? |
58 virtual base::Time GetRequestTime() const = 0; | 63 virtual base::Time GetRequestTime() const = 0; |
59 | 64 |
60 // Is data supplied from cache, or fresh across the net? | 65 // Is data supplied from cache, or fresh across the net? |
61 virtual bool IsCachedContent() const = 0; | 66 virtual bool IsCachedContent() const = 0; |
62 | 67 |
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? | 68 // Was this data flagged as a response to a request with an SDCH dictionary? |
66 virtual bool IsSdchResponse() const = 0; | 69 virtual bool IsSdchResponse() const = 0; |
67 | 70 |
| 71 // How many bytes were read from the net or cache so far (and potentially |
| 72 // pushed into a filter for processing)? |
| 73 virtual int64 GetByteReadCount() const = 0; |
| 74 |
68 // What is the desirable input buffer size for these filters? | 75 // What is the desirable input buffer size for these filters? |
69 virtual int GetInputStreambufferSize() const = 0; | 76 // This value is currently supplied by the context, and is constant for all |
70 | 77 // filters, even when they are part of a chain of filters. (i.e., we currently |
71 private: | 78 // don't change the input buffer sizes for a linked chain of filters, and the |
72 DISALLOW_COPY_AND_ASSIGN(FilterContext); | 79 // buffer size for input to all filters in a chain is this one constant). |
| 80 virtual int GetInputStreamBufferSize() const = 0; |
73 }; | 81 }; |
74 | 82 |
75 //------------------------------------------------------------------------------ | 83 //------------------------------------------------------------------------------ |
76 class Filter { | 84 class Filter { |
77 public: | 85 public: |
78 // Return values of function ReadFilteredData. | 86 // Return values of function ReadFilteredData. |
79 enum FilterStatus { | 87 enum FilterStatus { |
80 // Read filtered data successfully | 88 // Read filtered data successfully |
81 FILTER_OK, | 89 FILTER_OK, |
82 // Read filtered data successfully, and the data in the buffer has been | 90 // Read filtered data successfully, and the data in the buffer has been |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 // start filtering. Then after this function is called, the caller can get | 152 // start filtering. Then after this function is called, the caller can get |
145 // post-filtered data using ReadFilteredData. The caller must not write to | 153 // post-filtered data using ReadFilteredData. The caller must not write to |
146 // stream_buffer_ and call this function again before stream_buffer_ is | 154 // stream_buffer_ and call this function again before stream_buffer_ is |
147 // emptied out by ReadFilteredData. | 155 // emptied out by ReadFilteredData. |
148 // | 156 // |
149 // The input stream_data_len is the length (in number of chars) of valid | 157 // The input stream_data_len is the length (in number of chars) of valid |
150 // data in stream_buffer_. It can not be greater than stream_buffer_size_. | 158 // data in stream_buffer_. It can not be greater than stream_buffer_size_. |
151 // The function returns true if success, and false otherwise. | 159 // The function returns true if success, and false otherwise. |
152 bool FlushStreamBuffer(int stream_data_len); | 160 bool FlushStreamBuffer(int stream_data_len); |
153 | 161 |
154 void SetURL(const GURL& url); | |
155 const GURL& url() const { return url_; } | |
156 | |
157 void SetMimeType(const std::string& mime_type); | |
158 const std::string& mime_type() const { return mime_type_; } | |
159 | |
160 void SetConnectTime(const base::Time& time, bool was_cached); | |
161 | |
162 // 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 |
163 // FilterType. | 163 // FilterType. |
164 static FilterType ConvertEncodingToType(const std::string& filter_type); | 164 static FilterType ConvertEncodingToType(const std::string& filter_type); |
165 | 165 |
166 // 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 |
167 // 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 |
168 // redundant gzip encoding is specified), as well as issues regarding SDCH | 168 // redundant gzip encoding is specified), as well as issues regarding SDCH |
169 // 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 |
170 // encodings. These fixups require context, which includes whether this | 170 // encodings. These fixups require context, which includes whether this |
171 // 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 |
172 // 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. |
173 static void FixupEncodingTypes(bool is_sdch_response, | 173 static void FixupEncodingTypes(const FilterContext& filter_context, |
174 const std::string& mime_type, | |
175 std::vector<FilterType>* encoding_types); | 174 std::vector<FilterType>* encoding_types); |
176 protected: | 175 protected: |
177 explicit Filter(const FilterContext& filter_context); | 176 explicit Filter(const FilterContext& filter_context); |
178 | 177 |
179 FRIEND_TEST(SdchFilterTest, ContentTypeId); | 178 FRIEND_TEST(SdchFilterTest, ContentTypeId); |
180 // Filters the data stored in stream_buffer_ and writes the output into the | 179 // Filters the data stored in stream_buffer_ and writes the output into the |
181 // dest_buffer passed in. | 180 // dest_buffer passed in. |
182 // | 181 // |
183 // Upon entry, *dest_len is the total size (in number of chars) of the | 182 // Upon entry, *dest_len is the total size (in number of chars) of the |
184 // destination buffer. Upon exit, *dest_len is the actual number of chars | 183 // destination buffer. Upon exit, *dest_len is the actual number of chars |
185 // written into the destination buffer. | 184 // written into the destination buffer. |
186 // | 185 // |
187 // This function will fail if there is no pre-filter data in the | 186 // This function will fail if there is no pre-filter data in the |
188 // stream_buffer_. On the other hand, *dest_len can be 0 upon successful | 187 // stream_buffer_. On the other hand, *dest_len can be 0 upon successful |
189 // return. For example, a decoding filter may process some pre-filter data | 188 // return. For example, a decoding filter may process some pre-filter data |
190 // but not produce output yet. | 189 // but not produce output yet. |
191 virtual FilterStatus ReadFilteredData(char* dest_buffer, int* dest_len); | 190 virtual FilterStatus ReadFilteredData(char* dest_buffer, int* dest_len); |
192 | 191 |
193 // Copy pre-filter data directly to destination buffer without decoding. | 192 // Copy pre-filter data directly to destination buffer without decoding. |
194 FilterStatus CopyOut(char* dest_buffer, int* dest_len); | 193 FilterStatus CopyOut(char* dest_buffer, int* dest_len); |
195 | 194 |
196 // Allocates and initializes stream_buffer_ based on filter_context_. | |
197 // Establishes a buffer large enough to handle the amount specified in | |
198 // filter_context_.GetInputStreambufferSize(). | |
199 bool InitBuffer(); | |
200 | |
201 // A factory helper for creating filters for within a chain of potentially | |
202 // multiple encodings. If a chain of filters is created, then this may be | |
203 // called multiple times during the filter creation process. In most simple | |
204 // cases, this is only called once. Returns NULL and cleans up (deleting | |
205 // filter_list) if a new filter can't be constructed. | |
206 static Filter* PrependNewFilter(FilterType type_id, | |
207 const FilterContext& filter_context, | |
208 Filter* filter_list); | |
209 | |
210 FilterStatus last_status() const { return last_status_; } | 195 FilterStatus last_status() const { return last_status_; } |
211 | 196 |
212 base::Time connect_time() const { return connect_time_; } | 197 const FilterContext& filter_context() const { return filter_context_; } |
213 | |
214 bool was_cached() const { return was_cached_; } | |
215 | 198 |
216 // Buffer to hold the data to be filtered (the input queue). | 199 // Buffer to hold the data to be filtered (the input queue). |
217 scoped_refptr<net::IOBuffer> stream_buffer_; | 200 scoped_refptr<net::IOBuffer> stream_buffer_; |
218 | 201 |
219 // Maximum size of stream_buffer_ in number of chars. | 202 // Maximum size of stream_buffer_ in number of chars. |
220 int stream_buffer_size_; | 203 int stream_buffer_size_; |
221 | 204 |
222 // Pointer to the next data in stream_buffer_ to be filtered. | 205 // Pointer to the next data in stream_buffer_ to be filtered. |
223 char* next_stream_data_; | 206 char* next_stream_data_; |
224 | 207 |
225 // Total number of remaining chars in stream_buffer_ to be filtered. | 208 // Total number of remaining chars in stream_buffer_ to be filtered. |
226 int stream_data_len_; | 209 int stream_data_len_; |
227 | 210 |
228 private: // TODO(jar): Make more data private by moving this up higher. | 211 private: |
229 // The URL that is currently being filtered. | 212 // A factory helper for creating filters for within a chain of potentially |
230 // This is used by SDCH filters which need to restrict use of a dictionary to | 213 // multiple encodings. If a chain of filters is created, then this may be |
231 // a specific URL or path. | 214 // called multiple times during the filter creation process. In most simple |
232 GURL url_; | 215 // cases, this is only called once. Returns NULL and cleans up (deleting |
| 216 // filter_list) if a new filter can't be constructed. |
| 217 static Filter* PrependNewFilter(FilterType type_id, |
| 218 const FilterContext& filter_context, |
| 219 Filter* filter_list); |
233 | 220 |
234 // To facilitate histogramming by individual filters, we store the connect | 221 // Allocates and initializes stream_buffer_ based on filter_context_. |
235 // time for the corresponding HTTP transaction, as well as whether this time | 222 // Establishes a buffer large enough to handle the amount specified in |
236 // was recalled from a cached entry. | 223 // filter_context_.GetInputStreamBufferSize(). |
237 base::Time connect_time_; | 224 bool InitBuffer(); |
238 bool was_cached_; | |
239 | 225 |
240 // Helper function to empty our output into the next filter's input. | 226 // Helper function to empty our output into the next filter's input. |
241 void PushDataIntoNextFilter(); | 227 void PushDataIntoNextFilter(); |
242 | 228 |
243 // To facilitate error recovery in SDCH filters, allow filter to know if | |
244 // content is text/html by checking within this mime type (SDCH filter may | |
245 // do a meta-refresh via html). | |
246 std::string mime_type_; | |
247 | |
248 // An optional filter to process output from this filter. | 229 // An optional filter to process output from this filter. |
249 scoped_ptr<Filter> next_filter_; | 230 scoped_ptr<Filter> next_filter_; |
250 // Remember what status or local filter last returned so we can better handle | 231 // Remember what status or local filter last returned so we can better handle |
251 // chained filters. | 232 // chained filters. |
252 FilterStatus last_status_; | 233 FilterStatus last_status_; |
253 | 234 |
254 // Context data from the owner of this filter. Some filters need additional | 235 // Context data from the owner of this filter. Some filters need additional |
255 // context information (mime type, etc.) to properly function, and they access | 236 // context information (mime type, etc.) to properly function, and they access |
256 // this data via this reference member. | 237 // this data via this reference member. |
257 const FilterContext& filter_context_; | 238 const FilterContext& filter_context_; |
258 | 239 |
259 DISALLOW_COPY_AND_ASSIGN(Filter); | 240 DISALLOW_COPY_AND_ASSIGN(Filter); |
260 }; | 241 }; |
261 | 242 |
262 #endif // NET_BASE_FILTER_H__ | 243 #endif // NET_BASE_FILTER_H__ |
OLD | NEW |