cd83f9f0eb
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.
96 lines
1.9 KiB
Go
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
|
|
}
|