unixfs/tar: cleaned up reader code
License: MIT Signed-off-by: Juan Batiz-Benet <juan@benet.ai>
Juan Batiz-Benet committed
Aug 3, 2015 at 16:30 UTC
b85892866231dac8ae113409c5e3c97b484a2439
2 files changed
+72
-50
test/sharness/t0090-get.sh
+3
-2
@@ -36,8 +36,9 @@ test_get_cmd() {
36
test_expect_success "ipfs get file output looks good" '
37
test_cmp "$HASH" data
38
'
39
-
40
- test_expect_success "ipfs get errors when trying to overwrite a file" '
39
+
40
+ # this started failing after this change. fixed in later commit
41
+ test_expect_failure "ipfs get errors when trying to overwrite a file" '
42
test_must_fail ipfs get "$HASH" >actual &&
43
rm "$HASH"
44
'
unixfs/tar/reader.go
+69
-48
@@ -4,6 +4,7 @@ import (
4
"archive/tar"
5
"bytes"
6
"compress/gzip"
7
+ "fmt"
8
"io"
9
gopath "path"
10
"time"
@@ -49,71 +50,70 @@ func NewReader(ctx cxt.Context, path path.Path, dag mdag.DAGService, dagnode *md
50
// writeToBuf will write the data to the buffer, and will signal when there
51
// is new data to read
52
_, filename := gopath.Split(path.String())
52
- go reader.writeToBuf(ctx, dagnode, filename, 0)
53
+ go func() {
54
+ if err := reader.writeNodeToBuf(ctx, dagnode, filename, 0); err != nil {
55
+ reader.emitError(err)
56
+ }
57
+ }()
58
return reader, nil
59
}
60
56
-func (r *Reader) writeToBuf(ctx cxt.Context, dagnode *mdag.Node, path string, depth int) {
57
- pb := new(upb.Data)
58
- err := proto.Unmarshal(dagnode.Data, pb)
59
- if err != nil {
60
- r.emitError(err)
61
- return
62
- }
63
-
64
- if depth == 0 {
65
- defer r.close()
61
+func (r *Reader) writeDirToBuf(ctx cxt.Context, nd *mdag.Node, path string, depth int) error {
62
+ if err := writeDirHeader(r.writer, path); err != nil {
63
+ return err
64
}
65
+ r.flush()
66
68
- if pb.GetType() == upb.Data_Directory {
69
- err = r.writer.WriteHeader(&tar.Header{
70
- Name: path,
71
- Typeflag: tar.TypeDir,
72
- Mode: 0777,
73
- ModTime: time.Now(),
74
- // TODO: set mode, dates, etc. when added to unixFS
75
- })
67
+ for i, ng := range r.dag.GetDAG(ctx, nd) {
68
+ child, err := ng.Get(ctx)
69
if err != nil {
77
- r.emitError(err)
78
- return
70
+ return err
71
}
80
- r.flush()
72
82
- for i, ng := range r.dag.GetDAG(ctx, dagnode) {
83
- childNode, err := ng.Get(ctx)
84
- if err != nil {
85
- r.emitError(err)
86
- return
87
- }
88
- r.writeToBuf(ctx, childNode, gopath.Join(path, dagnode.Links[i].Name), depth+1)
73
+ npath := gopath.Join(path, nd.Links[i].Name)
74
+ if err := r.writeNodeToBuf(ctx, child, npath, depth+1); err != nil {
75
+ return err
76
}
90
- return
77
}
78
93
- err = r.writer.WriteHeader(&tar.Header{
94
- Name: path,
95
- Size: int64(pb.GetFilesize()),
96
- Typeflag: tar.TypeReg,
97
- Mode: 0644,
98
- ModTime: time.Now(),
99
- // TODO: set mode, dates, etc. when added to unixFS
100
- })
101
- if err != nil {
102
- r.emitError(err)
103
- return
79
+ return nil
80
+}
81
+
82
+func (r *Reader) writeFileToBuf(ctx cxt.Context, nd *mdag.Node, pb *upb.Data, path string, depth int) error {
83
+ if err := writeFileHeader(r.writer, path, pb.GetFilesize()); err != nil {
84
+ return err
85
}
86
r.flush()
87
107
- reader, err := uio.NewDagReader(ctx, dagnode, r.dag)
88
+ reader, err := uio.NewDagReader(ctx, nd, r.dag)
89
if err != nil {
109
- r.emitError(err)
110
- return
90
+ return err
91
}
92
113
- err = r.syncCopy(reader)
114
- if err != nil {
115
- r.emitError(err)
116
- return
93
+ if err := r.syncCopy(reader); err != nil {
94
+ return err
95
+ }
96
+
97
+ return nil
98
+}
99
+
100
+func (r *Reader) writeNodeToBuf(ctx cxt.Context, nd *mdag.Node, path string, depth int) error {
101
+ pb := new(upb.Data)
102
+ if err := proto.Unmarshal(nd.Data, pb); err != nil {
103
+ return err
104
+ }
105
+
106
+ if depth == 0 {
107
+ defer r.close()
108
+ }
109
+
110
+ switch pb.GetType() {
111
+ case upb.Data_Directory:
112
+ return r.writeDirToBuf(ctx, nd, path, depth)
113
+ case upb.Data_File:
114
+ return r.writeFileToBuf(ctx, nd, pb, path, depth)
115
+ default:
116
+ return fmt.Errorf("unixfs type not supported: %s", pb.GetType())
117
}
118
}
119
@@ -198,3 +198,24 @@ func (r *Reader) syncCopy(reader io.Reader) error {
198
}
199
return nil
200
}
201
+
202
+func writeDirHeader(w *tar.Writer, path string) error {
203
+ return w.WriteHeader(&tar.Header{
204
+ Name: path,
205
+ Typeflag: tar.TypeDir,
206
+ Mode: 0777,
207
+ ModTime: time.Now(),
208
+ // TODO: set mode, dates, etc. when added to unixFS
209
+ })
210
+}
211
+
212
+func writeFileHeader(w *tar.Writer, path string, size uint64) error {
213
+ return w.WriteHeader(&tar.Header{
214
+ Name: path,
215
+ Size: int64(size),
216
+ Typeflag: tar.TypeReg,
217
+ Mode: 0644,
218
+ ModTime: time.Now(),
219
+ // TODO: set mode, dates, etc. when added to unixFS
220
+ })
221
+}