package main import ( "archive/zip" "context" "flag" "fmt" "io" "net/http" "net/url" "os" "path/filepath" "strings" "time" ) func downloadToken(path string) (string, error) { contents, err := os.ReadFile(path) if err != nil { return "", fmt.Errorf("read IP2Location credential") } token := strings.TrimSpace(string(contents)) if token == "" { return "", fmt.Errorf("IP2Location credential is empty") } return token, nil } func fetch(ctx context.Context, client *http.Client, token, code, output string) error { query := url.Values{"token": {token}, "file": {code}} request, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://www.ip2location.com/download?"+query.Encode(), nil) if err != nil { return fmt.Errorf("create IP2Proxy request") } request.Header.Set("User-Agent", "oci-l4-relay-admission-publisher/1") response, err := client.Do(request) if err != nil { return fmt.Errorf("download IP2Proxy package") } defer func() { _ = response.Body.Close() }() if response.StatusCode != http.StatusOK { return fmt.Errorf("download IP2Proxy package: HTTP %d", response.StatusCode) } if err := os.MkdirAll(filepath.Dir(output), 0o700); err != nil { return err } temporary, err := os.CreateTemp(filepath.Dir(output), ".ip2proxy-*") if err != nil { return err } temporaryPath := temporary.Name() defer func() { _ = os.Remove(temporaryPath) }() if err := temporary.Chmod(0o600); err != nil { _ = temporary.Close() return err } written, copyErr := io.Copy(temporary, io.LimitReader(response.Body, (512<<20)+1)) closeErr := temporary.Close() if copyErr != nil { return copyErr } if closeErr != nil { return closeErr } if written > 512<<20 { return fmt.Errorf("IP2Proxy package exceeds size limit") } archive, err := zip.OpenReader(temporaryPath) if err != nil { return fmt.Errorf("validate IP2Proxy archive") } defer func() { _ = archive.Close() }() found := false for _, file := range archive.File { if strings.HasSuffix(file.Name, "IP2PROXY-LITE-PX12.CSV") { found = true break } } if !found { return fmt.Errorf("IP2Proxy PX12 archive member is missing") } if err := os.Rename(temporaryPath, output); err != nil { return err } fmt.Printf("source=ip2proxy bytes=%d\n", written) return nil } func main() { downloadTokenFile := flag.String("download-token-file", "/credentials/ip2location/download-token", "IP2Location download-token file") packageCode := flag.String("package-code", "PX12LITE", "entitled IP2Proxy package code") dataDirectory := flag.String("data-directory", "/work/data", "validated source cache") flag.Parse() token, err := downloadToken(*downloadTokenFile) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute) defer cancel() client := &http.Client{Timeout: 15 * time.Minute} if err := fetch(ctx, client, token, *packageCode, filepath.Join(*dataDirectory, "ip2proxy.zip")); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } }