WebP无法解析原图时直接返回原图数据

This commit is contained in:
GoEdgeLab
2021-10-13 11:11:57 +08:00
parent 7e40bdd83f
commit decafbebb4
2 changed files with 27 additions and 10 deletions

View File

@@ -249,10 +249,12 @@ func (this *HTTPRequest) doReverseProxy() {
shouldAutoFlush := this.reverseProxy.AutoFlush || this.RawReq.Header.Get("Accept") == "text/event-stream" shouldAutoFlush := this.reverseProxy.AutoFlush || this.RawReq.Header.Get("Accept") == "text/event-stream"
// 准备 // 准备
this.writer.Prepare(resp.ContentLength, resp.StatusCode) delayHeaders := this.writer.Prepare(resp.ContentLength, resp.StatusCode)
// 设置响应代码 // 设置响应代码
if !delayHeaders {
this.writer.WriteHeader(resp.StatusCode) this.writer.WriteHeader(resp.StatusCode)
}
// 输出到客户端 // 输出到客户端
pool := this.bytePool(resp.ContentLength) pool := this.bytePool(resp.ContentLength)

View File

@@ -18,7 +18,6 @@ import (
_ "image/gif" _ "image/gif"
_ "image/jpeg" _ "image/jpeg"
_ "image/png" _ "image/png"
"io"
"net" "net"
"net/http" "net/http"
"path/filepath" "path/filepath"
@@ -43,6 +42,7 @@ type HTTPWriter struct {
webpIsEncoding bool webpIsEncoding bool
webpBuffer *bytes.Buffer webpBuffer *bytes.Buffer
webpIsWriting bool webpIsWriting bool
webpOriginContentType string
compressionConfig *serverconfigs.HTTPCompressionConfig compressionConfig *serverconfigs.HTTPCompressionConfig
compressionWriter compressions.Writer compressionWriter compressions.Writer
@@ -93,12 +93,16 @@ func (this *HTTPWriter) SetCompression(config *serverconfigs.HTTPCompressionConf
// Prepare 准备输出 // Prepare 准备输出
// 缓存不调用此函数 // 缓存不调用此函数
func (this *HTTPWriter) Prepare(size int64, status int) { func (this *HTTPWriter) Prepare(size int64, status int) (delayHeaders bool) {
this.size = size this.size = size
this.statusCode = status this.statusCode = status
if status == http.StatusOK { if status == http.StatusOK {
this.prepareWebP(size) this.prepareWebP(size)
if this.webpIsEncoding {
delayHeaders = true
}
} }
this.prepareCache(size) this.prepareCache(size)
@@ -107,6 +111,8 @@ func (this *HTTPWriter) Prepare(size int64, status int) {
if !this.webpIsEncoding { if !this.webpIsEncoding {
this.PrepareCompression(size) this.PrepareCompression(size)
} }
return
} }
// Raw 包装前的原始的Writer // Raw 包装前的原始的Writer
@@ -262,11 +268,15 @@ func (this *HTTPWriter) Close() {
// webp writer // webp writer
if this.isOk && this.webpIsEncoding { if this.isOk && this.webpIsEncoding {
var bufferLen = int64(this.webpBuffer.Len()) var bufferLen = int64(this.webpBuffer.Len())
atomic.AddInt64(&webpTotalBufferSize, bufferLen*8) atomic.AddInt64(&webpTotalBufferSize, bufferLen*4)
// 需要把字节读取出来做备份防止在image.Decode()过程中丢失
var imageBytes = this.webpBuffer.Bytes()
imageData, _, err := image.Decode(this.webpBuffer) imageData, _, err := image.Decode(this.webpBuffer)
if err != nil { if err != nil {
_, _ = io.Copy(this.writer, this.webpBuffer) this.Header().Set("Content-Type", this.webpOriginContentType)
this.WriteHeader(http.StatusOK)
_, _ = this.writer.Write(imageBytes)
// 处理缓存 // 处理缓存
if this.cacheWriter != nil { if this.cacheWriter != nil {
@@ -290,6 +300,10 @@ func (this *HTTPWriter) Close() {
remotelogs.Error("HTTP_WRITER", "encode webp failed: "+err.Error()) remotelogs.Error("HTTP_WRITER", "encode webp failed: "+err.Error())
} }
this.Header().Set("Content-Type", this.webpOriginContentType)
this.WriteHeader(http.StatusOK)
_, _ = this.writer.Write(imageBytes)
// 处理缓存 // 处理缓存
if this.cacheWriter != nil { if this.cacheWriter != nil {
_ = this.cacheWriter.Discard() _ = this.cacheWriter.Discard()
@@ -298,7 +312,7 @@ func (this *HTTPWriter) Close() {
} }
} }
atomic.AddInt64(&webpTotalBufferSize, -bufferLen*8) atomic.AddInt64(&webpTotalBufferSize, -bufferLen*4)
this.webpBuffer.Reset() this.webpBuffer.Reset()
} }
@@ -373,6 +387,7 @@ func (this *HTTPWriter) prepareWebP(size int64) {
atomic.LoadInt64(&webpTotalBufferSize) < webpMaxBufferSize { atomic.LoadInt64(&webpTotalBufferSize) < webpMaxBufferSize {
this.webpIsEncoding = true this.webpIsEncoding = true
this.webpBuffer = webpBufferPool.Get() this.webpBuffer = webpBufferPool.Get()
this.webpOriginContentType = this.Header().Get("Content-Type")
this.Header().Del("Content-Length") this.Header().Del("Content-Length")
this.Header().Set("Content-Type", "image/webp") this.Header().Set("Content-Type", "image/webp")