multipart

原文:https://pkg.go.dev/mime/multipart@go1.23.0

Package multipart implements MIME multipart parsing, as defined in RFC 2046.

​ Package multipart 实现 MIME multipart 解析,如 RFC 2046 中所定义。

The implementation is sufficient for HTTP (RFC 2388) and the multipart bodies generated by popular browsers.

​ 该实现足以用于 HTTP (RFC 2388) 和流行浏览器生成的 multipart 主体。

Copyright 2023 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

​ 版权所有 2023 The Go Authors。保留所有权利。本源代码的使用受 BSD 式许可证管辖,可在 LICENSE 文件中找到该许可证。

常量

This section is empty.

变量

View Source

1
var ErrMessageTooLarge = errors.New("multipart: message too large")

ErrMessageTooLarge is returned by ReadForm if the message form data is too large to be processed.

​ 如果消息表单数据太大而无法处理,则 ReadForm 会返回 ErrMessageTooLarge。

函数

This section is empty.

​ 此部分为空。

类型

type File

1
2
3
4
5
6
type File interface {
	io.Reader
	io.ReaderAt
	io.Seeker
	io.Closer
}

File is an interface to access the file part of a multipart message. Its contents may be either stored in memory or on disk. If stored on disk, the File’s underlying concrete type will be an *os.File.

​ File 是一个用于访问 multipart 消息的文件部分的接口。其内容可以存储在内存中或磁盘上。如果存储在磁盘上,则 File 的底层具体类型将是 *os.File。

type FileHeader

1
2
3
4
5
6
type FileHeader struct {
	Filename string
	Header   textproto.MIMEHeader
	Size     int64
	// contains filtered or unexported fields
}

A FileHeader describes a file part of a multipart request.

​ FileHeader 描述 multipart 请求的文件部分。

(*FileHeader) Open

1
func (fh *FileHeader) Open() (File, error)

Open opens and returns the FileHeader’s associated File.

​ Open 打开并返回 FileHeader 关联的 File。

type Form

1
2
3
4
type Form struct {
	Value map[string][]string
	File  map[string][]*FileHeader
}

Form is a parsed multipart form. Its File parts are stored either in memory or on disk, and are accessible via the *FileHeader’s Open method. Its Value parts are stored as strings. Both are keyed by field name.

​ 表单是一个已解析的多部分表单。它的文件部分存储在内存或磁盘中,可通过 *FileHeader 的 Open 方法访问。它的值部分存储为字符串。两者都以字段名称为键。

(*Form) RemoveAll

1
func (f *Form) RemoveAll() error

RemoveAll removes any temporary files associated with a Form.

​ RemoveAll 删除与表单关联的任何临时文件。

type Part

1
2
3
4
5
6
7
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
}

A Part represents a single part in a multipart body.

​ Part 表示多部分正文中的单个部分。

(*Part) Close

1
func (p *Part) Close() error

(*Part) FileName

1
func (p *Part) FileName() string

FileName returns the filename parameter of the Part’s Content-Disposition header. If not empty, the filename is passed through filepath.Base (which is platform dependent) before being returned.

​ FileName 返回 Part 的 Content-Disposition 标头的 filename 参数。如果非空,则在返回之前将文件名通过 filepath.Base(它依赖于平台)进行传递。

(*Part) FormName

1
func (p *Part) FormName() string

FormName returns the name parameter if p has a Content-Disposition of type “form-data”. Otherwise it returns the empty string.

​ 如果 p 的 Content-Disposition 类型为“form-data”,则 FormName 返回 name 参数。否则,它返回空字符串。

(*Part) Read

1
func (p *Part) Read(d []byte) (n int, err error)

Read reads the body of a part, after its headers and before the next part (if any) begins.

​ Read 在其标头之后和下一个部分(如果有)开始之前读取部分的主体。

type Reader

1
2
3
type Reader struct {
	// contains filtered or unexported fields
}

Reader is an iterator over parts in a MIME multipart body. Reader’s underlying parser consumes its input as needed. Seeking isn’t supported.

​ Reader 是 MIME 多部分主体中部分的迭代器。Reader 的底层解析器根据需要使用其输入。不支持寻址。

func NewReader

1
func NewReader(r io.Reader, boundary string) *Reader

NewReader creates a new multipart Reader reading from r using the given MIME boundary.

​ NewReader 使用给定的 MIME 边界从 r 创建新的多部分 Reader。

The boundary is usually obtained from the “boundary” parameter of the message’s “Content-Type” header. Use mime.ParseMediaType to parse such headers.

​ 边界通常从消息的“Content-Type”标头的“boundary”参数获取。使用 mime.ParseMediaType 解析此类标头。

NewReader Example
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package main

import (
	"fmt"
	"io"
	"log"
	"mime"
	"mime/multipart"
	"net/mail"
	"strings"
)

func main() {
	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)
		}
	}

}
Output:

