diff options
Diffstat (limited to 'httputil/static_test.go')
-rw-r--r-- | httputil/static_test.go | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/httputil/static_test.go b/httputil/static_test.go new file mode 100644 index 0000000..a258d52 --- /dev/null +++ b/httputil/static_test.go | |||
@@ -0,0 +1,175 @@ | |||
1 | // Copyright 2013 The Go Authors. All rights reserved. | ||
2 | // | ||
3 | // Use of this source code is governed by a BSD-style | ||
4 | // license that can be found in the LICENSE file or at | ||
5 | // https://developers.google.com/open-source/licenses/bsd. | ||
6 | |||
7 | package httputil_test | ||
8 | |||
9 | import ( | ||
10 | "crypto/sha1" | ||
11 | "encoding/hex" | ||
12 | "io/ioutil" | ||
13 | "net/http" | ||
14 | "net/http/httptest" | ||
15 | "net/url" | ||
16 | "os" | ||
17 | "strconv" | ||
18 | "testing" | ||
19 | "time" | ||
20 | |||
21 | "github.com/golang/gddo/httputil" | ||
22 | "github.com/google/go-cmp/cmp" | ||
23 | ) | ||
24 | |||
25 | var ( | ||
26 | testHash = computeTestHash() | ||
27 | testEtag = `"` + testHash + `"` | ||
28 | testContentLength = computeTestContentLength() | ||
29 | ) | ||
30 | |||
31 | func mustParseURL(urlStr string) *url.URL { | ||
32 | u, err := url.Parse(urlStr) | ||
33 | if err != nil { | ||
34 | panic(err) | ||
35 | } | ||
36 | return u | ||
37 | } | ||
38 | |||
39 | func computeTestHash() string { | ||
40 | p, err := ioutil.ReadFile("static_test.go") | ||
41 | if err != nil { | ||
42 | panic(err) | ||
43 | } | ||
44 | w := sha1.New() | ||
45 | w.Write(p) | ||
46 | return hex.EncodeToString(w.Sum(nil)) | ||
47 | } | ||
48 | |||
49 | func computeTestContentLength() string { | ||
50 | info, err := os.Stat("static_test.go") | ||
51 | if err != nil { | ||
52 | panic(err) | ||
53 | } | ||
54 | return strconv.FormatInt(info.Size(), 10) | ||
55 | } | ||
56 | |||
57 | var fileServerTests = []*struct { | ||
58 | name string // test name for log | ||
59 | ss *httputil.StaticServer | ||
60 | r *http.Request | ||
61 | header http.Header // expected response headers | ||
62 | status int // expected response status | ||
63 | empty bool // true if response body not expected. | ||
64 | }{ | ||
65 | { | ||
66 | name: "get", | ||
67 | ss: &httputil.StaticServer{MaxAge: 3 * time.Second}, | ||
68 | r: &http.Request{ | ||
69 | URL: mustParseURL("/dir/static_test.go"), | ||
70 | Method: "GET", | ||
71 | }, | ||
72 | status: http.StatusOK, | ||
73 | header: http.Header{ | ||
74 | "Etag": {testEtag}, | ||
75 | "Cache-Control": {"public, max-age=3"}, | ||
76 | "Content-Length": {testContentLength}, | ||
77 | "Content-Type": {"application/octet-stream"}, | ||
78 | }, | ||
79 | }, | ||
80 | { | ||
81 | name: "get .", | ||
82 | ss: &httputil.StaticServer{Dir: ".", MaxAge: 3 * time.Second}, | ||
83 | r: &http.Request{ | ||
84 | URL: mustParseURL("/dir/static_test.go"), | ||
85 | Method: "GET", | ||
86 | }, | ||
87 | status: http.StatusOK, | ||
88 | header: http.Header{ | ||
89 | "Etag": {testEtag}, | ||
90 | "Cache-Control": {"public, max-age=3"}, | ||
91 | "Content-Length": {testContentLength}, | ||
92 | "Content-Type": {"application/octet-stream"}, | ||
93 | }, | ||
94 | }, | ||
95 | { | ||
96 | name: "get with ?v=", | ||
97 | ss: &httputil.StaticServer{MaxAge: 3 * time.Second}, | ||
98 | r: &http.Request{ | ||
99 | URL: mustParseURL("/dir/static_test.go?v=xxxxx"), | ||
100 | Method: "GET", | ||
101 | }, | ||
102 | status: http.StatusOK, | ||
103 | header: http.Header{ | ||
104 | "Etag": {testEtag}, | ||
105 | "Cache-Control": {"public, max-age=31536000"}, | ||
106 | "Content-Length": {testContentLength}, | ||
107 | "Content-Type": {"application/octet-stream"}, | ||
108 | }, | ||
109 | }, | ||
110 | { | ||
111 | name: "head", | ||
112 | ss: &httputil.StaticServer{MaxAge: 3 * time.Second}, | ||
113 | r: &http.Request{ | ||
114 | URL: mustParseURL("/dir/static_test.go"), | ||
115 | Method: "HEAD", | ||
116 | }, | ||
117 | status: http.StatusOK, | ||
118 | header: http.Header{ | ||
119 | "Etag": {testEtag}, | ||
120 | "Cache-Control": {"public, max-age=3"}, | ||
121 | "Content-Length": {testContentLength}, | ||
122 | "Content-Type": {"application/octet-stream"}, | ||
123 | }, | ||
124 | empty: true, | ||
125 | }, | ||
126 | { | ||
127 | name: "if-none-match", | ||
128 | ss: &httputil.StaticServer{MaxAge: 3 * time.Second}, | ||
129 | r: &http.Request{ | ||
130 | URL: mustParseURL("/dir/static_test.go"), | ||
131 | Method: "GET", | ||
132 | Header: http.Header{"If-None-Match": {testEtag}}, | ||
133 | }, | ||
134 | status: http.StatusNotModified, | ||
135 | header: http.Header{ | ||
136 | "Cache-Control": {"public, max-age=3"}, | ||
137 | "Etag": {testEtag}, | ||
138 | }, | ||
139 | empty: true, | ||
140 | }, | ||
141 | } | ||
142 | |||
143 | func testStaticServer(t *testing.T, f func(*httputil.StaticServer) http.Handler) { | ||
144 | for _, tt := range fileServerTests { | ||
145 | w := httptest.NewRecorder() | ||
146 | |||
147 | h := f(tt.ss) | ||
148 | h.ServeHTTP(w, tt.r) | ||
149 | |||
150 | if w.Code != tt.status { | ||
151 | t.Errorf("%s, status=%d, want %d", tt.name, w.Code, tt.status) | ||
152 | } | ||
153 | |||
154 | if !cmp.Equal(w.HeaderMap, tt.header) { | ||
155 | t.Errorf("%s\n\theader=%v,\n\twant %v", tt.name, w.HeaderMap, tt.header) | ||
156 | } | ||
157 | |||
158 | empty := w.Body.Len() == 0 | ||
159 | if empty != tt.empty { | ||
160 | t.Errorf("%s empty=%v, want %v", tt.name, empty, tt.empty) | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | |||
165 | func TestFileHandler(t *testing.T) { | ||
166 | testStaticServer(t, func(ss *httputil.StaticServer) http.Handler { return ss.FileHandler("static_test.go") }) | ||
167 | } | ||
168 | |||
169 | func TestDirectoryHandler(t *testing.T) { | ||
170 | testStaticServer(t, func(ss *httputil.StaticServer) http.Handler { return ss.DirectoryHandler("/dir", ".") }) | ||
171 | } | ||
172 | |||
173 | func TestFilesHandler(t *testing.T) { | ||
174 | testStaticServer(t, func(ss *httputil.StaticServer) http.Handler { return ss.FilesHandler("static_test.go") }) | ||
175 | } | ||