1

I've set up a simple Go static file server with http.FileServer. If I have a directory structure like public > about > index.html, the server will correctly resolve /about to about > index.html, but it adds a trailing slash so the url becomes /about/.

Is there a simple way to remove these trailing slashes when using http.FileServer? Ultimately, it works either way - it's mostly just a personal preference to not have the trailing slashes if possible.

Luke Johnson
  • 183
  • 2
  • 12
  • 1
    It's not a personal preference. An URL's pathname ending in `/` tells the server the client wants a representation representing the list of resources available at that path, while a pathname not ending in `/` asks the server to send the representation of a particular entity at that path. – kostix Jun 29 '20 at 16:21
  • ([More info](http://sebastians-pamphlets.com/the-anatomy-of-http-redirects-301-302-307/#invisible-server-redirects), with references to relevant material.) – kostix Jun 29 '20 at 16:26
  • 1
    @kostix that could be a convention for _some_ but it's certainly not in any HTTP standard documents – Evert Jun 29 '20 at 16:37
  • Unfortunately, this is a rare case where Go is arbitrarily opinionated about something and hard-coded that opinion into the stdlib. There is no way to "fix" it while using `http.FileServer`. – Adrian Jun 29 '20 at 16:40
  • 1
    @Adrian you can actually work around this by registering two explicit routes. – colm.anseo Jun 29 '20 at 19:46
  • @colm.anseo yes, *if you don't use* `FileServer` for one of them. So, as I said - there is not way to fix this **while using** `http.FileServer`. – Adrian Jun 29 '20 at 20:00
  • @Adrian your comment gave the impression that this was a dead-end from the Go `stdlib` perspective. But the OP can work around this by working with `http.ServeMux`. – colm.anseo Jun 29 '20 at 20:05

1 Answers1

1

When you register the route /about/ an implicit route of /about is added (which redirects clients to /about/).

To work around this, you can register two explicit routes:

  • /about to serve your index.html
  • /about/ to serve the http.FileServer to handle any HTML assets for the page

like so:

// what you had before
h.Handle("/about/",
    http.StripPrefix(
        "/about/",
        http.FileServer(http.Dir("/tmp/about-files")),
    ),
)

// prevents implicit redirect to `/about/`
h.HandleFunc("/about",
    func(w http.ResponseWriter, r *http.Request) {
        http.ServeFile(w, r, "index.html") // serves a single file from this route
    },
)

https://play.golang.org/p/WLwLPV5WuJm

colm.anseo
  • 19,337
  • 4
  • 43
  • 52