diff --git a/server/common/crypto.go b/server/common/crypto.go index 09465a91..0c801289 100644 --- a/server/common/crypto.go +++ b/server/common/crypto.go @@ -8,6 +8,7 @@ import ( "crypto/rand" "crypto/sha256" "encoding/base64" + "hash/fnv" "io" "io/ioutil" mathrand "math/rand" @@ -62,6 +63,24 @@ func Hash(str string, n int) string { return h } +func QuickHash(str string, n int) string { + hash := fnv.New32() + hash.Write([]byte(str)) + d := string(hash.Sum(nil)) + h := "" + for i:=0; i 0 && len(h) >= n { + break + } + h += ReversedBaseChange(Letters, int(d[i])) + } + + if len(h) > n { + return h[0:len(h) - 1] + } + return h +} + func ReversedBaseChange(alphabet []rune, i int) string { str := "" for { diff --git a/server/common/files.go b/server/common/files.go index be8be21d..1039d02a 100644 --- a/server/common/files.go +++ b/server/common/files.go @@ -6,7 +6,12 @@ import ( "strings" ) +var MOCK_CURRENT_DIR string + func GetCurrentDir() string { + if MOCK_CURRENT_DIR != "" { + return MOCK_CURRENT_DIR + } ex, _ := os.Executable() return filepath.Dir(ex) } diff --git a/server/common/response.go b/server/common/response.go index ba82ba0d..34c8f5c0 100644 --- a/server/common/response.go +++ b/server/common/response.go @@ -33,6 +33,17 @@ func SendSuccessResult(res http.ResponseWriter, data interface{}) { encoder.Encode(APISuccessResult{"ok", data}) } +func SendSuccessResultWithEtag(res http.ResponseWriter, req *http.Request, data interface{}) { + json, _ := json.Marshal(APISuccessResult{"ok", data}) + hash := QuickHash(string(json), 20) + if req.Header.Get("If-None-Match") == hash { + res.WriteHeader(http.StatusNotModified) + return + } + res.Header().Set("Etag", hash) + res.Write(json) +} + func SendSuccessResults(res http.ResponseWriter, data interface{}) { encoder := json.NewEncoder(res) encoder.SetEscapeHTML(false) diff --git a/server/ctrl/admin.go b/server/ctrl/admin.go index e4619eff..f960b01a 100644 --- a/server/ctrl/admin.go +++ b/server/ctrl/admin.go @@ -76,21 +76,12 @@ func AdminSessionAuthenticate(ctx App, res http.ResponseWriter, req *http.Reques SendSuccessResult(res, true) } - -func AdminBackend(ctx App, res http.ResponseWriter, req *http.Request) { - backends := make(map[string]Form) +func AdminBackend(ctx App, res http.ResponseWriter, req *http.Request) { drivers := Backend.Drivers() + backends := make(map[string]Form, len(drivers)) for key := range drivers { backends[key] = drivers[key].LoginForm() } - - if c, err := json.Marshal(backends); err == nil { - hash := Hash(string(c), 20) - if req.Header.Get("If-None-Match") == hash { - res.WriteHeader(http.StatusNotModified) - return - } - res.Header().Set("Etag", hash) - } - SendSuccessResult(res, backends) + SendSuccessResultWithEtag(res, req, backends) + return } diff --git a/server/ctrl/config.go b/server/ctrl/config.go index 15c450d7..652d6dd3 100644 --- a/server/ctrl/config.go +++ b/server/ctrl/config.go @@ -1,7 +1,6 @@ package ctrl import ( - "encoding/json" . "github.com/mickael-kerjean/filestash/server/common" "io" "io/ioutil" @@ -14,10 +13,11 @@ import ( var ( logpath = filepath.Join(GetCurrentDir(), LOG_PATH, "access.log") cachepath = filepath.Join(GetCurrentDir(), CONFIG_PATH, "config.json") + pluginpath = filepath.Join(GetCurrentDir(), PLUGIN_PATH) ) func FetchPluginsHandler(ctx App, res http.ResponseWriter, req *http.Request) { - f, err := os.OpenFile(filepath.Join(GetCurrentDir(), PLUGIN_PATH), os.O_RDONLY, os.ModePerm) + f, err := os.OpenFile(pluginpath, os.O_RDONLY, os.ModePerm) if err != nil { SendErrorResult(res, err) return @@ -90,14 +90,5 @@ func PrivateConfigUpdateHandler(ctx App, res http.ResponseWriter, req *http.Requ func PublicConfigHandler(ctx App, res http.ResponseWriter, req *http.Request) { cfg := Config.Export() - - if c, err := json.Marshal(cfg); err == nil { - hash := Hash(string(c), 20) - if req.Header.Get("If-None-Match") == hash { - res.WriteHeader(http.StatusNotModified) - return - } - res.Header().Set("Etag", hash) - } - SendSuccessResult(res, cfg) + SendSuccessResultWithEtag(res, req, cfg) } diff --git a/server/ctrl/files.go b/server/ctrl/files.go index c2a627c6..c8d769ae 100644 --- a/server/ctrl/files.go +++ b/server/ctrl/files.go @@ -1,7 +1,7 @@ package ctrl import ( - "encoding/json" + "fmt" . "github.com/mickael-kerjean/filestash/server/common" "github.com/mickael-kerjean/filestash/server/model" "io" @@ -19,13 +19,12 @@ type FileInfo struct { } func FileLs(ctx App, res http.ResponseWriter, req *http.Request) { - var files []FileInfo = make([]FileInfo, 0) if model.CanRead(&ctx) == false { if model.CanUpload(&ctx) == false { SendErrorResult(res, NewError("Permission denied", 403)) return } - SendSuccessResults(res, files) + SendSuccessResults(res, make([]FileInfo, 0)) return } path, err := pathBuilder(ctx, req.URL.Query().Get("path")) @@ -40,21 +39,23 @@ func FileLs(ctx App, res http.ResponseWriter, req *http.Request) { return } - for _, entry := range entries { - f := FileInfo{ - Name: entry.Name(), - Size: entry.Size(), + files := make([]FileInfo, len(entries)) + etag := fmt.Sprintf("%d", len(entries)) + path + for i:=0; i