Пакет multipart
Обзор
Пакет multipart реализует разбор MIME multipart в соответствии с RFC 2046.
Реализация подходит для HTTP (RFC 2388) и тел multipart, создаваемых популярными браузерами.
Ограничения
Для защиты от вредоносных данных этот пакет ограничивает размер обрабатываемых им данных MIME.
Reader.NextPart и Reader.NextRawPart ограничивают количество заголовков в одной части значением 10000, а Reader.ReadForm ограничивает общее количество заголовков во всех FileHeaders значением 10000. Эти ограничения можно изменить с помощью настройки GODEBUG=multipartmaxheaders=<values>.
Кроме того, Reader.ReadForm ограничивает количество частей формы значением 1000. Это ограничение можно изменить с помощью настройки GODEBUG=multipartmaxparts=<value>.
Указатель
Примеры
Файлы пакета
formdata.go multipart.go readmimeheader.go writer.go
Переменные
ErrMessageTooLarge возвращается методом ReadForm, если данные формы в сообщении слишком велики для обработки.
var ErrMessageTooLarge = errors.New("multipart: message too large") func FileContentDisposition 1.25
func FileContentDisposition(fieldname, filename string) string
FileContentDisposition возвращает значение заголовка Content-Disposition с указанными именем поля и именем файла.
type File
File — это интерфейс для доступа к файловой части multipart-сообщения. Содержимое может храниться как в памяти, так и на диске. Если оно хранится на диске, конкретный тип, лежащий в основе File, будет *os.File.
type File interface {
io.Reader
io.ReaderAt
io.Seeker
io.Closer
} type FileHeader
FileHeader описывает файловую часть multipart-запроса.
type FileHeader struct {
Filename string
Header textproto.MIMEHeader
Size int64 // Go 1.9
// contains filtered or unexported fields
}
func (*FileHeader) Open
func (fh *FileHeader) Open() (File, error)
Open открывает и возвращает связанный с FileHeader файл File.
type Form
Form — это разобранная multipart-форма. Ее файловые части хранятся в памяти или на диске, и доступ к ним осуществляется с помощью метода Open у *FileHeader. Части Value хранятся в виде строк. И те и другие индексируются по имени поля.
type Form struct {
Value map[string][]string
File map[string][]*FileHeader
}
func (*Form) RemoveAll
func (f *Form) RemoveAll() error
RemoveAll удаляет все временные файлы, связанные с Form.
type Part
Part представляет одну часть multipart-тела.
type Part struct {
// The headers of the body, if any, with the keys canonicalized
// in the same fashion that the Go http.Request headers are.
// For example, "foo-bar" changes case to "Foo-Bar"
Header textproto.MIMEHeader
// contains filtered or unexported fields
}
func (*Part) Close
func (p *Part) Close() error
func (*Part) FileName
func (p *Part) FileName() string
FileName возвращает параметр filename заголовка Content-Disposition у Part. Если значение не пустое, перед возвратом оно обрабатывается функцией filepath.Base (поведение которой зависит от платформы).
func (*Part) FormName
func (p *Part) FormName() string
FormName возвращает параметр name, если для p задан Content-Disposition типа "form-data". В противном случае возвращается пустая строка.
func (*Part) Read
func (p *Part) Read(d []byte) (n int, err error)
Read считывает тело части после ее заголовков и до начала следующей части (если она есть).
type Reader
Reader — это итератор по частям MIME multipart-тела. Внутренний анализатор Reader считывает входные данные по мере необходимости. Поддержка поиска не предусмотрена.
type Reader struct {
// contains filtered or unexported fields
}
func NewReader
func NewReader(r io.Reader, boundary string) *Reader
NewReader создает новый multipart-Reader, считывающий данные из r с использованием заданной MIME-границы.
Обычно граница берется из параметра "boundary" заголовка сообщения "Content-Type". Для разбора таких заголовков используйте mime.ParseMediaType.
Пример
Код:
msg := &mail.Message{
Header: map[string][]string{
"Content-Type": {"multipart/mixed; boundary=foo"},
},
Body: strings.NewReader(
"--foo\r\nFoo: one\r\n\r\nA section\r\n" +
"--foo\r\nFoo: two\r\n\r\nAnd another\r\n" +
"--foo--\r\n"),
}
mediaType, params, err := mime.ParseMediaType(msg.Header.Get("Content-Type"))
if err != nil {
log.Fatal(err)
}
if strings.HasPrefix(mediaType, "multipart/") {
mr := multipart.NewReader(msg.Body, params["boundary"])
for {
p, err := mr.NextPart()
if err == io.EOF {
return
}
if err != nil {
log.Fatal(err)
}
slurp, err := io.ReadAll(p)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Part %q: %q\n", p.Header.Get("Foo"), slurp)
}
}
Вывод:
Part "one": "A section" Part "two": "And another"
func (*Reader) NextPart
func (r *Reader) NextPart() (*Part, error)
NextPart возвращает следующую часть multipart-данных или ошибку. Когда частей больше нет, возвращается ошибка io.EOF.
В особом случае, если заголовок "Content-Transfer-Encoding" имеет значение "quoted-printable", этот заголовок скрывается, а тело автоматически декодируется при вызовах Read.
func (*Reader) NextRawPart 1.14
func (r *Reader) NextRawPart() (*Part, error)
NextRawPart возвращает следующую часть multipart-данных или ошибку. Когда частей больше нет, возвращается ошибка io.EOF.
В отличие от Reader.NextPart, этот метод не обрабатывает особым образом "Content-Transfer-Encoding: quoted-printable".
func (*Reader) ReadForm
func (r *Reader) ReadForm(maxMemory int64) (*Form, error)
ReadForm разбирает целое multipart-сообщение, части которого имеют Content-Disposition со значением "form-data". Он хранит в памяти до maxMemory байт + 10 МБ (зарезервированных для частей, не являющихся файлами). Части-файлы, которые невозможно хранить в памяти, сохраняются на диске во временных файлах. Если все части, не являющиеся файлами, невозможно сохранить в памяти, возвращается ErrMessageTooLarge.
тип Writer
Writer формирует multipart-сообщения.
type Writer struct {
// contains filtered or unexported fields
}
func NewWriter
func NewWriter(w io.Writer) *Writer
NewWriter возвращает новый multipart-объект Writer со случайной границей, записывающий данные в w.
func (*Writer) Boundary
func (w *Writer) Boundary() string
Boundary возвращает границу объекта Writer.
func (*Writer) Close
func (w *Writer) Close() error
Close завершает multipart-сообщение и записывает в выходной поток завершающую строку границы.
func (*Writer) CreateFormField
func (w *Writer) CreateFormField(fieldname string) (io.Writer, error)
CreateFormField вызывает Writer.CreatePart с заголовком, использующим указанное имя поля.
func (*Writer) CreateFormFile
func (w *Writer) CreateFormFile(fieldname, filename string) (io.Writer, error)
CreateFormFile — это удобная обёртка вокруг Writer.CreatePart. Она создаёт новый заголовок form-data с указанными именем поля и именем файла.
func (*Writer) CreatePart
func (w *Writer) CreatePart(header textproto.MIMEHeader) (io.Writer, error)
CreatePart создаёт новую multipart-секцию с указанным заголовком. Тело части следует записывать в возвращённый Writer. После вызова CreatePart запись в предыдущую часть может стать невозможной.
func (*Writer) FormDataContentType
func (w *Writer) FormDataContentType() string
FormDataContentType возвращает Content-Type для HTTP multipart/form-data с границей объекта Writer.
func (*Writer) SetBoundary 1.1
func (w *Writer) SetBoundary(boundary string) error
SetBoundary заменяет границу-разделитель, случайно сгенерированную по умолчанию для объекта Writer, на явно заданное значение.
SetBoundary необходимо вызвать до создания любых частей; значение может содержать только определённые символы ASCII, должно быть непустым и иметь длину не более 70 байт.
func (*Writer) WriteField
func (w *Writer) WriteField(fieldname, value string) error
WriteField вызывает Writer.CreateFormField, а затем записывает указанное значение.
© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/mime/multipart/