示例#1
0
// TestCompressedValue ...
func TestCompressedValue(t *testing.T) {
	Convey("Check nil value", t, func() {
		val := Compressed{Data: nil}
		result, err := val.Value()
		So(result, ShouldBeNil)
		So(err, ShouldBeNil)
	})

	Convey("Check empty value", t, func() {
		val := Compressed{Data: []byte("")}
		result, err := val.Value()
		So(result, ShouldBeNil)
		So(err, ShouldBeNil)
	})

	Convey("Check not nil value", t, func() {
		msg := []byte("text text text")

		var zContent bytes.Buffer
		w, _ := zlib.NewWriterLevelDict(&zContent, 6, nil)
		_, err := w.Write(msg)
		So(err, ShouldBeNil)
		err = w.Close()
		So(err, ShouldBeNil)

		val := Compressed{Data: msg}
		result, err := val.Value()
		So(result, ShouldResemble, zContent.Bytes())
		So(err, ShouldBeNil)
	})

}
示例#2
0
文件: zlib.go 项目: playnb/mustang
//进行zlib压缩
func DoZlibCompress(src []byte) []byte {
	var in bytes.Buffer
	w, _ := zlib.NewWriterLevelDict(&in, zlib.BestCompression, dict)
	w.Write(src)
	w.Close()
	//	fmt.Printf("%d -> %d\n", len(src), len(in.Bytes()))
	return in.Bytes()
}
示例#3
0
文件: types.go 项目: kr/spdy
// NewFramer allocates a new Framer for a given SPDY connection, repesented by
// a io.Writer and io.Reader. Note that Framer will read and write individual fields
// from/to the Reader and Writer, so the caller should pass in an appropriately
// buffered implementation to optimize performance.
func NewFramer(w io.Writer, r io.Reader) *Framer {
	compressBuf := new(bytes.Buffer)
	// The only error from NewWriterLevelDict is out of range compression level.
	compressor, _ := zlib.NewWriterLevelDict(compressBuf, zlib.BestCompression, []byte(headerDictionary))
	return &Framer{
		w:                w,
		headerBuf:        compressBuf,
		headerCompressor: compressor,
		r:                r,
	}
}
示例#4
0
文件: zlib.go 项目: Jordanzuo/goutil
// 压缩
// in:待压缩数据
// level:压缩等级
// 返回值:
// 压缩后数据
// 对应的错误
func Compress(data []byte, level int) ([]byte, error) {
	var buffer bytes.Buffer
	compressor, err := zlib.NewWriterLevelDict(&buffer, level, nil)
	if err != nil {
		return nil, err
	}

	compressor.Write(data)
	compressor.Close()

	return buffer.Bytes(), nil
}
示例#5
0
// Compress - compress c.Data value
func (c *Compressed) Compress() []byte {
	if len(c.Data) == 0 {
		return nil
	}

	var zContent bytes.Buffer
	w, _ := zlib.NewWriterLevelDict(&zContent, 6, nil)
	_, _ = w.Write(c.Data)
	_ = w.Close()

	return zContent.Bytes()
}
示例#6
0
文件: types.go 项目: 98pm/docker
// NewFramer allocates a new Framer for a given SPDY connection, repesented by
// a io.Writer and io.Reader. Note that Framer will read and write individual fields
// from/to the Reader and Writer, so the caller should pass in an appropriately
// buffered implementation to optimize performance.
func NewFramer(w io.Writer, r io.Reader) (*Framer, error) {
	compressBuf := new(bytes.Buffer)
	compressor, err := zlib.NewWriterLevelDict(compressBuf, zlib.BestCompression, []byte(headerDictionary))
	if err != nil {
		return nil, err
	}
	framer := &Framer{
		w:                w,
		headerBuf:        compressBuf,
		headerCompressor: compressor,
		r:                r,
	}
	return framer, nil
}
示例#7
0
func (self *ZlibCompressor) Compress(src []byte) ([]byte, error) {
	var err error
	var compressor *zlib.Writer
	cdest := bytes.NewBuffer(make([]byte, 0, len(src)))
	if self.dict == nil {
		compressor, err = zlib.NewWriterLevel(cdest, self.level)
	} else {
		compressor, err = zlib.NewWriterLevelDict(cdest, self.level, self.dict)
	}
	compressor.Write(src)
	err = compressor.Close()
	if err != nil {
		fmt.Println("Compress Close err:%s", err.Error())
	}
	return cdest.Bytes(), err
}
示例#8
0
// Compress uses zlib compression to compress the provided
// data, according to the SPDY specification of the given version.
func (c *compressor) Compress(h http.Header) ([]byte, error) {
	c.Lock()
	defer c.Unlock()

	// Ensure the buffer is prepared.
	if c.buf == nil {
		c.buf = new(bytes.Buffer)
	} else {
		c.buf.Reset()
	}

	// Same for the compressor.
	if c.w == nil {
		var err error
		switch c.version {
		case 2:
			select {
			case c.w = <-zlibV2Writers:
				c.w.Reset(c.buf)
			default:
				c.w, err = zlib.NewWriterLevelDict(c.buf, CompressionLevel, HeaderDictionaryV2)
			}
		case 3:
			select {
			case c.w = <-zlibV3Writers:
				c.w.Reset(c.buf)
			default:
				c.w, err = zlib.NewWriterLevelDict(c.buf, CompressionLevel, HeaderDictionaryV3)
			}
		default:
			err = versionError
		}
		if err != nil {
			return nil, err
		}
	}

	var size int // Size of length values.
	switch c.version {
	case 2:
		size = 2
	case 3:
		size = 4
	default:
		return nil, versionError
	}

	// Remove invalid headers.
	h.Del("Connection")
	h.Del("Keep-Alive")
	h.Del("Proxy-Connection")
	h.Del("Transfer-Encoding")

	length := size                   // The 4-byte or 2-byte number of name/value pairs.
	pairs := make(map[string]string) // Used to store the validated, joined headers.
	for name, values := range h {
		// Ignore invalid names.
		if _, ok := pairs[name]; ok { // We've already seen this name.
			return nil, errors.New("Error: Duplicate header name discovered.")
		}
		if name == "" { // Ignore empty names.
			continue
		}

		// Multiple values are separated by a single null byte.
		pairs[name] = strings.Join(values, "\x00")

		// +size for len(name), +size for len(values).
		length += len(name) + size + len(pairs[name]) + size
	}

	// Uncompressed data.
	out := make([]byte, length)

	// Current offset into out.
	var offset uint32

	// Write the number of name/value pairs.
	num := uint32(len(pairs))
	switch c.version {
	case 3:
		out[0] = byte(num >> 24)
		out[1] = byte(num >> 16)
		out[2] = byte(num >> 8)
		out[3] = byte(num)
		offset = 4
	case 2:
		out[0] = byte(num >> 8)
		out[1] = byte(num)
		offset = 2
	}

	// For each name/value pair...
	for name, value := range pairs {

		// The length of the name.
		nLen := uint32(len(name))
		switch c.version {
		case 3:
			out[offset+0] = byte(nLen >> 24)
			out[offset+1] = byte(nLen >> 16)
			out[offset+2] = byte(nLen >> 8)
			out[offset+3] = byte(nLen)
			offset += 4
		case 2:
			out[offset+0] = byte(nLen >> 8)
			out[offset+1] = byte(nLen)
			offset += 2
		}

		// The name itself.
		copy(out[offset:], []byte(strings.ToLower(name)))
		offset += nLen

		// The length of the value.
		vLen := uint32(len(value))
		switch c.version {
		case 3:
			out[offset+0] = byte(vLen >> 24)
			out[offset+1] = byte(vLen >> 16)
			out[offset+2] = byte(vLen >> 8)
			out[offset+3] = byte(vLen)
			offset += 4
		case 2:
			out[offset+0] = byte(vLen >> 8)
			out[offset+1] = byte(vLen)
			offset += 2
		}

		// The value itself.
		copy(out[offset:], []byte(value))
		offset += vLen
	}

	// Compress.
	err := WriteExactly(c.w, out)
	if err != nil {
		return nil, err
	}

	c.w.Flush()
	return c.buf.Bytes(), nil
}
示例#9
0
// 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) },
	}
}
示例#10
0
文件: header.go 项目: horiga/spdy
// creates a headerWriter ready to compress headers
func newHeaderWriter() (hw *headerWriter) {
	hw = &headerWriter{buffer: new(bytes.Buffer)}
	hw.compressor, _ = zlib.NewWriterLevelDict(hw.buffer, zlib.BestCompression, headerDictionary)
	return
}
示例#11
0
文件: protocol.go 项目: lkundrak/spdy
// NewHeaderWriter creates a HeaderWriter ready to compress headers.
func NewHeaderWriter(level int) (hw *HeaderWriter) {
	hw = &HeaderWriter{buffer: new(bytes.Buffer)}
	hw.compressor, _ = zlib.NewWriterLevelDict(hw.buffer, level, []byte(headerDictionary))
	return
}
示例#12
0
// Compress uses zlib compression to compress the provided
// data, according to the SPDY specification of the given version.
func (c *compressor) Compress(h http.Header) ([]byte, error) {
	c.m.Lock()
	defer c.m.Unlock()

	var err error
	if c.buf == nil {
		c.buf = new(bytes.Buffer)

		if c.w == nil {
			switch c.version {
			case 2:
				c.w, err = zlib.NewWriterLevelDict(c.buf, zlib.BestCompression, headerDictionaryV2)
			case 3:
				c.w, err = zlib.NewWriterLevelDict(c.buf, zlib.BestCompression, headerDictionaryV3)
			default:
				err = versionError
			}
		}

		if err != nil {
			return nil, err
		}
	} else {
		c.buf.Reset()
	}

	h.Del("Connection")
	h.Del("Keep-Alive")
	h.Del("Proxy-Connection")
	h.Del("Transfer-Encoding")

	length := 4
	num := len(h)
	lens := make(map[string]int)
	for name, values := range h {
		length += len(name) + 8
		lens[name] = len(values) - 1
		for _, value := range values {
			length += len(value)
			lens[name] += len(value)
		}
	}

	out := make([]byte, length)
	switch c.version {
	case 3:
		out[0] = byte(num >> 24)
		out[1] = byte(num >> 16)
		out[2] = byte(num >> 8)
		out[3] = byte(num)
	case 2:
		out[0] = byte(num >> 8)
		out[1] = byte(num)
	}

	offset := 4
	if c.version == 2 {
		offset = 2
	}
	for name, values := range h {
		nLen := len(name)
		switch c.version {
		case 3:
			out[offset+0] = byte(nLen >> 24)
			out[offset+1] = byte(nLen >> 16)
			out[offset+2] = byte(nLen >> 8)
			out[offset+3] = byte(nLen)
			offset += 4
		case 2:
			out[offset+0] = byte(nLen >> 8)
			out[offset+1] = byte(nLen)
			offset += 2
		}

		for i, b := range []byte(strings.ToLower(name)) {
			out[offset+i] = b
		}

		offset += nLen

		vLen := lens[name]
		switch c.version {
		case 3:
			out[offset+0] = byte(vLen >> 24)
			out[offset+1] = byte(vLen >> 16)
			out[offset+2] = byte(vLen >> 8)
			out[offset+3] = byte(vLen)
			offset += 4
		case 2:
			out[offset+0] = byte(vLen >> 8)
			out[offset+1] = byte(vLen)
			offset += 2
		}

		for n, value := range values {
			for i, b := range []byte(value) {
				out[offset+i] = b
			}
			offset += len(value)
			if n < len(values)-1 {
				out[offset] = '\x00'
				offset += 1
			}
		}
	}

	_, err = c.w.Write(out)
	if err != nil {
		return nil, err
	}

	c.w.Flush()
	return c.buf.Bytes(), nil
}