返回 DeepSeek-Reasonix
session_path.go
根目录 / internal / serve / session_path.go
1 package serve
2
3 import (
4 "errors"
5 "os"
6 "path/filepath"
7 "strings"
8
9 "reasonix/internal/agent"
10 "reasonix/internal/pathidentity"
11 "reasonix/internal/store"
12 )
13
14 // resolveSessionPath validates a client-supplied transcript against the
15 // configured session directory and returns its symlink-resolved access path.
16 func (s *Server) resolveSessionPath(raw string) (string, error) {
17 dir := s.ctl().SessionDir()
18 if dir == "" {
19 return "", errors.New("sessions disabled")
20 }
21 absDir, err := filepath.Abs(dir)
22 if err != nil {
23 return "", errors.New("invalid session dir")
24 }
25 dirIdentity, err := pathidentity.Resolve(absDir, pathidentity.Options{FollowLeaf: true})
26 if err != nil {
27 return "", errors.New("invalid session dir")
28 }
29 absPath, err := filepath.Abs(strings.TrimSpace(raw))
30 if err != nil || !store.IsSessionTranscriptName(filepath.Base(absPath)) {
31 return "", errors.New("invalid session path")
32 }
33 pathIdentity, err := pathidentity.Resolve(absPath, pathidentity.Options{FollowLeaf: true})
34 if err != nil {
35 return "", errors.New("invalid session path")
36 }
37 rel, err := filepath.Rel(dirIdentity.Key, pathIdentity.Key)
38 if err != nil || rel == "." || rel == ".." || strings.HasPrefix(rel, ".."+string(os.PathSeparator)) {
39 return "", errors.New("path outside session dir")
40 }
41 realPath := pathIdentity.PhysicalPath
42 if agent.IsCleanupPending(realPath) {
43 return "", errors.New("session is pending cleanup")
44 }
45 return realPath, nil
46 }
47
47 lines GO