mirror of
https://github.com/darmiel/yaxc.git
synced 2025-09-06 06:25:33 +08:00
Implemented GET hash
for redis (cache is currently fucked up)
This commit is contained in:
parent
1b00d3f66a
commit
884db95a54
11 changed files with 159 additions and 58 deletions
15
cmd/serve.go
15
cmd/serve.go
|
@ -58,7 +58,8 @@ var serveCmd = &cobra.Command{
|
|||
redisAddr := viper.GetString("redis-addr")
|
||||
redisPass := viper.GetString("redis-pass")
|
||||
redisDB := viper.GetInt("redis-db")
|
||||
redisPrefix := viper.GetString("redis-prefix")
|
||||
redisPrefixVal := viper.GetString("redis-prefix-value")
|
||||
redisPrefixHsh := viper.GetString("redis-prefix-hash")
|
||||
if redisAddr == "" {
|
||||
log.Println("WARN: Not using redis")
|
||||
}
|
||||
|
@ -71,10 +72,11 @@ var serveCmd = &cobra.Command{
|
|||
s := server.NewServer(&server.YAxCConfig{
|
||||
BindAddress: bind,
|
||||
// Redis
|
||||
RedisAddress: redisAddr,
|
||||
RedisPassword: redisPass,
|
||||
RedisDatabase: redisDB,
|
||||
RedisPrefix: redisPrefix,
|
||||
RedisAddress: redisAddr,
|
||||
RedisPassword: redisPass,
|
||||
RedisDatabase: redisDB,
|
||||
RedisPrefixVal: redisPrefixVal,
|
||||
RedisPrefixHsh: redisPrefixHsh,
|
||||
// TTL
|
||||
DefaultTTL: defTTL,
|
||||
MinTTL: minTTL,
|
||||
|
@ -97,7 +99,8 @@ func init() {
|
|||
regStrP(serveCmd, "redis-addr", "r", "", "Redis Address")
|
||||
regStr(serveCmd, "redis-pass", "", "Redis Password")
|
||||
regInt(serveCmd, "redis-db", 0, "Redis Database")
|
||||
regStr(serveCmd, "redis-prefix", "yaxc::", "Redis Prefix")
|
||||
regStr(serveCmd, "redis-prefix-value", "yaxc::val::", "Redis Prefix (Value)")
|
||||
regStr(serveCmd, "redis-prefix-hash", "yaxc::hash::", "Redis Prefix (Hash)")
|
||||
|
||||
// ttl
|
||||
regDurP(serveCmd, "default-ttl", "t", 60*time.Second, "Default TTL")
|
||||
|
|
12
internal/common/hashing.go
Normal file
12
internal/common/hashing.go
Normal file
|
@ -0,0 +1,12 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func Hash(text string) string {
|
||||
data := []byte(text)
|
||||
sum := md5.Sum(data)
|
||||
return fmt.Sprintf("%x", sum)
|
||||
}
|
|
@ -7,4 +7,7 @@ import (
|
|||
type Backend interface {
|
||||
Get(key string) (string, error)
|
||||
Set(key, value string, ttl time.Duration) error
|
||||
|
||||
GetHash(key string) (string, error)
|
||||
SetHash(key, value string, ttl time.Duration) error
|
||||
}
|
||||
|
|
|
@ -6,12 +6,45 @@ import (
|
|||
)
|
||||
|
||||
type CacheBackend struct {
|
||||
c *cache.Cache
|
||||
errCast error
|
||||
cacheVal *cache.Cache
|
||||
cacheHsh *cache.Cache
|
||||
errCast error
|
||||
}
|
||||
|
||||
func (b *CacheBackend) Get(key string) (res string, err error) {
|
||||
if v, ok := b.c.Get(key); ok {
|
||||
return b.get(b.cacheVal, key)
|
||||
}
|
||||
|
||||
func (b *CacheBackend) GetHash(key string) (res string, err error) {
|
||||
return b.get(b.cacheHsh, key)
|
||||
}
|
||||
|
||||
func (b *CacheBackend) Set(key, value string, ttl time.Duration) error {
|
||||
log.Info("Updating cache cacheVal with key", key, "and ttl", ttl)
|
||||
b.cacheVal.Set(key, value, ttl)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *CacheBackend) SetHash(key, value string, ttl time.Duration) error {
|
||||
log.Info("Updating cache cacheHsh with key", key, "and ttl", ttl)
|
||||
b.cacheHsh.Set(key, value, ttl)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *CacheBackend) get(c *cache.Cache, key string) (res string, err error) {
|
||||
var cName string
|
||||
if c == b.cacheVal {
|
||||
cName = "val"
|
||||
} else if c == b.cacheHsh {
|
||||
cName = "hsh"
|
||||
} else {
|
||||
cName = "unknown"
|
||||
}
|
||||
|
||||
r1, r2, r3 := c.GetWithExpiration(key)
|
||||
log.Info("Requesting cache >", cName, "(", c, ")", "< with key", key, "with result:", r1, "=>", r2, "=>", r3)
|
||||
|
||||
if v, ok := c.Get(key); ok {
|
||||
if s, ok := v.(string); ok {
|
||||
return s, nil
|
||||
}
|
||||
|
@ -19,8 +52,3 @@ func (b *CacheBackend) Get(key string) (res string, err error) {
|
|||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (b *CacheBackend) Set(key, value string, ttl time.Duration) error {
|
||||
b.c.Set(key, value, ttl)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -7,13 +7,32 @@ import (
|
|||
)
|
||||
|
||||
type RedisBackend struct {
|
||||
ctx context.Context
|
||||
client *redis.Client
|
||||
prefix string
|
||||
ctx context.Context
|
||||
client *redis.Client
|
||||
prefixVal string
|
||||
prefixHsh string
|
||||
}
|
||||
|
||||
func (b *RedisBackend) Get(key string) (res string, err error) {
|
||||
cmd := b.client.Get(b.ctx, b.prefix+key)
|
||||
return b.get(b.prefixVal, key)
|
||||
}
|
||||
|
||||
func (b *RedisBackend) GetHash(key string) (res string, err error) {
|
||||
return b.get(b.prefixHsh, key)
|
||||
}
|
||||
|
||||
func (b *RedisBackend) Set(key, value string, ttl time.Duration) (err error) {
|
||||
return b.set(b.prefixVal, key, value, ttl)
|
||||
}
|
||||
|
||||
func (b *RedisBackend) SetHash(key, value string, ttl time.Duration) (err error) {
|
||||
return b.set(b.prefixHsh, key, value, ttl)
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
func (b *RedisBackend) get(prefix, key string) (res string, err error) {
|
||||
cmd := b.client.Get(b.ctx, prefix+key)
|
||||
if err := cmd.Err(); err != nil && err != redis.Nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -21,8 +40,8 @@ func (b *RedisBackend) Get(key string) (res string, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (b *RedisBackend) Set(key, value string, ttl time.Duration) (err error) {
|
||||
cmd := b.client.Set(b.ctx, b.prefix+key, value, ttl)
|
||||
func (b *RedisBackend) set(prefix, key, value string, ttl time.Duration) (err error) {
|
||||
cmd := b.client.Set(b.ctx, prefix+key, value, ttl)
|
||||
err = cmd.Err()
|
||||
return
|
||||
}
|
||||
|
|
|
@ -8,4 +8,11 @@ const body = `
|
|||
\/_____/ \/_/\/_/ \/_/\/_/ \/_____/
|
||||
|
||||
Just POST your contents to /:anywhere
|
||||
`
|
||||
POST /:anywhere your contents
|
||||
GET /:anywhere for your contents
|
||||
|
||||
GET /hash/:anywhere for content hash
|
||||
POST /:anywhere?ttl=3m for custom TTL
|
||||
|
||||
POST /:anywhere?secret=password to protect your contents
|
||||
GET /:anywhere?secret=password to get protected contents`
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
package server
|
48
internal/server/request_get.go
Normal file
48
internal/server/request_get.go
Normal file
|
@ -0,0 +1,48 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"github.com/darmiel/yaxc/internal/common"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func (s *yAxCServer) handleGetAnywhere(ctx *fiber.Ctx) (err error) {
|
||||
path := ctx.Params("anywhere")
|
||||
var res string
|
||||
if res, err = s.Backend.Get(path); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Encryption
|
||||
if q := ctx.Query("secret"); q != "" {
|
||||
if !s.EnableEncryption {
|
||||
return errEncryptionNotEnabled
|
||||
}
|
||||
// do not fail on error
|
||||
if encrypt, err := common.Decrypt(res, q); err == nil {
|
||||
res = string(encrypt)
|
||||
}
|
||||
}
|
||||
|
||||
// log.Debug(ctx.IP(), "requested", path)
|
||||
|
||||
if res == "" {
|
||||
ctx.Status(404)
|
||||
} else {
|
||||
ctx.Status(200)
|
||||
}
|
||||
return ctx.SendString(res)
|
||||
}
|
||||
|
||||
func (s *yAxCServer) handleGetHashAnywhere(ctx *fiber.Ctx) (err error) {
|
||||
path := ctx.Params("anywhere")
|
||||
var res string
|
||||
if res, err = s.Backend.GetHash(path); err != nil {
|
||||
return
|
||||
}
|
||||
if res == "" {
|
||||
ctx.Status(404)
|
||||
} else {
|
||||
ctx.Status(200)
|
||||
}
|
||||
return ctx.SendString(res)
|
||||
}
|
|
@ -50,35 +50,13 @@ func (s *yAxCServer) handlePostAnywhere(ctx *fiber.Ctx) (err error) {
|
|||
return ctx.Status(400).SendString("ERROR: " + err.Error())
|
||||
}
|
||||
|
||||
log.Debug(ctx.IP(), "updated", path)
|
||||
// Set hash
|
||||
hash := common.Hash(content)
|
||||
if err := s.Backend.SetHash(path, hash, 5*time.Minute); err != nil {
|
||||
return ctx.Status(400).SendString("ERROR: " + err.Error())
|
||||
}
|
||||
|
||||
log.Debug(ctx.IP(), "updated", path, "with hash", hash)
|
||||
|
||||
return ctx.Status(200).SendString(content)
|
||||
}
|
||||
|
||||
func (s *yAxCServer) handleGetAnywhere(ctx *fiber.Ctx) (err error) {
|
||||
path := ctx.Params("anywhere")
|
||||
var res string
|
||||
if res, err = s.Backend.Get(path); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Encryption
|
||||
if q := ctx.Query("secret"); q != "" {
|
||||
if !s.EnableEncryption {
|
||||
return errEncryptionNotEnabled
|
||||
}
|
||||
// do not fail on error
|
||||
if encrypt, err := common.Decrypt(res, q); err == nil {
|
||||
res = string(encrypt)
|
||||
}
|
||||
}
|
||||
|
||||
log.Debug(ctx.IP(), "requested", path)
|
||||
|
||||
if res == "" {
|
||||
ctx.Status(404)
|
||||
} else {
|
||||
ctx.Status(200)
|
||||
}
|
||||
return ctx.SendString(res)
|
||||
}
|
|
@ -39,6 +39,7 @@ func (s *yAxCServer) Start() {
|
|||
return ctx.SendString(body)
|
||||
})
|
||||
|
||||
s.App.Get("/hash/:anywhere", s.handleGetHashAnywhere)
|
||||
s.App.Get("/:anywhere", s.handleGetAnywhere)
|
||||
s.App.Post("/:anywhere", s.handlePostAnywhere)
|
||||
|
||||
|
|
|
@ -28,10 +28,11 @@ type YAxCConfig struct {
|
|||
// Address
|
||||
BindAddress string // required
|
||||
// Redis
|
||||
RedisAddress string // "" -> only use cache
|
||||
RedisPassword string
|
||||
RedisDatabase int
|
||||
RedisPrefix string
|
||||
RedisAddress string // "" -> only use cache
|
||||
RedisPassword string
|
||||
RedisDatabase int
|
||||
RedisPrefixVal string
|
||||
RedisPrefixHsh string
|
||||
// Timeout
|
||||
DefaultTTL time.Duration // 0 -> infinite
|
||||
MinTTL time.Duration // == MaxTTL -> cannot specify TTL
|
||||
|
@ -59,8 +60,9 @@ func NewServer(cfg *YAxCConfig) (s *yAxCServer) {
|
|||
if s.RedisAddress == "" {
|
||||
// use cache backend
|
||||
s.Backend = &CacheBackend{
|
||||
c: cache.New(s.DefaultTTL, s.DefaultTTL+time.Minute),
|
||||
errCast: errors.New("not a string"),
|
||||
cacheVal: cache.New(s.DefaultTTL, s.DefaultTTL+time.Minute),
|
||||
cacheHsh: cache.New(s.DefaultTTL, s.DefaultTTL+time.Minute),
|
||||
errCast: errors.New("not a string"),
|
||||
}
|
||||
} else {
|
||||
rb := &RedisBackend{
|
||||
|
@ -70,7 +72,8 @@ func NewServer(cfg *YAxCConfig) (s *yAxCServer) {
|
|||
Password: s.RedisPassword,
|
||||
DB: s.RedisDatabase,
|
||||
}),
|
||||
prefix: s.RedisPrefix,
|
||||
prefixVal: s.RedisPrefixVal,
|
||||
prefixHsh: s.RedisPrefixHsh,
|
||||
}
|
||||
s.Backend = rb
|
||||
// ping test
|
||||
|
|
Loading…
Add table
Reference in a new issue