mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-10-22 01:04:24 +00:00
refine
This commit is contained in:
@@ -2,7 +2,6 @@ package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
gonet "net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -11,18 +10,24 @@ import (
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
)
|
||||
|
||||
// ParseTrustedXForwardedFor parses forwarding headers only when a configured trusted header is present.
|
||||
func ParseTrustedXForwardedFor(header http.Header, trusted []string, remoteAddr gonet.Addr) net.Address {
|
||||
// ApplyTrustedXForwardedFor returns remoteAddr overridden by X-Forwarded-For only when a configured trusted header is present.
|
||||
func ApplyTrustedXForwardedFor(header http.Header, trusted []string, remoteAddr net.Addr) net.Addr {
|
||||
value := header.Get("X-Forwarded-For")
|
||||
if value == "" {
|
||||
return nil
|
||||
return remoteAddr
|
||||
}
|
||||
for _, t := range trusted {
|
||||
if len(header.Values(t)) > 0 {
|
||||
if idx := strings.IndexByte(value, ','); idx >= 0 {
|
||||
value = value[:idx]
|
||||
}
|
||||
return net.ParseAddress(value)
|
||||
if addr := net.ParseAddress(value); addr.Family().IsIP() {
|
||||
return &net.TCPAddr{
|
||||
IP: addr.IP(),
|
||||
Port: 0,
|
||||
}
|
||||
}
|
||||
return remoteAddr
|
||||
}
|
||||
}
|
||||
if len(trusted) == 0 {
|
||||
@@ -30,7 +35,7 @@ func ParseTrustedXForwardedFor(header http.Header, trusted []string, remoteAddr
|
||||
} else {
|
||||
errors.LogError(context.Background(), `ignored potentially forged "X-Forwarded-For" from `, remoteAddr, `: `, value)
|
||||
}
|
||||
return nil
|
||||
return remoteAddr
|
||||
}
|
||||
|
||||
// RemoveHopByHopHeaders removes hop by hop headers in http header list.
|
||||
|
||||
@@ -12,15 +12,15 @@ import (
|
||||
. "github.com/xtls/xray-core/common/protocol/http"
|
||||
)
|
||||
|
||||
func TestParseTrustedXForwardedFor(t *testing.T) {
|
||||
func TestApplyTrustedXForwardedFor(t *testing.T) {
|
||||
remoteAddr := &gonet.TCPAddr{IP: gonet.ParseIP("127.0.0.1"), Port: 12345}
|
||||
|
||||
t.Run("ignore X-Forwarded-For without trusted header", func(t *testing.T) {
|
||||
header := http.Header{}
|
||||
header.Add("X-Forwarded-For", "129.78.138.66, 129.78.64.103")
|
||||
|
||||
if addr := ParseTrustedXForwardedFor(header, nil, remoteAddr); addr != nil {
|
||||
t.Fatalf("unexpected trusted X-Forwarded-For: %v", addr)
|
||||
if addr := ApplyTrustedXForwardedFor(header, nil, remoteAddr); addr != remoteAddr {
|
||||
t.Fatalf("unexpected remote address: %v", addr)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -29,9 +29,19 @@ func TestParseTrustedXForwardedFor(t *testing.T) {
|
||||
header.Add("X-Forwarded-For", "129.78.138.66, 129.78.64.103")
|
||||
header.Add("X-Trusted-CDN", "")
|
||||
|
||||
addr := ParseTrustedXForwardedFor(header, []string{"X-Trusted-CDN"}, remoteAddr)
|
||||
if addr != net.ParseAddress("129.78.138.66") {
|
||||
t.Fatalf("unexpected trusted X-Forwarded-For: %v", addr)
|
||||
addr := ApplyTrustedXForwardedFor(header, []string{"X-Trusted-CDN"}, remoteAddr)
|
||||
if addr.String() != "129.78.138.66:0" {
|
||||
t.Fatalf("unexpected remote address: %v", addr)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ignore non-IP X-Forwarded-For", func(t *testing.T) {
|
||||
header := http.Header{}
|
||||
header.Add("X-Forwarded-For", "example.com")
|
||||
header.Add("X-Trusted-CDN", "")
|
||||
|
||||
if addr := ApplyTrustedXForwardedFor(header, []string{"X-Trusted-CDN"}, remoteAddr); addr != remoteAddr {
|
||||
t.Fatalf("unexpected remote address: %v", addr)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -85,13 +85,7 @@ func (s *server) upgrade(conn net.Conn) (stat.Connection, error) {
|
||||
if s.socketSettings != nil {
|
||||
trustedXFF = s.socketSettings.TrustedXForwardedFor
|
||||
}
|
||||
forwardedAddr := http_proto.ParseTrustedXForwardedFor(req.Header, trustedXFF, remoteAddr)
|
||||
if forwardedAddr != nil && forwardedAddr.Family().IsIP() {
|
||||
remoteAddr = &net.TCPAddr{
|
||||
IP: forwardedAddr.IP(),
|
||||
Port: int(0),
|
||||
}
|
||||
}
|
||||
remoteAddr = http_proto.ApplyTrustedXForwardedFor(req.Header, trustedXFF, remoteAddr)
|
||||
|
||||
return stat.Connection(newConnection(conn, remoteAddr)), nil
|
||||
}
|
||||
|
||||
@@ -174,13 +174,7 @@ func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Req
|
||||
if h.socketSettings != nil {
|
||||
trustedXFF = h.socketSettings.TrustedXForwardedFor
|
||||
}
|
||||
forwardedAddr := http_proto.ParseTrustedXForwardedFor(request.Header, trustedXFF, remoteAddr)
|
||||
if forwardedAddr != nil && forwardedAddr.Family().IsIP() {
|
||||
remoteAddr = &net.TCPAddr{
|
||||
IP: forwardedAddr.IP(),
|
||||
Port: 0,
|
||||
}
|
||||
}
|
||||
remoteAddr = http_proto.ApplyTrustedXForwardedFor(request.Header, trustedXFF, remoteAddr)
|
||||
|
||||
var currentSession *httpSession
|
||||
if sessionId != "" {
|
||||
|
||||
@@ -70,13 +70,7 @@ func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Req
|
||||
if h.socketSettings != nil {
|
||||
trustedXFF = h.socketSettings.TrustedXForwardedFor
|
||||
}
|
||||
forwardedAddr := http_proto.ParseTrustedXForwardedFor(request.Header, trustedXFF, remoteAddr)
|
||||
if forwardedAddr != nil && forwardedAddr.Family().IsIP() {
|
||||
remoteAddr = &net.TCPAddr{
|
||||
IP: forwardedAddr.IP(),
|
||||
Port: int(0),
|
||||
}
|
||||
}
|
||||
remoteAddr = http_proto.ApplyTrustedXForwardedFor(request.Header, trustedXFF, remoteAddr)
|
||||
|
||||
h.ln.addConn(NewConnection(conn, remoteAddr, extraReader, h.ln.config.HeartbeatPeriod))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user