Gin: Response Content-Type Header not set when using c.JSON (while doc says it should)

Created on 12 Dec 2016  路  6Comments  路  Source: gin-gonic/gin

I am not sure but it seems this function just do nothing, so when using c.JSON, the Content-Type header is not set.

func writeContentType(w http.ResponseWriter, value []string) {
    header := w.Header()
    if val := header["Content-Type"]; len(val) == 0 {
        header["Content-Type"] = value
    }
}

I have the problem on my code and I opened this thread on Stackoverflow : http://stackoverflow.com/questions/41109065/golang-gin-gonic-content-type-not-setting-to-application-json-with-c-json

bug

Most helpful comment

Already release v1.2, but still found this problem.

In most cases锛宨t works fine. but if C.BindJSON goes wrong, it write header immediately before set Content-Type .

In the file gin-gonic/gin/context.go:

BindJSON()----> MustBindWith()---> AbortWithError()->AbortWithStatus()--> WriteHeaderNow()

func (c *Context) AbortWithStatus(code int) {
    c.Status(code)
    c.Writer.WriteHeaderNow()
    c.Abort()
}

All 6 comments

I think my problem also same this problem because when gin.Context.Json is called, API return a content-type: text/plain

same issue.

Already fix in develop branch. See: https://github.com/gin-gonic/gin/pull/855 and we will release v1.2 version asap.

Already release v1.2, but still found this problem.

In most cases锛宨t works fine. but if C.BindJSON goes wrong, it write header immediately before set Content-Type .

In the file gin-gonic/gin/context.go:

BindJSON()----> MustBindWith()---> AbortWithError()->AbortWithStatus()--> WriteHeaderNow()

func (c *Context) AbortWithStatus(code int) {
    c.Status(code)
    c.Writer.WriteHeaderNow()
    c.Abort()
}

update:
@adriendomoison writeContentType have set Header, it's not your expect, the reason is as @javasgl said.
when c.BindJSON errors, it will call c.Writer.WriteHeaderNow(), maybe c.ShouldBindJSON is you want method.

please @javasgl post your http client, I use curl -v 'http://localhost:8080/' -X POST --data '["x":"1", "y":2]' -H "Content-type: application/json" -H "Accept: application/json", it will return 400 and the follow info:

*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> POST / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Content-type: application/json
> Accept: application/json
> Content-Length: 16
>
* upload completely sent off: 16 out of 16 bytes
< HTTP/1.1 400 Bad Request
< Date: Wed, 05 Sep 2018 15:14:07 GMT
< Content-Length: 0

when c.BindJSON errors, it will call c.Writer.WriteHeaderNow(), maybe c.ShouldBindJSON is you want method.

In that case c.BindJSON() should probably raise an exception, and those headers be written from the exception handling code. Otherwise it behaves _exceptionally_ without raising an exception.

At any rate, attempts to change headers after WriteHeaderNow() should trigger some sort of exception.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mdnight picture mdnight  路  3Comments

oryband picture oryband  路  3Comments

frederikhors picture frederikhors  路  3Comments

olegsobchuk picture olegsobchuk  路  3Comments

kekemuyu picture kekemuyu  路  3Comments