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