فهرست منبع

remove header operation to http protocol package

Darien Raymond 7 سال پیش
والد
کامیت
1f226797bc
4فایلهای تغییر یافته به همراه66 افزوده شده و 79 حذف شده
  1. 23 0
      common/protocol/http/headers.go
  2. 35 0
      common/protocol/http/headers_test.go
  3. 8 31
      proxy/http/server.go
  4. 0 48
      proxy/http/server_test.go

+ 23 - 0
common/protocol/http/headers.go

@@ -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))
+	}
+}

+ 35 - 0
common/protocol/http/headers_test.go

@@ -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)
+}

+ 8 - 31
proxy/http/server.go

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

+ 0 - 48
proxy/http/server_test.go

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