mirror of
https://github.com/mickael-kerjean/filestash
synced 2025-12-07 17:02:29 +01:00
fix (concurrency): fix concurrency problem
This commit is contained in:
parent
14e177026d
commit
c9c3a9f5e2
4 changed files with 16 additions and 48 deletions
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mitchellh/hashstructure"
|
"github.com/mitchellh/hashstructure"
|
||||||
"github.com/patrickmn/go-cache"
|
"github.com/patrickmn/go-cache"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -60,6 +61,7 @@ func NewAppCache(arg ...time.Duration) AppCache {
|
||||||
|
|
||||||
type KeyValueStore struct {
|
type KeyValueStore struct {
|
||||||
cache map[string]interface{}
|
cache map[string]interface{}
|
||||||
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewKeyValueStore() KeyValueStore {
|
func NewKeyValueStore() KeyValueStore {
|
||||||
|
|
@ -67,13 +69,19 @@ func NewKeyValueStore() KeyValueStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this KeyValueStore) Get(key string) interface{} {
|
func (this KeyValueStore) Get(key string) interface{} {
|
||||||
|
this.RLock()
|
||||||
|
defer this.RUnlock()
|
||||||
return this.cache[key]
|
return this.cache[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *KeyValueStore) Set(key string, value interface{}) {
|
func (this *KeyValueStore) Set(key string, value interface{}) {
|
||||||
|
this.Lock()
|
||||||
|
defer this.Unlock()
|
||||||
this.cache[key] = value
|
this.cache[key] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *KeyValueStore) Clear() {
|
func (this *KeyValueStore) Clear() {
|
||||||
|
this.Lock()
|
||||||
|
defer this.Unlock()
|
||||||
this.cache = make(map[string]interface{})
|
this.cache = make(map[string]interface{})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package common
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"sync"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewBool(t bool) *bool {
|
func NewBool(t bool) *bool {
|
||||||
|
|
@ -67,30 +66,3 @@ func PrettyPrint(json_dirty []byte) []byte {
|
||||||
json_pretty.Write([]byte("\n"))
|
json_pretty.Write([]byte("\n"))
|
||||||
return json_pretty.Bytes()
|
return json_pretty.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
type SafeMapStringString struct {
|
|
||||||
sync.RWMutex
|
|
||||||
internal map[string]string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSafeMapStringString() SafeMapStringString {
|
|
||||||
return SafeMapStringString{
|
|
||||||
internal: make(map[string]string),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func(this SafeMapStringString) Set(key string, value string) {
|
|
||||||
this.Lock()
|
|
||||||
this.internal[key] = value
|
|
||||||
this.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func(this SafeMapStringString) Gets(keys ...string) []string{
|
|
||||||
this.RLock()
|
|
||||||
res := make([]string, len(keys))
|
|
||||||
for i, key := range keys {
|
|
||||||
res[i] = this.internal[key]
|
|
||||||
}
|
|
||||||
this.RUnlock()
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ETAGS SafeMapStringString = NewSafeMapStringString()
|
|
||||||
|
|
||||||
func StaticHandler(_path string) func(App, http.ResponseWriter, *http.Request) {
|
func StaticHandler(_path string) func(App, http.ResponseWriter, *http.Request) {
|
||||||
return func(ctx App, res http.ResponseWriter, req *http.Request) {
|
return func(ctx App, res http.ResponseWriter, req *http.Request) {
|
||||||
var base string = GetAbsolutePath(_path)
|
var base string = GetAbsolutePath(_path)
|
||||||
|
|
@ -95,16 +93,15 @@ func hashFile (path string, n int) string {
|
||||||
|
|
||||||
stat, err := f.Stat()
|
stat, err := f.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "UNKNOWN"
|
return ""
|
||||||
}
|
}
|
||||||
return QuickHash(fmt.Sprintf("%s %d %d %s", path, stat.Size(), stat.Mode(), stat.ModTime()), n)
|
return QuickHash(fmt.Sprintf("%s %d %d %s", path, stat.Size(), stat.Mode(), stat.ModTime()), n)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ServeFile(res http.ResponseWriter, req *http.Request, filePath string) {
|
func ServeFile(res http.ResponseWriter, req *http.Request, filePath string) {
|
||||||
zFilePath := filePath + ".gz"
|
zFilePath := filePath + ".gz"
|
||||||
tags := ETAGS.Gets(filePath, zFilePath)
|
etagNormal := hashFile(filePath, 10)
|
||||||
etagNormal := tags[0]
|
etagGzip := hashFile(zFilePath, 10)
|
||||||
etagGzip := tags[1]
|
|
||||||
|
|
||||||
if req.Header.Get("If-None-Match") != "" {
|
if req.Header.Get("If-None-Match") != "" {
|
||||||
browserTag := req.Header.Get("If-None-Match")
|
browserTag := req.Header.Get("If-None-Match")
|
||||||
|
|
@ -120,13 +117,7 @@ func ServeFile(res http.ResponseWriter, req *http.Request, filePath string) {
|
||||||
if strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") {
|
if strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") {
|
||||||
if file, err := os.OpenFile(zFilePath, os.O_RDONLY, os.ModePerm); err == nil {
|
if file, err := os.OpenFile(zFilePath, os.O_RDONLY, os.ModePerm); err == nil {
|
||||||
head.Set("Content-Encoding", "gzip")
|
head.Set("Content-Encoding", "gzip")
|
||||||
if etagGzip == "" {
|
|
||||||
tag := hashFile(zFilePath, 10)
|
|
||||||
ETAGS.Set(zFilePath, tag)
|
|
||||||
head.Set("Etag", tag)
|
|
||||||
} else {
|
|
||||||
head.Set("Etag", etagGzip)
|
head.Set("Etag", etagGzip)
|
||||||
}
|
|
||||||
io.Copy(res, file)
|
io.Copy(res, file)
|
||||||
file.Close()
|
file.Close()
|
||||||
return
|
return
|
||||||
|
|
@ -138,13 +129,7 @@ func ServeFile(res http.ResponseWriter, req *http.Request, filePath string) {
|
||||||
http.NotFound(res, req)
|
http.NotFound(res, req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if etagNormal == "" {
|
|
||||||
tag := hashFile(filePath, 10)
|
|
||||||
ETAGS.Set(filePath, tag)
|
|
||||||
head.Set("Etag", tag)
|
|
||||||
} else {
|
|
||||||
head.Set("Etag", etagNormal)
|
head.Set("Etag", etagNormal)
|
||||||
}
|
|
||||||
io.Copy(res, file)
|
io.Copy(res, file)
|
||||||
file.Close()
|
file.Close()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,9 @@ func NewBackend(ctx *App, conn map[string]string) (IBackend, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if val, ok := d["path"]; ok == true {
|
if val, ok := d["path"]; ok == true {
|
||||||
|
if val == nil {
|
||||||
|
val = "/"
|
||||||
|
}
|
||||||
if val != conn["path"] {
|
if val != conn["path"] {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue