Search code examples
gomuxgorilla

Changing a value of a variable which is inside an if statement that referencing a flag


I have the following Go program, which is a static file server. I'm getting the following error in the console:

..\static\main.go:45:5: cannot use handlers.CombinedLoggingHandler(os.Stdout, r) (type http.Handler) as type *mux.Router in assignment: need type assertion
..\static\main.go:52:5: cannot use handlers.CompressHandler(l) (type http.Handler) as type *mux.Router in assignment: need type assertion

How can I use flags with the Gorilla Mux router and CombinedLoggingHandler or CompressHandler?

package main

import (
    "flag"
    "fmt"
    "log"
    "net/http"
    "os"
    "time"

    "github.com/gorilla/handlers"
    "github.com/gorilla/mux"

    controllers "<this_is_a_local_repo>"
    common "<this_is_a_local_repo>"
)

var (
    host     = flag.String("host", "127.0.0.1", "TCP host to listen to")
    port     = flag.String("port", "8081", "TCP port to listen to")
    logging  = flag.Bool("logging", false, "Whether to enable HTTP response logging")
    compress = flag.Bool("compress", true, "Whether to enable transparent response compression")
    dir      = flag.String("dir", common.Abs("public"), "Directory to serve static files from")
)

func main() {
    flag.Parse()

    r := mux.NewRouter().StrictSlash(true)
    r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(*dir))))
    r.PathPrefix("/").HandlerFunc(controllers.IndexHandler(*dir + "/index.html")) // catch-all route for 404

    l := r
    if *logging {
        l = handlers.CombinedLoggingHandler(os.Stdout, r)
    }

    h := l
    if *compress {
        h = handlers.CompressHandler(l) // gzip all responses
    }

    srv := &http.Server{
        Handler: h,
        Addr:    fmt.Sprintf("%s:%s", *host, *port),
        ReadTimeout:  5 * time.Second,
        WriteTimeout: 10 * time.Second,
        IdleTimeout:  15 * time.Second,
    }
    log.Fatal(srv.ListenAndServe())
}

Solution

  • It looks like you're trying to add middleware to your gorilla/mux router.

    You can add middleware with Router.Use().

    Router.Use() takes a mux.MiddlewareFunc, which is simply a function with the signature func (http.Handler) http.Handler. Most middleware you will run across matches this signature or can be easily wrapped to do so, as in the example below.

    Ripped off from some of my own internal code:

    func myLoggingHandler(next http.Handler) http.Handler {
        return handlers.CombinedLoggingHandler(os.Stdout, next)
    }
    
    func main() {
        r := mux.NewRouter()
    
        if logging {
            r.Use(myLoggingHandler)
        }
        if compress {
            r.Use(handlers.CompressHandler)
        }
    
        http.Handle("/", r)
    
        log.Fatal(http.ListenAndServe("[::]:8009", nil))
    
    }