与官方 Docker 图像相比,Go Mime 包 (1.14) 在本地表现不同
Go Mime package (1.14) behaves differently locally compared to the official Docker image
我已经将本地 Go 版本从 1.13
升级到 1.14
,然后我通过使用 go mod
.
重新初始化更新了我正在处理的项目
本地:
$ go version
go version go1.14 linux/amd64
go.mod
我的项目:
module example-project
go 1.14
Go 1.14 中的 mime
包中有一个更新,将 .js
文件的默认类型从 application/javascript
更改为 text/javascript
。
我有一个应用程序提供一个文件夹,里面有一个 JavaScript 文件,例如:
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)
}
我更新了一个测试用例以反映 Go 1.14 中的 mime 变化:
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)
}
}
当我在本地运行时,检查内容类型的测试用例失败:
TestStaticHandlerServeJS: main_test.go:27: handler returned unexpected Content-Type: got application/javascript want text/javascript; charset=utf-8
我还可以在浏览器中确认该文件确实使用 Mime 类型 "application/javascript" 提供,就像它在 Go 1.13 中一样。
当我 运行 使用官方 golang:1.14.0-alpine3.11
图像在 Docker 容器上进行此测试时,此测试通过,它反映了 mime
包的更改行为.
因此,我留下了一个在本地失败并传递给容器的测试用例。我在本地只维护一个单一版本的 Go,如上所示,即 1.14
。我的本地 Go 安装的 mime
包行为不同的原因可能是什么?
这对我来说也很有趣,我也有过和你一样的行为 - 在我的机器上交付 1.14 (macOs catalina) application/javascript 而不是 text/javascript.我调试了程序,在mime包的type.go中找到了这个函数:
func initMime() {
if fn := testInitMime; fn != nil {
fn()
} else {
setMimeTypes(builtinTypesLower, builtinTypesLower)
osInitMime()
}
}
else 块中发生了一些有趣的事情。在设置扩展名 js
分配给 text/javascript
的 builtInTypes 之后,存在 os 文件扩展名到内容类型的特定分配,这会覆盖内置分配。在 mac 上,它将归档 type_unix.go,其中文件
"/etc/mime.types",
"/etc/apache2/mime.types",
"/etc/apache/mime.types",
经过测试可用,在我的例子中,os 中存在一个文件 /etc/apache2/mime.types
,它包含...令人惊讶的一行
application/javascript js
并且这一行覆盖了 .js 扩展的 go 内置定义并导致 Content-Type: application/javascript
被传递给客户端并导致您的测试失败。
我已经将本地 Go 版本从 1.13
升级到 1.14
,然后我通过使用 go mod
.
本地:
$ go version
go version go1.14 linux/amd64
go.mod
我的项目:
module example-project
go 1.14
Go 1.14 中的 mime
包中有一个更新,将 .js
文件的默认类型从 application/javascript
更改为 text/javascript
。
我有一个应用程序提供一个文件夹,里面有一个 JavaScript 文件,例如:
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)
}
我更新了一个测试用例以反映 Go 1.14 中的 mime 变化:
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)
}
}
当我在本地运行时,检查内容类型的测试用例失败:
TestStaticHandlerServeJS: main_test.go:27: handler returned unexpected Content-Type: got application/javascript want text/javascript; charset=utf-8
我还可以在浏览器中确认该文件确实使用 Mime 类型 "application/javascript" 提供,就像它在 Go 1.13 中一样。
当我 运行 使用官方 golang:1.14.0-alpine3.11
图像在 Docker 容器上进行此测试时,此测试通过,它反映了 mime
包的更改行为.
因此,我留下了一个在本地失败并传递给容器的测试用例。我在本地只维护一个单一版本的 Go,如上所示,即 1.14
。我的本地 Go 安装的 mime
包行为不同的原因可能是什么?
这对我来说也很有趣,我也有过和你一样的行为 - 在我的机器上交付 1.14 (macOs catalina) application/javascript 而不是 text/javascript.我调试了程序,在mime包的type.go中找到了这个函数:
func initMime() {
if fn := testInitMime; fn != nil {
fn()
} else {
setMimeTypes(builtinTypesLower, builtinTypesLower)
osInitMime()
}
}
else 块中发生了一些有趣的事情。在设置扩展名 js
分配给 text/javascript
的 builtInTypes 之后,存在 os 文件扩展名到内容类型的特定分配,这会覆盖内置分配。在 mac 上,它将归档 type_unix.go,其中文件
"/etc/mime.types",
"/etc/apache2/mime.types",
"/etc/apache/mime.types",
经过测试可用,在我的例子中,os 中存在一个文件 /etc/apache2/mime.types
,它包含...令人惊讶的一行
application/javascript js
并且这一行覆盖了 .js 扩展的 go 内置定义并导致 Content-Type: application/javascript
被传递给客户端并导致您的测试失败。