mirror of
				https://github.com/TeaOSLab/EdgeNode.git
				synced 2025-11-04 07:40:56 +08:00 
			
		
		
		
	静态文件分发也支持压缩、WebP转换
This commit is contained in:
		@@ -51,7 +51,7 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
 | 
				
			|||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rootDir := this.web.Root.Dir
 | 
						var rootDir = this.web.Root.Dir
 | 
				
			||||||
	if this.web.Root.HasVariables() {
 | 
						if this.web.Root.HasVariables() {
 | 
				
			||||||
		rootDir = this.Format(rootDir)
 | 
							rootDir = this.Format(rootDir)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -59,9 +59,9 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
 | 
				
			|||||||
		rootDir = Tea.Root + Tea.DS + rootDir
 | 
							rootDir = Tea.Root + Tea.DS + rootDir
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	requestPath := this.uri
 | 
						var requestPath = this.uri
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	questionMarkIndex := strings.Index(this.uri, "?")
 | 
						var questionMarkIndex = strings.Index(this.uri, "?")
 | 
				
			||||||
	if questionMarkIndex > -1 {
 | 
						if questionMarkIndex > -1 {
 | 
				
			||||||
		requestPath = this.uri[:questionMarkIndex]
 | 
							requestPath = this.uri[:questionMarkIndex]
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -75,9 +75,11 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
 | 
				
			|||||||
		if err == nil {
 | 
							if err == nil {
 | 
				
			||||||
			requestPath = p
 | 
								requestPath = p
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
 | 
								if !this.canIgnore(err) {
 | 
				
			||||||
				logs.Error(err)
 | 
									logs.Error(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 去掉前缀
 | 
						// 去掉前缀
 | 
				
			||||||
	stripPrefix := this.web.Root.StripPrefix
 | 
						stripPrefix := this.web.Root.StripPrefix
 | 
				
			||||||
@@ -92,8 +94,8 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	filename := strings.Replace(requestPath, "/", Tea.DS, -1)
 | 
						var filename = strings.Replace(requestPath, "/", Tea.DS, -1)
 | 
				
			||||||
	filePath := ""
 | 
						var filePath = ""
 | 
				
			||||||
	if len(filename) > 0 && filename[0:1] == Tea.DS {
 | 
						if len(filename) > 0 && filename[0:1] == Tea.DS {
 | 
				
			||||||
		filePath = rootDir + filename
 | 
							filePath = rootDir + filename
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
@@ -113,7 +115,9 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
 | 
				
			|||||||
			return
 | 
								return
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			this.write50x(err, http.StatusInternalServerError, true)
 | 
								this.write50x(err, http.StatusInternalServerError, true)
 | 
				
			||||||
 | 
								if !this.canIgnore(err) {
 | 
				
			||||||
				logs.Error(err)
 | 
									logs.Error(err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			return true
 | 
								return true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -142,7 +146,9 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
 | 
				
			|||||||
					return
 | 
										return
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					this.write50x(err, http.StatusInternalServerError, true)
 | 
										this.write50x(err, http.StatusInternalServerError, true)
 | 
				
			||||||
 | 
										if !this.canIgnore(err) {
 | 
				
			||||||
						logs.Error(err)
 | 
											logs.Error(err)
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
					return true
 | 
										return true
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -152,24 +158,24 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 响应header
 | 
						// 响应header
 | 
				
			||||||
	respHeader := this.writer.Header()
 | 
						var respHeader = this.writer.Header()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// mime type
 | 
						// mime type
 | 
				
			||||||
	contentType := ""
 | 
						var contentType = ""
 | 
				
			||||||
	if this.web.ResponseHeaderPolicy == nil || !this.web.ResponseHeaderPolicy.IsOn || !this.web.ResponseHeaderPolicy.ContainsHeader("CONTENT-TYPE") {
 | 
						if this.web.ResponseHeaderPolicy == nil || !this.web.ResponseHeaderPolicy.IsOn || !this.web.ResponseHeaderPolicy.ContainsHeader("CONTENT-TYPE") {
 | 
				
			||||||
		ext := filepath.Ext(filePath)
 | 
							var ext = filepath.Ext(filePath)
 | 
				
			||||||
		if len(ext) > 0 {
 | 
							if len(ext) > 0 {
 | 
				
			||||||
			mimeType := mime.TypeByExtension(ext)
 | 
								mimeType := mime.TypeByExtension(ext)
 | 
				
			||||||
			if len(mimeType) > 0 {
 | 
								if len(mimeType) > 0 {
 | 
				
			||||||
				semicolonIndex := strings.Index(mimeType, ";")
 | 
									var semicolonIndex = strings.Index(mimeType, ";")
 | 
				
			||||||
				mimeTypeKey := mimeType
 | 
									var mimeTypeKey = mimeType
 | 
				
			||||||
				if semicolonIndex > 0 {
 | 
									if semicolonIndex > 0 {
 | 
				
			||||||
					mimeTypeKey = mimeType[:semicolonIndex]
 | 
										mimeTypeKey = mimeType[:semicolonIndex]
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if _, found := textMimeMap[mimeTypeKey]; found {
 | 
									if _, found := textMimeMap[mimeTypeKey]; found {
 | 
				
			||||||
					if this.web.Charset != nil && this.web.Charset.IsOn && len(this.web.Charset.Charset) > 0 {
 | 
										if this.web.Charset != nil && this.web.Charset.IsOn && len(this.web.Charset.Charset) > 0 {
 | 
				
			||||||
						charset := this.web.Charset.Charset
 | 
											var charset = this.web.Charset.Charset
 | 
				
			||||||
						if this.web.Charset.IsUpper {
 | 
											if this.web.Charset.IsUpper {
 | 
				
			||||||
							charset = strings.ToUpper(charset)
 | 
												charset = strings.ToUpper(charset)
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
@@ -197,7 +203,7 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 支持 ETag
 | 
						// 支持 ETag
 | 
				
			||||||
	eTag := "\"e" + fmt.Sprintf("%0x", xxhash.Sum64String(filename+strconv.FormatInt(stat.ModTime().UnixNano(), 10)+strconv.FormatInt(stat.Size(), 10))) + "\""
 | 
						var eTag = "\"e" + fmt.Sprintf("%0x", xxhash.Sum64String(filename+strconv.FormatInt(stat.ModTime().UnixNano(), 10)+strconv.FormatInt(stat.Size(), 10))) + "\""
 | 
				
			||||||
	if len(respHeader.Get("ETag")) == 0 {
 | 
						if len(respHeader.Get("ETag")) == 0 {
 | 
				
			||||||
		respHeader.Set("ETag", eTag)
 | 
							respHeader.Set("ETag", eTag)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -227,7 +233,7 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
 | 
				
			|||||||
	// 支持Range
 | 
						// 支持Range
 | 
				
			||||||
	respHeader.Set("Accept-Ranges", "bytes")
 | 
						respHeader.Set("Accept-Ranges", "bytes")
 | 
				
			||||||
	ifRangeHeaders, ok := this.RawReq.Header["If-Range"]
 | 
						ifRangeHeaders, ok := this.RawReq.Header["If-Range"]
 | 
				
			||||||
	supportRange := true
 | 
						var supportRange = true
 | 
				
			||||||
	if ok {
 | 
						if ok {
 | 
				
			||||||
		supportRange = false
 | 
							supportRange = false
 | 
				
			||||||
		for _, v := range ifRangeHeaders {
 | 
							for _, v := range ifRangeHeaders {
 | 
				
			||||||
@@ -244,7 +250,7 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
 | 
				
			|||||||
	// 支持Range
 | 
						// 支持Range
 | 
				
			||||||
	var ranges = []rangeutils.Range{}
 | 
						var ranges = []rangeutils.Range{}
 | 
				
			||||||
	if supportRange {
 | 
						if supportRange {
 | 
				
			||||||
		contentRange := this.RawReq.Header.Get("Range")
 | 
							var contentRange = this.RawReq.Header.Get("Range")
 | 
				
			||||||
		if len(contentRange) > 0 {
 | 
							if len(contentRange) > 0 {
 | 
				
			||||||
			if fileSize == 0 {
 | 
								if fileSize == 0 {
 | 
				
			||||||
				this.processResponseHeaders(http.StatusRequestedRangeNotSatisfiable)
 | 
									this.processResponseHeaders(http.StatusRequestedRangeNotSatisfiable)
 | 
				
			||||||
@@ -277,7 +283,7 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
 | 
				
			|||||||
		respHeader.Set("Content-Length", strconv.FormatInt(fileSize, 10))
 | 
							respHeader.Set("Content-Length", strconv.FormatInt(fileSize, 10))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	reader, err := os.OpenFile(filePath, os.O_RDONLY, 0444)
 | 
						fileReader, err := os.OpenFile(filePath, os.O_RDONLY, 0444)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		this.write50x(err, http.StatusInternalServerError, true)
 | 
							this.write50x(err, http.StatusInternalServerError, true)
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
@@ -291,12 +297,16 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
 | 
				
			|||||||
		this.cacheRef = nil // 不支持缓存
 | 
							this.cacheRef = nil // 不支持缓存
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this.writer.Prepare(nil, fileSize, http.StatusOK, true)
 | 
						var resp = &http.Response{
 | 
				
			||||||
 | 
							ContentLength: fileSize,
 | 
				
			||||||
 | 
							Body:          fileReader,
 | 
				
			||||||
 | 
							StatusCode:    http.StatusOK,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						this.writer.Prepare(resp, fileSize, http.StatusOK, true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pool := this.bytePool(fileSize)
 | 
						var pool = this.bytePool(fileSize)
 | 
				
			||||||
	buf := pool.Get()
 | 
						var buf = pool.Get()
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		_ = reader.Close()
 | 
					 | 
				
			||||||
		pool.Put(buf)
 | 
							pool.Put(buf)
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -304,12 +314,14 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
 | 
				
			|||||||
		respHeader.Set("Content-Range", ranges[0].ComposeContentRangeHeader(types.String(fileSize)))
 | 
							respHeader.Set("Content-Range", ranges[0].ComposeContentRangeHeader(types.String(fileSize)))
 | 
				
			||||||
		this.writer.WriteHeader(http.StatusPartialContent)
 | 
							this.writer.WriteHeader(http.StatusPartialContent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ok, err := httpRequestReadRange(reader, buf, ranges[0].Start(), ranges[0].End(), func(buf []byte, n int) error {
 | 
							ok, err := httpRequestReadRange(resp.Body, buf, ranges[0].Start(), ranges[0].End(), func(buf []byte, n int) error {
 | 
				
			||||||
			_, err := this.writer.Write(buf[:n])
 | 
								_, err := this.writer.Write(buf[:n])
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
 | 
								if !this.canIgnore(err) {
 | 
				
			||||||
				logs.Error(err)
 | 
									logs.Error(err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			return true
 | 
								return true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if !ok {
 | 
							if !ok {
 | 
				
			||||||
@@ -318,7 +330,7 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
 | 
				
			|||||||
			return true
 | 
								return true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if len(ranges) > 1 {
 | 
						} else if len(ranges) > 1 {
 | 
				
			||||||
		boundary := httpRequestGenBoundary()
 | 
							var boundary = httpRequestGenBoundary()
 | 
				
			||||||
		respHeader.Set("Content-Type", "multipart/byteranges; boundary="+boundary)
 | 
							respHeader.Set("Content-Type", "multipart/byteranges; boundary="+boundary)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.writer.WriteHeader(http.StatusPartialContent)
 | 
							this.writer.WriteHeader(http.StatusPartialContent)
 | 
				
			||||||
@@ -330,30 +342,38 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
 | 
				
			|||||||
				_, err = this.writer.WriteString("\r\n--" + boundary + "\r\n")
 | 
									_, err = this.writer.WriteString("\r\n--" + boundary + "\r\n")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
 | 
									if !this.canIgnore(err) {
 | 
				
			||||||
					logs.Error(err)
 | 
										logs.Error(err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				return true
 | 
									return true
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			_, err = this.writer.WriteString("Content-Range: " + r.ComposeContentRangeHeader(types.String(fileSize)) + "\r\n")
 | 
								_, err = this.writer.WriteString("Content-Range: " + r.ComposeContentRangeHeader(types.String(fileSize)) + "\r\n")
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
 | 
									if !this.canIgnore(err) {
 | 
				
			||||||
					logs.Error(err)
 | 
										logs.Error(err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				return true
 | 
									return true
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if len(contentType) > 0 {
 | 
								if len(contentType) > 0 {
 | 
				
			||||||
				_, err = this.writer.WriteString("Content-Type: " + contentType + "\r\n\r\n")
 | 
									_, err = this.writer.WriteString("Content-Type: " + contentType + "\r\n\r\n")
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
 | 
										if !this.canIgnore(err) {
 | 
				
			||||||
						logs.Error(err)
 | 
											logs.Error(err)
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
					return true
 | 
										return true
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			ok, err := httpRequestReadRange(reader, buf, r.Start(), r.End(), func(buf []byte, n int) error {
 | 
								ok, err := httpRequestReadRange(resp.Body, buf, r.Start(), r.End(), func(buf []byte, n int) error {
 | 
				
			||||||
				_, err := this.writer.Write(buf[:n])
 | 
									_, err := this.writer.Write(buf[:n])
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
 | 
									if !this.canIgnore(err) {
 | 
				
			||||||
					logs.Error(err)
 | 
										logs.Error(err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				return true
 | 
									return true
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if !ok {
 | 
								if !ok {
 | 
				
			||||||
@@ -365,14 +385,17 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		_, err = this.writer.WriteString("\r\n--" + boundary + "--\r\n")
 | 
							_, err = this.writer.WriteString("\r\n--" + boundary + "--\r\n")
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
 | 
								if !this.canIgnore(err) {
 | 
				
			||||||
				logs.Error(err)
 | 
									logs.Error(err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			return true
 | 
								return true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		_, err = io.CopyBuffer(this.writer, reader, buf)
 | 
							_, err = io.CopyBuffer(this.writer, resp.Body, buf)
 | 
				
			||||||
 | 
					 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
 | 
								if !this.canIgnore(err) {
 | 
				
			||||||
				logs.Error(err)
 | 
									logs.Error(err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			return true
 | 
								return true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -400,7 +423,9 @@ func (this *HTTPRequest) findIndexFile(dir string) (filename string, stat os.Fil
 | 
				
			|||||||
		if strings.Contains(index, "*") {
 | 
							if strings.Contains(index, "*") {
 | 
				
			||||||
			indexFiles, err := filepath.Glob(dir + Tea.DS + index)
 | 
								indexFiles, err := filepath.Glob(dir + Tea.DS + index)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
 | 
									if !this.canIgnore(err) {
 | 
				
			||||||
					logs.Error(err)
 | 
										logs.Error(err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				this.addError(err)
 | 
									this.addError(err)
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -449,7 +449,9 @@ func (this *HTTPWriter) PrepareCache(resp *http.Response, size int64) {
 | 
				
			|||||||
	this.rawReader = cacheReader
 | 
						this.rawReader = cacheReader
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cacheReader.OnFail(func(err error) {
 | 
						cacheReader.OnFail(func(err error) {
 | 
				
			||||||
 | 
							if this.cacheWriter != nil {
 | 
				
			||||||
			_ = this.cacheWriter.Discard()
 | 
								_ = this.cacheWriter.Discard()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		this.cacheWriter = nil
 | 
							this.cacheWriter = nil
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	cacheReader.OnEOF(func() {
 | 
						cacheReader.OnEOF(func() {
 | 
				
			||||||
@@ -860,6 +862,70 @@ func (this *HTTPWriter) SetOk() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Close 关闭
 | 
					// Close 关闭
 | 
				
			||||||
func (this *HTTPWriter) Close() {
 | 
					func (this *HTTPWriter) Close() {
 | 
				
			||||||
 | 
						this.finishWebP()
 | 
				
			||||||
 | 
						this.finishRequest()
 | 
				
			||||||
 | 
						this.finishCache()
 | 
				
			||||||
 | 
						this.finishCompression()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 统计
 | 
				
			||||||
 | 
						if this.sentBodyBytes == 0 {
 | 
				
			||||||
 | 
							this.sentBodyBytes = this.counterWriter.TotalBytes()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Hijack Hijack
 | 
				
			||||||
 | 
					func (this *HTTPWriter) Hijack() (conn net.Conn, buf *bufio.ReadWriter, err error) {
 | 
				
			||||||
 | 
						hijack, ok := this.rawWriter.(http.Hijacker)
 | 
				
			||||||
 | 
						if ok {
 | 
				
			||||||
 | 
							return hijack.Hijack()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Flush Flush
 | 
				
			||||||
 | 
					func (this *HTTPWriter) Flush() {
 | 
				
			||||||
 | 
						flusher, ok := this.rawWriter.(http.Flusher)
 | 
				
			||||||
 | 
						if ok {
 | 
				
			||||||
 | 
							flusher.Flush()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DelayRead 是否延迟读取Reader
 | 
				
			||||||
 | 
					func (this *HTTPWriter) DelayRead() bool {
 | 
				
			||||||
 | 
						return this.delayRead
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 计算stale时长
 | 
				
			||||||
 | 
					func (this *HTTPWriter) calculateStaleLife() int {
 | 
				
			||||||
 | 
						var staleLife = 600 // TODO 可以在缓存策略里设置此时间
 | 
				
			||||||
 | 
						var staleConfig = this.req.web.Cache.Stale
 | 
				
			||||||
 | 
						if staleConfig != nil && staleConfig.IsOn {
 | 
				
			||||||
 | 
							// 从Header中读取stale-if-error
 | 
				
			||||||
 | 
							var isDefinedInHeader = false
 | 
				
			||||||
 | 
							if staleConfig.SupportStaleIfErrorHeader {
 | 
				
			||||||
 | 
								var cacheControl = this.GetHeader("Cache-Control")
 | 
				
			||||||
 | 
								var pieces = strings.Split(cacheControl, ",")
 | 
				
			||||||
 | 
								for _, piece := range pieces {
 | 
				
			||||||
 | 
									var eqIndex = strings.Index(piece, "=")
 | 
				
			||||||
 | 
									if eqIndex > 0 && strings.TrimSpace(piece[:eqIndex]) == "stale-if-error" {
 | 
				
			||||||
 | 
										// 这里预示着如果stale-if-error=0,可以关闭stale功能
 | 
				
			||||||
 | 
										staleLife = types.Int(strings.TrimSpace(piece[eqIndex+1:]))
 | 
				
			||||||
 | 
										isDefinedInHeader = true
 | 
				
			||||||
 | 
										break
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 自定义
 | 
				
			||||||
 | 
							if !isDefinedInHeader && staleConfig.Life != nil {
 | 
				
			||||||
 | 
								staleLife = types.Int(staleConfig.Life.Duration().Seconds())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return staleLife
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 结束WebP
 | 
				
			||||||
 | 
					func (this *HTTPWriter) finishWebP() {
 | 
				
			||||||
	// 处理WebP
 | 
						// 处理WebP
 | 
				
			||||||
	if this.webpIsEncoding {
 | 
						if this.webpIsEncoding {
 | 
				
			||||||
		var webpCacheWriter caches.Writer
 | 
							var webpCacheWriter caches.Writer
 | 
				
			||||||
@@ -920,6 +986,7 @@ func (this *HTTPWriter) Close() {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
 | 
								// 发生了错误终止处理
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -949,7 +1016,7 @@ func (this *HTTPWriter) Close() {
 | 
				
			|||||||
			//webpConfig.SetLossless(1)
 | 
								//webpConfig.SetLossless(1)
 | 
				
			||||||
			webpConfig.SetQuality(f)
 | 
								webpConfig.SetQuality(f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			timeline := 0
 | 
								var timeline = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for i, img := range gifImage.Image {
 | 
								for i, img := range gifImage.Image {
 | 
				
			||||||
				err = anim.AddFrame(img, timeline, webpConfig)
 | 
									err = anim.AddFrame(img, timeline, webpConfig)
 | 
				
			||||||
@@ -989,15 +1056,10 @@ func (this *HTTPWriter) Close() {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if this.writer != nil {
 | 
					// 结束缓存相关处理
 | 
				
			||||||
		_ = this.writer.Close()
 | 
					func (this *HTTPWriter) finishCache() {
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if this.rawReader != nil {
 | 
					 | 
				
			||||||
		_ = this.rawReader.Close()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 缓存
 | 
						// 缓存
 | 
				
			||||||
	if this.cacheWriter != nil {
 | 
						if this.cacheWriter != nil {
 | 
				
			||||||
		if this.isOk && this.cacheIsFinished {
 | 
							if this.isOk && this.cacheIsFinished {
 | 
				
			||||||
@@ -1055,7 +1117,10 @@ func (this *HTTPWriter) Close() {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 结束压缩相关处理
 | 
				
			||||||
 | 
					func (this *HTTPWriter) finishCompression() {
 | 
				
			||||||
	if this.compressionCacheWriter != nil {
 | 
						if this.compressionCacheWriter != nil {
 | 
				
			||||||
		if this.isOk {
 | 
							if this.isOk {
 | 
				
			||||||
			err := this.compressionCacheWriter.Close()
 | 
								err := this.compressionCacheWriter.Close()
 | 
				
			||||||
@@ -1076,59 +1141,15 @@ func (this *HTTPWriter) Close() {
 | 
				
			|||||||
			_ = this.compressionCacheWriter.Discard()
 | 
								_ = this.compressionCacheWriter.Discard()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if this.sentBodyBytes == 0 {
 | 
					 | 
				
			||||||
		this.sentBodyBytes = this.counterWriter.TotalBytes()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Hijack Hijack
 | 
					// 最终关闭
 | 
				
			||||||
func (this *HTTPWriter) Hijack() (conn net.Conn, buf *bufio.ReadWriter, err error) {
 | 
					func (this *HTTPWriter) finishRequest() {
 | 
				
			||||||
	hijack, ok := this.rawWriter.(http.Hijacker)
 | 
						if this.writer != nil {
 | 
				
			||||||
	if ok {
 | 
							_ = this.writer.Close()
 | 
				
			||||||
		return hijack.Hijack()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Flush Flush
 | 
					 | 
				
			||||||
func (this *HTTPWriter) Flush() {
 | 
					 | 
				
			||||||
	flusher, ok := this.rawWriter.(http.Flusher)
 | 
					 | 
				
			||||||
	if ok {
 | 
					 | 
				
			||||||
		flusher.Flush()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// DelayRead 是否延迟读取Reader
 | 
					 | 
				
			||||||
func (this *HTTPWriter) DelayRead() bool {
 | 
					 | 
				
			||||||
	return this.delayRead
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 计算stale时长
 | 
					 | 
				
			||||||
func (this *HTTPWriter) calculateStaleLife() int {
 | 
					 | 
				
			||||||
	var staleLife = 600 // TODO 可以在缓存策略里设置此时间
 | 
					 | 
				
			||||||
	var staleConfig = this.req.web.Cache.Stale
 | 
					 | 
				
			||||||
	if staleConfig != nil && staleConfig.IsOn {
 | 
					 | 
				
			||||||
		// 从Header中读取stale-if-error
 | 
					 | 
				
			||||||
		var isDefinedInHeader = false
 | 
					 | 
				
			||||||
		if staleConfig.SupportStaleIfErrorHeader {
 | 
					 | 
				
			||||||
			var cacheControl = this.GetHeader("Cache-Control")
 | 
					 | 
				
			||||||
			var pieces = strings.Split(cacheControl, ",")
 | 
					 | 
				
			||||||
			for _, piece := range pieces {
 | 
					 | 
				
			||||||
				var eqIndex = strings.Index(piece, "=")
 | 
					 | 
				
			||||||
				if eqIndex > 0 && strings.TrimSpace(piece[:eqIndex]) == "stale-if-error" {
 | 
					 | 
				
			||||||
					// 这里预示着如果stale-if-error=0,可以关闭stale功能
 | 
					 | 
				
			||||||
					staleLife = types.Int(strings.TrimSpace(piece[eqIndex+1:]))
 | 
					 | 
				
			||||||
					isDefinedInHeader = true
 | 
					 | 
				
			||||||
					break
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// 自定义
 | 
						if this.rawReader != nil {
 | 
				
			||||||
		if !isDefinedInHeader && staleConfig.Life != nil {
 | 
							_ = this.rawReader.Close()
 | 
				
			||||||
			staleLife = types.Int(staleConfig.Life.Duration().Seconds())
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return staleLife
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user