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 "reflect"
16 "regexp"
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 !reflect.DeepEqual(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
84
85 func TestOmitHTTP2(t *testing.T) {
86 if testing.Short() {
87 t.Skip("skipping in short mode")
88 }
89 t.Parallel()
90 goTool := testenv.GoToolPath(t)
91 out, err := testenv.Command(t, goTool, "test", "-short", "-tags=nethttpomithttp2", "net/http").CombinedOutput()
92 if err != nil {
93 t.Fatalf("go test -short failed: %v, %s", err, out)
94 }
95 }
96
97
98
99
100 func TestOmitHTTP2Vet(t *testing.T) {
101 t.Parallel()
102 goTool := testenv.GoToolPath(t)
103 out, err := testenv.Command(t, goTool, "vet", "-tags=nethttpomithttp2", "net/http").CombinedOutput()
104 if err != nil {
105 t.Fatalf("go vet failed: %v, %s", err, out)
106 }
107 }
108
109 var valuesCount int
110
111 func BenchmarkCopyValues(b *testing.B) {
112 b.ReportAllocs()
113 src := url.Values{
114 "a": {"1", "2", "3", "4", "5"},
115 "b": {"2", "2", "3", "4", "5"},
116 "c": {"3", "2", "3", "4", "5"},
117 "d": {"4", "2", "3", "4", "5"},
118 "e": {"1", "1", "2", "3", "4", "5", "6", "7", "abcdef", "l", "a", "b", "c", "d", "z"},
119 "j": {"1", "2"},
120 "m": nil,
121 }
122 for i := 0; i < b.N; i++ {
123 dst := url.Values{"a": {"b"}, "b": {"2"}, "c": {"3"}, "d": {"4"}, "j": nil, "m": {"x"}}
124 copyValues(dst, src)
125 if valuesCount = len(dst["a"]); valuesCount != 6 {
126 b.Fatalf(`%d items in dst["a"] but expected 6`, valuesCount)
127 }
128 }
129 if valuesCount == 0 {
130 b.Fatal("Benchmark wasn't run")
131 }
132 }
133
134 var forbiddenStringsFunctions = map[string]bool{
135
136 "EqualFold": true,
137 "Title": true,
138 "ToLower": true,
139 "ToLowerSpecial": true,
140 "ToTitle": true,
141 "ToTitleSpecial": true,
142 "ToUpper": true,
143 "ToUpperSpecial": true,
144
145
146 "Fields": true,
147 "TrimSpace": true,
148 }
149
150
151
152
153 func TestNoUnicodeStrings(t *testing.T) {
154 if !testenv.HasSrc() {
155 t.Skip("source code not available")
156 }
157
158 re := regexp.MustCompile(`(strings|bytes).([A-Za-z]+)`)
159 if err := fs.WalkDir(os.DirFS("."), ".", func(path string, d fs.DirEntry, err error) error {
160 if err != nil {
161 t.Fatal(err)
162 }
163
164 if path == "internal/ascii" {
165 return fs.SkipDir
166 }
167 if !strings.HasSuffix(path, ".go") ||
168 strings.HasSuffix(path, "_test.go") ||
169 path == "h2_bundle.go" || d.IsDir() {
170 return nil
171 }
172
173 contents, err := os.ReadFile(path)
174 if err != nil {
175 t.Fatal(err)
176 }
177 for lineNum, line := range strings.Split(string(contents), "\n") {
178 for _, match := range re.FindAllStringSubmatch(line, -1) {
179 if !forbiddenStringsFunctions[match[2]] {
180 continue
181 }
182 t.Errorf("disallowed call to %s at %s:%d", match[0], path, lineNum+1)
183 }
184 }
185
186 return nil
187 }); err != nil {
188 t.Fatal(err)
189 }
190 }
191
192 const redirectURL = "/thisaredirect细雪withasciilettersのけぶabcdefghijk.html"
193
194 func BenchmarkHexEscapeNonASCII(b *testing.B) {
195 b.ReportAllocs()
196
197 for i := 0; i < b.N; i++ {
198 hexEscapeNonASCII(redirectURL)
199 }
200 }
201
View as plain text