multipart

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 15, 2026 License: MIT Imports: 3 Imported by: 0

README

multipart

import "github.com/kitsunium/sdk/pkg/v1/data/codec/multipart"

Package multipart registers the multipart/form-data codec with the SDK's codec registry — and no other codec — when it is imported (ADR 0134):

import _ "github.com/kitsunium/sdk/pkg/v1/data/codec/multipart"

The codec is RFC 7578's multipart/form-data on the standard library's mime/multipart. Its native value is a Form of [Part]s — a file upload is a part with a FileName and a ContentType; any other value travels as one JSON-mediated part. The boundary belongs in the Content-Type header, which a codec has nowhere to return, so ContentType recovers the header value from the body Marshal wrote. Parts, part sizes and the whole body are bounded. It streams.

Everything that dispatches through the registry by format name then reads and writes it: the codec package's Marshal and Unmarshal, config.FSSource and i18n.LoadFS. Importing github.com/kitsunium/sdk/pkg/v1/data/codec instead registers every format the SDK ships; this package links this one codec, the core package declaring its codes and the standard library, and nothing else. Importing both is harmless: a format is registered by the package that implements it, which Go initialises once however many packages import it.

Errors

Failures carry the range 0.3.41.*; match them with errs.HasCode, or the sentinels with errors.Is:

CodeMarshalFailed    0.3.41.1  a part could not be written
CodeUnmarshalFailed  0.3.41.2  a malformed part, a part with no name, a missing closing delimiter
CodeValueInvalid     0.3.41.3  an unusable value — no name, or a CR, LF or NUL in a header field
CodeBoundaryInvalid  0.3.41.4  no usable RFC 2046 boundary
CodeLimitExceeded    0.3.41.5  a part, the part count or the body crossed its bound
CodeLimitsInvalid    0.3.41.6  a negative bound

No error message quotes the input.

Index

Constants

const CodeBoundaryInvalid errs.Code = 207108

CodeBoundaryInvalid is 0.3.41.4: no usable RFC 2046 boundary.

Initialised with github.com/kitsunium/sdk/internal/core/data/codec/multipart.CodeMultipartBoundaryInvalid.

Code 0.3.41.4

const CodeLimitExceeded errs.Code = 207109

CodeLimitExceeded is 0.3.41.5: a part, the part count or the body crossed its bound.

Initialised with github.com/kitsunium/sdk/internal/core/data/codec/multipart.CodeMultipartLimitExceeded.

Code 0.3.41.5

const CodeLimitsInvalid errs.Code = 207110

CodeLimitsInvalid is 0.3.41.6: a negative bound.

Initialised with github.com/kitsunium/sdk/internal/core/data/codec/multipart.CodeMultipartLimitsInvalid.

Code 0.3.41.6

const CodeMarshalFailed errs.Code = 207105

CodeMarshalFailed is 0.3.41.1: a part could not be written.

Initialised with github.com/kitsunium/sdk/internal/core/data/codec/multipart.CodeMultipartMarshalFailed.

Code 0.3.41.1

const CodeUnmarshalFailed errs.Code = 207106

CodeUnmarshalFailed is 0.3.41.2: a malformed part, a part with no name, a missing closing delimiter.

Initialised with github.com/kitsunium/sdk/internal/core/data/codec/multipart.CodeMultipartUnmarshalFailed.

Code 0.3.41.2

const CodeValueInvalid errs.Code = 207107

CodeValueInvalid is 0.3.41.3: an unusable value — no name, or a CR, LF or NUL in a header field.

Initialised with github.com/kitsunium/sdk/internal/core/data/codec/multipart.CodeMultipartValueInvalid.

Code 0.3.41.3

const Format = "multipart"

Format is the name multipart/form-data is registered under. It is an untyped constant, so it goes wherever a format name is taken — the codec package's Marshal, config.FSSource's string, i18n.LoadFS's codec.Format — without a conversion.

Variables

var BoundaryInvalid *errs.Error

BoundaryInvalid is the sentinel of CodeBoundaryInvalid.

Initialised with github.com/kitsunium/sdk/internal/core/data/codec/multipart.BoundaryInvalid.

Code 0.3.41.4 · reason BOUNDARY_INVALID · public "multipart boundary is missing or invalid"

var LimitExceeded *errs.Error

LimitExceeded is the sentinel of CodeLimitExceeded.

Initialised with github.com/kitsunium/sdk/internal/core/data/codec/multipart.LimitExceeded.

