2021-03-24 23:33:28 +08:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"errors"
|
|
|
|
"github.com/go-redis/redis/v8"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
|
|
"github.com/op/go-logging"
|
|
|
|
"github.com/patrickmn/go-cache"
|
|
|
|
"os"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
log = logging.MustGetLogger("example")
|
|
|
|
format = logging.MustStringFormatter(
|
|
|
|
`%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}`,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
backend1 := logging.NewLogBackend(os.Stderr, "", 0)
|
|
|
|
backend2Formatter := logging.NewBackendFormatter(backend1, format)
|
|
|
|
logging.SetBackend(backend2Formatter)
|
|
|
|
}
|
|
|
|
|
|
|
|
type YAxCConfig struct {
|
|
|
|
// Address
|
|
|
|
BindAddress string // required
|
|
|
|
// Redis
|
2021-03-26 17:59:53 +08:00
|
|
|
RedisAddress string // "" -> only use cache
|
|
|
|
RedisPassword string
|
|
|
|
RedisDatabase int
|
|
|
|
RedisPrefixVal string
|
|
|
|
RedisPrefixHsh string
|
2021-03-24 23:33:28 +08:00
|
|
|
// Timeout
|
|
|
|
DefaultTTL time.Duration // 0 -> infinite
|
|
|
|
MinTTL time.Duration // == MaxTTL -> cannot specify TTL
|
|
|
|
MaxTTL time.Duration // == MinTTL -> cannot specify TTL
|
|
|
|
// Other
|
2021-03-25 21:25:51 +08:00
|
|
|
MaxBodyLength int
|
|
|
|
EnableEncryption bool
|
2021-03-25 21:36:25 +08:00
|
|
|
ProxyHeader string
|
2021-03-24 23:33:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
type yAxCServer struct {
|
|
|
|
*YAxCConfig
|
|
|
|
App *fiber.App
|
|
|
|
Backend Backend
|
|
|
|
errBodyLen error
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewServer(cfg *YAxCConfig) (s *yAxCServer) {
|
|
|
|
s = &yAxCServer{
|
|
|
|
YAxCConfig: cfg,
|
|
|
|
errBodyLen: errors.New("exceeded max body length"),
|
|
|
|
}
|
|
|
|
|
|
|
|
// backend
|
|
|
|
if s.RedisAddress == "" {
|
|
|
|
// use cache backend
|
|
|
|
s.Backend = &CacheBackend{
|
2021-03-26 17:59:53 +08:00
|
|
|
cacheVal: cache.New(s.DefaultTTL, s.DefaultTTL+time.Minute),
|
|
|
|
cacheHsh: cache.New(s.DefaultTTL, s.DefaultTTL+time.Minute),
|
|
|
|
errCast: errors.New("not a string"),
|
2021-03-24 23:33:28 +08:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
rb := &RedisBackend{
|
|
|
|
ctx: context.TODO(),
|
|
|
|
client: redis.NewClient(&redis.Options{
|
|
|
|
Addr: s.RedisAddress,
|
|
|
|
Password: s.RedisPassword,
|
|
|
|
DB: s.RedisDatabase,
|
|
|
|
}),
|
2021-03-26 17:59:53 +08:00
|
|
|
prefixVal: s.RedisPrefixVal,
|
|
|
|
prefixHsh: s.RedisPrefixHsh,
|
2021-03-24 23:33:28 +08:00
|
|
|
}
|
|
|
|
s.Backend = rb
|
|
|
|
// ping test
|
|
|
|
if cmd := rb.client.Ping(rb.ctx); cmd == nil || cmd.Err() != nil {
|
|
|
|
log.Critical("Connection to redis failed:")
|
|
|
|
log.Critical(cmd.Err())
|
|
|
|
os.Exit(1)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if s.Backend == nil {
|
|
|
|
log.Critical("ERROR: No backend specified.")
|
|
|
|
os.Exit(1)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-03-25 21:25:51 +08:00
|
|
|
log.Info("Encryption:", s.EnableEncryption)
|
|
|
|
|
2021-03-24 23:33:28 +08:00
|
|
|
return
|
|
|
|
}
|