var emptyParams … const peekBufferSize … type Part … // FormName returns the name parameter if p has a Content-Disposition // of type "form-data". Otherwise it returns the empty string. func (p *Part) FormName() 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. func (p *Part) FileName() string { … } func (p *Part) parseContentDisposition() { … } // NewReader creates a new multipart [Reader] reading from r using the // given MIME boundary. // // The boundary is usually obtained from the "boundary" parameter of // the message's "Content-Type" header. Use [mime.ParseMediaType] to // parse such headers. func NewReader(r io.Reader, boundary string) *Reader { … } type stickyErrorReader … func (r *stickyErrorReader) Read(p []byte) (n int, _ error) { … } func newPart(mr *Reader, rawPart bool, maxMIMEHeaderSize, maxMIMEHeaders int64) (*Part, error) { … } func (p *Part) populateHeaders(maxMIMEHeaderSize, maxMIMEHeaders int64) error { … } // Read reads the body of a part, after its headers and before the // next part (if any) begins. func (p *Part) Read(d []byte) (n int, err error) { … } type partReader … func (pr partReader) Read(d []byte) (int, error) { … } // scanUntilBoundary scans buf to identify how much of it can be safely // returned as part of the Part body. // dashBoundary is "--boundary". // nlDashBoundary is "\r\n--boundary" or "\n--boundary", depending on what mode we are in. // The comments below (and the name) assume "\n--boundary", but either is accepted. // total is the number of bytes read out so far. If total == 0, then a leading "--boundary" is recognized. // readErr is the read error, if any, that followed reading the bytes in buf. // scanUntilBoundary returns the number of data bytes from buf that can be // returned as part of the Part body and also the error to return (if any) // once those data bytes are done. func scanUntilBoundary(buf, dashBoundary, nlDashBoundary []byte, total int64, readErr error) (int, error) { … } // matchAfterPrefix checks whether buf should be considered to match the boundary. // The prefix is "--boundary" or "\r\n--boundary" or "\n--boundary", // and the caller has verified already that bytes.HasPrefix(buf, prefix) is true. // // matchAfterPrefix returns +1 if the buffer does match the boundary, // meaning the prefix is followed by a double dash, space, tab, cr, nl, // or end of input. // It returns -1 if the buffer definitely does NOT match the boundary, // meaning the prefix is followed by some other character. // For example, "--foobar" does not match "--foo". // It returns 0 more input needs to be read to make the decision, // meaning that len(buf) == len(prefix) and readErr == nil. func matchAfterPrefix(buf, prefix []byte, readErr error) int { … } func (p *Part) Close() error { … } type Reader … const maxMIMEHeaderSize … var multipartmaxheaders … func maxMIMEHeaders() int64 { … } // NextPart returns the next part in the multipart or an error. // When there are no more parts, the error [io.EOF] is returned. // // 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. func (r *Reader) NextPart() (*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. // // Unlike [Reader.NextPart], it does not have special handling for // "Content-Transfer-Encoding: quoted-printable". func (r *Reader) NextRawPart() (*Part, error) { … } func (r *Reader) nextPart(rawPart bool, maxMIMEHeaderSize, maxMIMEHeaders int64) (*Part, error) { … } // isFinalBoundary reports whether line is the final boundary line // indicating that all parts are over. // It matches `^--boundary--[ \t]*(\r\n)?$` func (r *Reader) isFinalBoundary(line []byte) bool { … } func (r *Reader) isBoundaryDelimiterLine(line []byte) (ret bool) { … } // skipLWSPChar returns b with leading spaces and tabs removed. // RFC 822 defines: // // LWSP-char = SPACE / HTAB func skipLWSPChar(b []byte) []byte { … }