mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-10 20:50:25 +08:00
HTTP Header:实现请求方法、域名、状态码等限制,实现内容替换功能
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeNode/internal/metrics"
|
"github.com/TeaOSLab/EdgeNode/internal/metrics"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/stats"
|
"github.com/TeaOSLab/EdgeNode/internal/stats"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/utils"
|
"github.com/TeaOSLab/EdgeNode/internal/utils"
|
||||||
|
"github.com/iwind/TeaGo/lists"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"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
|
// Set
|
||||||
for _, header := range this.web.RequestHeaderPolicy.SetHeaders {
|
for _, header := range this.web.RequestHeaderPolicy.SetHeaders {
|
||||||
if !header.IsOn {
|
if !header.IsOn {
|
||||||
continue
|
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
|
// 支持修改Host
|
||||||
if header.Name == "Host" && len(header.Value) > 0 {
|
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
|
// 删除/添加/替换Header
|
||||||
// TODO 实现AddTrailers
|
// TODO 实现AddTrailers
|
||||||
// TODO 实现ReplaceHeaders
|
|
||||||
if this.web.ResponseHeaderPolicy != nil && this.web.ResponseHeaderPolicy.IsOn {
|
if this.web.ResponseHeaderPolicy != nil && this.web.ResponseHeaderPolicy.IsOn {
|
||||||
// 删除某些Header
|
// 删除某些Header
|
||||||
for name := range responseHeader {
|
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
|
// Set
|
||||||
for _, header := range this.web.ResponseHeaderPolicy.SetHeaders {
|
for _, header := range this.web.ResponseHeaderPolicy.SetHeaders {
|
||||||
if !header.IsOn {
|
if !header.IsOn {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if header.Match(statusCode) {
|
|
||||||
|
// 是否已删除
|
||||||
if this.web.ResponseHeaderPolicy.ContainsDeletedHeader(header.Name) {
|
if this.web.ResponseHeaderPolicy.ContainsDeletedHeader(header.Name) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if header.HasVariables() {
|
|
||||||
responseHeader[header.Name] = []string{this.Format(header.Value)}
|
// 状态码
|
||||||
} else {
|
if header.Status != nil && !header.Status.Match(statusCode) {
|
||||||
responseHeader[header.Name] = []string{header.Value}
|
continue
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace
|
// 请求方法
|
||||||
// TODO
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
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}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HSTS
|
// HSTS
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
|
teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/utils"
|
"github.com/TeaOSLab/EdgeNode/internal/utils"
|
||||||
"io"
|
"io"
|
||||||
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
@@ -129,6 +130,15 @@ func httpRequestGenBoundary() string {
|
|||||||
return fmt.Sprintf("%x", buf[:])
|
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
|
// 生成请求ID
|
||||||
var httpRequestTimestamp int64
|
var httpRequestTimestamp int64
|
||||||
var httpRequestId int32 = 1_000_000
|
var httpRequestId int32 = 1_000_000
|
||||||
|
|||||||
Reference in New Issue
Block a user