diff --git a/next/assets/assets.go b/next/assets/assets.go index 0d48269..04e855c 100644 --- a/next/assets/assets.go +++ b/next/assets/assets.go @@ -1,29 +1,75 @@ package assets +import ( + "XProxy/next/logger" + urlpkg "net/url" + "strings" + "sync" +) + var buildinAssets = map[string]string{ - "geoip.dat": "geoip.dat.xz", - "geosite.dat": "geosite.dat.xz", + "geoip.dat": "/geoip.dat.xz", + "geosite.dat": "/geosite.dat.xz", +} + +type UpdateSettings struct { + cron string + mutex sync.Mutex + proxy *urlpkg.URL + assets map[string]string } -func Demo() { +var update UpdateSettings - remoteAssets := map[string]string{ - "geoip.dat": "https://cdn.dnomd343.top/v2ray-rules-dat/geoip.dat.xz", - "geosite.dat": "https://cdn.dnomd343.top/v2ray-rules-dat/geosite.dat.xz", +func assetsClone(raw map[string]string) map[string]string { + assets := make(map[string]string, len(raw)) + for file, url := range raw { + assets[file] = strings.Clone(url) } + return assets +} - //updateLocalAssets(buildinAssets, true) - //updateLocalAssets(buildinAssets, false) +func SetCron(cron string) error { + // TODO: setting up crond service + return nil +} - updateRemoteAssets(remoteAssets, "", true) - //updateRemoteAssets(remoteAssets, "", false) - //updateRemoteAssets(remoteAssets, "socks5://192.168.2.2:1084", true) - //updateRemoteAssets(remoteAssets, "socks5://192.168.2.2:1084", false) +func GetProxy() string { + update.mutex.Lock() + proxy := update.proxy.String() + update.mutex.Unlock() + return proxy +} - //time.Sleep(10 * time.Second) +func SetProxy(proxy string) error { + var proxyUrl *urlpkg.URL // clear proxy by empty string + if proxy != "" { + url, err := urlpkg.Parse(proxy) + if err != nil { + logger.Errorf("Invalid proxy url `%s` -> %v", proxy, err) + return err + } + proxyUrl = url + } + update.mutex.Lock() + update.proxy = proxyUrl + update.mutex.Unlock() + return nil +} - //updateRemoteAsset("geosite.dat", "http://cdn.dnomd343.top/v2ray-rules-dat/geosite.dat.xz", "") - //updateRemoteAsset("geosite.dat", "http://cdn.dnomd343.top/v2ray-rules-dat/geosite.dat.xz", "socks5://192.168.2.2:1084") - //updateLocalAsset("geosite.dat", "geosite.dat.xz") +func SetAssets(assets map[string]string) { + update.mutex.Lock() + update.assets = assetsClone(assets) + update.mutex.Unlock() +} + +func GetAssets() map[string]string { + update.mutex.Lock() + assets := assetsClone(update.assets) + update.mutex.Unlock() + return assets +} +func LoadBuildin() { + updateLocalAssets(buildinAssets, true) } diff --git a/next/assets/remote.go b/next/assets/remote.go index 855a021..e648621 100644 --- a/next/assets/remote.go +++ b/next/assets/remote.go @@ -11,7 +11,7 @@ import ( "github.com/klauspost/compress/gzip" "io" "net/http" - "net/url" + urlpkg "net/url" "time" ) @@ -69,25 +69,21 @@ func nonDecode(stream io.Reader) ([]byte, error) { } // createClient build http client based on http or socks proxy url. -func createClient(remoteUrl string, proxyUrl string) (http.Client, error) { - if proxyUrl == "" { - logger.Infof("Downloading `%s` without proxy", remoteUrl) +func createClient(remote string, proxy *urlpkg.URL) http.Client { + timeout := DownloadTimeout * time.Second + if proxy == nil { + logger.Infof("Downloading `%s` without proxy", remote) return http.Client{ - Timeout: DownloadTimeout * time.Second, - }, nil - } - logger.Infof("Downloading `%s` via `%s`", remoteUrl, proxyUrl) - proxy, err := url.Parse(proxyUrl) - if err != nil { - logger.Errorf("Invalid proxy url `%s` -> %v", proxyUrl, err) - return http.Client{}, err + Timeout: timeout, + } } + logger.Infof("Downloading `%s` via `%s`", remote, proxy) return http.Client{ Transport: &http.Transport{ Proxy: http.ProxyURL(proxy), }, - Timeout: DownloadTimeout * time.Second, - }, nil + Timeout: timeout, + } } // doRequest initiates http request and allows retries. @@ -130,12 +126,7 @@ func assetDate(resp *http.Response) *time.Time { // downloadAsset obtains resource file from the remote server, gets its // modification time, and supports proxy acquisition. -func downloadAsset(url string, proxy string) ([]byte, *time.Time, error) { - client, err := createClient(url, proxy) - if err != nil { - return nil, nil, err - } - +func downloadAsset(url string, proxy *urlpkg.URL) ([]byte, *time.Time, error) { req, err := http.NewRequest("GET", url, nil) if err != nil { logger.Errorf("Failed to create http request -> %v", err) @@ -143,7 +134,7 @@ func downloadAsset(url string, proxy string) ([]byte, *time.Time, error) { } req.Header.Set(headers.AcceptEncoding, "gzip, deflate, br") - resp, err := doRequest(client, req) + resp, err := doRequest(createClient(url, proxy), req) if err != nil { return nil, nil, err } diff --git a/next/assets/update.go b/next/assets/update.go index f8dc4c3..ddec46f 100644 --- a/next/assets/update.go +++ b/next/assets/update.go @@ -2,6 +2,7 @@ package assets import ( "XProxy/next/logger" + urlpkg "net/url" "os" "sync" "time" @@ -36,7 +37,7 @@ func saveAsset(file string, content []byte, date *time.Time) error { // updateRemoteAsset will download remote asset via the optional proxy and // save them locally. Local files will be overwritten if they exist. -func updateRemoteAsset(file string, url string, proxy string) error { +func updateRemoteAsset(file string, url string, proxy *urlpkg.URL) error { logger.Debugf("Start downloading remote asset `%s` to `%s`", url, file) asset, date, err := downloadAsset(url, proxy) if err != nil { @@ -104,7 +105,7 @@ func updateMultiple(updates []func(), parallel bool) { } // updateRemoteAssets will update multiple remote assets in batches. -func updateRemoteAssets(assets map[string]string, proxy string, parallel bool) { +func updateRemoteAssets(assets map[string]string, proxy *urlpkg.URL, parallel bool) { var tasks []func() for file, url := range assets { file_, url_ := file, url diff --git a/next/main.go b/next/main.go index bb618ee..b9d01c3 100644 --- a/next/main.go +++ b/next/main.go @@ -3,5 +3,16 @@ package main import "XProxy/next/assets" func main() { - assets.Demo() + + assets.LoadBuildin() + + //remoteAssets := map[string]string{ + // "geoip.dat": "https://cdn.dnomd343.top/v2ray-rules-dat/geoip.dat.xz", + // "geosite.dat": "https://cdn.dnomd343.top/v2ray-rules-dat/geosite.dat.xz", + //} + //assets.Update(false) + //assets.SetUpdateConfig(assets.UpdateSettings{ + // cron: "", + // ass + //}) }