file

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Jun 8, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Index

Constants

View Source
const MaxFileFieldStringBytes = 8 * 1024

MaxFileFieldStringBytes caps the length of any FileField string field — anything past this is rejected at validation time. A legitimate URL, MIME, or storage ref does not need 8 KB.

View Source
const MaxProcessFileSize int64 = 32 << 20 // 32 MiB

MaxProcessFileSize caps the in-memory size of a single upload read by ProcessFileField. The default protects callers that haven't wired a stricter limit elsewhere from unbounded memory consumption — a hostile client can otherwise stream gigabytes into RAM.

Variables

View Source
var (
	ErrFileFieldURLScheme     = errors.New("filefield: URL has unsafe scheme")
	ErrFileFieldTraversal     = errors.New("filefield: contains path traversal")
	ErrFileFieldMimeUnsafe    = errors.New("filefield: MIME type contains unsafe characters")
	ErrFileFieldSize          = errors.New("filefield: size is negative or oversize")
	ErrFileFieldOversize      = errors.New("filefield: field exceeds length limit")
	ErrFileFieldTooLarge      = errors.New("filefield: file exceeds maximum size")
	ErrFileFieldUnsafeContent = errors.New("filefield: file content is unsafe by default")
)

Validation errors returned by FileField.Validate. Callers can match on these without parsing the message.

Functions

func DeleteFileField

func DeleteFileField(ctx context.Context, store upload.Storage, ff *FileField) error

DeleteFileField removes a previously stored file from the storage backend. Returns nil if the FileField is nil or has no storage reference. The ctx parameter should come from the HTTP request.

func GenerateFilePath

func GenerateFilePath(entityName, fieldName, filename string) string

GenerateFilePath produces a safe, unique file path for storage. The format is: uploads/{entityName}/{fieldName}/{sanitized_name}_{timestamp}_{rand}{ext} Example: "uploads/posts/avatar/photo_1683398400000000000_3f9a1c2b.png"

The path carries a crypto/rand component in addition to the timestamp so that two uploads of the same filename to the same field never collide — uniqueness must not depend on clock resolution. Without it, two requests landing within the same nanosecond (or the same clock tick on platforms whose clock does not advance every nanosecond) would resolve to the same path and one upload would silently overwrite the other.

Types

type FileField

type FileField struct {
	// URL is the publicly accessible path or URL to the file.
	URL string `json:"url"`

	// Filename is the original filename as provided by the client.
	Filename string `json:"filename"`

	// MimeType is the detected MIME type of the file.
	MimeType string `json:"mime_type"`

	// Size is the file size in bytes.
	Size int64 `json:"size"`

	// StorageRef is the storage backend key used to reference this file.
	StorageRef string `json:"storage_ref"`
}

FileField holds metadata about an uploaded file associated with an entity field.

func ProcessFileField

func ProcessFileField(ctx context.Context, store upload.Storage, file interface {
	Read([]byte) (int, error)
}, filename string, entityName, fieldName string) (*FileField, error)

ProcessFileField reads a file from the given reader, saves it via the storage backend, and returns a FileField with all metadata. The file is stored at a path generated by GenerateFilePath.

Defaults that protect callers from common upload abuse paths:

  • Size is capped at MaxProcessFileSize. Anything larger returns ErrFileFieldTooLarge without buffering the rest of the body.
  • Content is sniffed from the first 512 bytes (and an XML/HTML probe of the leading non-whitespace) and rejected when it matches a known-dangerous shape: SVG / XML, HTML, or executable magic bytes (MZ for PE, 0x7fELF for ELF, Mach-O headers). The filename extension and any client-supplied Content-Type are ignored — attackers can lie about both.

The ctx parameter should come from the HTTP request so cancellation and deadlines are respected during slow uploads.

func (*FileField) Validate

func (f *FileField) Validate() error

Validate enforces invariants on a FileField that came from an untrusted source (typically JSON unmarshal in a CRUD body). It is NOT called automatically — callers that accept FileField as request input should call it before persisting or rendering. The constructors in this package (ProcessFileField) already produce valid FileFields.

Rejected inputs:

  • URL with javascript:, vbscript:, or data: scheme — would XSS when rendered as href/src by a downstream consumer.
  • URL or StorageRef containing `..` segments — would escape the storage root on a vulnerable filesystem backend.
  • MimeType containing characters outside the MIME-safe set — normal MIME types are `type/subtype` with letters, digits, `+`, `-`, `.`; angle brackets / quotes indicate an XSS attempt.
  • Size < 0 — unsigned conventions require non-negative.
  • Any string field over MaxFileFieldStringBytes.

Jump to

Keyboard shortcuts

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