upload

package
v2.8.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 19, 2026 License: BSD-3-Clause Imports: 26 Imported by: 0

Documentation

Overview

Package upload owns chunked upload sessions: filesystem-backed staging for large files that arrive as independently retryable chunks, consumed by the image, volume-backup, and build-workspace endpoints.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func LegacyMultipartMiddleware

func LegacyMultipartMiddleware(api huma.API, service *UploadService, kind string) huma.Middlewares

LegacyMultipartMiddleware converts a deprecated multipart/form-data request into a complete upload session and rewrites the request into the JSON {"uploadId"} form, so clients predating chunked uploads keep working. It runs after authentication (a huma global middleware) but before the operation's permission middleware, so it enforces the kind permission itself to avoid staging files for unauthorized callers.

This compatibility path is deprecated for API consumers; delete this middleware when multipart upload support is removed.

func RegisterUploads

func RegisterUploads(api huma.API, service *UploadService)

RegisterUploads registers the upload-session routes. The required permission depends on the {kind} path parameter, so the operations carry no static permission metadata; enforcement happens in-handler and, for remote environments, in the proxy's upload special case.

func SessionHTTPError

func SessionHTTPError(err error) error

SessionHTTPError maps upload-session errors to HTTP errors for this package and the domain endpoints that consume sessions. It returns nil for errors that are not upload-session errors.

Types

type CreateUploadSessionInput

type CreateUploadSessionInput struct {
	EnvironmentID string `path:"id"`
	Kind          string `path:"kind" enum:"image,volume-backup,build-workspace"`
	Body          uploadtypes.CreateSessionRequest
}

type DeleteUploadSessionInput

type DeleteUploadSessionInput struct {
	EnvironmentID string `path:"id"`
	Kind          string `path:"kind" enum:"image,volume-backup,build-workspace"`
	UploadID      string `path:"uploadId"`
}

type DeleteUploadSessionOutput

type DeleteUploadSessionOutput struct {
	Body base.ApiResponse[base.MessageResponse]
}

type GetUploadSessionInput

type GetUploadSessionInput struct {
	EnvironmentID string `path:"id"`
	Kind          string `path:"kind" enum:"image,volume-backup,build-workspace"`
	UploadID      string `path:"uploadId"`
}

type Module

type Module struct {
	// contains filtered or unexported fields
}

Module wires the upload domain and mounts its routes.

func New

func New(service *UploadService) *Module

New builds the upload module around its session service.

func (*Module) RegisterRoutes

func (m *Module) RegisterRoutes(api huma.API)

RegisterRoutes mounts the upload-session endpoints. A nil module still registers, so OpenAPI spec generation can discover the routes without a service graph.

func (*Module) Service

func (m *Module) Service() *UploadService

Service exposes the upload session service to the domain endpoints that consume completed sessions.

type UploadChunkInput

type UploadChunkInput struct {
	EnvironmentID string `path:"id"`
	Kind          string `path:"kind" enum:"image,volume-backup,build-workspace"`
	UploadID      string `path:"uploadId"`
	Index         int    `path:"index"`
	RawBody       []byte `contentType:"application/octet-stream"`
}

type UploadHandler

type UploadHandler struct {
	// contains filtered or unexported fields
}

UploadHandler provides the Huma-based chunked upload-session endpoints.

func (*UploadHandler) CreateSession

func (*UploadHandler) DeleteSession

func (*UploadHandler) GetSession

func (*UploadHandler) UploadChunk

func (h *UploadHandler) UploadChunk(ctx context.Context, input *UploadChunkInput) (*UploadSessionOutput, error)

type UploadService

type UploadService struct {
	// contains filtered or unexported fields
}

UploadService stages chunked upload sessions on local disk. Sessions are node-local by design: chunks and the consuming request must reach the same instance, which holds for Arcane's single-instance-per-node deployment (for remote environments the session lives on that environment's agent).

func NewUploadService

func NewUploadService(settingsService *settings.SettingsService) *UploadService

NewUploadService builds the session service rooted in the system temp directory; the root is created lazily on first session.

func (*UploadService) Consume

func (s *UploadService) Consume(ctx context.Context, kind, uploadID string) (io.ReadSeekCloser, *uploadtypes.Session, func(), error)

Consume validates that the session matches kind and is complete, then opens the assembled file for reading. The session metadata is removed under the session lock before returning, so a session can be consumed at most once even by concurrent requests; the returned cleanup closes the file and deletes the remaining session data.

func (*UploadService) CreateSession

func (s *UploadService) CreateSession(ctx context.Context, kind string, request uploadtypes.CreateSessionRequest) (*uploadtypes.Session, error)

CreateSession validates the request against the kind's filename and size rules and stages a new empty session on disk.

func (*UploadService) DeleteSession

func (s *UploadService) DeleteSession(ctx context.Context, kind, uploadID string) error

DeleteSession aborts a session and discards its received chunks.

func (*UploadService) GetSession

func (s *UploadService) GetSession(ctx context.Context, kind, uploadID string) (*uploadtypes.Session, error)

GetSession reports the session state, including which chunks have been received so clients can resume.

func (*UploadService) IngestSession

func (s *UploadService) IngestSession(ctx context.Context, kind, filename string, size int64, source io.Reader) (*uploadtypes.Session, error)

IngestSession creates a session already containing the complete file. It backs the deprecated single-request multipart compatibility path, applying the same per-kind validation as chunked sessions.

func (*UploadService) PurgeExpiredSessions

func (s *UploadService) PurgeExpiredSessions(ctx context.Context, maxAge time.Duration) (int, error)

PurgeExpiredSessions removes sessions that have been idle for longer than maxAge. Idleness is judged by the newest modification time among the session's files — the data file advances on every chunk write and the metadata on every chunk recorded — so a slow but active upload is never swept, and the check runs under the session lock so an in-flight chunk write cannot race the removal.

func (*UploadService) WriteChunk

func (s *UploadService) WriteChunk(ctx context.Context, kind, uploadID string, index int, data []byte) (*uploadtypes.Session, error)

WriteChunk stores one chunk at its final offset and records it as received. Re-sending an already-received chunk is an idempotent overwrite.

type UploadSessionOutput

type UploadSessionOutput struct {
	Body base.ApiResponse[uploadtypes.Session]
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL