1

I have the following handler in my go web application:

func pleaseLoginHandler(w http.ResponseWriter, req *http.Request) {
    http.ServeFile(w, req, "./pleaselogin.html")
}

This handler is called for the route http://a.b.org/pleaselogin by using:

rtr.HandleFunc("/pleaselogin", pleaseLoginHandler)

The application works without any problems locally. Also, it works on the remote server if I run the executable from the folder in which all the application files are present. That is, if the application is in the location /home/username/go/src/appdirectory/appexecfile and I start the application by going to this directory and starting it as ./appexecfile then all routes works as expected.

The problem occurs when I start the application using supervisord. In this case if I visit the route http://a.b.org/pleaselogin the server returns 404 not found error. My guess is that this is because the http.ServeFile is using a relative path and when the application is started with supervisord it does not know to look for the file in /home/user/go/src/appdirectory.

Can someone please suggest a solution to this problem? Can I use another method for serving the file in the golang application that avoids this problem? Or, can I use a setting in supervisord that makes it look for any file relative to the executable of the application?

Thank you.

Curious2learn
  • 31,692
  • 43
  • 108
  • 125
  • 1
    Related: 1. [how to reference a relative file from code and tests](http://stackoverflow.com/questions/31059023/how-to-reference-a-relative-file-from-code-and-tests); 2. [With golang webserver where does the root of the website map onto the filesystem>](http://stackoverflow.com/questions/28745161/with-golang-webserver-where-does-the-root-of-the-website-map-onto-the-filesystem) – icza May 08 '16 at 05:00

1 Answers1

1

Okay, just figured out that I can add the directory option in supervisord configuration. Adding,

directory=/home/username/go/src/appdirectory/

solves the problem. However, if there are other better solutions, I would love to see them.

Curious2learn
  • 31,692
  • 43
  • 108
  • 125
  • Yes: don't use relative paths in your application! Pass a path to your static files as a configuration option (e.g. using [envconfig](https://github.com/kelseyhightower/envconfig)), and if that's not set, then fallback to the result `os.Getwd` (or just bail out). Be explicit, because as you're finding, relying on 'implicit' behaviour breaks very quickly once you're on another machine. – elithrar May 08 '16 at 02:09
  • @elithrar Can you please give an example? It is not clear what you are suggesting. I have a folder from which I serve static files directly using `fs := http.StripPrefix("/static/", http.FileServer(http.Dir("./static")))`. However, I am not sure how to use this to convert `http.ServeFile(w, req, "./pleaselogin.html")` to an absolute path. If you could give me an example, I would be happy to accept that as the answer. – Curious2learn May 08 '16 at 16:56
  • `./static` is a relative path. Have your application take an argument/config file/environmental variable that passes the full path - e.g. `/Users/you/Code/static/` so that the application can find the static directory no matter where it's run from. Supervisord allows you to set environmental variables as well. – elithrar May 08 '16 at 18:02
  • @elithrar Thanks! Now I understand. I will have to maintain separate values for dev and prod environments in that case (since full path is different in each case). However, I can use the appropriate flags when I start the process to specify these paths and have the application use them. – Curious2learn May 09 '16 at 14:31