Part "one": "A section"
Part "two": "And another"

(*Reader) NextPart

1
func (r *Reader) NextPart() (*Part, error)

NextPart returns the next part in the multipart or an error. When there are no more parts, the error io.EOF is returned.

​ NextPart 返回多部分中的下一个部分或错误。如果没有更多部分,则返回错误 io.EOF。

As a special case, if the “Content-Transfer-Encoding” header has a value of “quoted-printable”, that header is instead hidden and the body is transparently decoded during Read calls.

​ 作为特例,如果“Content-Transfer-Encoding”标头具有“quoted-printable”的值,则隐藏该标头,并在 Read 调用期间透明地解码主体。

(*Reader) NextRawPart <- go1.14

1
func (r *Reader) NextRawPart() (*Part, error)

NextRawPart returns the next part in the multipart or an error. When there are no more parts, the error io.EOF is returned.

​ NextRawPart 返回多部分中的下一部分或错误。当没有更多部分时,将返回错误 io.EOF。

Unlike NextPart, it does not have special handling for “Content-Transfer-Encoding: quoted-printable”.

​ 与 NextPart 不同,它没有对“Content-Transfer-Encoding: quoted-printable”进行特殊处理。

(*Reader) ReadForm

1
func (r *Reader) ReadForm(maxMemory int64) (*Form, error)

ReadForm parses an entire multipart message whose parts have a Content-Disposition of “form-data”. It stores up to maxMemory bytes + 10MB (reserved for non-file parts) in memory. File parts which can’t be stored in memory will be stored on disk in temporary files. It returns ErrMessageTooLarge if all non-file parts can’t be stored in memory.

​ ReadForm 解析整个多部分消息,其部分具有“form-data”的 Content-Disposition。它将最多 maxMemory 字节 + 10MB(为非文件部分保留)存储在内存中。无法存储在内存中的文件部分将存储在磁盘上的临时文件中。如果无法将所有非文件部分存储在内存中,它将返回 ErrMessageTooLarge。

type Writer

1
2
3
type Writer struct {
	// contains filtered or unexported fields
}

A Writer generates multipart messages.

​ Writer 生成多部分消息。

func NewWriter

1
func NewWriter(w io.Writer) *Writer

NewWriter returns a new multipart Writer with a random boundary, writing to w.

​ NewWriter 返回一个新的多部分 Writer,具有随机边界,写入 w。

(*Writer) Boundary

1
func (w *Writer) Boundary() string

Boundary returns the Writer’s boundary.

​ Boundary 返回 Writer 的边界。

(*Writer) Close

1
func (w *Writer) Close() error

Close finishes the multipart message and writes the trailing boundary end line to the output.

​ Close 完成多部分消息并将尾随边界结束行写入输出。

(*Writer) CreateFormField

1
func (w *Writer) CreateFormField(fieldname string) (io.Writer, error)

CreateFormField calls CreatePart with a header using the given field name.

​ CreateFormField 使用给定的字段名调用 CreatePart 并使用标头。

(*Writer) CreateFormFile

1
func (w *Writer) CreateFormFile(fieldname, filename string) (io.Writer, error)

CreateFormFile is a convenience wrapper around CreatePart. It creates a new form-data header with the provided field name and file name.

​ CreateFormFile 是 CreatePart 的一个便捷包装器。它使用提供的字段名和文件名创建一个新的表单数据标头。

(*Writer) CreatePart

1
func (w *Writer) CreatePart(header textproto.MIMEHeader) (io.Writer, error)

CreatePart creates a new multipart section with the provided header. The body of the part should be written to the returned Writer. After calling CreatePart, any previous part may no longer be written to.

​ CreatePart 使用提供的标头创建一个新的多部分部分。部分的主体应写入返回的 Writer。调用 CreatePart 后,任何以前的部分都无法再写入。

(*Writer) FormDataContentType

1
func (w *Writer) FormDataContentType() string

FormDataContentType returns the Content-Type for an HTTP multipart/form-data with this Writer’s Boundary.

​ FormDataContentType 返回具有此 Writer 边界的 HTTP multipart/form-data 的 Content-Type。

(*Writer) SetBoundary <- go1.1

1
func (w *Writer) SetBoundary(boundary string) error

SetBoundary overrides the Writer’s default randomly-generated boundary separator with an explicit value.

​ SetBoundary 使用显式值覆盖 Writer 的默认随机生成的边界分隔符。

SetBoundary must be called before any parts are created, may only contain certain ASCII characters, and must be non-empty and at most 70 bytes long.

​ 必须在创建任何部分之前调用 SetBoundary,只能包含某些 ASCII 字符,并且必须是非空且长度最多为 70 个字节。

(*Writer) WriteField

1
func (w *Writer) WriteField(fieldname, value string) error

WriteField calls CreateFormField and then writes the given value.

​ WriteField 调用 CreateFormField,然后写入给定值。