Initial 423down proxy service
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/dgraph-io/badger/v4"
|
||||
)
|
||||
|
||||
const cookieDBKey = "cookie:423down"
|
||||
|
||||
var errCookieNotFound = errors.New("cookie not found")
|
||||
|
||||
type DB struct {
|
||||
client *badger.DB
|
||||
}
|
||||
|
||||
func NewDB(path string) (*DB, error) {
|
||||
db, err := badger.Open(badger.DefaultOptions(path))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &DB{
|
||||
client: db,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *DB) GetArticleHtml(articleID string) (string, error) {
|
||||
var valueCopy []byte
|
||||
err := d.client.View(func(txn *badger.Txn) error {
|
||||
item, err := txn.Get([]byte("article:" + articleID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return item.Value(func(val []byte) error {
|
||||
valueCopy = append(valueCopy, val...)
|
||||
return nil
|
||||
})
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(valueCopy), nil
|
||||
}
|
||||
|
||||
func (d *DB) SetArticleHtml(articleID string, html string, ttl time.Duration) error {
|
||||
if ttl <= 0 {
|
||||
return errors.New("ttl 必须大于 0")
|
||||
}
|
||||
return d.client.Update(func(txn *badger.Txn) error {
|
||||
entry := badger.NewEntry([]byte("article:"+articleID), []byte(html)).WithTTL(ttl)
|
||||
return txn.SetEntry(entry)
|
||||
})
|
||||
}
|
||||
|
||||
// GetCookie 读取缓存中的登录 Cookie。
|
||||
func (d *DB) GetCookie() ([]*http.Cookie, error) {
|
||||
var valueCopy []byte
|
||||
err := d.client.View(func(txn *badger.Txn) error {
|
||||
item, err := txn.Get([]byte(cookieDBKey))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return item.Value(func(val []byte) error {
|
||||
valueCopy = append(valueCopy, val...)
|
||||
return nil
|
||||
})
|
||||
})
|
||||
if errors.Is(err, badger.ErrKeyNotFound) {
|
||||
return nil, errCookieNotFound
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var cookies []*http.Cookie
|
||||
if err := json.Unmarshal(valueCopy, &cookies); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(cookies) == 0 {
|
||||
return nil, errCookieNotFound
|
||||
}
|
||||
|
||||
return cookies, nil
|
||||
}
|
||||
|
||||
// SetCookie 保存登录 Cookie,有效期固定为 7 天。
|
||||
func (d *DB) SetCookie(cookies []*http.Cookie) error {
|
||||
if len(cookies) == 0 {
|
||||
return errors.New("cookies 不能为空")
|
||||
}
|
||||
|
||||
data, err := json.Marshal(cookies)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return d.client.Update(func(txn *badger.Txn) error {
|
||||
entry := badger.NewEntry([]byte(cookieDBKey), data).WithTTL(cookieCacheTTL)
|
||||
return txn.SetEntry(entry)
|
||||
})
|
||||
}
|
||||
|
||||
// AddCookie 增加或更新单个登录 Cookie,并刷新 7 天有效期。
|
||||
func (d *DB) AddCookie(cookie *http.Cookie) error {
|
||||
if cookie == nil {
|
||||
return errors.New("cookie 不能为空")
|
||||
}
|
||||
|
||||
cookies, err := d.GetCookie()
|
||||
if err != nil && !errors.Is(err, errCookieNotFound) {
|
||||
return err
|
||||
}
|
||||
|
||||
replaced := false
|
||||
for i, existingCookie := range cookies {
|
||||
if existingCookie.Name == cookie.Name {
|
||||
cookies[i] = cookie
|
||||
replaced = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !replaced {
|
||||
cookies = append(cookies, cookie)
|
||||
}
|
||||
|
||||
return d.SetCookie(cookies)
|
||||
}
|
||||
|
||||
func (d *DB) Close() error {
|
||||
return d.client.Close()
|
||||
}
|
||||
Reference in New Issue
Block a user