upload

package
v1.8.3 Latest Latest
Warning

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

Go to latest
Published: Jul 2, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package upload provides multipart/form-data parsing and file saving.

Features:

  • File parts: saved to disk with content-type, filename, field-name metadata
  • Form fields: collected with support for repeated names (array aggregation)
  • Empty file parts: detected and marked with IsEmpty=true
  • Size limits: per-file and total upload size enforcement
  • Same field name multiple files: all saved independently
  • Extension inference: from Content-Type or original filename

Index

Constants

This section is empty.

Variables

View Source
var ErrFileTooLarge = errors.New("goose: file exceeds max file size limit")

ErrFileTooLarge is returned when a single file exceeds MaxFileSize.

View Source
var ErrMissBoundary = fmt.Errorf("goose: multipart missing boundary")

ErrMissBoundary is return when multipart missing boundary

View Source
var ErrTotalTooLarge = errors.New("goose: upload exceeds max total size limit")

ErrTotalTooLarge is returned when total upload size exceeds MaxTotalSize.

Functions

func ExtensionFromContentType

func ExtensionFromContentType(contentType string) string

ExtensionFromContentType returns a file extension for the given MIME content type. Falls back to ".bin" for unknown or unsupported content types.

Parameters:

  • contentType: MIME Content-Type string (e.g. "image/png", "application/pdf")

Returns:

  • string: File extension including the leading dot (e.g. ".png", ".pdf")

func ExtensionFromFilename

func ExtensionFromFilename(name string) string

ExtensionFromFilename returns the file extension from a filename. Falls back to ".bin" if the filename has no extension.

Parameters:

  • name: Original filename (e.g. "report.pdf", "photo")

Returns:

  • string: File extension including the leading dot (e.g. ".pdf", ".bin")

func FormatBytes

func FormatBytes(b int64) string

FormatBytes returns a human-readable byte size string using binary units.

Parameters:

  • b: Size in bytes

Returns:

  • string: Human-readable size string (e.g. "1.5 MB", "256 B")

Types

type FormField

type FormField struct {
	Name   string   `json:"name"`
	Values []string `json:"values"` // supports repeated field names
}

FormField records a regular (non-file) form field. Same field name appearing multiple times → Values is a slice.

type Handler

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

Handler processes multipart/form-data requests and saves files to disk.

func NewHandler

func NewHandler(opts ...Option) (*Handler, error)

NewHandler creates a Handler with the given functional options. The upload directory is created automatically if it does not exist.

Parameters:

  • opts: Functional options to configure the Handler

Returns:

  • *Handler: Configured upload handler
  • error: Error if the upload directory cannot be created

Behavior:

  1. Applies all functional options to default Options
  2. Falls back to "./uploads" if UploadDir is empty
  3. Creates the upload directory if it does not exist

func (*Handler) Handle

func (h *Handler) Handle(data []byte, contentType string) (*Result, error)

Handle is the main entry point for processing uploaded data. It auto-detects multipart vs raw body based on the Content-Type header.

Parameters:

  • data: Raw request body bytes
  • contentType: HTTP Content-Type header value

Returns:

  • *Result: Parsed result containing saved files and form fields
  • error: Error if parsing or saving fails

Behavior:

  1. If Content-Type is multipart/form-data or multipart/mixed, delegates to ParseMultipart
  2. Otherwise, saves the raw body as a single file via SaveSingleFile
  3. Returns ErrTotalTooLarge if the data exceeds MaxTotalSize

func (*Handler) ParseMultipart

func (h *Handler) ParseMultipart(data []byte, boundary string) (*Result, error)

ParseMultipart parses multipart/form-data, saves file parts, and collects form fields.

Parameters:

  • data: Raw multipart body bytes
  • boundary: Multipart boundary string from Content-Type header

Returns:

  • *Result: Parsed result containing saved files and form fields
  • error: Error if parsing or saving fails

Behavior:

  1. Checks total size against MaxTotalSize limit
  2. Iterates over each part in the multipart body
  3. For file parts (with filename), infers extension and saves to disk
  4. For regular form fields, aggregates values by field name
  5. Returns ErrFileTooLarge if any single file exceeds MaxFileSize

func (*Handler) SaveSingleFile

func (h *Handler) SaveSingleFile(data []byte, ext string, fieldName, origName, contentType string) (SavedFile, error)

SaveSingleFile writes data to a timestamped file on disk.

Parameters:

  • data: File content bytes to write
  • ext: File extension (e.g. ".png", ".pdf")
  • fieldName: Form field name from the multipart part
  • origName: Original filename from the client
  • contentType: MIME Content-Type of the file

Returns:

  • SavedFile: Metadata of the saved file
  • error: Error if size check fails or disk write fails

Behavior:

  1. Checks data size against MaxFileSize limit
  2. Generates a unique filename using current UnixNano timestamp
  3. Writes data to the upload directory

type Option

type Option func(*Options)

Option is a functional option that mutates a Config.

func WithMaxFileSize

func WithMaxFileSize(n int64) Option

WithMaxFileSize sets the per-file size limit in bytes (0 = unlimited).

Parameters:

  • n: Maximum file size in bytes

Returns:

  • Option: Functional option that sets MaxFileSize

func WithMaxTotalSize

func WithMaxTotalSize(n int64) Option

WithMaxTotalSize sets the total upload size limit in bytes (0 = unlimited).

Parameters:

  • n: Maximum total upload size in bytes

Returns:

  • Option: Functional option that sets MaxTotalSize

func WithUploadDir

func WithUploadDir(dir string) Option

WithUploadDir sets the directory where uploaded files are saved.

Parameters:

  • dir: Directory path for saving uploaded files

Returns:

  • Option: Functional option that sets UploadDir

type Options

type Options struct {
	// UploadDir is the directory where uploaded files are saved.
	UploadDir string
	// MaxFileSize is the per-file size limit in bytes (0 = unlimited).
	MaxFileSize int64
	// MaxTotalSize is the total upload size limit in bytes (0 = unlimited).
	MaxTotalSize int64
}

Options controls multipart parsing and file saving behavior.

type Result

type Result struct {
	Files      []SavedFile `json:"files,omitempty"`
	Fields     []FormField `json:"fields,omitempty"`
	TotalSize  int64       `json:"total_size"`
	FileCount  int         `json:"file_count"`
	FieldCount int         `json:"field_count"`
}

Result holds both files and form fields from a multipart request.

func (*Result) JSON

func (r *Result) JSON() string

JSON returns the result serialized as a JSON string.

type SavedFile

type SavedFile struct {
	FieldName   string `json:"field_name"`   // form field name (e.g. "files[]", "avatar")
	OrigName    string `json:"orig_name"`    // original filename from client
	ContentType string `json:"content_type"` // MIME type from part Content-Type header
	SavedAs     string `json:"saved_as"`     // filename on disk
	Size        int64  `json:"size"`         // bytes written
	IsEmpty     bool   `json:"is_empty"`     // true if uploaded file was 0 bytes
}

SavedFile records a successfully saved file with full multipart metadata.

Jump to

Keyboard shortcuts

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