Skip to content

Conversation

@rgarcia
Copy link
Contributor

@rgarcia rgarcia commented Jan 16, 2026

Summary

  • New zstd directory transfer endpoints - 2.45x faster than zip with better compression
  • Chromium restart optimization - 19x faster (8 seconds → 0.4 seconds)
  • Benchmark tests for both improvements with documented results

Zstd Endpoints

Added new DownloadDirZstd and UploadZstd endpoints using tar+zstd compression:

Method Total Time Archive Size vs Zip
Zip 216ms 1491 KB (23%) baseline
Zstd (fastest) 88ms 1148 KB (18%) 2.45x faster
Zstd (default) 89ms 1133 KB (18%) 2.43x faster

Uses klauspost/compress library. Supports compression levels: fastest, default, better, best.

Chromium Restart Optimization

Updated supervisor config for chromium:

-startsecs=5
+startsecs=0
+stopsignal=KILL
+stopwaitsecs=0
Phase Before After Improvement
Stop 2166ms 156ms 92.8% faster
Start 5814ms 157ms 97.3% faster
Total 8090ms 423ms 19x faster

The startsecs=5 delay was unnecessary because the API server's UpstreamManager already detects readiness by watching for "DevTools listening on..." in the log output.

Test plan

  • Ran TestZipVsZstdComparison - verified zstd is 2.45x faster
  • Ran TestChromiumRestartTiming - verified 19x speedup
  • Manual testing of new zstd endpoints
# Run all new benchmarks
go test -v -run TestZipVsZstdComparison ./e2e/...
go test -v -run TestChromiumRestartTiming ./e2e/...

🤖 Generated with Claude Code


Note

Introduces fast tar.zst-based directory transfer and significantly speeds up Chromium restarts.

  • API: tar.zst transfer – Adds streaming DownloadDirZstd and UploadZstd endpoints with selectable compression levels (fastest|default|better|best); updates openapi.yaml and regenerates oapi client/server; new zstdutil (tar+zstd stream/untar via klauspost/compress).
  • Chromium restart perf – Supervisor tweaks (startsecs=0, stopsignal=KILL, stopwaitsecs=0) and launcher improvements (cleanup Singleton*, wait-for-port without SO_REUSEADDR) to minimize stop/start latency.
  • Tests/benchmarks – New e2e timing tests for zip vs zstd transfers and Chromium restart; go.mod adds klauspost/compress.

Written by Cursor Bugbot for commit 2316b9e. This will update automatically on new commits. Configure here.

…tart

This PR adds two major improvements:

1. New zstd directory transfer endpoints (2.45x faster than zip):
   - GET /fs/download_dir_zstd - Download directory as tar.zst archive
   - POST /fs/upload_zstd - Upload and extract tar.zst archive
   - Supports compression levels: fastest, default, better, best
   - Uses klauspost/compress library for high-performance compression

2. Chromium restart optimization (19x faster):
   - Changed startsecs=5 to startsecs=0 (API server already detects readiness)
   - Added stopsignal=KILL for immediate termination
   - Added stopwaitsecs=0 to eliminate shutdown grace period
   - Reduces restart time from ~8 seconds to ~0.4 seconds

Includes benchmark tests for both improvements with documented results.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@rgarcia rgarcia force-pushed the feat/zstd-endpoints-and-chromium-restart-optimization branch from eabaf62 to a3b60f4 Compare January 16, 2026 13:55
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Addresses security issue found by Cursor Bugbot: symlink targets
were not validated, allowing malicious archives to write files
outside the destination directory via symlink path traversal.

Changes:
- Reject absolute symlink targets
- Validate that symlink targets resolve within destDir
- Validate that hardlink targets are within destDir

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

When stripComponents > 0, hard link entries whose target paths have
too few components should be skipped (like regular files), not
processed with unchanged paths that would cause extraction failures.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@rgarcia rgarcia requested a review from archandatta January 16, 2026 14:49
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

return oapi.UploadZstd400JSONResponse{BadRequestErrorJSONResponse: oapi.BadRequestErrorJSONResponse{Message: "invalid archive: path traversal detected"}}, nil
}
log.Error("failed to extract tar.zst archive", "err", err)
return oapi.UploadZstd500JSONResponse{InternalErrorJSONResponse: oapi.InternalErrorJSONResponse{Message: "failed to extract archive"}}, nil
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Symlink/hardlink path traversal errors return 500 instead of 400

Low Severity

The UploadZstd error handling only checks for "illegal file path" to return a 400 response, but UntarZstd can also return security errors with different text: "illegal symlink target (absolute path)", "illegal symlink target (escapes destination)", and "illegal hard link target". These path traversal attempts are correctly blocked, but incorrectly return HTTP 500 with message "failed to extract archive" instead of HTTP 400 with "invalid archive: path traversal detected". This miscategorizes client errors as server errors.

Fix in Cursor Fix in Web

Copy link
Contributor

@archandatta archandatta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

- Add lock file cleanup (SingletonLock, SingletonSocket, SingletonCookie)
  to handle stale files from SIGKILL termination
- Add waitForPort function that checks port availability before starting
  chromium, with SO_REUSEADDR disabled to accurately match chromium's
  bind behavior
- This allows keeping stopwaitsecs=0 for fast restarts while ensuring
  the port is actually free before chromium tries to bind

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

// Security check: prevent path traversal
if !strings.HasPrefix(filepath.Clean(destPath), filepath.Clean(destDir)+string(os.PathSeparator)) {
return fmt.Errorf("illegal file path: %s", header.Name)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Path traversal check fails when extracting to root directory

Low Severity

The path traversal security check incorrectly rejects all valid files when destDir is "/". The check uses strings.HasPrefix(filepath.Clean(destPath), filepath.Clean(destDir)+string(os.PathSeparator)), but when destDir is /, this becomes strings.HasPrefix(path, "//") since filepath.Clean("/") + "/" equals "//". Any valid path like /etc/passwd doesn't start with //, causing all extractions to the root directory to fail. The symlink check at lines 215-216 has different logic that handles the equality case, but regular files and hard links don't have this handling.

Additional Locations (1)

Fix in Cursor Fix in Web

Chromium creates symlinks to /tmp (e.g., SingletonSocket -> /tmp/org.chromium.Chromium.xxx/SingletonSocket). The previous security check rejected all absolute symlinks, but absolute paths aren't a path traversal risk - only relative symlinks using ../ to escape the destination are.

Now we only check relative symlinks for path traversal while allowing absolute symlinks.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@rgarcia rgarcia merged commit 3cae121 into main Jan 16, 2026
5 checks passed
@rgarcia rgarcia deleted the feat/zstd-endpoints-and-chromium-restart-optimization branch January 16, 2026 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants