Home > Backend Development > Golang > How to change the response code of http request using middleware?

How to change the response code of http request using middleware?

WBOY
Release: 2024-02-08 21:00:04
forward
588 people have browsed it

How to change the response code of http request using middleware?

Question content

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)
}
Copy after login

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)
        }
    })
}
Copy after login

Always returns 404. Is there any way to solve this problem?


Correct answer


There are at least two problems in the code.

  1. 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".

  2. 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
    Copy after login

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>
Copy after login

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!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template