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