mirror of https://github.com/v2ray/v2ray-core
remove header operation to http protocol package
parent
91ca88bcff
commit
1f226797bc
|
@ -19,3 +19,26 @@ func ParseXForwardedFor(header http.Header) []net.Address {
|
|||
}
|
||||
return addrs
|
||||
}
|
||||
|
||||
func RemoveHopByHopHeaders(header http.Header) {
|
||||
// Strip hop-by-hop header based on RFC:
|
||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1
|
||||
// https://www.mnot.net/blog/2011/07/11/what_proxies_must_do
|
||||
|
||||
header.Del("Proxy-Connection")
|
||||
header.Del("Proxy-Authenticate")
|
||||
header.Del("Proxy-Authorization")
|
||||
header.Del("TE")
|
||||
header.Del("Trailers")
|
||||
header.Del("Transfer-Encoding")
|
||||
header.Del("Upgrade")
|
||||
|
||||
connections := header.Get("Connection")
|
||||
header.Del("Connection")
|
||||
if len(connections) == 0 {
|
||||
return
|
||||
}
|
||||
for _, h := range strings.Split(connections, ",") {
|
||||
header.Del(strings.TrimSpace(h))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package http_test
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
. "v2ray.com/core/common/protocol/http"
|
||||
|
@ -18,3 +20,36 @@ func TestParseXForwardedFor(t *testing.T) {
|
|||
assert(addrs[0].String(), Equals, "129.78.138.66")
|
||||
assert(addrs[1].String(), Equals, "129.78.64.103")
|
||||
}
|
||||
|
||||
func TestHopByHopHeadersRemoving(t *testing.T) {
|
||||
assert := With(t)
|
||||
|
||||
rawRequest := `GET /pkg/net/http/ HTTP/1.1
|
||||
Host: golang.org
|
||||
Connection: keep-alive,Foo, Bar
|
||||
Foo: foo
|
||||
Bar: bar
|
||||
Proxy-Connection: keep-alive
|
||||
Proxy-Authenticate: abc
|
||||
Accept-Encoding: gzip
|
||||
Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7
|
||||
Cache-Control: no-cache
|
||||
Accept-Language: de,en;q=0.7,en-us;q=0.3
|
||||
|
||||
`
|
||||
b := bufio.NewReader(strings.NewReader(rawRequest))
|
||||
req, err := http.ReadRequest(b)
|
||||
assert(err, IsNil)
|
||||
assert(req.Header.Get("Foo"), Equals, "foo")
|
||||
assert(req.Header.Get("Bar"), Equals, "bar")
|
||||
assert(req.Header.Get("Connection"), Equals, "keep-alive,Foo, Bar")
|
||||
assert(req.Header.Get("Proxy-Connection"), Equals, "keep-alive")
|
||||
assert(req.Header.Get("Proxy-Authenticate"), Equals, "abc")
|
||||
|
||||
RemoveHopByHopHeaders(req.Header)
|
||||
assert(req.Header.Get("Connection"), IsEmpty)
|
||||
assert(req.Header.Get("Foo"), IsEmpty)
|
||||
assert(req.Header.Get("Bar"), IsEmpty)
|
||||
assert(req.Header.Get("Proxy-Connection"), IsEmpty)
|
||||
assert(req.Header.Get("Proxy-Authenticate"), IsEmpty)
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"v2ray.com/core/common/buf"
|
||||
"v2ray.com/core/common/errors"
|
||||
"v2ray.com/core/common/net"
|
||||
http_proto "v2ray.com/core/common/protocol/http"
|
||||
"v2ray.com/core/common/signal"
|
||||
"v2ray.com/core/transport/internet"
|
||||
)
|
||||
|
@ -210,35 +211,6 @@ func (s *Server) handleConnect(ctx context.Context, request *http.Request, reade
|
|||
return nil
|
||||
}
|
||||
|
||||
// @VisibleForTesting
|
||||
func StripHopByHopHeaders(header http.Header) {
|
||||
// Strip hop-by-hop header basaed on RFC:
|
||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1
|
||||
// https://www.mnot.net/blog/2011/07/11/what_proxies_must_do
|
||||
|
||||
header.Del("Proxy-Connection")
|
||||
header.Del("Proxy-Authenticate")
|
||||
header.Del("Proxy-Authorization")
|
||||
header.Del("TE")
|
||||
header.Del("Trailers")
|
||||
header.Del("Transfer-Encoding")
|
||||
header.Del("Upgrade")
|
||||
|
||||
connections := header.Get("Connection")
|
||||
header.Del("Connection")
|
||||
if len(connections) == 0 {
|
||||
return
|
||||
}
|
||||
for _, h := range strings.Split(connections, ",") {
|
||||
header.Del(strings.TrimSpace(h))
|
||||
}
|
||||
|
||||
// Prevent UA from being set to golang's default ones
|
||||
if len(header.Get("User-Agent")) == 0 {
|
||||
header.Set("User-Agent", "")
|
||||
}
|
||||
}
|
||||
|
||||
var errWaitAnother = newError("keep alive")
|
||||
|
||||
func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, writer io.Writer, dest net.Destination, dispatcher dispatcher.Interface) error {
|
||||
|
@ -263,7 +235,12 @@ func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, wri
|
|||
if len(request.URL.Host) > 0 {
|
||||
request.Host = request.URL.Host
|
||||
}
|
||||
StripHopByHopHeaders(request.Header)
|
||||
http_proto.RemoveHopByHopHeaders(request.Header)
|
||||
|
||||
// Prevent UA from being set to golang's default ones
|
||||
if len(request.Header.Get("User-Agent")) == 0 {
|
||||
request.Header.Set("User-Agent", "")
|
||||
}
|
||||
|
||||
ray, err := dispatcher.Dispatch(ctx, dest)
|
||||
if err != nil {
|
||||
|
@ -290,7 +267,7 @@ func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, wri
|
|||
responseReader := bufio.NewReaderSize(buf.NewBufferedReader(ray.InboundOutput()), buf.Size)
|
||||
response, err := http.ReadResponse(responseReader, request)
|
||||
if err == nil {
|
||||
StripHopByHopHeaders(response.Header)
|
||||
http_proto.RemoveHopByHopHeaders(response.Header)
|
||||
if response.ContentLength >= 0 {
|
||||
response.Header.Set("Proxy-Connection", "keep-alive")
|
||||
response.Header.Set("Connection", "keep-alive")
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
package http_test
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
. "v2ray.com/core/proxy/http"
|
||||
. "v2ray.com/ext/assert"
|
||||
|
||||
_ "v2ray.com/core/transport/internet/tcp"
|
||||
)
|
||||
|
||||
func TestHopByHopHeadersStrip(t *testing.T) {
|
||||
assert := With(t)
|
||||
|
||||
rawRequest := `GET /pkg/net/http/ HTTP/1.1
|
||||
Host: golang.org
|
||||
Connection: keep-alive,Foo, Bar
|
||||
Foo: foo
|
||||
Bar: bar
|
||||
Proxy-Connection: keep-alive
|
||||
Proxy-Authenticate: abc
|
||||
Accept-Encoding: gzip
|
||||
Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7
|
||||
Cache-Control: no-cache
|
||||
Accept-Language: de,en;q=0.7,en-us;q=0.3
|
||||
|
||||
`
|
||||
b := bufio.NewReader(strings.NewReader(rawRequest))
|
||||
req, err := http.ReadRequest(b)
|
||||
assert(err, IsNil)
|
||||
assert(req.Header.Get("Foo"), Equals, "foo")
|
||||
assert(req.Header.Get("Bar"), Equals, "bar")
|
||||
assert(req.Header.Get("Connection"), Equals, "keep-alive,Foo, Bar")
|
||||
assert(req.Header.Get("Proxy-Connection"), Equals, "keep-alive")
|
||||
assert(req.Header.Get("Proxy-Authenticate"), Equals, "abc")
|
||||
assert(req.Header.Get("User-Agent"), IsEmpty)
|
||||
|
||||
StripHopByHopHeaders(req.Header)
|
||||
assert(req.Header.Get("Connection"), IsEmpty)
|
||||
assert(req.Header.Get("Foo"), IsEmpty)
|
||||
assert(req.Header.Get("Bar"), IsEmpty)
|
||||
assert(req.Header.Get("Proxy-Connection"), IsEmpty)
|
||||
assert(req.Header.Get("Proxy-Authenticate"), IsEmpty)
|
||||
assert(req.Header.Get("User-Agent"), IsEmpty)
|
||||
}
|
Loading…
Reference in New Issue