英文:
Go - middleware blocks MIME type of each requests
问题
我修改了这个教程的中间件,以检查所有PUT和POST请求的JSON MIME类型。
但是中间件似乎每次都回复"不支持的媒体类型"。我尝试了下面的curl命令,其中明确设置了正确的MIME类型。我在每个请求中打印了客户端的Content-Type头字段,它始终是"text/plain; charset=utf-8"。
中间件代码如下:
func EnforceJSON(h httprouter.Handle) httprouter.Handle {
return func(rw http.ResponseWriter, req *http.Request, ps httprouter.Params) {
// 检查请求体是否存在
if req.ContentLength == 0 {
http.Error(rw, http.StatusText(400), http.StatusBadRequest)
return
}
// 检查MIME类型
buf := new(bytes.Buffer)
buf.ReadFrom(req.Body)
// 打印"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命令如下:
curl -H "Content-Type: application/json; charset=utf-8" \
-X POST \
-d '{"JSON": "在中间件接受MIME类型后将被检查。"}' \
http://localhost:8080/api/v1/users
我还尝试了Postman,但结果是一样的。
英文:
I modiefied the middleware of this tutorial to check for all PUT and POST request the JSON MIME type.
But the middleware seems to respond everytime with "Mediatype Not Supported". I tried the curl command below where I set explicitly the right MIME type. I print which each request the client's Content-Type header field which is allways "text/plain; charset=utf-8".
<!-- language: go-lang -->
The Middleware:
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))
My curl command:
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
Alternativly I tried Postman but the result was the same.
答案1
得分: 1
根据DetectContentType函数的实现,它遵循"MIME Sniffing"指南(https://mimesniff.spec.whatwg.org/)中描述的规则。
为了通过内容确定MIME类型,该特定函数使用了"7. Determining the computed MIME type of a resource"这一项。该项没有确定"application/json"类型的规定,按照这些规则,结果将是"text/plain" MIME类型。
这在DetectContentType实现的match函数(https://golang.org/src/net/http/sniff.go)的第252行可见。
英文:
Looking at the implementation of DetectContentType function they follow the rules described on "MIME Sniffing" guide (https://mimesniff.spec.whatwg.org/).
To determine the MIME Type by the content this specific function use the item "7. Determining the computed MIME type of a resource". That item doesn't have a determination for 'application/json' type and following these rules will result in a 'text/plain' MIME type.
This is visible on the function match on the DetectContentType implementation (https://golang.org/src/net/http/sniff.go) line 252.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论