Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate go-ipfs-files #20

Merged
merged 104 commits into from
Jan 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
2d3f8dc
add files/ - was previously in go-ipfs-cmds
keks Apr 16, 2017
088a785
make tests also except EOF error
keks Apr 26, 2017
e493697
fix 'file already closed' in Go 1.9
Oct 15, 2017
b407a66
use goang.org/x/sys/windows
Stebalien Nov 18, 2017
7894205
Import MultiFileReader from go-ipfs-cmds
Nov 19, 2017
27e92b6
fall back to application/octet-stream if Content-Type is empty
Dec 11, 2017
6cfc790
only count size for regular files
Stebalien Jul 26, 2018
f215642
Feat: add WebFile File implementation.
hsanjuan Aug 19, 2018
69fcace
Webfile tests: use httptest.Server
hsanjuan Aug 20, 2018
0a522e3
Add README, LICENSE
magik6k Oct 16, 2018
ef11939
[WIP] Refactor filename - file relation
magik6k Oct 23, 2018
239810e
Allow Close on dirs, make sure errors make sense
magik6k Oct 24, 2018
49d7a0e
fix IsHidden on windows
magik6k Nov 5, 2018
8ec0a67
Separate file/directory types
magik6k Nov 7, 2018
8e6f6db
Directory iterators
magik6k Nov 7, 2018
e8aa730
Rename File/Regular to Node/File
magik6k Nov 9, 2018
5a00a26
move the MultipartFile iterator note
magik6k Nov 14, 2018
aa310c6
Fix some iterators after rename
magik6k Nov 16, 2018
5a89821
Fix errors import
magik6k Nov 19, 2018
ee6b055
Don't return error from Entries
magik6k Nov 24, 2018
9956a2b
Fix error return in multipartfile
magik6k Nov 26, 2018
e449707
Don't expose io.EOF in multifilereader
magik6k Nov 29, 2018
a4e5147
files2.0: Add some convenience functions
magik6k Dec 3, 2018
9bdb3d2
files2.0: no error from NewMultiFileReader
magik6k Dec 3, 2018
5d0cdac
Allow skipping entries in multipartIterator
magik6k Dec 9, 2018
2c1df9d
Expand docstring for Directory.Entries
magik6k Dec 9, 2018
d2515d7
More type-safe utility functions
magik6k Dec 10, 2018
44f354a
Improve Directory docs
magik6k Dec 12, 2018
976a044
More type-safety for multipartFile
magik6k Dec 12, 2018
584821c
Reword note on Directory.Entries
magik6k Dec 13, 2018
6015fd6
Merge pull request ipfs/go-ipfs-files#2 from ipfs/feat/refactor-dir
magik6k Dec 13, 2018
e52b4c0
TarWriter
magik6k Jan 24, 2019
dbb8fc1
TarWriter test
magik6k Jan 24, 2019
b6c3239
Writer -> TarWriter
magik6k Jan 25, 2019
46f63ae
Merge pull request ipfs/go-ipfs-files#4 from ipfs/feat/tarwriter
Stebalien Jan 29, 2019
96b049e
create implicit directories from multipart requests
Stebalien Feb 9, 2019
93e77ee
multipart: attach nextFile to multipartWalker
magik6k Feb 11, 2019
4e2b29f
multipart: comment on why we stash EOF in the iterator
Stebalien Feb 11, 2019
67707d0
Merge pull request ipfs/go-ipfs-files#6 from ipfs/fix/5
Stebalien Feb 11, 2019
85db9ec
multipart: fix handling of common prefixes
Stebalien Feb 11, 2019
88b1f80
Merge pull request ipfs/go-ipfs-files#7 from ipfs/fix/common-prefix
Stebalien Feb 11, 2019
72615d9
simplify content type checking
Stebalien Feb 21, 2019
270c79b
remove extra webfile test code
jmank88 Mar 17, 2019
c5f5321
Merge pull request ipfs/go-ipfs-files#12 from jmank88/webfile-test
Stebalien Mar 20, 2019
d12be9d
Merge pull request ipfs/go-ipfs-files#9 from ipfs/nit/content-type-ch…
Stebalien Mar 20, 2019
b0f20ff
go format
Stebalien Mar 20, 2019
ca34ecc
Merge pull request ipfs/go-ipfs-files#15 from ipfs/fix/gofmt
Stebalien Mar 20, 2019
8bf5a97
fix the content disposition header
Stebalien Mar 20, 2019
880ae9f
return url as AbsPath from WebFile to implement FileInfo
jmank88 Mar 19, 2019
4b7eabe
Merge pull request ipfs/go-ipfs-files#14 from ipfs/fix/content-dispos…
Stebalien Mar 20, 2019
9ea7640
Merge pull request ipfs/go-ipfs-files#13 from jmank88/webfile-abspath
Stebalien Mar 21, 2019
4fed0b8
check http status code during WebFile reads and return error for non-2XX
jmank88 Apr 22, 2019
cf1d3b4
Merge pull request ipfs/go-ipfs-files#17 from jmank88/webfile-err
Stebalien Apr 22, 2019
84f9621
webfile: make Size() work before Read
Stebalien Apr 26, 2019
357442b
Merge pull request ipfs/go-ipfs-files#18 from ipfs/fix/webfile-size
Stebalien Apr 26, 2019
4b06448
doc: fix formdata documentation
Stebalien Aug 9, 2019
9cdf6a4
Merge pull request ipfs/go-ipfs-files#19 from ipfs/fix/doc-nit
Stebalien Aug 9, 2019
264faca
feat: add WriteTo function
Stebalien Aug 16, 2019
9961952
Merge pull request ipfs/go-ipfs-files#20 from ipfs/feat/write-to
Stebalien Aug 16, 2019
fc2a1a2
serialfile: fix handling of hidden paths on windows
Stebalien Aug 16, 2019
caa31c7
test: fix an edge case
Stebalien Aug 16, 2019
694bbf0
walk: add a walk function
Stebalien Aug 16, 2019
626c7bf
test: test walk, serialfile, and hidden
Stebalien Aug 16, 2019
d475ef3
Merge pull request ipfs/go-ipfs-files#21 from ipfs/fix/11
Stebalien Aug 16, 2019
49818ba
doc: add a lead maintainer
Stebalien Sep 19, 2019
280ebca
feat: correctly report the size of symlinks
Stebalien Sep 26, 2019
92aa596
Merge pull request ipfs/go-ipfs-files#22 from ipfs/feat/symlink-size
Stebalien Sep 26, 2019
dbc14ee
revert(symlink): keep stat argument
Stebalien Sep 26, 2019
a62d4bc
Merge pull request ipfs/go-ipfs-files#23 from ipfs/revert/symlink-con…
Stebalien Sep 26, 2019
89a0951
chore: remove dead code
Stebalien Mar 17, 2020
8225cc0
Merge pull request ipfs/go-ipfs-files#29 from ipfs/chore/remove-dead-…
Stebalien Mar 17, 2020
497fdd7
feat(file-ignore): add file ignore rules to serialfile
corntoole Feb 16, 2020
afe2a5b
Merge pull request ipfs/go-ipfs-files#26 from fission-suite/feat/add-…
Stebalien Mar 18, 2020
b865765
fix: skip ignored files when calculating size
Stebalien Mar 29, 2020
88bf274
test: test file size when ignoring
Stebalien Mar 30, 2020
7e3fd4f
Merge pull request ipfs/go-ipfs-files#30 from ipfs/fix/skip-files-size
Stebalien Mar 30, 2020
e43b527
fix go vet
marten-seemann Jun 2, 2021
f8b03ed
fix staticcheck
marten-seemann Jun 2, 2021
aae0024
Merge pull request ipfs/go-ipfs-files#33 from ipfs/fix-linters
marten-seemann Jun 2, 2021
bf03bd6
fix staticcheck
marten-seemann Jun 2, 2021
1c18dbc
Merge pull request ipfs/go-ipfs-files#35 from ipfs/fix-staticcheck
marten-seemann Jun 2, 2021
b973565
Fix test failure on Windows caused by nil `sys` in mock `FileInfo`
masih Jul 22, 2021
9345abc
Merge pull request ipfs/go-ipfs-files#39 from ipfs/masih/fix-win-test…
marten-seemann Jul 22, 2021
ecef908
Mock `FileInfo.Sys()` to return `nil` explicitly
masih Jul 22, 2021
302094f
Normalize path separator in tests based in OS
masih Jul 22, 2021
1a66dc4
Merge pull request ipfs/go-ipfs-files#34 from ipfs/web3-bot/sync
marten-seemann Jul 22, 2021
f2b9025
fix: round timestamps down by truncating them to seconds
Stebalien Sep 5, 2021
5c40acb
Merge pull request ipfs/go-ipfs-files#41 from ipfs/fix/tar-time-rounding
Stebalien Sep 9, 2021
ecf58d5
fix: manually parse the content disposition to preserve directories
Stebalien Sep 21, 2021
97be592
Merge pull request ipfs/go-ipfs-files#42 from ipfs/fix/multipart-parsing
lidel Oct 5, 2021
589fb77
run gofmt -s
web3-bot Sep 15, 2021
bb987bc
Merge pull request ipfs/go-ipfs-files#40 from ipfs/web3-bot/sync
lidel Oct 5, 2021
221144f
chore(filewriter): cleanup writes (#43)
schomatis Jan 14, 2022
45fc941
docs: fix community CONTRIBUTING.md link (#45)
armujahid Jan 14, 2022
38ce1df
fix: add freebsd build option for filewriter flags
aschmahmann Jan 18, 2022
4ebe090
fix: add dragonfly build option for filewriter flags
waybackarchiver Jan 23, 2022
7418db2
chore(Directory): add DirIterator API restriction: iterate only once
schomatis Aug 2, 2022
4940354
bump go.mod to Go 1.18 and run go fix
web3-bot Sep 1, 2022
8520c19
stop using the deprecated io/ioutil package
web3-bot Sep 1, 2022
e6e3c80
fix: type of contents in serialfile
galargh Sep 1, 2022
49b8249
Merge pull request ipfs/go-ipfs-files#55 from ipfs/web3-bot/sync
galargh Sep 1, 2022
83a75d2
fix: error when TAR has files outside of root (#56)
hacdias Nov 9, 2022
1731c7b
Merge commits from ipfs/go-ipfs-files/master
hacdias Jan 11, 2023
ad29d57
go mod tidy
hacdias Jan 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions files/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# go-ipfs-files

[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io)
[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/)
[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs)
[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)

> File interfaces and utils used in IPFS

## Lead Maintainer

[Steven Allen](https://github.com/Stebalien)

## Documentation

https://godoc.org/github.com/ipfs/go-ipfs-files

## Contribute

Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-ipfs-files/issues)!

This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).

### Want to hack on IPFS?

[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md)

## License

MIT

96 changes: 96 additions & 0 deletions files/file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package files

import (
"errors"
"io"
"os"
)

var (
ErrNotDirectory = errors.New("file isn't a directory")
ErrNotReader = errors.New("file isn't a regular file")

ErrNotSupported = errors.New("operation not supported")
)

// Node is a common interface for files, directories and other special files
type Node interface {
io.Closer

// Size returns size of this file (if this file is a directory, total size of
// all files stored in the tree should be returned). Some implementations may
// choose not to implement this
Size() (int64, error)
}

// Node represents a regular Unix file
type File interface {
Node

io.Reader
io.Seeker
}

// DirEntry exposes information about a directory entry
type DirEntry interface {
// Name returns base name of this entry, which is the base name of referenced
// file
Name() string

// Node returns the file referenced by this DirEntry
Node() Node
}

// DirIterator is a iterator over directory entries.
// See Directory.Entries for more
type DirIterator interface {
// DirEntry holds information about current directory entry.
// Note that after creating new iterator you MUST call Next() at least once
// before accessing these methods. Calling these methods without prior calls
// to Next() and after Next() returned false may result in undefined behavior
DirEntry

// Next advances iterator to the next file.
Next() bool

// Err may return an error after previous call to Next() returned `false`.
// If previous call to Next() returned `true`, Err() is guaranteed to
// return nil
Err() error
}

// Directory is a special file which can link to any number of files.
type Directory interface {
Node

// Entries returns a stateful iterator over directory entries. The iterator
// may consume the Directory state so it must be called only once (this
// applies specifically to the multipartIterator).
//
// Example usage:
//
// it := dir.Entries()
// for it.Next() {
// name := it.Name()
// file := it.Node()
// [...]
// }
// if it.Err() != nil {
// return err
// }
//
// Note that you can't store the result of it.Node() and use it after
// advancing the iterator
Entries() DirIterator
}

// FileInfo exposes information on files in local filesystem
type FileInfo interface {
Node

// AbsPath returns full real file path.
AbsPath() string

// Stat returns os.Stat of this file, may be nil for some files
Stat() os.FileInfo
}
142 changes: 142 additions & 0 deletions files/file_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package files

import (
"io"
"mime/multipart"
"strings"
"testing"
)

func TestSliceFiles(t *testing.T) {
sf := NewMapDirectory(map[string]Node{
"1": NewBytesFile([]byte("Some text!\n")),
"2": NewBytesFile([]byte("beep")),
"3": NewBytesFile([]byte("boop")),
})

CheckDir(t, sf, []Event{
{
kind: TFile,
name: "1",
value: "Some text!\n",
},
{
kind: TFile,
name: "2",
value: "beep",
},
{
kind: TFile,
name: "3",
value: "boop",
},
})
}

func TestReaderFiles(t *testing.T) {
message := "beep boop"
rf := NewBytesFile([]byte(message))
buf := make([]byte, len(message))

if n, err := rf.Read(buf); n == 0 || err != nil {
t.Fatal("Expected to be able to read")
}
if err := rf.Close(); err != nil {
t.Fatal("Should be able to close")
}
if n, err := rf.Read(buf); n != 0 || err != io.EOF {
t.Fatal("Expected EOF when reading after close")
}
}
func TestMultipartFiles(t *testing.T) {
data := `
--Boundary!
Content-Type: text/plain
Content-Disposition: file; filename="name"
Some-Header: beep

beep
--Boundary!
Content-Type: application/x-directory
Content-Disposition: file; filename="dir"

--Boundary!
Content-Type: text/plain
Content-Disposition: file; filename="dir/nested"

some content
--Boundary!
Content-Type: application/symlink
Content-Disposition: file; filename="dir/simlynk"

anotherfile
--Boundary!
Content-Type: text/plain
Content-Disposition: file; filename="implicit1/implicit2/deep_implicit"

implicit file1
--Boundary!
Content-Type: text/plain
Content-Disposition: file; filename="implicit1/shallow_implicit"

implicit file2
--Boundary!--

`

reader := strings.NewReader(data)
mpReader := multipart.NewReader(reader, "Boundary!")
dir, err := NewFileFromPartReader(mpReader, multipartFormdataType)
if err != nil {
t.Fatal(err)
}

CheckDir(t, dir, []Event{
{
kind: TFile,
name: "name",
value: "beep",
},
{
kind: TDirStart,
name: "dir",
},
{
kind: TFile,
name: "nested",
value: "some content",
},
{
kind: TSymlink,
name: "simlynk",
value: "anotherfile",
},
{
kind: TDirEnd,
},
{
kind: TDirStart,
name: "implicit1",
},
{
kind: TDirStart,
name: "implicit2",
},
{
kind: TFile,
name: "deep_implicit",
value: "implicit file1",
},
{
kind: TDirEnd,
},
{
kind: TFile,
name: "shallow_implicit",
value: "implicit file2",
},
{
kind: TDirEnd,
},
})
}
59 changes: 59 additions & 0 deletions files/filewriter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package files

import (
"errors"
"fmt"
"io"
"os"
"path/filepath"
)

var ErrInvalidDirectoryEntry = errors.New("invalid directory entry name")
var ErrPathExistsOverwrite = errors.New("path already exists and overwriting is not allowed")

// WriteTo writes the given node to the local filesystem at fpath.
func WriteTo(nd Node, fpath string) error {
if _, err := os.Lstat(fpath); err == nil {
return ErrPathExistsOverwrite
} else if !os.IsNotExist(err) {
return err
}
switch nd := nd.(type) {
case *Symlink:
return os.Symlink(nd.Target, fpath)
case File:
f, err := createNewFile(fpath)
defer f.Close()
if err != nil {
return err
}
_, err = io.Copy(f, nd)
if err != nil {
return err
}
return nil
case Directory:
err := os.Mkdir(fpath, 0777)
if err != nil {
return err
}

entries := nd.Entries()
for entries.Next() {
entryName := entries.Name()
if entryName == "" ||
entryName == "." ||
entryName == ".." ||
!isValidFilename(entryName) {
return ErrInvalidDirectoryEntry
}
child := filepath.Join(fpath, entryName)
if err := WriteTo(entries.Node(), child); err != nil {
return err
}
}
return entries.Err()
default:
return fmt.Errorf("file type %T at %q is not supported", nd, fpath)
}
}
Loading