I am trying to develop an api gateway using go-chi. I want to set the status code to 200 if the request contains "_always200=true" in the query. Here's what I've tried: custom_response_writer.go:
type CustomResponseWriter struct { http.ResponseWriter Buf *bytes.Buffer StatusCode int WroteHeader bool } func NewCustomResponseWriter(w http.ResponseWriter) *CustomResponseWriter { return &CustomResponseWriter{ResponseWriter: w, Buf: new(bytes.Buffer)} } func (c *CustomResponseWriter) WriteHeader(code int) { c.StatusCode = code c.ResponseWriter.WriteHeader(code) } func (c *CustomResponseWriter) Write(b []byte) (int, error) { return c.Buf.Write(b) }
middleware:
func HeaderFilterMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { always200, _ := r.Context().Value(always200QueryKey).(bool) crw := NewCustomResponseWriter(w) next.ServeHTTP(crw, r) if always200 { crw.WriteHeader(http.StatusOK) } }) }
Always returns 404. Is there any way to solve this problem?
There are at least two problems in the code.
always200, _ := r.Context().Value(always200QueryKey).(bool)
is not the correct way to get query parameters. I think you should use r.URL.Query().Get("_always200")
to read it and compare the value with the string "true"
.
It is too late to call crw.WriteHeader(http.StatusOK)
after next.ServeHTTP(crw, r)
. When I tested the code, it printed this warning message:
http: superfluous response.WriteHeader call from main.(*CustomResponseWriter).WriteHeader
The following is a modified example to change the response status code:
<code>package main import ( "bytes" "net/http" "strings" "github.com/go-chi/chi/v5" ) type CustomResponseWriter struct { http.ResponseWriter Buf *bytes.Buffer OriginalStatusCode int WroteHeader bool always200 bool } func NewCustomResponseWriter(w http.ResponseWriter, always200 bool) *CustomResponseWriter { return &CustomResponseWriter{ ResponseWriter: w, Buf: new(bytes.Buffer), always200: always200, } } func (c *CustomResponseWriter) WriteHeader(code int) { c.OriginalStatusCode = code if c.always200 { code = http.StatusOK } c.ResponseWriter.WriteHeader(code) } func (c *CustomResponseWriter) Write(b []byte) (int, error) { return c.Buf.Write(b) } func HeaderFilterMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { always200 := r.URL.Query().Get("_always200") crw := NewCustomResponseWriter(w, strings.EqualFold(always200, "true")) next.ServeHTTP(crw, r) }) } func main() { r := chi.NewRouter() r.Use(HeaderFilterMiddleware) r.Get("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("welcome")) }) http.ListenAndServe(":3000", r) } </code>
The above is the detailed content of How to change the response code of http request using middleware?. For more information, please follow other related articles on the PHP Chinese website!