Skip to content

[BUG]SetCompress(CompressNone) 后无法正确读取内容 #110

Description

@NeverENG

What happened:
如果调用 setCompress(compressNone),会出现坏流现象,
原因:setCompress 会使得 gettyTCPconn 的 writer and reader 封装成 flate 压缩算法的接口,而 Send 函数判定CompressNone 会直接让他走系统底层 writev,这样导致读写格式不一致,代码如下

if t.compress == CompressNone {
				netBuf := net.Buffers(buffers)
				lg, err = netBuf.WriteTo(t.conn)
		}
func (t *gettyTCPConn) SetCompressType(c CompressType) {
	switch c {
	case CompressNone, CompressZip, CompressBestSpeed, CompressBestCompression, CompressHuffman:
		ioReader := io.Reader(t.conn)
		t.reader = flate.NewReader(ioReader)

		ioWriter := io.Writer(t.conn)
		w, err := flate.NewWriter(ioWriter, int(c))
		if err != nil {
			panic(fmt.Sprintf("flate.NewReader(flate.DefaultCompress) = err(%s)", err))
		}
		t.writer = &writeFlusher{flusher: w}

	case CompressSnappy:
		ioReader := io.Reader(t.conn)
		t.reader = snappy.NewReader(ioReader)
		ioWriter := io.Writer(t.conn)
		t.writer = newSnappyWriteFlusher(snappy.NewBufferedWriter(ioWriter))

	default:
		panic(fmt.Sprintf("illegal comparess type %d", c))
	}
	t.compress = c

What you expected to happen
统一读写,避免坏流
How to reproduce it (as minimally and precisely as possible):
方案一:给 Send 函数 if t.CompressType = CompressNone 加上判定,改为

if t.CompressType = CompressNone{
// 判定 t.writer 有没有被封装成 flate
if _, isRaw := t.writer.(net.Conn); isRaw {
				.....
			}
}

方案二:改回 PR#102,加回 iscompress 字段判定

Anything else we need to know?:
或许可以对性能进一步优化
目前其他分支太慢了:

for _, b := range buffers {
				var n int
				n, err = t.writer.Write(b)
				if err != nil {
					break
				}
				lg += int64(n)
			}

是否可以改用 flush?将每一个模式都封装一个函数,写入字节下沉到 writer?

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions