107 lines
3 KiB
Go
107 lines
3 KiB
Go
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)
|
|
}
|
|
}
|