feat: harden workspace file APIs

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
tao.chen
2026-07-02 17:22:26 +08:00
co-authored by Claude Fable 5
parent c1b8982e3b
commit 04b309d3fc
18 changed files with 1262 additions and 76 deletions
+14 -4
View File
@@ -2,17 +2,23 @@ package service
import (
"codespace/internal/fs"
"codespace/internal/util"
"codespace/internal/workspace"
)
// FileService handles file operations within workspaces.
type FileService struct {
workspaces workspace.Manager
workspaces workspace.Manager
maxWriteBytes int64
}
// NewFileService creates a FileService.
func NewFileService(workspaces workspace.Manager) *FileService {
return &FileService{workspaces: workspaces}
// NewFileService creates a FileService with a per-write byte limit.
// If maxWriteBytes is zero or negative, a 1 MiB default is applied.
func NewFileService(workspaces workspace.Manager, maxWriteBytes int64) *FileService {
if maxWriteBytes <= 0 {
maxWriteBytes = 1 << 20
}
return &FileService{workspaces: workspaces, maxWriteBytes: maxWriteBytes}
}
// List lists files at the given workspace-relative path.
@@ -34,7 +40,11 @@ func (s *FileService) Read(workspaceID, path string) ([]byte, error) {
}
// Write writes data to a file at the given workspace-relative path.
// Writes exceeding maxWriteBytes are rejected before touching the filesystem.
func (s *FileService) Write(workspaceID, path string, data []byte) error {
if int64(len(data)) > s.maxWriteBytes {
return util.New(util.CodeBadRequest, "file exceeds max write size")
}
ws, err := s.workspaces.Get(workspaceID)
if err != nil {
return err
+5
View File
@@ -38,6 +38,11 @@ func (s *WorkspaceService) Get(id string) (*workspace.Workspace, error) {
return s.workspaces.Get(id)
}
// List returns all workspaces sorted by ID.
func (s *WorkspaceService) List() ([]workspace.Workspace, error) {
return s.workspaces.List()
}
// Delete stops any running process for the workspace, then removes it.
func (s *WorkspaceService) Delete(id string) error {
status := s.processes.Status(id)