Subby
Subby

Reputation: 2036

Golang gorilla expects trailing slash on static serving

I want to serve the swagger-ui using gorilla/mux and http.FileServer.

This is the routing that works so far:

router := mux.NewRouter()
router.PathPrefix("/swagger-ui/").Handler(http.StripPrefix("/swagger-ui/", 
http.FileServer(http.Dir("swagger-ui/"))))
http.ListenAndServe(":8080", router)

The problem is: only a GET /swagger-ui/ returns the swagger page. When I do (what most users also expect) a GET /swagger-ui without trailing slash I get a 404.

How can this be solved?

Upvotes: 5

Views: 2849

Answers (2)

mcgtrt
mcgtrt

Reputation: 787

I think I found a solution to the issue with the trailing slash.

Suffix slash is the most annoying thing when the request method is different than "GET" as there is no use of r.StrictSlash(true).

Instead of writing complex or inelegant solutions like multiplying the r.HandlerFunc routes for "/path" and "/path/", a middleware might come useful:

func routingMiddleware(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        url := *r.URL
        url.Path = strings.TrimSuffix(r.URL.Path, "/")
        r.URL = &url

        h.ServeHTTP(w, r)
    })
}

And wherever your mux.Router is - do this:

r := mux.NewRouter()
r.Use(routingMiddleware)

Hope it helps!

Upvotes: 0

c_anirudh
c_anirudh

Reputation: 394

You have probably found the answer as the question is nearly two years old, but I will write the answer here so that anybody who comes across this question can see it.

You just need to define your gorilla router as: router := mux.NewRouter().StrictSlash(true)

StrictSlash func(value bool) *Router StrictSlash defines the trailing slash behavior for new routes. The initial value is false.

When true, if the route path is "/path/", accessing "/path" will perform a redirect to the former and vice versa. In other words, your application will always see the path as specified in the route.

When false, if the route path is "/path", accessing "/path/" will not match this route and vice versa.

The re-direct is a HTTP 301 (Moved Permanently). Note that when this is set for routes with a non-idempotent method (e.g. POST, PUT), the subsequent re-directed request will be made as a GET by most clients. Use middleware or client settings to modify this behaviour as needed.

Special case: when a route sets a path prefix using the PathPrefix() method, strict slash is ignored for that route because the redirect behavior can't be determined from a prefix alone. However, any subrouters created from that route inherit the original StrictSlash setting.

Upvotes: 3

Related Questions