diff --git a/internal/nodes/http_request.go b/internal/nodes/http_request.go index d6f26b1..62378f7 100644 --- a/internal/nodes/http_request.go +++ b/internal/nodes/http_request.go @@ -11,6 +11,7 @@ import ( "github.com/TeaOSLab/EdgeNode/internal/metrics" "github.com/TeaOSLab/EdgeNode/internal/stats" "github.com/TeaOSLab/EdgeNode/internal/utils" + "github.com/iwind/TeaGo/lists" "github.com/iwind/TeaGo/types" "io" "io/ioutil" @@ -1144,44 +1145,53 @@ func (this *HTTPRequest) processRequestHeaders(reqHeader http.Header) { } } - // Add - for _, header := range this.web.RequestHeaderPolicy.AddHeaders { - if !header.IsOn { - continue - } - oldValues, _ := this.RawReq.Header[header.Name] - newHeaderValue := header.Value // 因为我们不能修改header,所以在这里使用新变量 - if header.HasVariables() { - newHeaderValue = this.Format(header.Value) - } - oldValues = append(oldValues, newHeaderValue) - reqHeader[header.Name] = oldValues - - // 支持修改Host - if header.Name == "Host" && len(header.Value) > 0 { - this.RawReq.Host = newHeaderValue - } - } - // Set for _, header := range this.web.RequestHeaderPolicy.SetHeaders { if !header.IsOn { continue } - newHeaderValue := header.Value // 因为我们不能修改header,所以在这里使用新变量 - if header.HasVariables() { - newHeaderValue = this.Format(header.Value) + + // 是否已删除 + if this.web.ResponseHeaderPolicy.ContainsDeletedHeader(header.Name) { + continue + } + + // 请求方法 + if len(header.Methods) > 0 && !lists.ContainsString(header.Methods, this.RawReq.Method) { + continue + } + + // 域名 + if len(header.Domains) > 0 && !configutils.MatchDomains(header.Domains, this.Host) { + continue + } + + var headerValue = header.Value + if header.ShouldReplace { + if len(headerValue) == 0 { + headerValue = reqHeader.Get(header.Name) // 原有值 + } else if header.HasVariables() { + headerValue = this.Format(header.Value) + } + + for _, v := range header.ReplaceValues { + headerValue = v.Replace(headerValue) + } + } else if header.HasVariables() { + headerValue = this.Format(header.Value) } - reqHeader[header.Name] = []string{newHeaderValue} // 支持修改Host if header.Name == "Host" && len(header.Value) > 0 { - this.RawReq.Host = newHeaderValue + this.RawReq.Host = headerValue + } else { + if header.ShouldAppend { + reqHeader[header.Name] = append(reqHeader[header.Name], headerValue) + } else { + reqHeader[header.Name] = []string{headerValue} + } } } - - // Replace - // TODO 需要实现 } } @@ -1206,7 +1216,6 @@ func (this *HTTPRequest) processResponseHeaders(statusCode int) { // 删除/添加/替换Header // TODO 实现AddTrailers - // TODO 实现ReplaceHeaders if this.web.ResponseHeaderPolicy != nil && this.web.ResponseHeaderPolicy.IsOn { // 删除某些Header for name := range responseHeader { @@ -1215,44 +1224,58 @@ func (this *HTTPRequest) processResponseHeaders(statusCode int) { } } - // Add - for _, header := range this.web.ResponseHeaderPolicy.AddHeaders { - if !header.IsOn { - continue - } - if header.Match(statusCode) { - if this.web.ResponseHeaderPolicy.ContainsDeletedHeader(header.Name) { - continue - } - oldValues, _ := responseHeader[header.Name] - if header.HasVariables() { - oldValues = append(oldValues, this.Format(header.Value)) - } else { - oldValues = append(oldValues, header.Value) - } - responseHeader[header.Name] = oldValues - } - } - // Set for _, header := range this.web.ResponseHeaderPolicy.SetHeaders { if !header.IsOn { continue } - if header.Match(statusCode) { - if this.web.ResponseHeaderPolicy.ContainsDeletedHeader(header.Name) { - continue + + // 是否已删除 + if this.web.ResponseHeaderPolicy.ContainsDeletedHeader(header.Name) { + continue + } + + // 状态码 + if header.Status != nil && !header.Status.Match(statusCode) { + continue + } + + // 请求方法 + if len(header.Methods) > 0 && !lists.ContainsString(header.Methods, this.RawReq.Method) { + continue + } + + // 域名 + if len(header.Domains) > 0 && !configutils.MatchDomains(header.Domains, this.Host) { + continue + } + + // 是否为跳转 + if header.DisableRedirect && httpStatusIsRedirect(statusCode) { + continue + } + + var headerValue = header.Value + if header.ShouldReplace { + if len(headerValue) == 0 { + headerValue = responseHeader.Get(header.Name) // 原有值 + } else if header.HasVariables() { + headerValue = this.Format(header.Value) } - if header.HasVariables() { - responseHeader[header.Name] = []string{this.Format(header.Value)} - } else { - responseHeader[header.Name] = []string{header.Value} + + for _, v := range header.ReplaceValues { + headerValue = v.Replace(headerValue) } + } else if header.HasVariables() { + headerValue = this.Format(header.Value) + } + + if header.ShouldAppend { + responseHeader[header.Name] = append(responseHeader[header.Name], headerValue) + } else { + responseHeader[header.Name] = []string{headerValue} } } - - // Replace - // TODO } // HSTS diff --git a/internal/nodes/http_request_utils.go b/internal/nodes/http_request_utils.go index 8687260..5a86b1d 100644 --- a/internal/nodes/http_request_utils.go +++ b/internal/nodes/http_request_utils.go @@ -6,6 +6,7 @@ import ( teaconst "github.com/TeaOSLab/EdgeNode/internal/const" "github.com/TeaOSLab/EdgeNode/internal/utils" "io" + "net/http" "strconv" "strings" "sync/atomic" @@ -129,6 +130,15 @@ func httpRequestGenBoundary() string { return fmt.Sprintf("%x", buf[:]) } +// 判断状态是否为跳转 +func httpStatusIsRedirect(statusCode int) bool { + return statusCode == http.StatusPermanentRedirect || + statusCode == http.StatusTemporaryRedirect || + statusCode == http.StatusMovedPermanently || + statusCode == http.StatusSeeOther || + statusCode == http.StatusFound +} + // 生成请求ID var httpRequestTimestamp int64 var httpRequestId int32 = 1_000_000