chore: save etag in bbolt by msgpack

This commit is contained in:
wwqgtxx
2024-09-23 19:25:35 +08:00
parent 966eeae41b
commit 59a2b24593
6 changed files with 97 additions and 66 deletions

View File

@@ -1,12 +1,10 @@
package cachefile
import (
"math"
"os"
"sync"
"time"
"github.com/metacubex/mihomo/common/utils"
"github.com/metacubex/mihomo/component/profile"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/log"
@@ -72,58 +70,6 @@ func (c *CacheFile) SelectedMap() map[string]string {
return mapping
}
func (c *CacheFile) SetETagWithHash(url string, hash utils.HashType, etag string) {
if c.DB == nil {
return
}
lenHash := hash.Len()
if lenHash > math.MaxUint8 {
return // maybe panic is better
}
data := make([]byte, 1, 1+lenHash+len(etag))
data[0] = uint8(lenHash)
data = append(data, hash.Bytes()...)
data = append(data, etag...)
err := c.DB.Batch(func(t *bbolt.Tx) error {
bucket, err := t.CreateBucketIfNotExists(bucketETag)
if err != nil {
return err
}
return bucket.Put([]byte(url), data)
})
if err != nil {
log.Warnln("[CacheFile] write cache to %s failed: %s", c.DB.Path(), err.Error())
return
}
}
func (c *CacheFile) GetETagWithHash(key string) (hash utils.HashType, etag string) {
if c.DB == nil {
return
}
c.DB.View(func(t *bbolt.Tx) error {
if bucket := t.Bucket(bucketETag); bucket != nil {
if v := bucket.Get([]byte(key)); v != nil {
if len(v) == 0 {
return nil
}
lenHash := int(v[0])
if len(v) < 1+lenHash {
return nil
}
hash = utils.MakeHashFromBytes(v[1 : 1+lenHash])
etag = string(v[1+lenHash:])
}
}
return nil
})
return
}
func (c *CacheFile) Close() error {
return c.DB.Close()
}

View File

@@ -0,0 +1,58 @@
package cachefile
import (
"time"
"github.com/metacubex/mihomo/common/utils"
"github.com/metacubex/mihomo/log"
"github.com/metacubex/bbolt"
"github.com/vmihailenco/msgpack/v5"
)
type EtagWithHash struct {
Hash utils.HashType
ETag string
Time time.Time
}
func (c *CacheFile) SetETagWithHash(url string, etagWithHash EtagWithHash) {
if c.DB == nil {
return
}
data, err := msgpack.Marshal(etagWithHash)
if err != nil {
return // maybe panic is better
}
err = c.DB.Batch(func(t *bbolt.Tx) error {
bucket, err := t.CreateBucketIfNotExists(bucketETag)
if err != nil {
return err
}
return bucket.Put([]byte(url), data)
})
if err != nil {
log.Warnln("[CacheFile] write cache to %s failed: %s", c.DB.Path(), err.Error())
return
}
}
func (c *CacheFile) GetETagWithHash(key string) (etagWithHash EtagWithHash) {
if c.DB == nil {
return
}
c.DB.View(func(t *bbolt.Tx) error {
if bucket := t.Bucket(bucketETag); bucket != nil {
if v := bucket.Get([]byte(key)); v != nil {
if err := msgpack.Unmarshal(v, &etagWithHash); err != nil {
return err
}
}
}
return nil
})
return
}

View File

@@ -117,14 +117,14 @@ func (h *HTTPVehicle) Read(ctx context.Context, oldHash utils.HashType) (buf []b
header := h.header
setIfNoneMatch := false
if etag && oldHash.IsValid() {
hashBytes, etag := cachefile.Cache().GetETagWithHash(h.url)
if oldHash.Equal(hashBytes) && etag != "" {
etagWithHash := cachefile.Cache().GetETagWithHash(h.url)
if oldHash.Equal(etagWithHash.Hash) && etagWithHash.ETag != "" {
if header == nil {
header = http.Header{}
} else {
header = header.Clone()
}
header.Set("If-None-Match", etag)
header.Set("If-None-Match", etagWithHash.ETag)
setIfNoneMatch = true
}
}
@@ -146,7 +146,11 @@ func (h *HTTPVehicle) Read(ctx context.Context, oldHash utils.HashType) (buf []b
}
hash = utils.MakeHash(buf)
if etag {
cachefile.Cache().SetETagWithHash(h.url, hash, resp.Header.Get("ETag"))
cachefile.Cache().SetETagWithHash(h.url, cachefile.EtagWithHash{
Hash: hash,
ETag: resp.Header.Get("ETag"),
Time: time.Now(),
})
}
return
}