X-Git-Url: http://git.osdn.net/view?p=bytom%2Fvapor.git;a=blobdiff_plain;f=vendor%2Fgithub.com%2Fipfs%2Fgo-ipfs-files%2Fmultipartfile.go;fp=vendor%2Fgithub.com%2Fipfs%2Fgo-ipfs-files%2Fmultipartfile.go;h=0000000000000000000000000000000000000000;hp=17681653f45fcf3e216cf4c938c026d370ff5776;hb=54373c1a3efe0e373ec1605840a4363e4b246c46;hpb=ee01d543fdfe1fd0a4d548965c66f7923ea7b062 diff --git a/vendor/github.com/ipfs/go-ipfs-files/multipartfile.go b/vendor/github.com/ipfs/go-ipfs-files/multipartfile.go deleted file mode 100644 index 17681653..00000000 --- a/vendor/github.com/ipfs/go-ipfs-files/multipartfile.go +++ /dev/null @@ -1,236 +0,0 @@ -package files - -import ( - "io" - "io/ioutil" - "mime" - "mime/multipart" - "net/url" - "path" - "strings" -) - -const ( - multipartFormdataType = "multipart/form-data" - multipartMixedType = "multipart/mixed" - - applicationDirectory = "application/x-directory" - applicationSymlink = "application/symlink" - applicationFile = "application/octet-stream" - - contentTypeHeader = "Content-Type" -) - -type multipartDirectory struct { - path string - walker *multipartWalker - - // part is the part describing the directory. It's nil when implicit. - part *multipart.Part -} - -type multipartWalker struct { - part *multipart.Part - reader *multipart.Reader -} - -func (m *multipartWalker) consumePart() { - m.part = nil -} - -func (m *multipartWalker) getPart() (*multipart.Part, error) { - if m.part != nil { - return m.part, nil - } - if m.reader == nil { - return nil, io.EOF - } - - var err error - m.part, err = m.reader.NextPart() - if err == io.EOF { - m.reader = nil - } - return m.part, err -} - -func NewFileFromPartReader(reader *multipart.Reader, mediatype string) (Directory, error) { - if !isDirectory(mediatype) { - return nil, ErrNotDirectory - } - - return &multipartDirectory{ - path: "/", - walker: &multipartWalker{ - reader: reader, - }, - }, nil -} - -func (w *multipartWalker) nextFile() (Node, error) { - part, err := w.getPart() - if err != nil { - return nil, err - } - w.consumePart() - - contentType := part.Header.Get(contentTypeHeader) - switch contentType { - case applicationSymlink: - out, err := ioutil.ReadAll(part) - if err != nil { - return nil, err - } - - return NewLinkFile(string(out), nil), nil - case "": // default to application/octet-stream - fallthrough - case applicationFile: - return &ReaderFile{ - reader: part, - abspath: part.Header.Get("abspath"), - }, nil - } - - mediatype, _, err := mime.ParseMediaType(contentType) - if err != nil { - return nil, err - } - - if !isDirectory(mediatype) { - return &ReaderFile{ - reader: part, - abspath: part.Header.Get("abspath"), - }, nil - } - - return &multipartDirectory{ - part: part, - path: fileName(part), - walker: w, - }, nil -} - -// fileName returns a normalized filename from a part. -func fileName(part *multipart.Part) string { - filename := part.FileName() - if escaped, err := url.QueryUnescape(filename); err == nil { - filename = escaped - } // if there is a unescape error, just treat the name as unescaped - - return path.Clean("/" + filename) -} - -// dirName appends a slash to the end of the filename, if not present. -// expects a _cleaned_ path. -func dirName(filename string) string { - if !strings.HasSuffix(filename, "/") { - filename += "/" - } - return filename -} - -// isDirectory checks if the media type is a valid directory media type. -func isDirectory(mediatype string) bool { - return mediatype == multipartFormdataType || mediatype == applicationDirectory -} - -// isChild checks if child is a child of parent directory. -// expects a _cleaned_ path. -func isChild(child, parent string) bool { - return strings.HasPrefix(child, dirName(parent)) -} - -// makeRelative makes the child path relative to the parent path. -// expects a _cleaned_ path. -func makeRelative(child, parent string) string { - return strings.TrimPrefix(child, dirName(parent)) -} - -type multipartIterator struct { - f *multipartDirectory - - curFile Node - curName string - err error -} - -func (it *multipartIterator) Name() string { - return it.curName -} - -func (it *multipartIterator) Node() Node { - return it.curFile -} - -func (it *multipartIterator) Next() bool { - if it.f.walker.reader == nil || it.err != nil { - return false - } - var part *multipart.Part - for { - part, it.err = it.f.walker.getPart() - if it.err != nil { - return false - } - - name := fileName(part) - - // Is the file in a different directory? - if !isChild(name, it.f.path) { - return false - } - - // Have we already entered this directory? - if it.curName != "" && isChild(name, path.Join(it.f.path, it.curName)) { - it.f.walker.consumePart() - continue - } - - // Make the path relative to the current directory. - name = makeRelative(name, it.f.path) - - // Check if we need to create a fake directory (more than one - // path component). - if idx := strings.IndexByte(name, '/'); idx >= 0 { - it.curName = name[:idx] - it.curFile = &multipartDirectory{ - path: path.Join(it.f.path, it.curName), - walker: it.f.walker, - } - return true - } - it.curName = name - - // Finally, advance to the next file. - it.curFile, it.err = it.f.walker.nextFile() - - return it.err == nil - } -} - -func (it *multipartIterator) Err() error { - // We use EOF to signal that this iterator is done. That way, we don't - // need to check every time `Next` is called. - if it.err == io.EOF { - return nil - } - return it.err -} - -func (f *multipartDirectory) Entries() DirIterator { - return &multipartIterator{f: f} -} - -func (f *multipartDirectory) Close() error { - if f.part != nil { - return f.part.Close() - } - return nil -} - -func (f *multipartDirectory) Size() (int64, error) { - return 0, ErrNotSupported -} - -var _ Directory = &multipartDirectory{}