0

So I am trying to get CSS working using my Go server, but the css file is not loading correcly, I get 404 file not found. It works fine when I run Index.html straight from the browser.

My directory structure with # representing a folder and - a file:

- Main.go
# static
    - index.html
    # css
       - Styles.css

Index.html contains:

<link rel="stylesheet" type="text/css" href="css/Styles.css"/>

These are all my handlers:

muxRouter := mux.NewRouter()
muxRouter.HandleFunc("/", basicHandler)
muxRouter.HandleFunc("/ws", wsHandler)
muxRouter.Handle("/css/", http.StripPrefix("/css/", http.FileServer(http.Dir("static/css"))))

basicHandler contains:

toSend := template.HTMLEscapeString(outputMessage)
toSend = strings.Replace(toSend, "\n", "<br>", -1)

templateError := allTemplates.ExecuteTemplate(responseWriter, "index.html", template.HTML(toSend))
if templateError != nil {
    log.Fatal("Template error: ", templateError)
}

wsHandler handles the websocket which my program uses.

Dylan
  • 305
  • 3
  • 18
  • Shot in the dark, is the leading slash an issue? You're requesting `resources/Style.css` and handling `/resources/`. – Phix Feb 20 '19 at 01:10
  • @Phix No, sadly not. I have tried every combination of slashes I could come up with. The address the `href` trys to access is `http://localhost:8080/resources/Styles.css` regardless of slashes. – Dylan Feb 20 '19 at 01:12
  • Ultimately you'lll probably also need to send the content type for CSS, but the text file should display if your path is right. Did you check file and directory permissions? – jrefior Feb 20 '19 at 01:42
  • @jrefior I strip the prefix resource but also include `http.FileServer(http.Dir("resources"))` hence putting the location to look for `/resources/Styles.css` after being stripped to `Styles.css` in the resources folder. I did try `resources/resources/Styles.css` regardless and sadly it did not work. – Dylan Feb 20 '19 at 01:46
  • In all the examples in the package documentation, they use the full path in the parameter passed to `http.Dir`. Have you tried that? See https://golang.org/pkg/net/http/#FileServer – jrefior Feb 20 '19 at 01:48
  • Yes I did try the full path. The permissions are good. – Dylan Feb 20 '19 at 01:49
  • since your Index.html is at a higher level that the CSS content - how are you serving the route for Index.html? – colm.anseo Feb 20 '19 at 03:46
  • @colminator To serve Index.html I am using HandleFunc() on the "/" path where the function simply does serveFile(ResponseWriter, HttpRequest, "Index.html) no matter the address. As I am new to Go and HTML currently my server only show Index.html no matter what. – Dylan Feb 20 '19 at 03:56
  • 1
    @Dylan I would put your html/css files like so `static/Index.html` and `static/resources/Styles.css` - and have a single handle for both. I'll update my answer below to demonstrate. – colm.anseo Feb 20 '19 at 04:00

1 Answers1

2

I'd suggest moving your files like so (note I renamed index.html to lowercase - so it will be loaded by default when visiting the document root URL):

Main.go
static/
static/index.html
static/css/Styles.css

modify index.html to refer to the more aptly named css directory:

<link rel="stylesheet" type="text/css" href="css/Styles.css"/>

EDIT: update to adjust for gorilla/mux.

H/T to this answer.

package main

import (
        "github.com/gorilla/mux"
        "log"
        "net/http"
)

func main() {
        r := mux.NewRouter()

        r.PathPrefix("/css/").Handler(
                http.StripPrefix("/css/", http.FileServer(http.Dir("static/css/"))),
        )   

        err := http.ListenAndServe(":8080", r)
        if err != nil {
                log.Fatal(err)
        }   

        // curl 'localhost:8080/css/Styles.css'
        // <style> ...  </style>
}
colm.anseo
  • 19,337
  • 4
  • 43
  • 52
  • I won't be able to try till tomorrow. – Dylan Feb 20 '19 at 04:24
  • I'll update the question to better communicate what I actually have, I had simplified it earlier. – Dylan Feb 20 '19 at 19:09
  • @Dylan looking at your updated question - I have to think if you are still getting a 404 for the `css` route - your go-server is not being run from the correct relative location for the `http.FileServer` to work. As a test, can you put an absolute path in `http.Dir` to ensure the executable find the files? – colm.anseo Feb 20 '19 at 19:52
  • Just tried, using the absolute path makes no difference. – Dylan Feb 20 '19 at 19:56
  • add log statements at the head of each of your handlers - to see which one is being triggered. I suspect your basic handler must be intercepting the css path (but based on the route definitions I don't see how that is possible...) – colm.anseo Feb 20 '19 at 20:04
  • also note in your `index.html` you use a relative path `css/Styles.css` - so if your index page is off another url - this will fail. So try `/css/Styles.css` – colm.anseo Feb 20 '19 at 20:06
  • I tried using log statements yesterday and can confirm `basicHandler `does not intercept. Changing it to `/css/Styles.css` had no effect, in fact, changing it meant css would not even load by launching `index.html` in the web browser. – Dylan Feb 20 '19 at 20:08
  • try ``. Also try testing the CSS url directly in a browser to debug e.g. `localhost:8080:/css/Styles.css` – colm.anseo Feb 20 '19 at 20:13
  • Just get `404 file not found` – Dylan Feb 20 '19 at 20:16
  • Wait, you are using NewRouter() - is this gorilla mux? If you are chaining routers - you'll need the previous route's prefix, to prefix to your html url path. – colm.anseo Feb 20 '19 at 20:20
  • I am indeed using `github.com/gorilla/mux`. Not sure what you mean by changing routers, but if it helps I only execute `mux.NewRouter()` once throughout the programs life. – Dylan Feb 20 '19 at 20:23
  • figured it out - gorilla/mux and http package routers are chained hence the confusion. Answer updated above to fix gorilla's router. See referenced other answer for details on why http.FileServer was being confused by gorilla/mux. – colm.anseo Feb 20 '19 at 20:47
  • It makes sense now! I'll give it a go. – Dylan Feb 20 '19 at 20:50