How do you serve a static html file using a go web server?
NOT a FTP server: That is something different than what I intended, which would be to serve the
index.html
homepage, like a normal web server would. Like, when I go to mydomain.com in my browser, I wantindex.html
rendered.
That is mainly what "Writing Web Applications" describes, and what a project like hugo (static html site generator) does.
It is about reading a file, and responsing with a ContentType "text/html":
func (server *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
err := server.renderFile(w, r.URL.Path)
if err != nil {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusNotFound)
server.fn404(w, r)
}
}
with renderFile()
essentially reading and setting the right type:
file, err = ioutil.ReadFile(server.MediaPath + filename)
if ext != "" {
w.Header().Set("Content-Type", mime.TypeByExtension(ext))
}
If you only want to serve 1 file and not a full directory, you can use http.ServeFile
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "index.html")
})
I prefer using http.ServeFile
for this over http.FileServer
. I wanted directory browsing disabled, a proper 404 if files are missing and an easy way to special case the index file. This way, you can just drop the built binary into a folder and it will serve everything relative to that binary. Of course, you can use strings.Replace
on p
if you have the files stored in another directory.
func main() {
fmt.Println("Now Listening on 80")
http.HandleFunc("/", serveFiles)
log.Fatal(http.ListenAndServe(":80", nil))
}
func serveFiles(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.URL.Path)
p := "." + r.URL.Path
if p == "./" {
p = "./static/index.html"
}
http.ServeFile(w, r, p)
}
That task is very easy with Golang net/http package.
All You need to do is:
package main
import (
"net/http"
)
func main() {
http.Handle("/", http.FileServer(http.Dir("./static")))
http.ListenAndServe(":3000", nil)
}
assuming that static files are in folder named static
in the root directory of the project.
If it's in folder static
, you'll have index.html
file calling http://localhost:3000/
which will result in rendering that index file instead of listing all the files availible.
Additionally, calling any other file in that folder (for example http://localhost:3000/clients.html
) will show that file, properly rendered by the browser (at least Chrome, Firefox and Safari :))
UPDATE: serving files from url different than "/"
If You want to serve files, say from folder ./public
under url: localhost:3000/static
You have to use additional function: func StripPrefix(prefix string, h Handler) Handler
like this:
package main
import (
"net/http"
)
func main() {
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./public"))))
http.ListenAndServe(":3000", nil)
}
Thanks to that, all your files from ./public
are avalible under localhost:3000/static
Without http.StripPrefix
function, if you would try to access file localhost:3000/static/test.html
, the server would look for it in ./public/static/test.html
This is because the server treats the whole URI as a relative path to the file.
Fortunately, it's easily solved with the built-in function.