mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-05 01:20:26 +08:00
内容压缩支持对已压缩内容重新压缩
This commit is contained in:
@@ -39,21 +39,22 @@ func (this *LogWriter) Init() {
|
|||||||
|
|
||||||
func (this *LogWriter) Write(message string) {
|
func (this *LogWriter) Write(message string) {
|
||||||
// 文件和行号
|
// 文件和行号
|
||||||
var callDepth = 3
|
var callDepth = 2
|
||||||
var file string
|
var file string
|
||||||
var line int
|
var line int
|
||||||
var ok bool
|
var ok bool
|
||||||
_, file, line, ok = runtime.Caller(callDepth)
|
_, file, line, ok = runtime.Caller(callDepth)
|
||||||
if !ok {
|
if ok {
|
||||||
file = "???"
|
|
||||||
line = 0
|
|
||||||
} else {
|
|
||||||
file = filepath.Base(file)
|
file = filepath.Base(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
backgroundEnv, _ := os.LookupEnv("EdgeBackground")
|
backgroundEnv, _ := os.LookupEnv("EdgeBackground")
|
||||||
if backgroundEnv != "on" {
|
if backgroundEnv != "on" {
|
||||||
|
if len(file) > 0 {
|
||||||
log.Println(message + " (" + file + ":" + strconv.Itoa(line) + ")")
|
log.Println(message + " (" + file + ":" + strconv.Itoa(line) + ")")
|
||||||
|
} else {
|
||||||
|
log.Println(message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if this.fileAppender != nil {
|
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"
|
"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) {
|
func NewWriter(writer io.Writer, compressType serverconfigs.HTTPCompressionType, level int) (Writer, error) {
|
||||||
switch compressType {
|
switch compressType {
|
||||||
case serverconfigs.HTTPCompressionTypeGzip:
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,6 +459,12 @@ func (this *HTTPWriter) PrepareCompression(size int64) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 压缩前后如果编码一致,则不处理
|
||||||
|
if compressionEncoding == contentEncoding {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
this.compressionType = compressionType
|
this.compressionType = compressionType
|
||||||
|
|
||||||
// compression writer
|
// compression writer
|
||||||
@@ -468,6 +475,15 @@ func (this *HTTPWriter) PrepareCompression(size int64) {
|
|||||||
return
|
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
|
// body copy
|
||||||
if this.bodyCopying {
|
if this.bodyCopying {
|
||||||
this.compressionBodyBuffer = bytes.NewBuffer([]byte{})
|
this.compressionBodyBuffer = bytes.NewBuffer([]byte{})
|
||||||
|
|||||||
Reference in New Issue
Block a user