From 43c432dc08210ff0c84f6a18aec55d78e5bb4ea1 Mon Sep 17 00:00:00 2001 From: Simon Thulbourn Date: Fri, 4 Nov 2016 11:33:44 +0000 Subject: [PATCH] Remove pkg from vendor --- .../sthulb/mime/multipart/formdata.go | 157 ------- .../sthulb/mime/multipart/multipart.go | 388 ------------------ .../sthulb/mime/multipart/writer.go | 191 --------- vendor/vendor.json | 4 - 4 files changed, 740 deletions(-) delete mode 100644 vendor/github.com/sthulb/mime/multipart/formdata.go delete mode 100644 vendor/github.com/sthulb/mime/multipart/multipart.go delete mode 100644 vendor/github.com/sthulb/mime/multipart/writer.go diff --git a/vendor/github.com/sthulb/mime/multipart/formdata.go b/vendor/github.com/sthulb/mime/multipart/formdata.go deleted file mode 100644 index eee53fc8dd..0000000000 --- a/vendor/github.com/sthulb/mime/multipart/formdata.go +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright 2011 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. - -package multipart - -import ( - "bytes" - "errors" - "io" - "io/ioutil" - "net/textproto" - "os" -) - -// TODO(adg,bradfitz): find a way to unify the DoS-prevention strategy here -// with that of the http package's ParseForm. - -// ReadForm parses an entire multipart message whose parts have -// a Content-Disposition of "form-data". -// It stores up to maxMemory bytes of the file parts in memory -// and the remainder on disk in temporary files. -func (r *Reader) ReadForm(maxMemory int64) (f *Form, err error) { - form := &Form{make(map[string][]string), make(map[string][]*FileHeader)} - defer func() { - if err != nil { - form.RemoveAll() - } - }() - - maxValueBytes := int64(10 << 20) // 10 MB is a lot of text. - for { - p, err := r.NextPart() - if err == io.EOF { - break - } - if err != nil { - return nil, err - } - - name := p.FormName() - if name == "" { - continue - } - filename := p.FileName() - - var b bytes.Buffer - - if filename == "" { - // value, store as string in memory - n, err := io.CopyN(&b, p, maxValueBytes) - if err != nil && err != io.EOF { - return nil, err - } - maxValueBytes -= n - if maxValueBytes == 0 { - return nil, errors.New("multipart: message too large") - } - form.Value[name] = append(form.Value[name], b.String()) - continue - } - - // file, store in memory or on disk - fh := &FileHeader{ - Filename: filename, - Header: p.Header, - } - n, err := io.CopyN(&b, p, maxMemory+1) - if err != nil && err != io.EOF { - return nil, err - } - if n > maxMemory { - // too big, write to disk and flush buffer - file, err := ioutil.TempFile("", "multipart-") - if err != nil { - return nil, err - } - defer file.Close() - _, err = io.Copy(file, io.MultiReader(&b, p)) - if err != nil { - os.Remove(file.Name()) - return nil, err - } - fh.tmpfile = file.Name() - } else { - fh.content = b.Bytes() - maxMemory -= n - } - form.File[name] = append(form.File[name], fh) - } - - return form, nil -} - -// 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. -type Form struct { - Value map[string][]string - File map[string][]*FileHeader -} - -// RemoveAll removes any temporary files associated with a Form. -func (f *Form) RemoveAll() error { - var err error - for _, fhs := range f.File { - for _, fh := range fhs { - if fh.tmpfile != "" { - e := os.Remove(fh.tmpfile) - if e != nil && err == nil { - err = e - } - } - } - } - return err -} - -// A FileHeader describes a file part of a multipart request. -type FileHeader struct { - Filename string - Header textproto.MIMEHeader - - content []byte - tmpfile string -} - -// Open opens and returns the FileHeader's associated File. -func (fh *FileHeader) Open() (File, error) { - if b := fh.content; b != nil { - r := io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b))) - return sectionReadCloser{r}, nil - } - return os.Open(fh.tmpfile) -} - -// 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. -type File interface { - io.Reader - io.ReaderAt - io.Seeker - io.Closer -} - -// helper types to turn a []byte into a File - -type sectionReadCloser struct { - *io.SectionReader -} - -func (rc sectionReadCloser) Close() error { - return nil -} diff --git a/vendor/github.com/sthulb/mime/multipart/multipart.go b/vendor/github.com/sthulb/mime/multipart/multipart.go deleted file mode 100644 index 3b746a5e15..0000000000 --- a/vendor/github.com/sthulb/mime/multipart/multipart.go +++ /dev/null @@ -1,388 +0,0 @@ -// Copyright 2010 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. -// - -/* -Package multipart implements MIME multipart parsing, as defined in RFC -2046. - -The implementation is sufficient for HTTP (RFC 2388) and the multipart -bodies generated by popular browsers. -*/ -package multipart - -import ( - "bufio" - "bytes" - "fmt" - "io" - "io/ioutil" - "mime" - "mime/quotedprintable" - "net/textproto" -) - -var emptyParams = make(map[string]string) - -// This constant needs to be at least 76 for this package to work correctly. -// This is because \r\n--separator_of_len_70- would fill the buffer and it -// wouldn't be safe to consume a single byte from it. -const peekBufferSize = 4096 - -// A Part represents a single part in a multipart body. -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" - // - // As a special case, if the "Content-Transfer-Encoding" header - // has a value of "quoted-printable", that header is instead - // hidden from this map and the body is transparently decoded - // during Read calls. - Header textproto.MIMEHeader - - buffer *bytes.Buffer - mr *Reader - bytesRead int - - disposition string - dispositionParams map[string]string - - // r is either a reader directly reading from mr, or it's a - // wrapper around such a reader, decoding the - // Content-Transfer-Encoding - r io.Reader -} - -// 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 { - // See http://tools.ietf.org/html/rfc2183 section 2 for EBNF - // of Content-Disposition value format. - if p.dispositionParams == nil { - p.parseContentDisposition() - } - if p.disposition != "form-data" { - return "" - } - return p.dispositionParams["name"] -} - -// FileName returns the filename parameter of the Part's -// Content-Disposition header. -func (p *Part) FileName() string { - if p.dispositionParams == nil { - p.parseContentDisposition() - } - return p.dispositionParams["filename"] -} - -func (p *Part) parseContentDisposition() { - v := p.Header.Get("Content-Disposition") - var err error - p.disposition, p.dispositionParams, err = mime.ParseMediaType(v) - if err != nil { - p.dispositionParams = emptyParams - } -} - -// 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 { - b := []byte("\r\n--" + boundary + "--") - return &Reader{ - bufReader: bufio.NewReaderSize(r, peekBufferSize), - nl: b[:2], - nlDashBoundary: b[:len(b)-2], - dashBoundaryDash: b[2:], - dashBoundary: b[2 : len(b)-2], - } -} - -func newPart(mr *Reader) (*Part, error) { - bp := &Part{ - Header: make(map[string][]string), - mr: mr, - buffer: new(bytes.Buffer), - } - if err := bp.populateHeaders(); err != nil { - return nil, err - } - bp.r = partReader{bp} - const cte = "Content-Transfer-Encoding" - if bp.Header.Get(cte) == "quoted-printable" { - bp.Header.Del(cte) - bp.r = quotedprintable.NewReader(bp.r) - } - return bp, nil -} - -func (bp *Part) populateHeaders() error { - r := textproto.NewReader(bp.mr.bufReader) - header, err := r.ReadMIMEHeader() - if err == nil { - bp.Header = header - } - return err -} - -// 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) { - return p.r.Read(d) -} - -// partReader implements io.Reader by reading raw bytes directly from the -// wrapped *Part, without doing any Transfer-Encoding decoding. -type partReader struct { - p *Part -} - -func (pr partReader) Read(d []byte) (n int, err error) { - p := pr.p - defer func() { - p.bytesRead += n - }() - if p.buffer.Len() >= len(d) { - // Internal buffer of unconsumed data is large enough for - // the read request. No need to parse more at the moment. - return p.buffer.Read(d) - } - peek, err := p.mr.bufReader.Peek(peekBufferSize) // TODO(bradfitz): add buffer size accessor - - // Look for an immediate empty part without a leading \r\n - // before the boundary separator. Some MIME code makes empty - // parts like this. Most browsers, however, write the \r\n - // before the subsequent boundary even for empty parts and - // won't hit this path. - if p.bytesRead == 0 && p.mr.peekBufferIsEmptyPart(peek) { - return 0, io.EOF - } - unexpectedEOF := err == io.EOF - if err != nil && !unexpectedEOF { - return 0, fmt.Errorf("multipart: Part Read: %v", err) - } - if peek == nil { - panic("nil peek buf") - } - // Search the peek buffer for "\r\n--boundary". If found, - // consume everything up to the boundary. If not, consume only - // as much of the peek buffer as cannot hold the boundary - // string. - nCopy := 0 - foundBoundary := false - if idx, isEnd := p.mr.peekBufferSeparatorIndex(peek); idx != -1 { - nCopy = idx - foundBoundary = isEnd - if !isEnd && nCopy == 0 { - nCopy = 1 // make some progress. - } - } else if safeCount := len(peek) - len(p.mr.nlDashBoundary); safeCount > 0 { - nCopy = safeCount - } else if unexpectedEOF { - // If we've run out of peek buffer and the boundary - // wasn't found (and can't possibly fit), we must have - // hit the end of the file unexpectedly. - return 0, io.ErrUnexpectedEOF - } - if nCopy > 0 { - if _, err := io.CopyN(p.buffer, p.mr.bufReader, int64(nCopy)); err != nil { - return 0, err - } - } - n, err = p.buffer.Read(d) - if err == io.EOF && !foundBoundary { - // If the boundary hasn't been reached there's more to - // read, so don't pass through an EOF from the buffer - err = nil - } - return -} - -func (p *Part) Close() error { - io.Copy(ioutil.Discard, p) - return nil -} - -// Reader is an iterator over parts in a MIME multipart body. -// Reader's underlying parser consumes its input as needed. Seeking -// isn't supported. -type Reader struct { - bufReader *bufio.Reader - - currentPart *Part - partsRead int - - nl []byte // "\r\n" or "\n" (set after seeing first boundary line) - nlDashBoundary []byte // nl + "--boundary" - dashBoundaryDash []byte // "--boundary--" - dashBoundary []byte // "--boundary" -} - -// NextPart returns the next part in the multipart or an error. -// When there are no more parts, the error io.EOF is returned. -func (r *Reader) NextPart() (*Part, error) { - if r.currentPart != nil { - r.currentPart.Close() - } - - expectNewPart := false - for { - line, err := r.bufReader.ReadSlice('\n') - - if err == io.EOF && r.isFinalBoundary(line) { - // If the buffer ends in "--boundary--" without the - // trailing "\r\n", ReadSlice will return an error - // (since it's missing the '\n'), but this is a valid - // multipart EOF so we need to return io.EOF instead of - // a fmt-wrapped one. - return nil, io.EOF - } - if err != nil { - return nil, fmt.Errorf("multipart: NextPart: %v", err) - } - - if r.isBoundaryDelimiterLine(line) { - r.partsRead++ - bp, err := newPart(r) - if err != nil { - return nil, err - } - r.currentPart = bp - return bp, nil - } - - if r.isFinalBoundary(line) { - // Expected EOF - return nil, io.EOF - } - - if expectNewPart { - return nil, fmt.Errorf("multipart: expecting a new Part; got line %q", string(line)) - } - - if r.partsRead == 0 { - // skip line - continue - } - - // Consume the "\n" or "\r\n" separator between the - // body of the previous part and the boundary line we - // now expect will follow. (either a new part or the - // end boundary) - if bytes.Equal(line, r.nl) { - expectNewPart = true - continue - } - - return nil, fmt.Errorf("multipart: unexpected line in Next(): %q", line) - } -} - -// isFinalBoundary reports whether line is the final boundary line -// indicating that all parts are over. -// It matches `^--boundary--[ \t]*(\r\n)?$` -func (mr *Reader) isFinalBoundary(line []byte) bool { - if !bytes.HasPrefix(line, mr.dashBoundaryDash) { - return false - } - rest := line[len(mr.dashBoundaryDash):] - rest = skipLWSPChar(rest) - return len(rest) == 0 || bytes.Equal(rest, mr.nl) -} - -func (mr *Reader) isBoundaryDelimiterLine(line []byte) (ret bool) { - // http://tools.ietf.org/html/rfc2046#section-5.1 - // The boundary delimiter line is then defined as a line - // consisting entirely of two hyphen characters ("-", - // decimal value 45) followed by the boundary parameter - // value from the Content-Type header field, optional linear - // whitespace, and a terminating CRLF. - if !bytes.HasPrefix(line, mr.dashBoundary) { - return false - } - rest := line[len(mr.dashBoundary):] - rest = skipLWSPChar(rest) - - // On the first part, see our lines are ending in \n instead of \r\n - // and switch into that mode if so. This is a violation of the spec, - // but occurs in practice. - if mr.partsRead == 0 && len(rest) == 1 && rest[0] == '\n' { - mr.nl = mr.nl[1:] - mr.nlDashBoundary = mr.nlDashBoundary[1:] - } - return bytes.Equal(rest, mr.nl) -} - -// peekBufferIsEmptyPart reports whether the provided peek-ahead -// buffer represents an empty part. It is called only if we've not -// already read any bytes in this part and checks for the case of MIME -// software not writing the \r\n on empty parts. Some does, some -// doesn't. -// -// This checks that what follows the "--boundary" is actually the end -// ("--boundary--" with optional whitespace) or optional whitespace -// and then a newline, so we don't catch "--boundaryFAKE", in which -// case the whole line is part of the data. -func (mr *Reader) peekBufferIsEmptyPart(peek []byte) bool { - // End of parts case. - // Test whether peek matches `^--boundary--[ \t]*(?:\r\n|$)` - if bytes.HasPrefix(peek, mr.dashBoundaryDash) { - rest := peek[len(mr.dashBoundaryDash):] - rest = skipLWSPChar(rest) - return bytes.HasPrefix(rest, mr.nl) || len(rest) == 0 - } - if !bytes.HasPrefix(peek, mr.dashBoundary) { - return false - } - // Test whether rest matches `^[ \t]*\r\n`) - rest := peek[len(mr.dashBoundary):] - rest = skipLWSPChar(rest) - return bytes.HasPrefix(rest, mr.nl) -} - -// peekBufferSeparatorIndex returns the index of mr.nlDashBoundary in -// peek and whether it is a real boundary (and not a prefix of an -// unrelated separator). To be the end, the peek buffer must contain a -// newline after the boundary or contain the ending boundary (--separator--). -func (mr *Reader) peekBufferSeparatorIndex(peek []byte) (idx int, isEnd bool) { - idx = bytes.Index(peek, mr.nlDashBoundary) - if idx == -1 { - return - } - - peek = peek[idx+len(mr.nlDashBoundary):] - if len(peek) == 0 || len(peek) == 1 && peek[0] == '-' { - return idx, false - } - if len(peek) > 1 && peek[0] == '-' && peek[1] == '-' { - return idx, true - } - peek = skipLWSPChar(peek) - // Don't have a complete line after the peek. - if bytes.IndexByte(peek, '\n') == -1 { - return idx, false - } - if len(peek) > 0 && peek[0] == '\n' { - return idx, true - } - if len(peek) > 1 && peek[0] == '\r' && peek[1] == '\n' { - return idx, true - } - return idx, false -} - -// skipLWSPChar returns b with leading spaces and tabs removed. -// RFC 822 defines: -// LWSP-char = SPACE / HTAB -func skipLWSPChar(b []byte) []byte { - for len(b) > 0 && (b[0] == ' ' || b[0] == '\t') { - b = b[1:] - } - return b -} diff --git a/vendor/github.com/sthulb/mime/multipart/writer.go b/vendor/github.com/sthulb/mime/multipart/writer.go deleted file mode 100644 index ffb4b9d53c..0000000000 --- a/vendor/github.com/sthulb/mime/multipart/writer.go +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright 2011 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. - -package multipart - -import ( - "bytes" - "crypto/rand" - "errors" - "fmt" - "io" - "net/textproto" - "sort" - "strings" -) - -// A Writer generates multipart messages. -type Writer struct { - w io.Writer - boundary string - lastpart *part -} - -// NewWriter returns a new multipart Writer with a random boundary, -// writing to w. -func NewWriter(w io.Writer) *Writer { - return &Writer{ - w: w, - boundary: randomBoundary(), - } -} - -// Boundary returns the Writer's boundary. -func (w *Writer) Boundary() string { - return w.boundary -} - -// SetBoundary overrides the Writer's default randomly-generated -// boundary separator with an explicit value. -// -// SetBoundary must be called before any parts are created, may only -// contain certain ASCII characters, and must be non-empty and -// at most 69 bytes long. -func (w *Writer) SetBoundary(boundary string) error { - if w.lastpart != nil { - return errors.New("mime: SetBoundary called after write") - } - // rfc2046#section-5.1.1 - if len(boundary) < 1 || len(boundary) > 69 { - return errors.New("mime: invalid boundary length") - } - for _, b := range boundary { - if 'A' <= b && b <= 'Z' || 'a' <= b && b <= 'z' || '0' <= b && b <= '9' { - continue - } - switch b { - case '\'', '(', ')', '+', '_', ',', '-', '.', '/', ':', '=', '?': - continue - } - return errors.New("mime: invalid boundary character") - } - w.boundary = boundary - return nil -} - -// FormDataContentType returns the Content-Type for an HTTP -// multipart/form-data with this Writer's Boundary. -func (w *Writer) FormDataContentType() string { - return "multipart/form-data; boundary=" + w.boundary -} - -func randomBoundary() string { - var buf [30]byte - _, err := io.ReadFull(rand.Reader, buf[:]) - if err != nil { - panic(err) - } - return fmt.Sprintf("%x", buf[:]) -} - -// 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. -func (w *Writer) CreatePart(header textproto.MIMEHeader) (io.Writer, error) { - if w.lastpart != nil { - if err := w.lastpart.close(); err != nil { - return nil, err - } - } - var b bytes.Buffer - if w.lastpart != nil { - fmt.Fprintf(&b, "\r\n--%s\r\n", w.boundary) - } else { - fmt.Fprintf(&b, "--%s\r\n", w.boundary) - } - - keys := make([]string, 0, len(header)) - for k := range header { - keys = append(keys, k) - } - sort.Strings(keys) - - for _, k := range keys { - for _, v := range header[k] { - fmt.Fprintf(&b, "%s: %s\r\n", k, v) - } - } - fmt.Fprintf(&b, "\r\n") - _, err := io.Copy(w.w, &b) - if err != nil { - return nil, err - } - p := &part{ - mw: w, - } - w.lastpart = p - return p, nil -} - -var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"") - -func escapeQuotes(s string) string { - return quoteEscaper.Replace(s) -} - -// CreateFormFile is a convenience wrapper around CreatePart. It creates -// a new form-data header with the provided field name and file name. -func (w *Writer) CreateFormFile(fieldname, filename string) (io.Writer, error) { - h := make(textproto.MIMEHeader) - h.Set("Content-Disposition", - fmt.Sprintf(`form-data; name="%s"; filename="%s"`, - escapeQuotes(fieldname), escapeQuotes(filename))) - h.Set("Content-Type", "application/octet-stream") - return w.CreatePart(h) -} - -// CreateFormField calls CreatePart with a header using the -// given field name. -func (w *Writer) CreateFormField(fieldname string) (io.Writer, error) { - h := make(textproto.MIMEHeader) - h.Set("Content-Disposition", - fmt.Sprintf(`form-data; name="%s"`, escapeQuotes(fieldname))) - return w.CreatePart(h) -} - -// WriteField calls CreateFormField and then writes the given value. -func (w *Writer) WriteField(fieldname, value string) error { - p, err := w.CreateFormField(fieldname) - if err != nil { - return err - } - _, err = p.Write([]byte(value)) - return err -} - -// Close finishes the multipart message and writes the trailing -// boundary end line to the output. -func (w *Writer) Close() error { - if w.lastpart != nil { - if err := w.lastpart.close(); err != nil { - return err - } - w.lastpart = nil - } - _, err := fmt.Fprintf(w.w, "\r\n--%s--\r\n", w.boundary) - return err -} - -type part struct { - mw *Writer - closed bool - we error // last error that occurred writing -} - -func (p *part) close() error { - p.closed = true - return p.we -} - -func (p *part) Write(d []byte) (n int, err error) { - if p.closed { - return 0, errors.New("multipart: can't write to finished part") - } - n, err = p.mw.w.Write(d) - if err != nil { - p.we = err - } - return -} diff --git a/vendor/vendor.json b/vendor/vendor.json index e5de85bfd5..aec14e6a98 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1830,10 +1830,6 @@ "path": "github.com/soniah/dnsmadeeasy", "revision": "5578a8c15e33958c61cf7db720b6181af65f4a9e" }, - { - "path": "github.com/sthulb/mime/multipart", - "revision": "698462dc9685d7743511c26da726c1b0c1cfb111" - }, { "path": "github.com/tent/http-link-go", "revision": "ac974c61c2f990f4115b119354b5e0b47550e888"