I have upgraded my local Go version from 1.13
to 1.14
and then I updated a project I was working on via re-initializing using go mod
.
Locally:
$ go version
go version go1.14 linux/amd64
go.mod
of my project:
module example-project
go 1.14
There has been an update in the mime
package in Go 1.14 that changes the default type of .js
files from application/javascript
to text/javascript
.
I have an application that serves a folder with a JavaScript file in it like:
func main() {
http.HandleFunc("/static/", StaticHandler)
http.ListenAndServe(":3000", nil)
}
func StaticHandler(w http.ResponseWriter, r *http.Request) {
fs := http.StripPrefix("/static", http.FileServer(http.Dir("public/")))
fs.ServeHTTP(w, r)
}
I updated a test case to reflect the mime changes in Go 1.14:
func TestStaticHandlerServeJS(t *testing.T) {
req, err := http.NewRequest("GET", "/static/index.js", nil)
if err != nil {
t.Fatal(err)
}
rr := httptest.NewRecorder()
handler := http.HandlerFunc(StaticHandler)
handler.ServeHTTP(rr, req)
if status := rr.Code; status != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v",
status, http.StatusOK)
}
expected := "text/javascript; charset=utf-8"
if rr.Header().Get("Content-Type") != expected {
t.Errorf("handler returned unexpected Content-Type: got %v want %v",
rr.Header().Get("Content-Type"), expected)
}
}
When I run this locally, the test case which checks the Content-Type fails:
TestStaticHandlerServeJS: main_test.go:27: handler returned unexpected Content-Type: got application/javascript want text/javascript; charset=utf-8
I can also confirm in the browser that the file is indeed served with the Mime Type "application/javascript" as it was back in Go 1.13.
When I run this test on a Docker container using the official golang:1.14.0-alpine3.11
image, this test passes, and it reflects the changed behavior of the mime
package.
So as a result, I'm left with a test case that fails locally and passes on the container. I maintain only a single version of Go locally, and that's 1.14
as I've shown above. What could be the reason why my local Go installation has the mime
package behaving differently?
It was interesting to me too and I have had the same behaviour like you - go 1.14 delivered on my mashine (macOs catalina) application/javascript instead of text/javascript. I debugged the program and found this function in type.go of mime package:
func initMime() {
if fn := testInitMime; fn != nil {
fn()
} else {
setMimeTypes(builtinTypesLower, builtinTypesLower)
osInitMime()
}
}
interesting stuff is going on in else block. After setting builtInTypes where extention js
is assigned to text/javascript
there is os specific assignment of file extention to content type, which overwrites the built-in assignment. On mac it is going to file type_unix.go where files
"/etc/mime.types",
"/etc/apache2/mime.types",
"/etc/apache/mime.types",
are tested to be available and in my case a file /etc/apache2/mime.types
was present in the os and it contains ... surprise a line
application/javascript js
and this line overwrites the go built-in definition for .js extention and results in Content-Type: application/javascript
to be delivered to client and cause your test to fail.