Skip to content

Commit 3f6ad2f

Browse files
committed
Fix serving static files with go run
The sequence is now: 1) Look in Config.StaticDir 2) Look in the 'static' directory in the parent directory of the executable. 3) Look in 'static' directory in the current working directory `go run` places the executable in a temp directory, so the only option is to also look in the current working directory.
1 parent 0b82c6b commit 3f6ad2f

File tree

1 file changed

+44
-28
lines changed

1 file changed

+44
-28
lines changed

web.go

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -158,25 +158,24 @@ func (ctx *Context) GetSecureCookie(name string) (string, bool) {
158158
// small optimization: cache the context type instead of repeteadly calling reflect.Typeof
159159
var contextType reflect.Type
160160

161-
var exeFile string
162-
163-
// default
164-
func defaultStaticDir() string {
165-
root, _ := path.Split(exeFile)
166-
return path.Join(root, "static")
167-
}
161+
var defaultStaticDirs []string
168162

169163
func init() {
170164
contextType = reflect.TypeOf(Context{})
171165
//find the location of the exe file
172-
arg0 := path.Clean(os.Args[0])
173166
wd, _ := os.Getwd()
167+
arg0 := path.Clean(os.Args[0])
168+
var exeFile string
174169
if strings.HasPrefix(arg0, "/") {
175170
exeFile = arg0
176171
} else {
177172
//TODO for robustness, search each directory in $PATH
178173
exeFile = path.Join(wd, arg0)
179174
}
175+
parent, _ := path.Split(exeFile)
176+
defaultStaticDirs = append(defaultStaticDirs, path.Join(parent, "static"))
177+
defaultStaticDirs = append(defaultStaticDirs, path.Join(wd, "static"))
178+
return
180179
}
181180

182181
type route struct {
@@ -256,6 +255,32 @@ func requiresContext(handlerType reflect.Type) bool {
256255
return false
257256
}
258257

258+
// tryServingFile attempts to serve a static file, and returns
259+
// whether or not the operation is successful.
260+
// It checks the following directories for the file, in order:
261+
// 1) Config.StaticDir
262+
// 2) The 'static' directory in the parent directory of the executable.
263+
// 3) The 'static' directory in the current working directory
264+
func (s *Server) tryServingFile(name string, req *http.Request, w http.ResponseWriter) bool {
265+
//try to serve a static file
266+
if s.Config.StaticDir != "" {
267+
staticFile := path.Join(s.Config.StaticDir, name)
268+
if fileExists(staticFile) {
269+
http.ServeFile(w, req, staticFile)
270+
return true
271+
}
272+
} else {
273+
for _, staticDir := range defaultStaticDirs {
274+
staticFile := path.Join(staticDir, name)
275+
if fileExists(staticFile) {
276+
http.ServeFile(w, req, staticFile)
277+
return true
278+
}
279+
}
280+
}
281+
return false
282+
}
283+
259284
// the main route handler in web.go
260285
func (s *Server) routeHandler(req *http.Request, w http.ResponseWriter) {
261286
requestPath := req.URL.Path
@@ -273,23 +298,17 @@ func (s *Server) routeHandler(req *http.Request, w http.ResponseWriter) {
273298
}
274299
fmt.Fprintf(&logEntry, "\n\033[37;1mParams: %v\033[0m\n", ctx.Params)
275300
}
276-
277301
ctx.Server.Logger.Print(logEntry.String())
278302

279303
//set some default headers
280304
ctx.SetHeader("Server", "web.go", true)
281305
tm := time.Now().UTC()
282306
ctx.SetHeader("Date", webTime(tm), true)
283307

284-
//try to serve a static file
285-
staticDir := s.Config.StaticDir
286-
if staticDir == "" {
287-
staticDir = defaultStaticDir()
288-
}
289-
staticFile := path.Join(staticDir, requestPath)
290-
if fileExists(staticFile) && (req.Method == "GET" || req.Method == "HEAD") {
291-
http.ServeFile(&ctx, req, staticFile)
292-
return
308+
if req.Method == "GET" || req.Method == "HEAD" {
309+
if s.tryServingFile(requestPath, req, w) {
310+
return
311+
}
293312
}
294313

295314
//Set the default content-type
@@ -344,17 +363,14 @@ func (s *Server) routeHandler(req *http.Request, w http.ResponseWriter) {
344363
return
345364
}
346365

347-
//try to serve index.html || index.htm
348-
if indexPath := path.Join(path.Join(staticDir, requestPath), "index.html"); fileExists(indexPath) {
349-
http.ServeFile(&ctx, ctx.Request, indexPath)
350-
return
351-
}
352-
353-
if indexPath := path.Join(path.Join(staticDir, requestPath), "index.htm"); fileExists(indexPath) {
354-
http.ServeFile(&ctx, ctx.Request, indexPath)
355-
return
366+
// try serving index.html or index.htm
367+
if req.Method == "GET" || req.Method == "HEAD" {
368+
if s.tryServingFile(path.Join(requestPath, "index.html"), req, w) {
369+
return
370+
} else if s.tryServingFile(path.Join(requestPath, "index.htm"), req, w) {
371+
return
372+
}
356373
}
357-
358374
ctx.Abort(404, "Page not found")
359375
}
360376

0 commit comments

Comments
 (0)