mirror of
https://github.com/filebrowser/filebrowser.git
synced 2026-02-25 03:29:06 +00:00
83 lines
2.0 KiB
Go
83 lines
2.0 KiB
Go
package fbhttp
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"strconv"
|
|
|
|
"github.com/redis/go-redis/v9"
|
|
)
|
|
|
|
// redisUploadCache is an upload cache for multi replica deployments
|
|
type redisUploadCache struct {
|
|
client *redis.Client
|
|
}
|
|
|
|
func newRedisUploadCache(redisURL string) (*redisUploadCache, error) {
|
|
if redisURL == "" {
|
|
return nil, fmt.Errorf("redis URL is required")
|
|
}
|
|
|
|
opts, err := redis.ParseURL(redisURL)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid redis URL: %w", err)
|
|
}
|
|
|
|
client := redis.NewClient(opts)
|
|
|
|
// Test connection
|
|
if err := client.Ping(context.Background()).Err(); err != nil {
|
|
return nil, fmt.Errorf("failed to connect to redis: %w", err)
|
|
}
|
|
|
|
return &redisUploadCache{client: client}, nil
|
|
}
|
|
|
|
func (c *redisUploadCache) filePathKey(filePath string) string {
|
|
return "filebrowser:upload:" + filePath
|
|
}
|
|
|
|
func (c *redisUploadCache) Register(filePath string, fileSize int64) {
|
|
err := c.client.Set(context.Background(), c.filePathKey(filePath), fileSize, uploadCacheTTL).Err()
|
|
if err != nil {
|
|
log.Printf("failed to register upload in redis cache: %v", err)
|
|
}
|
|
}
|
|
|
|
func (c *redisUploadCache) Complete(filePath string) {
|
|
err := c.client.Del(context.Background(), c.filePathKey(filePath)).Err()
|
|
if err != nil {
|
|
log.Printf("failed to complete upload in redis cache: %v", err)
|
|
}
|
|
}
|
|
|
|
func (c *redisUploadCache) GetLength(filePath string) (int64, error) {
|
|
result, err := c.client.Get(context.Background(), c.filePathKey(filePath)).Result()
|
|
if err != nil {
|
|
if errors.Is(err, redis.Nil) {
|
|
return 0, fmt.Errorf("no active upload found for the given path")
|
|
}
|
|
return 0, fmt.Errorf("redis error: %w", err)
|
|
}
|
|
|
|
size, err := strconv.ParseInt(result, 10, 64)
|
|
if err != nil {
|
|
return 0, fmt.Errorf("invalid upload length in cache: %w", err)
|
|
}
|
|
|
|
return size, nil
|
|
}
|
|
|
|
func (c *redisUploadCache) Touch(filePath string) {
|
|
err := c.client.Expire(context.Background(), c.filePathKey(filePath), uploadCacheTTL).Err()
|
|
if err != nil {
|
|
log.Printf("failed to touch upload in redis cache: %v", err)
|
|
}
|
|
}
|
|
|
|
func (c *redisUploadCache) Close() {
|
|
c.client.Close()
|
|
}
|