Skip to content

Commit 1ba8873

Browse files
mrasubrian-brazil
authored andcommitted
Implement common file server to return consistent Content-Type (#191)
* Implement common file server to return consistent Content-Type When `/etc/mime.types` has a unusual mime type, Content-Type of response becomes the type and you may get unexpected result. This server returns consistent Content-Type header for js and css files Signed-off-by: mrasu <[email protected]>
1 parent c873fb1 commit 1ba8873

File tree

3 files changed

+125
-0
lines changed

3 files changed

+125
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ components and libraries.
99
* **log**: A logging wrapper around [logrus](https://github.com/sirupsen/logrus)
1010
* **model**: Shared data structures
1111
* **route**: A routing wrapper around [httprouter](https://github.com/julienschmidt/httprouter) using `context.Context`
12+
* **server**: Common servers
1213
* **version**: Version information and metrics

server/static_file_server.go

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2019 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package server
15+
16+
import (
17+
"net/http"
18+
"path/filepath"
19+
)
20+
21+
var mimeTypes = map[string]string{
22+
".js": "application/javascript",
23+
".css": "text/css",
24+
".png": "image/png",
25+
".jpg": "image/jpeg",
26+
".gif": "image/gif",
27+
}
28+
29+
func StaticFileServer(root http.FileSystem) http.Handler {
30+
return http.HandlerFunc(
31+
func(w http.ResponseWriter, r *http.Request) {
32+
fileExt := filepath.Ext(r.URL.Path)
33+
34+
if t, ok := mimeTypes[fileExt]; ok {
35+
w.Header().Set("Content-Type", t)
36+
}
37+
38+
http.FileServer(root).ServeHTTP(w, r)
39+
},
40+
)
41+
}

server/static_file_server_test.go

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright 2019 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package server
15+
16+
import (
17+
"net/http"
18+
"net/http/httptest"
19+
"testing"
20+
)
21+
22+
type dummyFileSystem struct{}
23+
24+
func (fs dummyFileSystem) Open(path string) (http.File, error) {
25+
return http.Dir(".").Open(".")
26+
}
27+
28+
func TestServeHttp(t *testing.T) {
29+
cases := []struct {
30+
name string
31+
path string
32+
contentType string
33+
}{
34+
{
35+
name: "normal file",
36+
path: "index.html",
37+
contentType: "",
38+
},
39+
{
40+
name: "javascript",
41+
path: "test.js",
42+
contentType: "application/javascript",
43+
},
44+
{
45+
name: "css",
46+
path: "test.css",
47+
contentType: "text/css",
48+
},
49+
{
50+
name: "png",
51+
path: "test.png",
52+
contentType: "image/png",
53+
},
54+
{
55+
name: "jpg",
56+
path: "test.jpg",
57+
contentType: "image/jpeg",
58+
},
59+
{
60+
name: "gif",
61+
path: "test.gif",
62+
contentType: "image/gif",
63+
},
64+
}
65+
66+
for _, c := range cases {
67+
t.Run(c.name, func(t *testing.T) {
68+
rr := httptest.NewRecorder()
69+
req, err := http.NewRequest("GET", "http://localhost/"+c.path, nil)
70+
71+
if err != nil {
72+
t.Fatal(err)
73+
}
74+
75+
s := StaticFileServer(dummyFileSystem{})
76+
s.ServeHTTP(rr, req)
77+
78+
if rr.Header().Get("Content-Type") != c.contentType {
79+
t.Fatalf("Unexpected Content-Type: %s", rr.Header().Get("Content-Type"))
80+
}
81+
})
82+
}
83+
}

0 commit comments

Comments
 (0)