Code 0.3.41.5 · reason LIMIT_EXCEEDED · public "multipart payload exceeds a configured limit"

var LimitsInvalid *errs.Error

LimitsInvalid is the sentinel of CodeLimitsInvalid.

Initialised with github.com/kitsunium/sdk/internal/core/data/codec/multipart.LimitsInvalid.

Code 0.3.41.6 · reason LIMITS_INVALID · public "multipart limits are not usable"

var MarshalFailed *errs.Error

MarshalFailed is the sentinel of CodeMarshalFailed.

Initialised with github.com/kitsunium/sdk/internal/core/data/codec/multipart.MarshalFailed.

Code 0.3.41.1 · reason MARSHAL_FAILED · public "multipart encoding failed"

var UnmarshalFailed *errs.Error

UnmarshalFailed is the sentinel of CodeUnmarshalFailed.

Initialised with github.com/kitsunium/sdk/internal/core/data/codec/multipart.UnmarshalFailed.

Code 0.3.41.2 · reason UNMARSHAL_FAILED · public "multipart decoding failed"

var ValueInvalid *errs.Error

ValueInvalid is the sentinel of CodeValueInvalid.

Initialised with github.com/kitsunium/sdk/internal/core/data/codec/multipart.ValueInvalid.

Code 0.3.41.3 · reason VALUE_INVALID · public "multipart codec rejected the value shape"

func ContentType

func ContentType(body []byte) (value string, err error)

ContentType returns the Content-Type header value — "multipart/form-data; boundary=…", quoted when the boundary needs it — for a body Marshal wrote, read off its first delimiter line. A body with no recoverable delimiter is refused with CodeBoundaryInvalid.

type Form

Form is the native value of the multipart/form-data Format: a whole body — its RFC 2046 boundary and its parts, in wire order. Marshal one to build an upload; Unmarshal into a *Form to read one. An empty Boundary asks Marshal to generate a delimiter; Unmarshal always fills it with the one it recovered.

type Form = svcmultipart.FormValue

Form is an alias of github.com/kitsunium/sdk/internal/service/data/codec/multipart.FormValue, declared as:

type Form struct {
	// Boundary is the RFC 2046 delimiter framing the parts.
	Boundary string
	// Parts are the body's sections, in wire order.
	Parts    []PartValue
}

type Part

Part is one section of a Form: a named field, optionally a filename and a media type, and the bytes. Name is required, and a CR, an LF or a NUL in Name, FileName or ContentType is refused, never escaped. Decoding keeps a filename's last path element only.

type Part = svcmultipart.PartValue

Part is an alias of github.com/kitsunium/sdk/internal/service/data/codec/multipart.PartValue, declared as:

type Part struct {
	// Name is the form field name (Content-Disposition name=). Required: Encode
	// refuses a part without one, and decoding refuses a body carrying one.
	Name        string
	// FileName is the optional filename= parameter; empty for a plain field.
	// UTF-8 is written as-is (RFC 7578 §4.2); only CR, LF and NUL are refused.
	//
	// Decoding keeps only its LAST PATH ELEMENT, and reads both '/' and '\' as
	// separators on every operating system: RFC 7578 §4.2 has the receiver drop
	// the directory information a sender may include, and the sender writes it
	// with its own separator. `C:\Users\ada\cv.pdf` and `dir/cv.pdf` both
	// decode to `cv.pdf`, wherever the decoder runs. Nothing else is removed —
	// "." and ".." come back as sent — so a caller turning it into a path still
	// validates it first.
	FileName    string
	// ContentType is the optional per-part media type; empty omits the header.
	ContentType string
	// Data is the part body.
	Data        []byte
}

Generated from docs/api by tools/genindex.

Documentation

Overview

Package multipart registers the multipart/form-data codec with the SDK's codec registry — and no other codec — when it is imported (ADR 0134):

import _ "github.com/kitsunium/sdk/pkg/v1/data/codec/multipart"

The codec is RFC 7578's multipart/form-data on the standard library's mime/multipart. Its native value is a Form of [Part]s — a file upload is a part with a FileName and a ContentType; any other value travels as one JSON-mediated part. The boundary belongs in the Content-Type header, which a codec has nowhere to return, so ContentType recovers the header value from the body Marshal wrote. Parts, part sizes and the whole body are bounded. It streams.

