The problem is the pattern you register you handler with: "/download"
.
There are 2 problems with it:
The generated URLs are wrong because the handler returned by the http.FileServer()
function generates relative URLs to files and subfolders; relative to the root folder passed to http.FileServer()
, and if your page is available under the path /download
, a relative URL like href="a.xml"
will be resolved to /a.xml
, and not to /download/a.xml
.
Even if the URLs would be good, the files would not be served as the requests would not get routed to your handled (to the file server handler). You must add a trailing slash, as "/download"
only matches this single path, and not all paths starting with it. Add a trailing slash: "/download/"
and it will match the rooted subtree /download/*
.
So the solution is:
r.PathPrefix("/download/").Handler(
http.StripPrefix("/download", http.FileServer(http.Dir(dirPath))),
).Methods("GET")
This is documented at http.ServeMux
:
Patterns name fixed, rooted paths, like "/favicon.ico", or rooted subtrees, like "/images/" (note the trailing slash).
Note that even though we're now using the "/download/"
registered path, users are not required to type the trailing slash in the browser, as leaving that out the server will send a redirect to the path that ends with a trailing slash. This will happen automatically. This is also documented at http.ServeMux
:
If a subtree has been registered and a request is received naming the subtree root without its trailing slash, ServeMux redirects that request to the subtree root (adding the trailing slash). This behavior can be overridden with a separate registration for the path without the trailing slash. For example, registering "/images/" causes ServeMux to redirect a request for "/images" to "/images/", unless "/images" has been registered separately.
Read related question: Go web server is automatically redirecting POST requests
Here's a simple file server app using only the standard library:
http.Handle("/dl/",
http.StripPrefix("/dl", http.FileServer(http.Dir("/home/bob/Downloads"))),
)
panic(http.ListenAndServe("localhost:8080", nil))