1
0
mirror of https://github.com/zu1k/nali.git synced 2025-01-22 21:29:02 +08:00
nali/pkg/cdn/cdn.go

124 lines
2.4 KiB
Go
Raw Normal View History

2020-07-18 14:18:54 +08:00
package cdn
import (
2021-08-02 12:01:25 +08:00
"errors"
"fmt"
2020-07-18 14:18:54 +08:00
"io/ioutil"
"log"
"os"
"regexp"
2021-08-02 12:01:25 +08:00
"strings"
"github.com/zu1k/nali/pkg/download"
"github.com/zu1k/nali/pkg/re"
"gopkg.in/yaml.v2"
2020-07-18 14:18:54 +08:00
)
var DownloadUrls = []string{
"https://cdn.jsdelivr.net/gh/4ft35t/cdn/src/cdn.yml",
"https://raw.githubusercontent.com/4ft35t/cdn/master/src/cdn.yml",
"https://raw.githubusercontent.com/SukkaLab/cdn/master/src/cdn.yml",
}
2020-07-18 14:18:54 +08:00
type CDN struct {
Map map[string]CDNResult
ReMap []CDNReTuple
2020-07-18 14:18:54 +08:00
}
type CDNReTuple struct {
*regexp.Regexp
CDNResult
}
2020-07-18 14:18:54 +08:00
type CDNResult struct {
2023-05-20 17:14:03 +08:00
Name string `yaml:"name" json:"name"`
Link string `yaml:"link" json:"link"`
2020-07-18 14:18:54 +08:00
}
2021-08-02 12:01:25 +08:00
func (r CDNResult) String() string {
return r.Name
}
func NewCDN(filePath string) (*CDN, error) {
2023-08-24 11:10:52 +08:00
var fileData []byte
2020-07-18 14:18:54 +08:00
_, err := os.Stat(filePath)
if err != nil && os.IsNotExist(err) {
log.Println("文件不存在尝试从网络获取最新CDN数据库")
fileData, err = download.Download(filePath, DownloadUrls...)
2020-07-18 14:18:54 +08:00
if err != nil {
return nil, err
2020-07-18 14:18:54 +08:00
}
} else {
cdnFile, err := os.OpenFile(filePath, os.O_RDONLY, 0400)
if err != nil {
return nil, err
2020-07-18 14:18:54 +08:00
}
defer cdnFile.Close()
fileData, err = ioutil.ReadAll(cdnFile)
2020-07-18 14:18:54 +08:00
if err != nil {
return nil, err
2020-07-18 14:18:54 +08:00
}
}
cdnMap := make(map[string]CDNResult)
err = yaml.Unmarshal(fileData, &cdnMap)
2020-07-18 14:18:54 +08:00
if err != nil {
return nil, err
2020-07-18 14:18:54 +08:00
}
cdnReMap := make([]CDNReTuple, 0)
for k, v := range cdnMap {
if re.MaybeRegexp(k) {
rex, err := regexp.Compile(k)
if err != nil {
log.Printf("[CDN Database] entry %s not a valid regexp", k)
}
cdnReMap = append(cdnReMap, CDNReTuple{
Regexp: rex,
CDNResult: v,
})
}
}
return &CDN{Map: cdnMap, ReMap: cdnReMap}, nil
2021-08-02 12:01:25 +08:00
}
func (db CDN) Find(query string, params ...string) (result fmt.Stringer, err error) {
baseCname := parseBaseCname(query)
for _, domain := range baseCname {
if domain != "" {
cdnResult, found := db.Map[domain]
if found {
return cdnResult, nil
}
}
2021-08-02 12:01:25 +08:00
for _, entry := range db.ReMap {
if entry.Regexp.MatchString(domain) {
return entry.CDNResult, nil
}
}
2021-08-02 12:01:25 +08:00
}
2021-08-02 12:01:25 +08:00
return nil, errors.New("not found")
}
func (db CDN) Name() string {
return "cdn"
}
func parseBaseCname(domain string) (result []string) {
parts := strings.Split(domain, ".")
size := len(parts)
if size == 0 {
return []string{}
}
domain = parts[size-1]
result = append(result, domain)
for i := len(parts) - 2; i >= 0; i-- {
domain = parts[i] + "." + domain
result = append(result, domain)
2021-08-02 12:01:25 +08:00
}
return result
2020-07-18 14:18:54 +08:00
}