fix:encoding asset

This commit is contained in:
samwaf
2025-03-25 09:59:21 +08:00
parent 9dffd48825
commit a21afb2c0c
3 changed files with 63 additions and 30 deletions
+34 -15
View File
@@ -1,22 +1,12 @@
package utils
import "strings"
// IsContent 是否是内容
func IsContent(contentType string) bool {
var allowedSortFields = []string{"application/json", "text/xml", "application/xml",
"text/plain", "text/html", "text/csv", "application/html"}
for _, allowedField := range allowedSortFields {
if strings.Contains(contentType, allowedField) {
return true
}
}
return false
}
import (
"net/http"
"strings"
)
// IsStaticAssist 是否是静态资源
func IsStaticAssist(contentType string) bool {
func IsStaticAssist(res *http.Response, contentType string) bool {
var allowedSortFields = []string{"application/javascript", "text/css", "image/jpeg",
"image/png", "image/gif", "image/x-icon", "text/js"}
@@ -25,5 +15,34 @@ func IsStaticAssist(contentType string) bool {
return true
}
}
// 检查请求的Accept头,判断是否为资源类型请求
if res.Request != nil {
acceptHeader := res.Request.Header.Get("Accept")
if acceptHeader != "" {
// 检查Accept头是否主要请求图片或其他资源类型
isResourceRequest := strings.Contains(acceptHeader, "image/") ||
strings.Contains(acceptHeader, "font/") ||
strings.Contains(acceptHeader, "audio/") ||
strings.Contains(acceptHeader, "video/")
return isResourceRequest
}
// 检查Sec-Fetch-Dest头,这是一个更明确的指示
secFetchDest := res.Request.Header.Get("Sec-Fetch-Dest")
if secFetchDest == "image" || secFetchDest == "font" ||
secFetchDest == "audio" || secFetchDest == "video" ||
secFetchDest == "style" {
return true
}
}
//如果检测资源后发现还存在,那么进行判断处理
var textFields = []string{"application/json", "text/xml", "application/xml",
"text/plain", "text/html", "text/csv", "application/html"}
for _, textField := range textFields {
if strings.Contains(contentType, textField) {
return false
}
}
return false
}
+16 -2
View File
@@ -20,7 +20,14 @@ import (
)
// 返回内容前依据情况进行返回压缩数据
func (waf *WafEngine) compressContent(res *http.Response, inputBytes []byte) (respBytes []byte, err error) {
func (waf *WafEngine) compressContent(res *http.Response, isStaticAssist bool, inputBytes []byte) (respBytes []byte, err error) {
// 如果是静态资源响应或资源类型请求,直接返回原始内容
if isStaticAssist {
zlog.Debug("静态资源或资源类型请求,跳过编码转换")
return inputBytes, nil
}
// 首先检查Content-Type头中是否明确指定了字符集
contentType := res.Header.Get("Content-Type")
var encodedBytes []byte = inputBytes
@@ -70,13 +77,20 @@ func (waf *WafEngine) compressContent(res *http.Response, inputBytes []byte) (re
}
// 获取原始内容
func (waf *WafEngine) getOrgContent(resp *http.Response) (cntBytes []byte, err error) {
func (waf *WafEngine) getOrgContent(resp *http.Response, isStaticAssist bool) (cntBytes []byte, err error) {
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return bodyBytes, fmt.Errorf("读取原始响应体失败: %v", err)
}
// 重新设置响应体,以便后续处理
resp.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
// 如果是静态资源响应或资源类型请求,直接返回原始内容
if isStaticAssist {
zlog.Debug("静态资源或资源类型请求,跳过编码转换")
return bodyBytes, nil
}
// 根据内容编码处理压缩
var bodyReader io.Reader
switch resp.Header.Get("Content-Encoding") {
+13 -13
View File
@@ -600,6 +600,14 @@ func (waf *WafEngine) modifyResponse() func(*http.Response) error {
weblogfrist.STATUS = resp.Status
weblogfrist.STATUS_CODE = resp.StatusCode
//返回内容的类型
respContentType := strings.ToLower(resp.Header.Get("Content-Type"))
respContentType = strings.Replace(respContentType, "; charset=utf-8", "", -1)
respContentType = strings.Replace(respContentType, "; charset=gbk", "", -1)
//记录静态日志
isStaticAssist := utils.IsStaticAssist(resp, respContentType)
ldpFlag := false
// 将请求URL转为小写,用于不区分大小写的比较
lowerRequestURI := strings.ToLower(resp.Request.RequestURI)
@@ -633,10 +641,10 @@ func (waf *WafEngine) modifyResponse() func(*http.Response) error {
}
}
if ldpFlag == true {
orgContentBytes, responseEncodingError := waf.getOrgContent(resp)
orgContentBytes, responseEncodingError := waf.getOrgContent(resp, isStaticAssist)
if responseEncodingError == nil {
newPayload := []byte("" + utils.DeSenText(string(orgContentBytes)))
finalCompressBytes, _ := waf.compressContent(resp, newPayload)
finalCompressBytes, _ := waf.compressContent(resp, isStaticAssist, newPayload)
resp.Body = io.NopCloser(bytes.NewBuffer(finalCompressBytes))
// head 修改追加内容
@@ -648,20 +656,12 @@ func (waf *WafEngine) modifyResponse() func(*http.Response) error {
}
}
//返回内容的类型
respContentType := strings.ToLower(resp.Header.Get("Content-Type"))
respContentType = strings.Replace(respContentType, "; charset=utf-8", "", -1)
respContentType = strings.Replace(respContentType, "; charset=gbk", "", -1)
//记录静态日志
isStaticAssist := utils.IsStaticAssist(respContentType)
isText := utils.IsContent(respContentType)
//记录响应body
if isText && resp.Body != nil && resp.Body != http.NoBody {
if !isStaticAssist && resp.Body != nil && resp.Body != http.NoBody {
//编码转换,自动检测网页编码 resp *http.Response
orgContentBytes, responseEncodingError := waf.getOrgContent(resp)
orgContentBytes, responseEncodingError := waf.getOrgContent(resp, isStaticAssist)
if responseEncodingError == nil {
if global.GCONFIG_RECORD_RESP == 1 {
if resp.ContentLength < global.GCONFIG_RECORD_MAX_RES_BODY_LENGTH {
@@ -696,7 +696,7 @@ func (waf *WafEngine) modifyResponse() func(*http.Response) error {
}
}
//将数据在回写上去
finalCompressBytes, _ := waf.compressContent(resp, orgContentBytes)
finalCompressBytes, _ := waf.compressContent(resp, isStaticAssist, orgContentBytes)
resp.Body = io.NopCloser(bytes.NewBuffer(finalCompressBytes))
resp.ContentLength = int64(len(finalCompressBytes))
resp.Header.Set("Content-Length", strconv.FormatInt(int64(len(finalCompressBytes)), 10))