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 ¶
var ErrFileTooLarge = errors.New("goose: file exceeds max file size limit")
ErrFileTooLarge is returned when a single file exceeds MaxFileSize.
var ErrMissBoundary = fmt.Errorf("goose: multipart missing boundary")
ErrMissBoundary is return when multipart missing boundary
var ErrTotalTooLarge = errors.New("goose: upload exceeds max total size limit")
ErrTotalTooLarge is returned when total upload size exceeds MaxTotalSize.
Functions ¶
func ExtensionFromContentType ¶
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 ¶
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 ¶
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 ¶
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:
- Applies all functional options to default Options
- Falls back to "./uploads" if UploadDir is empty
- Creates the upload directory if it does not exist
func (*Handler) Handle ¶
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:
- If Content-Type is multipart/form-data or multipart/mixed, delegates to ParseMultipart
- Otherwise, saves the raw body as a single file via SaveSingleFile
- Returns ErrTotalTooLarge if the data exceeds MaxTotalSize
func (*Handler) ParseMultipart ¶
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:
- Checks total size against MaxTotalSize limit
- Iterates over each part in the multipart body
- For file parts (with filename), infers extension and saves to disk
- For regular form fields, aggregates values by field name
- 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:
- Checks data size against MaxFileSize limit
- Generates a unique filename using current UnixNano timestamp
- Writes data to the upload directory
type Option ¶
type Option func(*Options)
Option is a functional option that mutates a Config.
func WithMaxFileSize ¶
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 ¶
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 ¶
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.
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.