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 ¶
- func LegacyMultipartMiddleware(api huma.API, service *UploadService, kind string) huma.Middlewares
- func RegisterUploads(api huma.API, service *UploadService)
- func SessionHTTPError(err error) error
- type CreateUploadSessionInput
- type DeleteUploadSessionInput
- type DeleteUploadSessionOutput
- type GetUploadSessionInput
- type Module
- type UploadChunkInput
- type UploadHandler
- func (h *UploadHandler) CreateSession(ctx context.Context, input *CreateUploadSessionInput) (*UploadSessionOutput, error)
- func (h *UploadHandler) DeleteSession(ctx context.Context, input *DeleteUploadSessionInput) (*DeleteUploadSessionOutput, error)
- func (h *UploadHandler) GetSession(ctx context.Context, input *GetUploadSessionInput) (*UploadSessionOutput, error)
- func (h *UploadHandler) UploadChunk(ctx context.Context, input *UploadChunkInput) (*UploadSessionOutput, error)
- type UploadService
- func (s *UploadService) Consume(ctx context.Context, kind, uploadID string) (io.ReadSeekCloser, *uploadtypes.Session, func(), error)
- func (s *UploadService) CreateSession(ctx context.Context, kind string, request uploadtypes.CreateSessionRequest) (*uploadtypes.Session, error)
- func (s *UploadService) DeleteSession(ctx context.Context, kind, uploadID string) error
- func (s *UploadService) GetSession(ctx context.Context, kind, uploadID string) (*uploadtypes.Session, error)
- func (s *UploadService) IngestSession(ctx context.Context, kind, filename string, size int64, source io.Reader) (*uploadtypes.Session, error)
- func (s *UploadService) PurgeExpiredSessions(ctx context.Context, maxAge time.Duration) (int, error)
- func (s *UploadService) WriteChunk(ctx context.Context, kind, uploadID string, index int, data []byte) (*uploadtypes.Session, error)
- type UploadSessionOutput
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 ¶
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 DeleteUploadSessionOutput ¶
type DeleteUploadSessionOutput struct {
Body base.ApiResponse[base.MessageResponse]
}
type GetUploadSessionInput ¶
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 ¶
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 UploadHandler ¶
type UploadHandler struct {
// contains filtered or unexported fields
}
UploadHandler provides the Huma-based chunked upload-session endpoints.
func (*UploadHandler) CreateSession ¶
func (h *UploadHandler) CreateSession(ctx context.Context, input *CreateUploadSessionInput) (*UploadSessionOutput, error)
func (*UploadHandler) DeleteSession ¶
func (h *UploadHandler) DeleteSession(ctx context.Context, input *DeleteUploadSessionInput) (*DeleteUploadSessionOutput, error)
func (*UploadHandler) GetSession ¶
func (h *UploadHandler) GetSession(ctx context.Context, input *GetUploadSessionInput) (*UploadSessionOutput, error)
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]
}