实现gzip

This commit is contained in:
刘祥超
2020-09-29 17:21:46 +08:00
parent c8ed2f59be
commit 4218221e1c
3 changed files with 64 additions and 11 deletions

View File

@@ -60,7 +60,7 @@ type HTTPRequest struct {
// 初始化 // 初始化
func (this *HTTPRequest) init() { func (this *HTTPRequest) init() {
this.writer = NewHTTPWriter(this.RawWriter) this.writer = NewHTTPWriter(this, this.RawWriter)
this.web = &serverconfigs.HTTPWebConfig{} this.web = &serverconfigs.HTTPWebConfig{}
this.uri = this.RawReq.URL.RequestURI() this.uri = this.RawReq.URL.RequestURI()
this.rawURI = this.uri this.rawURI = this.uri
@@ -101,10 +101,18 @@ func (this *HTTPRequest) Do() {
} }
// Gzip // 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() 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 this.web.Websocket = web.Websocket
} }
// gzip
if web.GzipRef != nil && (web.GzipRef.IsPrior || isTop) {
this.web.Gzip = web.Gzip
}
// 重写规则 // 重写规则
if len(web.RewriteRefs) > 0 { if len(web.RewriteRefs) > 0 {
for index, ref := range web.RewriteRefs { for index, ref := range web.RewriteRefs {
@@ -235,7 +248,7 @@ func (this *HTTPRequest) configureWeb(web *serverconfigs.HTTPWebConfig, isTop bo
if !rewriteRule.IsOn { if !rewriteRule.IsOn {
continue 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.addVarMapping(varMapping)
this.rewriteRule = rewriteRule this.rewriteRule = rewriteRule
@@ -267,10 +280,11 @@ func (this *HTTPRequest) configureWeb(web *serverconfigs.HTTPWebConfig, isTop bo
} }
this.uri = replace this.uri = replace
// 终止解析的个条件: // 终止解析的几个个条件:
// isBreak = true // isBreak = true
// mode = redirect // mode = redirect
// replace = external url // replace = external url
// replace = uri
if rewriteRule.IsBreak || rewriteRule.Mode == serverconfigs.HTTPRewriteModeRedirect { if rewriteRule.IsBreak || rewriteRule.Mode == serverconfigs.HTTPRewriteModeRedirect {
return nil return nil
} }
@@ -363,6 +377,8 @@ func (this *HTTPRequest) Format(source string) string {
return this.rawURI return this.rawURI
case "requestPath": case "requestPath":
return this.requestPath() return this.requestPath()
case "requestPathExtension": // TODO 需要添加到文档中
return filepath.Ext(this.requestPath())
case "requestLength": case "requestLength":
return strconv.FormatInt(this.requestLength(), 10) return strconv.FormatInt(this.requestLength(), 10)
case "requestTime": case "requestTime":
@@ -455,7 +471,26 @@ func (this *HTTPRequest) Format(source string) string {
return this.requestHeader(suffix) 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 prefix == "origin" {
if this.origin != nil { if this.origin != nil {
switch suffix { switch suffix {

View File

@@ -151,7 +151,7 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
// mime type // mime type
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(requestPath) 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 {

View File

@@ -8,10 +8,12 @@ import (
"github.com/iwind/TeaGo/logs" "github.com/iwind/TeaGo/logs"
"net" "net"
"net/http" "net/http"
"strings"
) )
// 响应Writer // 响应Writer
type HTTPWriter struct { type HTTPWriter struct {
req *HTTPRequest
writer http.ResponseWriter writer http.ResponseWriter
gzipConfig *serverconfigs.HTTPGzipConfig 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{ return &HTTPWriter{
req: req,
writer: httpResponseWriter, writer: httpResponseWriter,
} }
} }
@@ -60,16 +63,31 @@ func (this *HTTPWriter) Prepare(size int64) {
return return
} }
// 尺寸和类型 // 判断Accept是否支持gzip
if size < this.gzipConfig.MinBytes() { if !strings.Contains(this.req.requestHeader("Accept-Encoding"), "gzip") {
return 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 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 { if len(this.writer.Header().Get("Content-Encoding")) > 0 {
return return