Source file
src/net/http/http_test.go
1
2
3
4
5
6
7 package http
8
9 import (
10 "bytes"
11 "internal/testenv"
12 "io/fs"
13 "net/url"
14 "os"
15 "regexp"
16 "slices"
17 "strings"
18 "testing"
19 )
20
21 func TestForeachHeaderElement(t *testing.T) {
22 tests := []struct {
23 in string
24 want []string
25 }{
26 {"Foo", []string{"Foo"}},
27 {" Foo", []string{"Foo"}},
28 {"Foo ", []string{"Foo"}},
29 {" Foo ", []string{"Foo"}},
30
31 {"foo", []string{"foo"}},
32 {"anY-cAsE", []string{"anY-cAsE"}},
33
34 {"", nil},
35 {",,,, , ,, ,,, ,", nil},
36
37 {" Foo,Bar, Baz,lower,,Quux ", []string{"Foo", "Bar", "Baz", "lower", "Quux"}},
38 }
39 for _, tt := range tests {
40 var got []string
41 foreachHeaderElement(tt.in, func(v string) {
42 got = append(got, v)
43 })
44 if !slices.Equal(got, tt.want) {
45 t.Errorf("foreachHeaderElement(%q) = %q; want %q", tt.in, got, tt.want)
46 }
47 }
48 }
49
50
51
52
53
54 func TestCmdGoNoHTTPServer(t *testing.T) {
55 t.Parallel()
56 goBin := testenv.GoToolPath(t)
57 out, err := testenv.Command(t, goBin, "tool", "nm", goBin).CombinedOutput()
58 if err != nil {
59 t.Fatalf("go tool nm: %v: %s", err, out)
60 }
61 wantSym := map[string]bool{
62
63 "net/http.(*Client).do": true,
64 "net/http.(*Transport).RoundTrip": true,
65
66
67 "net/http.http2Server": false,
68 "net/http.(*Server).Serve": false,
69 "net/http.(*ServeMux).ServeHTTP": false,
70 "net/http.DefaultServeMux": false,
71 }
72 for sym, want := range wantSym {
73 got := bytes.Contains(out, []byte(sym))
74 if !want && got {
75 t.Errorf("cmd/go unexpectedly links in HTTP server code; found symbol %q in cmd/go", sym)
76 }
77 if want && !got {
78 t.Errorf("expected to find symbol %q in cmd/go; not found", sym)
79 }
80 }
81 }
82
83 var valuesCount int
84
85 func BenchmarkCopyValues(b *testing.B) {
86 b.ReportAllocs()
87 src := url.Values{
88 "a": {"1", "2", "3", "4", "5"},
89 "b": {"2", "2", "3", "4", "5"},
90 "c": {"3", "2", "3", "4", "5"},
91 "d": {"4", "2", "3", "4", "5"},
92 "e": {"1", "1", "2", "3", "4", "5", "6", "7", "abcdef", "l", "a", "b", "c", "d", "z"},
93 "j": {"1", "2"},
94 "m": nil,
95 }
96 for i := 0; i < b.N; i++ {
97 dst := url.Values{"a": {"b"}, "b": {"2"}, "c": {"3"}, "d": {"4"}, "j": nil, "m": {"x"}}
98 copyValues(dst, src)
99 if valuesCount = len(dst["a"]); valuesCount != 6 {
100 b.Fatalf(`%d items in dst["a"] but expected 6`, valuesCount)
101 }
102 }
103 if valuesCount == 0 {
104 b.Fatal("Benchmark wasn't run")
105 }
106 }
107
108 var forbiddenStringsFunctions = map[string]bool{
109
110 "EqualFold": true,
111 "Title": true,
112 "ToLower": true,
113 "ToLowerSpecial": true,
114 "ToTitle": true,
115 "ToTitleSpecial": true,
116 "ToUpper": true,
117 "ToUpperSpecial": true,
118
119
120 "Fields": true,
121 "TrimSpace": true,
122 }
123
124
125
126
127 func TestNoUnicodeStrings(t *testing.T) {
128 testenv.MustHaveSource(t)
129
130 re := regexp.MustCompile(`(strings|bytes).([A-Za-z]+)`)
131 if err := fs.WalkDir(os.DirFS("."), ".", func(path string, d fs.DirEntry, err error) error {
132 if err != nil {
133 t.Fatal(err)
134 }
135
136 if path == "internal/ascii" {
137 return fs.SkipDir
138 }
139 if !strings.HasSuffix(path, ".go") ||
140 strings.HasSuffix(path, "_test.go") ||
141 path == "internal/http2/ascii.go" ||
142 path == "internal/httpcommon/httpcommon.go" ||
143 d.IsDir() {
144 return nil
145 }
146
147 contents, err := os.ReadFile(path)
148 if err != nil {
149 t.Fatal(err)
150 }
151 for lineNum, line := range strings.Split(string(contents), "\n") {
152 for _, match := range re.FindAllStringSubmatch(line, -1) {
153 if !forbiddenStringsFunctions[match[2]] {
154 continue
155 }
156 t.Errorf("disallowed call to %s at %s:%d", match[0], path, lineNum+1)
157 }
158 }
159
160 return nil
161 }); err != nil {
162 t.Fatal(err)
163 }
164 }
165
166 func TestProtocols(t *testing.T) {
167 var p Protocols
168 if p.HTTP1() {
169 t.Errorf("zero-value protocols: p.HTTP1() = true, want false")
170 }
171 p.SetHTTP1(true)
172 p.SetHTTP2(true)
173 if !p.HTTP1() {
174 t.Errorf("initialized protocols: p.HTTP1() = false, want true")
175 }
176 if !p.HTTP2() {
177 t.Errorf("initialized protocols: p.HTTP2() = false, want true")
178 }
179 p.SetHTTP1(false)
180 if p.HTTP1() {
181 t.Errorf("after unsetting HTTP1: p.HTTP1() = true, want false")
182 }
183 if !p.HTTP2() {
184 t.Errorf("after unsetting HTTP1: p.HTTP2() = false, want true")
185 }
186 }
187
188 const redirectURL = "/thisaredirect细雪withasciilettersのけぶabcdefghijk.html"
189
190 func BenchmarkHexEscapeNonASCII(b *testing.B) {
191 b.ReportAllocs()
192
193 for i := 0; i < b.N; i++ {
194 hexEscapeNonASCII(redirectURL)
195 }
196 }
197
198 func TestRemovePort(t *testing.T) {
199 tests := []struct {
200 in, want string
201 }{
202 {"example.com:8080", "example.com"},
203 {"example.com", "example.com"},
204 {"[2001:db8::1]:443", "[2001:db8::1]"},
205 {"[2001:db8::1]", "[2001:db8::1]"},
206 {"192.0.2.1:8080", "192.0.2.1"},
207 {"192.0.2.1", "192.0.2.1"},
208 }
209 for _, tc := range tests {
210 got := removePort(tc.in)
211 if got != tc.want {
212 t.Errorf("removePort(%q) = %q; want %q", tc.in, got, tc.want)
213 }
214 }
215 }
216
View as plain text