func (hr *headerReader) read() (h http.Header, err error) { var count uint32 if hr.decompressor == nil { hr.decompressor, err = zlib.NewReaderDict(&hr.source, headerDictionary) if err != nil { return } } err = binary.Read(hr.decompressor, binary.BigEndian, &count) if err != nil { return } h = make(http.Header, int(count)) for i := 0; i < int(count); i++ { var name, value string name, err = readHeaderString(hr.decompressor) if err != nil { return } value, err = readHeaderString(hr.decompressor) if err != nil { return } valueList := strings.Split(string(value), "\x00") for _, v := range valueList { h.Add(name, v) } } return }
//进行zlib解压缩 func DoZlibUnCompress(compressSrc []byte) ([]byte, error) { b := bytes.NewReader(compressSrc) var out bytes.Buffer r, err := zlib.NewReaderDict(b, dict) if err != nil { return nil, err } io.Copy(&out, r) return out.Bytes(), nil }
func (f *Framer) initHeaderDecompression() os.Error { if f.headerDecompressor != nil { return nil } decompressor, err := zlib.NewReaderDict(f.r, []byte(HeaderDictionary)) if err != nil { return err } f.headerDecompressor = decompressor return nil }
func (self *ZlibCompressor) DecompressFromReader(src io.Reader) ([]byte, error) { ddest := bytes.NewBuffer(nil) decompressor, err := zlib.NewReaderDict(src, self.dict) if err != nil { fmt.Println("DecompressFromReader err:%s", err.Error()) } else { _, err = io.Copy(ddest, decompressor) } if err != nil { fmt.Println("DecompressFromReader err:%s", err.Error()) } return ddest.Bytes(), err }
func (f *Framer) uncorkHeaderDecompressor(payloadSize int64) os.Error { if f.headerDecompressor != nil { f.headerReader.N = payloadSize return nil } f.headerReader = io.LimitedReader{R: f.r, N: payloadSize} decompressor, err := zlib.NewReaderDict(&f.headerReader, []byte(HeaderDictionary)) if err != nil { return err } f.headerDecompressor = decompressor return nil }
// Decompress uses zlib decompression to decompress the provided // data, according to the SPDY specification of the given version. func (d *decompressor) Decompress(data []byte) (headers http.Header, err error) { d.Lock() defer d.Unlock() // Make sure the buffer is ready. if d.in == nil { d.in = bytes.NewBuffer(data) } else { d.in.Reset() d.in.Write(data) } // Initialise the decompressor with the appropriate // dictionary, depending on SPDY version. if d.out == nil { switch d.version { case 2: d.out, err = zlib.NewReaderDict(d.in, HeaderDictionaryV2) case 3: d.out, err = zlib.NewReaderDict(d.in, HeaderDictionaryV3) default: err = versionError } if err != nil { return nil, err } } var size int var bytesToInt func([]byte) int // SPDY/2 uses 16-bit fixed fields, where SPDY/3 uses 32-bit fields. switch d.version { case 2: size = 2 bytesToInt = func(b []byte) int { return int(BytesToUint16(b)) } case 3: size = 4 bytesToInt = func(b []byte) int { return int(BytesToUint32(b)) } default: return nil, versionError } // Read in the number of name/value pairs. pairs, err := ReadExactly(d.out, size) if err != nil { return nil, err } numNameValuePairs := bytesToInt(pairs) headers = make(http.Header) bounds := MAX_FRAME_SIZE - 12 // Maximum frame size minus maximum non-headers data (SYN_STREAM) for i := 0; i < numNameValuePairs; i++ { var nameLength, valueLength int // Get the name's length. length, err := ReadExactly(d.out, size) if err != nil { return nil, err } nameLength = bytesToInt(length) bounds -= size if nameLength > bounds { debug.Printf("Error: Maximum header length is %d. Received name length %d.\n", bounds, nameLength) return nil, errors.New("Error: Incorrect header name length.") } bounds -= nameLength // Get the name. name, err := ReadExactly(d.out, nameLength) if err != nil { return nil, err } // Get the value's length. length, err = ReadExactly(d.out, size) if err != nil { return nil, err } valueLength = bytesToInt(length) bounds -= size if valueLength > bounds { debug.Printf("Error: Maximum header length is %d. Received values length %d.\n", bounds, valueLength) return nil, errors.New("Error: Incorrect header values length.") } bounds -= valueLength // Get the values. values, err := ReadExactly(d.out, valueLength) if err != nil { return nil, err } // Split the value on null boundaries. for _, value := range bytes.Split(values, []byte{'\x00'}) { headers.Add(string(name), string(value)) } } return headers, nil }
// NewZlibCompressionLevelDict returns a Zlib-based Compression with the given // level, based on the given dictionary. func NewZlibCompressionLevelDict(level int, dict []byte) Compression { return &genericCompression{ func(w io.Writer) (io.WriteCloser, error) { return zlib.NewWriterLevelDict(w, level, dict) }, func(r io.Reader) (io.ReadCloser, error) { return zlib.NewReaderDict(r, dict) }, } }
// Decompress uses zlib decompression to decompress the provided // data, according to the SPDY specification of the given version. func (d *decompressor) Decompress(data []byte) (headers http.Header, err error) { d.m.Lock() defer d.m.Unlock() if d.in == nil { d.in = bytes.NewBuffer(data) } else { d.in.Reset() d.in.Write(data) } // Initialise the decompressor with the appropriate // dictionary, depending on SPDY version. if d.out == nil { switch d.version { case 2: d.out, err = zlib.NewReaderDict(d.in, headerDictionaryV2) case 3: d.out, err = zlib.NewReaderDict(d.in, headerDictionaryV3) default: err = versionError } if err != nil { return nil, err } } var chunk []byte var dechunk func([]byte) int // SPDY/2 uses 16-bit fixed fields, where SPDY/3 uses 32-bit fields. switch d.version { case 2: chunk = make([]byte, 2) dechunk = func(b []byte) int { return int(bytesToUint16(b)) } case 3: chunk = make([]byte, 4) dechunk = func(b []byte) int { return int(bytesToUint32(b)) } default: return nil, versionError } // Read in the number of name/value pairs. if _, err = d.out.Read(chunk); err != nil { panic(err) return nil, err } numNameValuePairs := dechunk(chunk) headers = make(http.Header) length := 0 bounds := MAX_FRAME_SIZE - 12 // Maximum frame size minus maximum non-headers data (SYN_STREAM) for i := 0; i < numNameValuePairs; i++ { var nameLength, valueLength int // Get the name. if _, err = d.out.Read(chunk); err != nil { return nil, err } nameLength = dechunk(chunk) if nameLength > bounds { return nil, errors.New("Error: Incorrect header name length.") } bounds -= nameLength name := make([]byte, nameLength) if _, err = d.out.Read(name); err != nil { panic(err) return nil, err } // Get the value. if _, err = d.out.Read(chunk); err != nil { panic(err) return nil, err } valueLength = dechunk(chunk) if valueLength > bounds { return nil, errors.New("Error: Incorrect header values length.") } bounds -= valueLength values := make([]byte, valueLength) if _, err = d.out.Read(values); err != nil { return nil, err } // Count name and ': '. length += nameLength + 2 // Split the value on null boundaries. for _, value := range bytes.Split(values, []byte{'\x00'}) { headers.Add(string(name), string(value)) length += len(value) + 2 // count value and ', ' or '\n\r'. } } return headers, nil }