diff options
author | Tianon Gravi <admwiggin@gmail.com> | 2015-01-15 11:54:00 -0700 |
---|---|---|
committer | Tianon Gravi <admwiggin@gmail.com> | 2015-01-15 11:54:00 -0700 |
commit | f154da9e12608589e8d5f0508f908a0c3e88a1bb (patch) | |
tree | f8255d51e10c6f1e0ed69702200b966c9556a431 /src/pkg/mime/multipart/formdata.go | |
parent | 8d8329ed5dfb9622c82a9fbec6fd99a580f9c9f6 (diff) | |
download | golang-upstream/1.4.tar.gz |
Imported Upstream version 1.4upstream/1.4
Diffstat (limited to 'src/pkg/mime/multipart/formdata.go')
-rw-r--r-- | src/pkg/mime/multipart/formdata.go | 157 |
1 files changed, 0 insertions, 157 deletions
diff --git a/src/pkg/mime/multipart/formdata.go b/src/pkg/mime/multipart/formdata.go deleted file mode 100644 index eee53fc8d..000000000 --- a/src/pkg/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 -} |