返回 DeepSeek-Reasonix
main.go
1 package main
2
3 import (
4 "encoding/json"
5 "fmt"
6 "io"
7 "net/http"
8 "os"
9 "regexp"
10 "runtime"
11 "strings"
12 "time"
13 )
14
15 const manifestURL = "https://dl.reasonix.io/latest/latest.json"
16 const maxManifestBytes = 1 << 20
17
18 var stableVersion = regexp.MustCompile(`^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$`)
19 var stableManifestVersion = regexp.MustCompile(`^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$`)
20
21 func updaterUserAgent(version string) string {
22 return fmt.Sprintf("Reasonix-Updater/v%s (%s/%s; build=stable; update=stable)", version, runtime.GOOS, runtime.GOARCH)
23 }
24
25 func fetchManifest(client *http.Client, endpoint, version string) ([]byte, error) {
26 request, err := http.NewRequest(http.MethodGet, endpoint, nil)
27 if err != nil {
28 return nil, err
29 }
30 request.Header.Set("User-Agent", updaterUserAgent(version))
31 response, err := client.Do(request)
32 if err != nil {
33 return nil, err
34 }
35 defer response.Body.Close()
36 if response.StatusCode != http.StatusOK || response.Header.Get("cf-mitigated") != "" {
37 return nil, fmt.Errorf("public Stable manifest access failed: HTTP %d, cf-mitigated=%q, cf-ray=%q",
38 response.StatusCode, response.Header.Get("cf-mitigated"), response.Header.Get("cf-ray"))
39 }
40 body, err := io.ReadAll(io.LimitReader(response.Body, maxManifestBytes+1))
41 if err != nil {
42 return nil, err
43 }
44 if len(body) > maxManifestBytes {
45 return nil, fmt.Errorf("public Stable manifest exceeds %d bytes", maxManifestBytes)
46 }
47 var manifest struct {
48 Version string `json:"version"`
49 }
50 if err := json.Unmarshal(body, &manifest); err != nil {
51 return nil, fmt.Errorf("public Stable manifest is not JSON: %w", err)
52 }
53 if !stableManifestVersion.MatchString(manifest.Version) {
54 return nil, fmt.Errorf("public Stable manifest has no valid Stable version")
55 }
56 return body, nil
57 }
58
59 func main() {
60 if len(os.Args) != 3 || !stableVersion.MatchString(os.Args[1]) || strings.TrimSpace(os.Args[2]) == "" {
61 fmt.Fprintln(os.Stderr, "usage: release-manifest-fetch VERSION OUTPUT")
62 os.Exit(2)
63 }
64 client := &http.Client{Timeout: 45 * time.Second}
65 body, err := fetchManifest(client, manifestURL, os.Args[1])
66 if err != nil {
67 fmt.Fprintln(os.Stderr, err)
68 os.Exit(1)
69 }
70 if err := os.WriteFile(os.Args[2], body, 0o600); err != nil {
71 fmt.Fprintln(os.Stderr, err)
72 os.Exit(1)
73 }
74 }
75
75 lines GO