1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
| package http_test
|
| import (
| "bufio"
| "net/http"
| "strings"
| "testing"
|
| "github.com/google/go-cmp/cmp"
|
| "github.com/v2fly/v2ray-core/v5/common"
| "github.com/v2fly/v2ray-core/v5/common/net"
| . "github.com/v2fly/v2ray-core/v5/common/protocol/http"
| )
|
| func TestParseXForwardedFor(t *testing.T) {
| header := http.Header{}
| header.Add("X-Forwarded-For", "129.78.138.66, 129.78.64.103")
| addrs := ParseXForwardedFor(header)
| if r := cmp.Diff(addrs, []net.Address{net.ParseAddress("129.78.138.66"), net.ParseAddress("129.78.64.103")}); r != "" {
| t.Error(r)
| }
| }
|
| func TestHopByHopHeadersRemoving(t *testing.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)
| common.Must(err)
| headers := []struct {
| Key string
| Value string
| }{
| {
| Key: "Foo",
| Value: "foo",
| },
| {
| Key: "Bar",
| Value: "bar",
| },
| {
| Key: "Connection",
| Value: "keep-alive,Foo, Bar",
| },
| {
| Key: "Proxy-Connection",
| Value: "keep-alive",
| },
| {
| Key: "Proxy-Authenticate",
| Value: "abc",
| },
| }
| for _, header := range headers {
| if v := req.Header.Get(header.Key); v != header.Value {
| t.Error("header ", header.Key, " = ", v, " want ", header.Value)
| }
| }
|
| RemoveHopByHopHeaders(req.Header)
|
| for _, header := range []string{"Connection", "Foo", "Bar", "Proxy-Connection", "Proxy-Authenticate"} {
| if v := req.Header.Get(header); v != "" {
| t.Error("header ", header, " = ", v)
| }
| }
| }
|
| func TestParseHost(t *testing.T) {
| testCases := []struct {
| RawHost string
| DefaultPort net.Port
| Destination net.Destination
| Error bool
| }{
| {
| RawHost: "v2fly.org:80",
| DefaultPort: 443,
| Destination: net.TCPDestination(net.DomainAddress("v2fly.org"), 80),
| },
| {
| RawHost: "tls.v2fly.org",
| DefaultPort: 443,
| Destination: net.TCPDestination(net.DomainAddress("tls.v2fly.org"), 443),
| },
| {
| RawHost: "[2401:1bc0:51f0:ec08::1]:80",
| DefaultPort: 443,
| Destination: net.TCPDestination(net.ParseAddress("[2401:1bc0:51f0:ec08::1]"), 80),
| },
| }
|
| for _, testCase := range testCases {
| dest, err := ParseHost(testCase.RawHost, testCase.DefaultPort)
| if testCase.Error {
| if err == nil {
| t.Error("for test case: ", testCase.RawHost, " expected error, but actually nil")
| }
| } else {
| if dest != testCase.Destination {
| t.Error("for test case: ", testCase.RawHost, " expected host: ", testCase.Destination.String(), " but got ", dest.String())
| }
| }
| }
| }
|
|