HTTP Header:实现请求方法、域名、状态码等限制,实现内容替换功能

This commit is contained in:
刘祥超
2021-12-14 21:27:24 +08:00
parent 2e11c99b7a
commit a4a6e95099
2 changed files with 90 additions and 57 deletions

View File

@@ -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

View File

@@ -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