0

I'm trying to serve a static html file, and this file has script tags that point to other resources. I want to serve the html file from one directory but then redirect requests for assets to another directory. This is how I'm setting it up now:

// server.go
import (
    "fmt"
    "html/template"
    "log"
    "net/http"
    "path"
    "time"
)

func handle(w http.ResponseWriter, r *http.Request) {
    lp := path.Join("./", "index.html")
    fmt.Println(lp)
    tmpl, err := template.ParseFiles(lp)
    if err != nil {
        log.Fatal(err)
    }
    tmpl.ExecuteTemplate(w, "index", nil)
}

func main() {
    fs := http.FileServer(http.Dir("../../app_assets/"))
    http.Handle("/assets", fs)
    http.HandleFunc("/static/", handle)

    fmt.Println("Go Server listening on port 8000")
    http.ListenAndServe(":8000", nil)
}

Here is my template:

<!-- index.html -->
{{define "index"}}
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="assets/css/libs.css" type="text/css" />
</head>

<body>
<script type="text/javascript" src="assets/js/libs.js"></script>

<h1> Hello </h1>
</body>
</html>
{{end}}

I'm able to serve the index file from localhost:8000/static/, but asset requests are not going to the assets folder two levels up (../../). What am I doing wrong?

NOTE:

I'm getting this error in the console when libs.js is loaded:

Uncaught SyntaxError: Unexpected token <

This leads me to believe that the request for the libs.js file is being redirected to the html markup.

How is this happening?

NOTE 2:

When I browse the result of the request for libs.js, I see the html markup. Even after using StripPrefix as advised below. What am I doing wrong?

Community
  • 1
  • 1
dopatraman
  • 13,416
  • 29
  • 90
  • 154

2 Answers2

0

So I know it's a bit confusing, but you want to change fs := http.FileServer(http.Dir("../../assets/")) to be fs := http.FileServer(http.Dir("../.."))

The reason is that the path for "assets" is already specified in the request so as you have it, it is really pointing to ../../assets/assets/*

Hope that helps!

oh and just to prevent another error, that Handle() functions should be written with a trailing slash in the path. I almost forgot to catch that.

EDIT

To adjust my answer for your other need (using some sort of redirect) you'd have to use the http.StripPrefix handler https://golang.org/pkg/net/http/#StripPrefix

For your use case you would prepare your server with the following code:

fs := http.FileServer(http.Dir("../../app_assets"))
http.Handle("/assets/", http.StripPrefix("/assets/", fs))

This lets you do url rewrites for file system serving.

Corvus Crypto
  • 2,141
  • 1
  • 13
  • 14
  • What if I want to use a folder of a different name? say point the request toward `../../app_assets` or something like that? I updated the question so you can see what I mean. – dopatraman Mar 26 '16 at 02:36
  • Still does not work. Getting this error: `Uncaught SyntaxError: Unexpected token <` – dopatraman Mar 28 '16 at 01:34
  • @dopatraman, thats because your `src` attribute is `src="assets/js/libs.js"`. It should be `src="/assets/js/libs.js"`. With a `/` infront. See my answer. – Aruna Herath Mar 28 '16 at 01:48
0

In your html when you specify the src attributes of your css and js you have src="assets/js/libs.js". This makes those files to be requested relative to the current path. So the request goes to http://localhost:8000/static/assets/js/libs.js.

Since this has the /static prefix it will be handled by your /static handler and hence the html file is served.

To make it go to /assets handler, specify the src with a / prefixed.

<script type="text/javascript" src="/assets/js/libs.js"></script>

Now the server will look for the file at ../../app_assets/assets/js/libs.js.

If you want it to be ../../app_assets/js/libs.js, you can use StripPrefix to take out the assets part from the url in the server.

fs := http.StripPrefix("/assets/", http.FileServer(http.Dir("../../app_assets/")))
http.Handle("/assets/", fs)
Aruna Herath
  • 6,241
  • 1
  • 40
  • 59
  • But if the `src` attribute does not point to `/assets/*` the route handler set in the server will not be hit right? – dopatraman Mar 26 '16 at 05:29
  • Ah. Right! Use StripPrefix. – Aruna Herath Mar 26 '16 at 05:31
  • I don't get the downvote :( specially after I corrected my mistake. The rest of the answer should be quite useful to OP. – Aruna Herath Mar 28 '16 at 01:49
  • 1
    I got downvoted too. However I will upvote yours because it is entirely correct and any little errors like using the wrong asset src url are unrelated to the question, which was to show how to do redirects when using FS servers. Golang dev, man haha – Corvus Crypto Mar 28 '16 at 03:22