linx-server/fileserve.go
mutantmonkey cd83f9f0eb fix CSP referrer policy
The policy of "referrer none" was incorrect and was nonfunctional. With
this change, the CSP referrer policy is set to origin, which
will causes only the origin to be sent for requests made from the main
site.

A fix was also needed for referrer checks in two places.
2015-10-11 23:49:15 -07:00

96 lines
1.9 KiB
Go

package main
import (
"bytes"
"io"
"net/http"
"os"
"path"
"strings"
"github.com/zenazn/goji/web"
)
func fileServeHandler(c web.C, w http.ResponseWriter, r *http.Request) {
fileName := c.URLParams["name"]
filePath := path.Join(Config.filesDir, fileName)
err := checkFile(fileName)
if err == NotFoundErr {
notFoundHandler(c, w, r)
return
} else if err == BadMetadata {
oopsHandler(c, w, r, RespAUTO, "Corrupt metadata.")
return
}
if !Config.allowHotlink {
referer := r.Header.Get("Referer")
prefix := strings.TrimSuffix(Config.siteURL, "/")
if referer != "" && !strings.HasPrefix(referer, prefix) {
w.WriteHeader(403)
return
}
}
w.Header().Set("Content-Security-Policy", Config.fileContentSecurityPolicy)
http.ServeFile(w, r, filePath)
}
var staticCache = make(map[string][]byte)
func staticHandler(c web.C, w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
if path[len(path)-1:] == "/" {
notFoundHandler(c, w, r)
return
} else {
if path == "/favicon.ico" {
path = "/static/images/favicon.gif"
}
filePath := strings.TrimPrefix(path, "/static/")
_, exists := staticCache[filePath]
if !exists {
file, err := staticBox.Open(filePath)
if err != nil {
notFoundHandler(c, w, r)
return
}
buf := bytes.NewBuffer(nil)
io.Copy(buf, file)
staticCache[filePath] = buf.Bytes()
}
w.Header().Set("Etag", timeStartedStr)
w.Header().Set("Cache-Control", "max-age=86400")
http.ServeContent(w, r, filePath, timeStarted, bytes.NewReader(staticCache[filePath]))
return
}
}
func checkFile(filename string) error {
filePath := path.Join(Config.filesDir, filename)
_, err := os.Stat(filePath)
if err != nil {
return NotFoundErr
}
expired, err := isFileExpired(filename)
if err != nil {
return err
}
if expired {
os.Remove(path.Join(Config.filesDir, filename))
os.Remove(path.Join(Config.metaDir, filename))
return NotFoundErr
}
return nil
}