【发布时间】:2015-07-30 08:40:42
【问题描述】:
我修改了this tutorial 的中间件,以检查所有 JSON MIME 类型的 PUT 和 POST 请求。
但中间件似乎每次都以“不支持媒体类型”进行响应。我尝试了下面的 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) {
// 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 命令:
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,但结果是一样的。
【问题讨论】:
-
你自己说了答案,
DetectContentType返回text/plain。通常你只使用客户端提供的内容类型。 -
是的,我想要客户发送给我的内容类型。文档说:DetectContentType 实现了mimesniff.spec.whatwg.org 中描述的算法,以确定给定数据的 Content-Type。它最多考虑前 512 个字节的数据。 DetectContentType 总是返回一个有效的 MIME 类型:如果它不能确定一个更具体的类型,它返回“application/octet-stream”。为什么函数要确定错误的内容类型?
-
DetectContentType 只保证返回一个 valid 类型,它确实 - json 数据是 *text/plain`。有些类型不明确,嗅探无法可靠地检测到有效的 json,仅限于 512 字节的输入。
-
但是用“application/json”请求一个restful API不是很常见吗?
-
是的,那您为什么不阅读
Content-Type标头而不是尝试从请求正文中猜测它?
标签: api rest curl go mime-types