我修改了this tutorial的中间件来检查所有PUT和POST请求JSON MIME类型。
但是中间件似乎每次都响应" Mediatype Not Supported"。我尝试了下面的curl命令,我明确地设置了正确的MIME类型。我打印每个请求客户端的Content-Type头字段,这是总是" text / plain;字符集= UTF-8"
中间件:
func EnforceJSON(h httprouter.Handle) httprouter.Handle {
return func(rw http.ResponseWriter, req *http.Request, ps httprouter.Params) {
// Check the existence of a request body
if req.ContentLength == 0 {
http.Error(rw, http.StatusText(400), http.StatusBadRequest)
return
}
// Check the MIME type
buf := new(bytes.Buffer)
buf.ReadFrom(req.Body)
// Prints "text/plain; charset=utf-8"
fmt.Println(http.DetectContentType(buf.Bytes()))
if http.DetectContentType(buf.Bytes()) != "application/json; charset=utf-8" {
http.Error(rw, http.StatusText(415), http.StatusUnsupportedMediaType)
return
}
h(rw, req, ps)
}
}
...
router.POST("/api/v1/users", EnforceJSON(CreateUser))
我的卷曲命令:
curl -H "Content-Type: application/json; charset=utf-8" \
-X POST \
-d '{"JSON": "Will be checked after the middleware accepted the MIME type."}' \
http://localhost:8080/api/v1/users
另外,我试过Postman但结果是一样的。
答案 0 :(得分:1)
在研究DetectContentType函数的实现时,它们遵循“ MIME嗅探”指南(https://mimesniff.spec.whatwg.org/)中描述的规则。
要通过内容确定此MIME类型,请使用“ 7。确定计算出的资源的MIME类型”项。。该项目无法确定'application / json'类型,遵循这些规则将产生'text / plain' MIME类型。
这在 DetectContentType 实现(https://golang.org/src/net/http/sniff.go)行252上的函数 match 上可见。