gogo-chihttprouter

Set different middleware for a subroute in go-chi


I have a proxy server that can be deactivated by config, with mustBeSecure. I want this proxy to act different in a certain subdomain: "/application/health", allowing it always insecure. All changes i've tried so far have failed. Is there a way to configure a different group for "/application/health" that still uses the proxy but never requires authentication?

router := chi.NewRouter()
router.Route("/", func(r chi.Router) {
    r.Use(chimw.Recoverer)
    router.Use(hlog.NewHandler(log.Logger))
    if mustBeSecure() {
        r.Use(keycloak.MustStandardKeycloakAuth("url"))
    }
    setProxy(r)
    r.Group(func(r chi.Router) {
        r.Get("/health", handleHealth())
    })
})
return http.ListenAndServe("0.0.0.0", router)

As requested, here is an example of what does setProxy()

func setProxy(r chi.Router) {
    r.Route("/application", func(r chi.Router) {
        r.Use(func(next http.Handler) http.Handler {
            return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                ctx := context.WithValue(r.Context(), "target", "http:locahost:9999")
                r = r.WithContext(ctx)
                next.ServeHTTP(w, r)
            })
        })
        r.HandleFunc("/*", httputil.ReverseProxy{}.ServeHTTP)
    })
}

Solution

  • I believe you're trying this.

    I've simplified the code a bit just for ease of understanding. You can still use your setProxy function.

    func main() {
        proxy, err := NewProxy("http://localhost:4422")
        if err != nil {
            panic(err)
        }
    
        router := chi.NewRouter()
    
        router.Get("/health", handleHealth)
    
        router.Route("/application", func(r chi.Router) {
            r.Get("/health", ProxyRequestHandler(proxy))
    
            r.Group(func(r chi.Router) {
                if mustBeSecure() {
                    r.Use(keycloak.MustStandardKeycloakAuth("url"))
                }
                r.HandleFunc("/*", ProxyRequestHandler(proxy))
            })
        })
    
        http.ListenAndServe("0.0.0.0:4411", router)
    }
    
    func NewProxy(targetHost string) (*httputil.ReverseProxy, error) {
        targetUrl, err := url.Parse(targetHost)
        if err != nil {
            return nil, err
        }
    
        return httputil.NewSingleHostReverseProxy(targetUrl), nil
    }
    
    func ProxyRequestHandler(proxy *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request) {
        return func(w http.ResponseWriter, r *http.Request) {
            proxy.ServeHTTP(w, r)
        }
    }