summaryrefslogtreecommitdiff
path: root/http/static.go
diff options
context:
space:
mode:
Diffstat (limited to 'http/static.go')
-rw-r--r--http/static.go70
1 files changed, 70 insertions, 0 deletions
diff --git a/http/static.go b/http/static.go
new file mode 100644
index 00000000..bfcb87c2
--- /dev/null
+++ b/http/static.go
@@ -0,0 +1,70 @@
+package http
+
+import (
+ "net/http"
+ "strings"
+ "path"
+ "github.com/sirupsen/logrus"
+ "os"
+ "path/filepath"
+)
+
+var (
+ forbiddenFiles = []string{".php", ".htaccess"}
+)
+
+// staticServer serves static files
+type staticServer struct {
+ root http.Dir
+}
+
+// serve attempts to serve static file and returns true in case of success, will return false in case if file not
+// found, not allowed or on read error.
+func (svr *staticServer) serve(w http.ResponseWriter, r *http.Request) bool {
+ fpath := r.URL.Path
+ if !strings.HasPrefix(fpath, "/") {
+ fpath = "/" + fpath
+ }
+ fpath = path.Clean(fpath)
+
+ if svr.forbidden(fpath) {
+ logrus.Warningf("attempt to access forbidden file %s", fpath) // todo: better logs
+ return false
+ }
+
+ f, err := svr.root.Open(fpath)
+ if err != nil {
+ if !os.IsNotExist(err) {
+ logrus.Error(err) //todo: rr or access error
+ }
+
+ return false
+ }
+ defer f.Close()
+
+ d, err := f.Stat()
+ if err != nil {
+ logrus.Error(err) //todo: rr or access error
+ return false
+ }
+
+ if d.IsDir() {
+ // do not serve directories
+ return false
+ }
+
+ http.ServeContent(w, r, d.Name(), d.ModTime(), f)
+ return true
+}
+
+// forbidden returns true if file has forbidden extension.
+func (svr *staticServer) forbidden(path string) bool {
+ ext := strings.ToLower(filepath.Ext(path))
+ for _, exl := range forbiddenFiles {
+ if ext == exl {
+ return true
+ }
+ }
+
+ return false
+}