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
|
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
|
package http_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
. "v2ray.com/core/common/protocol/http"
|
. "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[0].String(), Equals, "129.78.138.66")
|
||||||
assert(addrs[1].String(), Equals, "129.78.64.103")
|
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/buf"
|
||||||
"v2ray.com/core/common/errors"
|
"v2ray.com/core/common/errors"
|
||||||
"v2ray.com/core/common/net"
|
"v2ray.com/core/common/net"
|
||||||
|
http_proto "v2ray.com/core/common/protocol/http"
|
||||||
"v2ray.com/core/common/signal"
|
"v2ray.com/core/common/signal"
|
||||||
"v2ray.com/core/transport/internet"
|
"v2ray.com/core/transport/internet"
|
||||||
)
|
)
|
||||||
|
@ -210,35 +211,6 @@ func (s *Server) handleConnect(ctx context.Context, request *http.Request, reade
|
||||||
return nil
|
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")
|
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 {
|
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 {
|
if len(request.URL.Host) > 0 {
|
||||||
request.Host = request.URL.Host
|
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)
|
ray, err := dispatcher.Dispatch(ctx, dest)
|
||||||
if err != nil {
|
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)
|
responseReader := bufio.NewReaderSize(buf.NewBufferedReader(ray.InboundOutput()), buf.Size)
|
||||||
response, err := http.ReadResponse(responseReader, request)
|
response, err := http.ReadResponse(responseReader, request)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
StripHopByHopHeaders(response.Header)
|
http_proto.RemoveHopByHopHeaders(response.Header)
|
||||||
if response.ContentLength >= 0 {
|
if response.ContentLength >= 0 {
|
||||||
response.Header.Set("Proxy-Connection", "keep-alive")
|
response.Header.Set("Proxy-Connection", "keep-alive")
|
||||||
response.Header.Set("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