实现gzip

This commit is contained in:
GoEdgeLab
2020-09-29 17:21:46 +08:00
parent 55313fc877
commit 17fc8295c4
3 changed files with 64 additions and 11 deletions

View File

@@ -60,7 +60,7 @@ type HTTPRequest struct {
// 初始化
func (this *HTTPRequest) init() {
this.writer = NewHTTPWriter(this.RawWriter)
this.writer = NewHTTPWriter(this, this.RawWriter)
this.web = &serverconfigs.HTTPWebConfig{}
this.uri = this.RawReq.URL.RequestURI()
this.rawURI = this.uri
@@ -101,10 +101,18 @@ func (this *HTTPRequest) Do() {
}
// Gzip
// TODO 需要实现
shouldCloseWriter := false
if this.web.Gzip != nil && this.web.Gzip.IsOn && this.web.Gzip.Level > 0 {
shouldCloseWriter = true
this.writer.Gzip(this.web.Gzip)
}
// 开始调用
this.doBegin()
if shouldCloseWriter {
this.writer.Close()
}
}
// 开始调用
@@ -225,6 +233,11 @@ func (this *HTTPRequest) configureWeb(web *serverconfigs.HTTPWebConfig, isTop bo
this.web.Websocket = web.Websocket
}
// gzip
if web.GzipRef != nil && (web.GzipRef.IsPrior || isTop) {
this.web.Gzip = web.Gzip
}
// 重写规则
if len(web.RewriteRefs) > 0 {
for index, ref := range web.RewriteRefs {
@@ -235,7 +248,7 @@ func (this *HTTPRequest) configureWeb(web *serverconfigs.HTTPWebConfig, isTop bo
if !rewriteRule.IsOn {
continue
}
if replace, varMapping, isMatched := rewriteRule.Match(rawPath, this.Format); isMatched {
if replace, varMapping, isMatched := rewriteRule.MatchRequest(rawPath, this.Format); isMatched {
this.addVarMapping(varMapping)
this.rewriteRule = rewriteRule
@@ -267,10 +280,11 @@ func (this *HTTPRequest) configureWeb(web *serverconfigs.HTTPWebConfig, isTop bo
}
this.uri = replace
// 终止解析的个条件:
// 终止解析的几个个条件:
// isBreak = true
// mode = redirect
// replace = external url
// replace = uri
if rewriteRule.IsBreak || rewriteRule.Mode == serverconfigs.HTTPRewriteModeRedirect {
return nil
}
@@ -363,6 +377,8 @@ func (this *HTTPRequest) Format(source string) string {
return this.rawURI
case "requestPath":
return this.requestPath()
case "requestPathExtension": // TODO 需要添加到文档中
return filepath.Ext(this.requestPath())
case "requestLength":
return strconv.FormatInt(this.requestLength(), 10)
case "requestTime":
@@ -455,7 +471,26 @@ func (this *HTTPRequest) Format(source string) string {
return this.requestHeader(suffix)
}
// backend.
// response.
// TODO 需要在文档中添加说明
if prefix == "response" {
switch suffix {
case "contentType":
return this.writer.Header().Get("Content-Type")
}
// response.xxx.xxx
dotIndex := strings.Index(suffix, ".")
if dotIndex < 0 {
return "${" + varName + "}"
}
switch suffix[:dotIndex] {
case "header":
return this.writer.Header().Get(suffix[dotIndex+1:])
}
}
// origin.
if prefix == "origin" {
if this.origin != nil {
switch suffix {

View File

@@ -151,7 +151,7 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
// mime type
if this.web.ResponseHeaderPolicy == nil || !this.web.ResponseHeaderPolicy.IsOn || !this.web.ResponseHeaderPolicy.ContainsHeader("CONTENT-TYPE") {
ext := filepath.Ext(requestPath)
ext := filepath.Ext(filePath)
if len(ext) > 0 {
mimeType := mime.TypeByExtension(ext)
if len(mimeType) > 0 {

View File

@@ -8,10 +8,12 @@ import (
"github.com/iwind/TeaGo/logs"
"net"
"net/http"
"strings"
)
// 响应Writer
type HTTPWriter struct {
req *HTTPRequest
writer http.ResponseWriter
gzipConfig *serverconfigs.HTTPGzipConfig
@@ -27,8 +29,9 @@ type HTTPWriter struct {
}
// 包装对象
func NewHTTPWriter(httpResponseWriter http.ResponseWriter) *HTTPWriter {
func NewHTTPWriter(req *HTTPRequest, httpResponseWriter http.ResponseWriter) *HTTPWriter {
return &HTTPWriter{
req: req,
writer: httpResponseWriter,
}
}
@@ -60,16 +63,31 @@ func (this *HTTPWriter) Prepare(size int64) {
return
}
// 尺寸和类型
if size < this.gzipConfig.MinBytes() {
// 判断Accept是否支持gzip
if !strings.Contains(this.req.requestHeader("Accept-Encoding"), "gzip") {
return
}
contentType := this.Header().Get("Content-Type")
if !this.gzipConfig.MatchContentType(contentType) {
// 尺寸和类型
if size < this.gzipConfig.MinBytes() || (this.gzipConfig.MaxBytes() > 0 && size > this.gzipConfig.MaxBytes()) {
return
}
// 校验其他条件
if this.gzipConfig.Conds != nil {
if len(this.gzipConfig.Conds.Groups) > 0 {
if !this.gzipConfig.Conds.MatchRequest(this.req.Format) || !this.gzipConfig.Conds.MatchResponse(this.req.Format) {
return
}
} else {
// 默认校验文档类型
contentType := this.writer.Header().Get("Content-Type")
if len(contentType) > 0 && (!strings.HasPrefix(contentType, "text/") && !strings.HasPrefix(contentType, "application/")) {
return
}
}
}
// 如果已经有编码则不处理
if len(this.writer.Header().Get("Content-Encoding")) > 0 {
return