Solve a problem with responsewriter in golang

Time:2021-12-5

When using the three methods set / writeheader / write in context.responsewriter, the order of use must be as follows, otherwise a setting will not take effect.


ctx.ResponseWriter.Header().Set("Content-type", "application/text")
 ctx.ResponseWriter.WriteHeader(403)
 ctx.ResponseWriter.Write([]byte(resp))

As shown in Figure 1:


ctx.ResponseWriter.Header().Set("Content-type", "application/text")
 ctx.ResponseWriter.Write([]byte(resp))
 ctx.ResponseWriter.WriteHeader(403)

It will cause the return code to be 200 all the time

Supplement: in go, w http.responsewriter calls w.write() method and an error is reported

Go w http.responsewriter write error

http: request method or response status code does not allow

1. The following is a screenshot of error reporting

2. Click in write method

It is first an interface;

Because it is an application scenario of HTTP web server, its specific implementation method is in net / HTTP / server.go:


func (w *response) Write(data []byte) (n int, err error) {
 return w.write(len(data), data, "")
}

Click in again and you’ll find a key judgment in the function

//Where errbodynotallowed
//Code content
// ErrBodyNotAllowed = errors.New("http: request method or response status code does not allow body")
if !w.bodyAllowed() {
 return 0, ErrBodyNotAllowed
}

Click in and find that it will panic when the header is not set. Of course, this has little to do with the problem we are going to discuss. The key is the bodyallowedforstatus() method


func (w *response) bodyAllowed() bool {
 if !w.wroteHeader {
  panic("")
 }
 return bodyAllowedForStatus(w.status)
}

Finally, I can see that this error will be reported when the status codes are set to [100199], 204 and 304, and the status code I just set is 204. I change it to 200 and try again to solve the problem.


func bodyAllowedForStatus(status int) bool {
 switch {
 case status >= 100 && status <= 199:
  return false
 case status == 204:
  return false
 case status == 304:
  return false
 }
 return true
}

The above is my personal experience. I hope I can give you a reference, and I hope you can support developpaer. If you have any mistakes or don’t consider completely, please don’t hesitate to comment.