package gocommon import ( "crypto/md5" "encoding/hex" "encoding/json" "fmt" "io" "net/http" "net/url" "os" "strings" "time" "repositories.action2quare.com/ayo/gocommon/flagx" ) var configfileflag = flagx.String("config", "", "") func configFilePath() string { configfilepath := "config.json" if configfileflag != nil && len(*configfileflag) > 0 { configfilepath = *configfileflag } // if !strings.HasPrefix(configfilepath, "/") { // exe, _ := os.Executable() // configfilepath = path.Join(path.Dir(exe), configfilepath) // } return configfilepath } func ConfigModTime() time.Time { fi, err := os.Stat(configFilePath()) if err == nil { return fi.ModTime() } return time.Time{} } func MonitorConfig[T any](onChanged func(newconf *T)) error { fi, err := os.Stat(configFilePath()) if err != nil { return err } go func(modTime time.Time, filepath string) { for { if fi, err := os.Stat(filepath); err == nil { if modTime != fi.ModTime() { var next T if err := LoadConfig(&next); err == nil { fi, _ := os.Stat(filepath) modTime = fi.ModTime() onChanged(&next) } } } time.Sleep(time.Second) } }(fi.ModTime(), configFilePath()) return nil } var configContents []byte func splitURL(inputURL string) (string, string, error) { parsedURL, err := url.Parse(inputURL) if err != nil { return "", "", err } base := fmt.Sprintf("%s://%s", parsedURL.Scheme, parsedURL.Host) path := parsedURL.Path return base, path, nil } func LoadConfig[T any](outptr *T) error { configfilepath := configFilePath() if len(configContents) == 0 { if strings.HasPrefix(configfilepath, "http") { // 여기서 다운받음 _, subpath, err := splitURL(configfilepath) if err != nil { return err } h := md5.New() h.Write([]byte(subpath)) at := hex.EncodeToString(h.Sum(nil)) req, _ := http.NewRequest("GET", configfilepath, nil) req.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51") req.Header.Add("As-X-UrlHash", at) resp, err := http.DefaultClient.Do(req) if err != nil { return err } defer resp.Body.Close() configContents, err = io.ReadAll(resp.Body) if err != nil { return err } } else { content, _ := os.ReadFile(configfilepath) if len(content) == 0 { content = []byte("{}") } configContents = content } } return json.Unmarshal([]byte(os.Expand(string(configContents), func(in string) string { envval := os.Getenv(in) if len(envval) == 0 { return "$" + in } return envval })), outptr) } type StorageAddr struct { Mongo string Redis map[string]string } type RegionStorageConfig struct { RegionStorage map[string]StorageAddr `json:"region_storage"` }