pages-server/pages/cname.go
2024-09-14 11:53:32 +08:00

98 lines
2.1 KiB
Go

package pages
import (
"encoding/json"
"fmt"
cmap "github.com/orcaman/concurrent-map/v2"
"os"
"strings"
"sync"
)
var shared = cmap.New[PageDomain]()
type CustomDomains struct {
/// 映射关系
Alias *cmap.ConcurrentMap[string, PageDomain] `json:"alias,omitempty"`
/// 反向链接
Reverse *cmap.ConcurrentMap[string, string] `json:"reverse,omitempty"`
/// 写锁
Mutex sync.Mutex `json:"-"`
/// 文件落盘
Local string `json:"-"`
// 是否全局共享
Share bool `json:"-"`
}
func (d *CustomDomains) Get(host string) (PageDomain, bool) {
get, b := d.Alias.Get(strings.ToLower(host))
if !b && d.Share {
return shared.Get(strings.ToLower(host))
}
return get, b
}
func (d *CustomDomains) add(domain *PageDomain, aliases ...string) {
d.Mutex.Lock()
defer d.Mutex.Unlock()
for _, alias := range aliases {
key := strings.ToLower(domain.Key())
alias = strings.ToLower(alias)
old, b := d.Reverse.Get(key)
if b {
// 移除旧的映射关系
if d.Share {
shared.Remove(old)
}
d.Alias.Remove(old)
d.Reverse.Remove(key)
}
if d.Share {
shared.Set(alias, *domain)
}
d.Alias.Set(alias, *domain)
d.Reverse.Set(key, alias)
}
if d.Local != "" {
marshal, err := json.Marshal(d)
err = os.WriteFile(d.Local, marshal, 0644)
if err != nil {
fmt.Printf("%v\n", err)
}
}
}
func NewCustomDomains(local string, share bool) (*CustomDomains, error) {
if share {
fmt.Printf("Global Alias Enabled.\n")
}
stat, err := os.Stat(local)
alias := cmap.New[PageDomain]()
reverse := cmap.New[string]()
result := &CustomDomains{
Alias: &alias,
Reverse: &reverse,
Mutex: sync.Mutex{},
Local: local,
Share: share,
}
fmt.Printf("Discover alias file :%s.\n", local)
if local != "" && err == nil && !stat.IsDir() {
bytes, err := os.ReadFile(local)
if err != nil {
return nil, err
}
err = json.Unmarshal(bytes, result)
fmt.Printf("Found %d Alias records.\n", result.Alias.Count())
if err != nil {
return nil, err
}
if share {
for k, v := range result.Alias.Items() {
shared.Set(k, v)
}
}
}
return result, nil
}