Nicholas Corin
Nicholas Corin

Reputation: 2404

Serving static content with GoLang Webserver

I'm exploring the depths of Go, and I've been trying to write a simple web application to wrap my head around everything. I'm trying to serve a React.js application.

Below is the code of the Go server. I've got the default route of / serving the index.html which is working fine. I'm struggling to allow static files to be served to that index file. I'm allowing the React App to do it's own client side routing, although I need to statically serve the JavaScript / CSS / Media files.

For example, I need to be able to serve the bundle.js file into the index.html for the React application to run. Currently, when I route to localhost:8000/dist/ I see the files being listed, but every file/folder that I click from there is throwing a 404 Page Not Found. Is there something that I'm missing? A push in the right direction would be greatly appreciated.

Webserver.go

package main

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

    "github.com/BurntSushi/toml"
    "github.com/gorilla/mux"
)

type ServerConfig struct {
    Environment string
    Host string
    HttpPort int
    HttpsPort int
    ServerRoot string
    StaticDirectories []string
}

func ConfigureServer () ServerConfig {
    _, err := os.Stat("env.toml")
    if err != nil {
        log.Fatal("Config file is missing: env.toml")
    }

    var config ServerConfig
    if _, err := toml.DecodeFile("env.toml", &config); err != nil {
        log.Fatal(err)
    }

    return config
}

func IndexHandler (w http.ResponseWriter, r *http.Request) {
    http.ServeFile(w, r, "./src/index.html")
}

func main () {
    Config := ConfigureServer()
    router := mux.NewRouter()

    // Configuring static content to be served.
    router.Handle("/dist/", http.StripPrefix("/dist/", http.FileServer(http.Dir("dist"))))

    // Routing to the Client-Side Application.
    router.HandleFunc("/", IndexHandler).Methods("GET")

    log.Printf(fmt.Sprintf("Starting HTTP Server on Host %s:%d.", Config.Host, Config.HttpPort))

    if err := http.ListenAndServe(fmt.Sprintf("%s:%d", Config.Host, Config.HttpPort), router); err != nil {
        log.Fatal(err)
    }
}

Upvotes: 4

Views: 3240

Answers (2)

photoionized
photoionized

Reputation: 5232

Per the gorilla mux docs, the proper way to do this would be a handler registered with PathPrefix, like this:

router.PathPrefix("/dist/").Handler(http.StripPrefix("/dist/", http.FileServer(http.Dir("dist"))))

An example can be found if you search the docs for something like PathPrefix("/static/").


This wildcard behavior actually comes by default with the pattern matching mechanism in net/http, so if you weren't using gorilla, but just the default net/http, you could do the following:

http.Handle("/dist/", http.StripPrefix("/dist/", http.FileServer(http.Dir("dist"))))

Upvotes: 2

abhink
abhink

Reputation: 9116

There could be an issue with file access path. Try:

// Strip away "/dist" instead of "/dist/"
router.Handle("/dist/", http.StripPrefix("/dist", http.FileServer(http.Dir("dist"))))

Upvotes: 0

Related Questions