15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SdchFilter applies open_vcdiff content decoding to a datastream.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This decoding uses a pre-cached dictionary of text fragments to decode
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (expand) the stream back to its original contents.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This SdchFilter internally uses open_vcdiff/vcdec library to do decoding.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SdchFilter is also a subclass of Filter. See the latter's header file
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// filter.h for sample usage.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NET_BASE_SDCH_FILTER_H_
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_BASE_SDCH_FILTER_H_
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/filter.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_export.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/sdch_manager.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace open_vcdiff {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VCDiffStreamingDecoder;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE SdchFilter : public Filter {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SdchFilter();
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes filter decoding mode and internal control blocks.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool InitDecoding(Filter::FilterType filter_type);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Decode the pre-filter data and writes the output into |dest_buffer|
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The function returns FilterStatus. See filter.h for its description.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Upon entry, *dest_len is the total size (in number of chars) of the
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // destination buffer. Upon exit, *dest_len is the actual number of chars
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // written into the destination buffer.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual FilterStatus ReadFilteredData(char* dest_buffer,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int* dest_len) OVERRIDE;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Internal status.  Once we enter an error state, we stop processing data.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum DecodingStatus {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DECODING_UNINITIALIZED,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WAITING_FOR_DICTIONARY_SELECTION,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DECODING_IN_PROGRESS,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DECODING_ERROR,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    META_REFRESH_RECOVERY,  // Decoding error being handled by a meta-refresh.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PASS_THROUGH,  // Non-sdch content being passed without alteration.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only to be instantiated by Filter::Factory.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit SdchFilter(const FilterContext& filter_context);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class Filter;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Identify the suggested dictionary, and initialize underlying decompressor.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Filter::FilterStatus InitializeDictionary();
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move data that was internally buffered (after decompression) to the
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // specified dest_buffer.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int OutputBufferExcess(char* const dest_buffer, size_t available_space);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Context data from the owner of this filter.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FilterContext& filter_context_;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tracks the status of decoding.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This variable is initialized by InitDecoding and updated only by
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ReadFilteredData.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DecodingStatus decoding_status_;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The underlying decoder that processes data.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This data structure is initialized by InitDecoding and updated in
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ReadFilteredData.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<open_vcdiff::VCDiffStreamingDecoder> vcdiff_streaming_decoder_;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In case we need to assemble the hash piecemeal, we have a place to store
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a part of the hash until we "get all 8 bytes plus a null."
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string dictionary_hash_;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After assembling an entire dictionary hash (the first 9 bytes of the
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sdch payload, we check to see if it is plausible, meaning it has a null
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // termination, and has 8 characters that are possible in a net-safe base64
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // encoding.  If the hash is not plausible, then the payload is probably not
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // an SDCH encoded bundle, and various error recovery strategies can be
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // attempted.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool dictionary_hash_is_plausible_;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We hold an in-memory copy of the dictionary during the entire decoding, as
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it is used directly by the VC-DIFF decoding system.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // That char* data is part of the dictionary_ we hold a reference to.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SdchManager::Dictionary> dictionary_;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The decoder may demand a larger output buffer than the target of
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ReadFilteredData so we buffer the excess output between calls.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string dest_buffer_excess_;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // To avoid moving strings around too much, we save the index into
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // dest_buffer_excess_ that has the next byte to output.
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t dest_buffer_excess_index_;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // To get stats on activities, we keep track of source and target bytes.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Visit about:histograms/Sdch to see histogram data.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t source_bytes_;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t output_bytes_;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Error recovery in content type may add an sdch filter type, in which case
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we should gracefully perform pass through if the format is incorrect, or
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // an applicable dictionary can't be found.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool possible_pass_through_;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The URL that is currently being filtered.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is used to restrict use of a dictionary to a specific URL or path.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url_;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // To facilitate error recovery, allow filter to know if content is text/html
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // by checking within this mime type (we may do a meta-refresh via html).
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string mime_type_;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SdchFilter);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // NET_BASE_SDCH_FILTER_H_
129