mirror of
				https://github.com/TeaOSLab/EdgeNode.git
				synced 2025-11-04 16:00:25 +08:00 
			
		
		
		
	内容压缩支持对已压缩内容重新压缩
This commit is contained in:
		@@ -39,21 +39,22 @@ func (this *LogWriter) Init() {
 | 
			
		||||
 | 
			
		||||
func (this *LogWriter) Write(message string) {
 | 
			
		||||
	// 文件和行号
 | 
			
		||||
	var callDepth = 3
 | 
			
		||||
	var callDepth = 2
 | 
			
		||||
	var file string
 | 
			
		||||
	var line int
 | 
			
		||||
	var ok bool
 | 
			
		||||
	_, file, line, ok = runtime.Caller(callDepth)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		file = "???"
 | 
			
		||||
		line = 0
 | 
			
		||||
	} else {
 | 
			
		||||
	if ok {
 | 
			
		||||
		file = filepath.Base(file)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	backgroundEnv, _ := os.LookupEnv("EdgeBackground")
 | 
			
		||||
	if backgroundEnv != "on" {
 | 
			
		||||
		if len(file) > 0 {
 | 
			
		||||
			log.Println(message + " (" + file + ":" + strconv.Itoa(line) + ")")
 | 
			
		||||
		} else {
 | 
			
		||||
			log.Println(message)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if this.fileAppender != nil {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								internal/compressions/reader.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								internal/compressions/reader.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
			
		||||
 | 
			
		||||
package compressions
 | 
			
		||||
 | 
			
		||||
type Reader interface {
 | 
			
		||||
	Read(p []byte) (n int, err error)
 | 
			
		||||
	Close() error
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								internal/compressions/reader_brotli.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								internal/compressions/reader_brotli.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
			
		||||
 | 
			
		||||
package compressions
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/andybalholm/brotli"
 | 
			
		||||
	"io"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type BrotliReader struct {
 | 
			
		||||
	reader *brotli.Reader
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewBrotliReader(reader io.Reader) (Reader, error) {
 | 
			
		||||
	return &BrotliReader{reader: brotli.NewReader(reader)}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *BrotliReader) Read(p []byte) (n int, err error) {
 | 
			
		||||
	return this.reader.Read(p)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *BrotliReader) Close() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								internal/compressions/reader_deflate.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								internal/compressions/reader_deflate.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
			
		||||
 | 
			
		||||
package compressions
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"compress/flate"
 | 
			
		||||
	"io"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type DeflateReader struct {
 | 
			
		||||
	reader io.ReadCloser
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewDeflateReader(reader io.Reader) (Reader, error) {
 | 
			
		||||
	return &DeflateReader{reader: flate.NewReader(reader)}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *DeflateReader) Read(p []byte) (n int, err error) {
 | 
			
		||||
	return this.reader.Read(p)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *DeflateReader) Close() error {
 | 
			
		||||
	return this.reader.Close()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								internal/compressions/reader_gzip.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								internal/compressions/reader_gzip.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
			
		||||
 | 
			
		||||
package compressions
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"compress/gzip"
 | 
			
		||||
	"io"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type GzipReader struct {
 | 
			
		||||
	reader *gzip.Reader
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewGzipReader(reader io.Reader) (Reader, error) {
 | 
			
		||||
	r, err := gzip.NewReader(reader)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return &GzipReader{
 | 
			
		||||
		reader: r,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *GzipReader) Read(p []byte) (n int, err error) {
 | 
			
		||||
	return this.reader.Read(p)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *GzipReader) Close() error {
 | 
			
		||||
	return this.reader.Close()
 | 
			
		||||
}
 | 
			
		||||
@@ -8,6 +8,31 @@ import (
 | 
			
		||||
	"io"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type ContentEncoding = string
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	ContentEncodingBr      ContentEncoding = "br"
 | 
			
		||||
	ContentEncodingGzip    ContentEncoding = "gzip"
 | 
			
		||||
	ContentEncodingDeflate ContentEncoding = "deflate"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var ErrNotSupportedContentEncoding = errors.New("not supported content encoding")
 | 
			
		||||
 | 
			
		||||
// NewReader 获取Reader
 | 
			
		||||
func NewReader(reader io.Reader, contentEncoding ContentEncoding) (Reader, error) {
 | 
			
		||||
	switch contentEncoding {
 | 
			
		||||
	case ContentEncodingBr:
 | 
			
		||||
		return NewBrotliReader(reader)
 | 
			
		||||
	case ContentEncodingGzip:
 | 
			
		||||
		return NewGzipReader(reader)
 | 
			
		||||
	case ContentEncodingDeflate:
 | 
			
		||||
		return NewDeflateReader(reader)
 | 
			
		||||
	}
 | 
			
		||||
	return nil, ErrNotSupportedContentEncoding
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewWriter 获取Writer
 | 
			
		||||
// TODO 考虑重用Writer
 | 
			
		||||
func NewWriter(writer io.Writer, compressType serverconfigs.HTTPCompressionType, level int) (Writer, error) {
 | 
			
		||||
	switch compressType {
 | 
			
		||||
	case serverconfigs.HTTPCompressionTypeGzip:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										51
									
								
								internal/compressions/writer_encoding.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								internal/compressions/writer_encoding.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
			
		||||
 | 
			
		||||
package compressions
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"io"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type EncodingWriter struct {
 | 
			
		||||
	contentEncoding ContentEncoding
 | 
			
		||||
	writer          Writer
 | 
			
		||||
	buf             *bytes.Buffer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewEncodingWriter(contentEncoding ContentEncoding, writer Writer) (Writer, error) {
 | 
			
		||||
	return &EncodingWriter{
 | 
			
		||||
		contentEncoding: contentEncoding,
 | 
			
		||||
		writer:          writer,
 | 
			
		||||
		buf:             &bytes.Buffer{},
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *EncodingWriter) Write(p []byte) (int, error) {
 | 
			
		||||
	return this.buf.Write(p)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *EncodingWriter) Flush() error {
 | 
			
		||||
	return this.writer.Flush()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *EncodingWriter) Close() error {
 | 
			
		||||
	reader, err := NewReader(this.buf, this.contentEncoding)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		_ = this.writer.Close()
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	_, err = io.Copy(this.writer, reader)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		_ = reader.Close()
 | 
			
		||||
		_ = this.writer.Close()
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_ = reader.Close()
 | 
			
		||||
	return this.writer.Close()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *EncodingWriter) Level() int {
 | 
			
		||||
	return this.writer.Level()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								internal/compressions/writer_encoding_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								internal/compressions/writer_encoding_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
			
		||||
 | 
			
		||||
package compressions
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestNewEncodingWriter(t *testing.T) {
 | 
			
		||||
	var buf = &bytes.Buffer{}
 | 
			
		||||
 | 
			
		||||
	subWriter, err := NewWriter(buf, serverconfigs.HTTPCompressionTypeGzip, 5)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	writer, err := NewEncodingWriter(ContentEncodingGzip, subWriter)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gzipBuf := &bytes.Buffer{}
 | 
			
		||||
	gzipWriter, err := NewGzipWriter(gzipBuf, 5)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	_, err = gzipWriter.Write([]byte("Hello"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err = gzipWriter.Write([]byte("World"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	_ = gzipWriter.Close()
 | 
			
		||||
 | 
			
		||||
	_, err = writer.Write(gzipBuf.Bytes())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_ = writer.Close()
 | 
			
		||||
 | 
			
		||||
	t.Log(buf.String())
 | 
			
		||||
}
 | 
			
		||||
@@ -444,7 +444,8 @@ func (this *HTTPWriter) PrepareCompression(size int64) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 如果已经有编码则不处理
 | 
			
		||||
	if len(this.writer.Header().Get("Content-Encoding")) > 0 {
 | 
			
		||||
	var contentEncoding = this.writer.Header().Get("Content-Encoding")
 | 
			
		||||
	if len(contentEncoding) > 0 && (!this.compressionConfig.DecompressData || !lists.ContainsString([]string{"gzip", "deflate", "br"}, contentEncoding)) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -458,6 +459,12 @@ func (this *HTTPWriter) PrepareCompression(size int64) {
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 压缩前后如果编码一致,则不处理
 | 
			
		||||
	if compressionEncoding == contentEncoding {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.compressionType = compressionType
 | 
			
		||||
 | 
			
		||||
	// compression writer
 | 
			
		||||
@@ -468,6 +475,15 @@ func (this *HTTPWriter) PrepareCompression(size int64) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// convert between encodings
 | 
			
		||||
	if len(contentEncoding) > 0 {
 | 
			
		||||
		this.compressionWriter, err = compressions.NewEncodingWriter(contentEncoding, this.compressionWriter)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			remotelogs.Error("HTTP_WRITER", err.Error())
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// body copy
 | 
			
		||||
	if this.bodyCopying {
 | 
			
		||||
		this.compressionBodyBuffer = bytes.NewBuffer([]byte{})
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user