| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |  | 
| 2 // Use of this source code is governed by a BSD-style license that can be |  | 
| 3 // found in the LICENSE file. |  | 
| 4 |  | 
| 5 // GZipFilter applies gzip and deflate content encoding/decoding to a data |  | 
| 6 // stream. As specified by HTTP 1.1, with gzip encoding the content is |  | 
| 7 // wrapped with a gzip header, and with deflate encoding the content is in |  | 
| 8 // a raw, headerless DEFLATE stream. |  | 
| 9 // |  | 
| 10 // Internally GZipFilter uses zlib inflate to do decoding. |  | 
| 11 // |  | 
| 12 // GZipFilter is a subclass of Filter. See the latter's header file filter.h |  | 
| 13 // for sample usage. |  | 
| 14 |  | 
| 15 #ifndef NET_FILTER_GZIP_FILTER_H_ |  | 
| 16 #define NET_FILTER_GZIP_FILTER_H_ |  | 
| 17 |  | 
| 18 #include <memory> |  | 
| 19 |  | 
| 20 #include "base/macros.h" |  | 
| 21 #include "net/filter/filter.h" |  | 
| 22 |  | 
| 23 typedef struct z_stream_s z_stream; |  | 
| 24 |  | 
| 25 namespace net { |  | 
| 26 |  | 
| 27 class GZipHeader; |  | 
| 28 |  | 
| 29 class GZipFilter : public Filter { |  | 
| 30  public: |  | 
| 31   ~GZipFilter() override; |  | 
| 32 |  | 
| 33   // Initializes filter decoding mode and internal control blocks. |  | 
| 34   // Parameter filter_type specifies the type of filter, which corresponds to |  | 
| 35   // either gzip or deflate decoding. The function returns true if success and |  | 
| 36   // false otherwise. |  | 
| 37   // The filter can only be initialized once. |  | 
| 38   bool InitDecoding(Filter::FilterType filter_type); |  | 
| 39 |  | 
| 40   // Decodes the pre-filter data and writes the output into the dest_buffer |  | 
| 41   // passed in. |  | 
| 42   // The function returns FilterStatus. See filter.h for its description. |  | 
| 43   // |  | 
| 44   // Upon entry, *dest_len is the total size (in number of chars) of the |  | 
| 45   // destination buffer. Upon exit, *dest_len is the actual number of chars |  | 
| 46   // written into the destination buffer. |  | 
| 47   // |  | 
| 48   // This function will fail if there is no pre-filter data in the |  | 
| 49   // stream_buffer_. On the other hand, *dest_len can be 0 upon successful |  | 
| 50   // return. For example, the internal zlib may process some pre-filter data |  | 
| 51   // but not produce output yet. |  | 
| 52   FilterStatus ReadFilteredData(char* dest_buffer, int* dest_len) override; |  | 
| 53 |  | 
| 54  private: |  | 
| 55   enum DecodingStatus { |  | 
| 56     DECODING_UNINITIALIZED, |  | 
| 57     DECODING_IN_PROGRESS, |  | 
| 58     DECODING_DONE, |  | 
| 59     DECODING_ERROR |  | 
| 60   }; |  | 
| 61 |  | 
| 62   enum DecodingMode { |  | 
| 63     DECODE_MODE_GZIP, |  | 
| 64     DECODE_MODE_DEFLATE, |  | 
| 65     DECODE_MODE_UNKNOWN |  | 
| 66   }; |  | 
| 67 |  | 
| 68   enum GZipCheckHeaderState { |  | 
| 69     GZIP_CHECK_HEADER_IN_PROGRESS, |  | 
| 70     GZIP_GET_COMPLETE_HEADER, |  | 
| 71     GZIP_GET_INVALID_HEADER |  | 
| 72   }; |  | 
| 73 |  | 
| 74   static const int kGZipFooterSize = 8; |  | 
| 75 |  | 
| 76   // Only to be instantiated by Filter::Factory. |  | 
| 77   explicit GZipFilter(FilterType type); |  | 
| 78   friend class Filter; |  | 
| 79 |  | 
| 80   // Parses and verifies the GZip header. |  | 
| 81   // Upon exit, the function updates gzip_header_status_ accordingly. |  | 
| 82   // |  | 
| 83   // The function returns Filter::FILTER_OK if it gets a complete header and |  | 
| 84   // there are more data in the pre-filter buffer. |  | 
| 85   // The function returns Filter::FILTER_NEED_MORE_DATA if it parses all data |  | 
| 86   // in the pre-filter buffer, either getting a complete header or a partial |  | 
| 87   // header. The caller needs to check gzip_header_status_ and call this |  | 
| 88   // function again for partial header. |  | 
| 89   // The function returns Filter::FILTER_ERROR if error occurs. |  | 
| 90   FilterStatus CheckGZipHeader(); |  | 
| 91 |  | 
| 92   // Internal function to decode the pre-filter data and writes the output into |  | 
| 93   // the dest_buffer passed in. |  | 
| 94   // |  | 
| 95   // This is the internal version of ReadFilteredData. See the latter's |  | 
| 96   // comments for the use of function. |  | 
| 97   FilterStatus DoInflate(char* dest_buffer, int* dest_len); |  | 
| 98 |  | 
| 99   // Inserts a zlib header to the data stream before calling zlib inflate. |  | 
| 100   // This is used to work around server bugs. See more comments at the place |  | 
| 101   // it is called in gzip_filter.cc. |  | 
| 102   // The function returns true on success and false otherwise. |  | 
| 103   bool InsertZlibHeader(); |  | 
| 104 |  | 
| 105   // Skip the 8 byte GZip footer after z_stream_end |  | 
| 106   void SkipGZipFooter(); |  | 
| 107 |  | 
| 108   // Tracks the status of decoding. |  | 
| 109   // This variable is initialized by InitDecoding and updated only by |  | 
| 110   // ReadFilteredData. |  | 
| 111   DecodingStatus decoding_status_; |  | 
| 112 |  | 
| 113   // Indicates the type of content decoding the GZipFilter is performing. |  | 
| 114   // This variable is set only once by InitDecoding. |  | 
| 115   DecodingMode decoding_mode_; |  | 
| 116 |  | 
| 117   // Used to parse the gzip header in gzip stream. |  | 
| 118   // It is used when the decoding_mode_ is DECODE_MODE_GZIP. |  | 
| 119   std::unique_ptr<GZipHeader> gzip_header_; |  | 
| 120 |  | 
| 121   // Tracks the progress of parsing gzip header. |  | 
| 122   // This variable is maintained by gzip_header_. |  | 
| 123   GZipCheckHeaderState gzip_header_status_; |  | 
| 124 |  | 
| 125   // A flag used by InsertZlibHeader to record whether we've successfully added |  | 
| 126   // a zlib header to this stream. |  | 
| 127   bool zlib_header_added_; |  | 
| 128 |  | 
| 129   // Tracks how many bytes of gzip footer have been received. |  | 
| 130   int gzip_footer_bytes_; |  | 
| 131 |  | 
| 132   // The control block of zlib which actually does the decoding. |  | 
| 133   // This data structure is initialized by InitDecoding and updated only by |  | 
| 134   // DoInflate, with InsertZlibHeader being the exception as a workaround. |  | 
| 135   std::unique_ptr<z_stream> zlib_stream_; |  | 
| 136 |  | 
| 137   // For robustness, when we see the solo sdch filter, we chain in a gzip filter |  | 
| 138   // in front of it, with this flag to indicate that the gzip decoding might not |  | 
| 139   // be needed.  This handles a strange case where "Content-Encoding: sdch,gzip" |  | 
| 140   // is reduced by an errant proxy to "Content-Encoding: sdch", while the |  | 
| 141   // content is indeed really gzipped result of sdch :-/. |  | 
| 142   // If this flag is set, then we will revert to being a pass through filter if |  | 
| 143   // we don't get a valid gzip header. |  | 
| 144   bool possible_sdch_pass_through_; |  | 
| 145 |  | 
| 146   DISALLOW_COPY_AND_ASSIGN(GZipFilter); |  | 
| 147 }; |  | 
| 148 |  | 
| 149 }  // namespace net |  | 
| 150 |  | 
| 151 #endif  // NET_FILTER_GZIP_FILTER_H__ |  | 
| OLD | NEW | 
|---|