返回 DeepSeek-Reasonix
serve_files.go
根目录 / internal / cli / serve_files.go
1 package cli
2
3 import (
4 "fmt"
5 "io"
6 "os"
7 "runtime"
8 "strconv"
9 "strings"
10
11 "reasonix/internal/fileutil"
12 )
13
14 // readServeTokenFile loads the auth=token pre-shared token from a file so the
15 // secret never appears in argv (visible via ps). The file must hold a single
16 // non-empty line and, on POSIX systems, must not be group/world accessible.
17 func readServeTokenFile(path string) (string, error) {
18 f, err := os.Open(path)
19 if err != nil {
20 return "", err
21 }
22 defer f.Close()
23 fi, err := f.Stat()
24 if err != nil {
25 return "", err
26 }
27 if !fi.Mode().IsRegular() {
28 return "", fmt.Errorf("token file %s must be a regular file", path)
29 }
30 if runtime.GOOS != "windows" && fi.Mode().Perm()&0o077 != 0 {
31 return "", fmt.Errorf("token file %s must not be group/world accessible (chmod 600)", path)
32 }
33 b, err := io.ReadAll(io.LimitReader(f, (64<<10)+1))
34 if err != nil {
35 return "", err
36 }
37 if len(b) > 64<<10 {
38 return "", fmt.Errorf("token file %s is too large", path)
39 }
40 tok := strings.TrimSpace(string(b))
41 if tok == "" {
42 return "", fmt.Errorf("token file %s is empty", path)
43 }
44 if strings.ContainsAny(tok, "\r\n") {
45 return "", fmt.Errorf("token file %s must hold a single line", path)
46 }
47 return tok, nil
48 }
49
50 // writeServeAddrFile records the actual bound listen address (host:port) so a
51 // supervisor that started serve with --addr 127.0.0.1:0 can discover the real
52 // port. Written atomically with owner-only permissions.
53 func writeServeAddrFile(path, addr string) error {
54 return fileutil.AtomicWriteFile(path, []byte(addr+"\n"), 0o600)
55 }
56
57 // writeServePidFile records the server's pid for supervisors that cannot
58 // capture the shell's $! (or want a belt-and-braces check).
59 func writeServePidFile(path string) error {
60 return fileutil.AtomicWriteFile(path, []byte(strconv.Itoa(os.Getpid())+"\n"), 0o600)
61 }
62
62 lines GO