Everything that dispatches through the registry by format name then reads and writes it: the codec package's Marshal and Unmarshal, config.FSSource and i18n.LoadFS. Importing github.com/kitsunium/sdk/pkg/v1/data/codec instead registers every format the SDK ships; this package links this one codec, the core package declaring its codes and the standard library, and nothing else. Importing both is harmless: a format is registered by the package that implements it, which Go initialises once however many packages import it.

Errors

Failures carry the range 0.3.41.*; match them with errs.HasCode, or the sentinels with errors.Is:

CodeMarshalFailed    0.3.41.1  a part could not be written
CodeUnmarshalFailed  0.3.41.2  a malformed part, a part with no name, a missing closing delimiter
CodeValueInvalid     0.3.41.3  an unusable value — no name, or a CR, LF or NUL in a header field
CodeBoundaryInvalid  0.3.41.4  no usable RFC 2046 boundary
CodeLimitExceeded    0.3.41.5  a part, the part count or the body crossed its bound
CodeLimitsInvalid    0.3.41.6  a negative bound

No error message quotes the input.

Index

Constants

View Source
const (
	// CodeMarshalFailed is 0.3.41.1: a part could not be written.
	CodeMarshalFailed errs.Code = coremultipart.CodeMultipartMarshalFailed
	// CodeUnmarshalFailed is 0.3.41.2: a malformed part, a part with no name,
	// a missing closing delimiter.
	CodeUnmarshalFailed errs.Code = coremultipart.CodeMultipartUnmarshalFailed
	// CodeValueInvalid is 0.3.41.3: an unusable value — no name, or a CR, LF
	// or NUL in a header field.
	CodeValueInvalid errs.Code = coremultipart.CodeMultipartValueInvalid
	// CodeBoundaryInvalid is 0.3.41.4: no usable RFC 2046 boundary.
	CodeBoundaryInvalid errs.Code = coremultipart.CodeMultipartBoundaryInvalid
	// CodeLimitExceeded is 0.3.41.5: a part, the part count or the body
	// crossed its bound.
	CodeLimitExceeded errs.Code = coremultipart.CodeMultipartLimitExceeded
	// CodeLimitsInvalid is 0.3.41.6: a negative bound.
	CodeLimitsInvalid errs.Code = coremultipart.CodeMultipartLimitsInvalid
)

The error codes, range 0.3.41.*, declared in the core (ADR 0160).

View Source
const Format = "multipart"

Format is the name multipart/form-data is registered under. It is an untyped constant, so it goes wherever a format name is taken — the codec package's Marshal, config.FSSource's string, i18n.LoadFS's codec.Format — without a conversion.

Variables

View Source
var (
	// MarshalFailed is the sentinel of [CodeMarshalFailed].
	MarshalFailed = coremultipart.MarshalFailed
	// UnmarshalFailed is the sentinel of [CodeUnmarshalFailed].
	UnmarshalFailed = coremultipart.UnmarshalFailed
	// ValueInvalid is the sentinel of [CodeValueInvalid].
	ValueInvalid = coremultipart.ValueInvalid
	// BoundaryInvalid is the sentinel of [CodeBoundaryInvalid].
	BoundaryInvalid = coremultipart.BoundaryInvalid
	// LimitExceeded is the sentinel of [CodeLimitExceeded].
	LimitExceeded = coremultipart.LimitExceeded
	// LimitsInvalid is the sentinel of [CodeLimitsInvalid].
	LimitsInvalid = coremultipart.LimitsInvalid
)

The sentinels, for errors.Is: each carries the code of the same name.

Functions

func ContentType

func ContentType(body []byte) (value string, err error)

ContentType returns the Content-Type header value — "multipart/form-data; boundary=…", quoted when the boundary needs it — for a body Marshal wrote, read off its first delimiter line. A body with no recoverable delimiter is refused with CodeBoundaryInvalid.

Types

type Form

type Form = svcmultipart.FormValue

Form is the native value of the multipart/form-data Format: a whole body — its RFC 2046 boundary and its parts, in wire order. Marshal one to build an upload; Unmarshal into a *Form to read one. An empty Boundary asks Marshal to generate a delimiter; Unmarshal always fills it with the one it recovered.

type Part

type Part = svcmultipart.PartValue

Part is one section of a Form: a named field, optionally a filename and a media type, and the bytes. Name is required, and a CR, an LF or a NUL in Name, FileName or ContentType is refused, never escaped. Decoding keeps a filename's last path element only.

Jump to

Keyboard shortcuts

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