Don't use tar reader for '-C' only flag
Currently `ipfs get -C <hash>` returns error even if <hash> is a file. This PR is for the case when the compress flag is enabled, use the dagreader directly and pipe to a gzip processor. License: MIT Signed-off-by: rht <rhtbot@gmail.com>
rht committed
Jun 11, 2015 at 20:44 UTC
37981787054fadf87615557f892dbd28a139ca79
1 file changed
+50
-18
core/commands/get.go
+50
-18
@@ -1,6 +1,7 @@
1
package commands
2
3
import (
4
+ "bufio"
5
"compress/gzip"
6
"errors"
7
"fmt"
@@ -16,6 +17,7 @@ import (
17
core "github.com/ipfs/go-ipfs/core"
18
path "github.com/ipfs/go-ipfs/path"
19
tar "github.com/ipfs/go-ipfs/thirdparty/tar"
20
+ uio "github.com/ipfs/go-ipfs/unixfs/io"
21
utar "github.com/ipfs/go-ipfs/unixfs/tar"
22
)
23
@@ -63,7 +65,20 @@ may also specify the level of compression by specifying '-l=<1-9>'.
65
return
66
}
67
66
- reader, err := get(req.Context().Context, node, req.Arguments()[0], cmplvl)
68
+ // Validate path string
69
+ p, err := path.ParsePath(req.Arguments()[0])
70
+ if err != nil {
71
+ res.SetError(fmt.Errorf("failed to validate path: %v", err), cmds.ErrNormal)
72
+ return
73
+ }
74
+ var reader io.Reader
75
+
76
+ if archive, _, _ := req.Option("archive").Bool(); !archive && cmplvl != gzip.NoCompression {
77
+ // only use this when the flag is '-C' without '-a'
78
+ reader, err = getZip(req.Context().Context, node, p, cmplvl)
79
+ } else {
80
+ reader, err = get(req.Context().Context, node, p, cmplvl)
81
+ }
82
if err != nil {
83
res.SetError(err, cmds.ErrNormal)
84
return
@@ -89,8 +104,8 @@ may also specify the level of compression by specifying '-l=<1-9>'.
104
return
105
}
106
92
- if archive, _, _ := req.Option("archive").Bool(); archive {
93
- if !strings.HasSuffix(outPath, ".tar") {
107
+ if archive, _, _ := req.Option("archive").Bool(); archive || cmplvl != gzip.NoCompression {
108
+ if archive && !strings.HasSuffix(outPath, ".tar") {
109
outPath += ".tar"
110
}
111
if cmplvl != gzip.NoCompression {
@@ -127,19 +142,7 @@ may also specify the level of compression by specifying '-l=<1-9>'.
142
bar.Output = os.Stderr
143
144
// wrap the reader with the progress bar proxy reader
130
- // if the output is compressed, also wrap it in a gzip.Reader
131
- var reader io.Reader
132
- if cmplvl != gzip.NoCompression {
133
- gzipReader, err := gzip.NewReader(outReader)
134
- if err != nil {
135
- res.SetError(err, cmds.ErrNormal)
136
- return
137
- }
138
- defer gzipReader.Close()
139
- reader = bar.NewProxyReader(gzipReader)
140
- } else {
141
- reader = bar.NewProxyReader(outReader)
142
- }
145
+ reader := bar.NewProxyReader(outReader)
146
147
bar.Start()
148
defer bar.Finish()
@@ -166,8 +169,7 @@ func getCompressOptions(req cmds.Request) (int, error) {
169
return gzip.NoCompression, nil
170
}
171
169
-func get(ctx context.Context, node *core.IpfsNode, p string, compression int) (io.Reader, error) {
170
- pathToResolve := path.Path(p)
172
+func get(ctx context.Context, node *core.IpfsNode, pathToResolve path.Path, compression int) (io.Reader, error) {
173
dagnode, err := core.Resolve(ctx, node, pathToResolve)
174
if err != nil {
175
return nil, err
@@ -175,3 +177,33 @@ func get(ctx context.Context, node *core.IpfsNode, p string, compression int) (i
177
178
return utar.NewReader(pathToResolve, node.DAG, dagnode, compression)
179
}
180
+
181
+// getZip is equivalent to `ipfs getdag $hash | gzip`
182
+func getZip(ctx context.Context, node *core.IpfsNode, pathToResolve path.Path, compression int) (io.Reader, error) {
183
+ dagnode, err := core.Resolve(ctx, node, pathToResolve)
184
+ if err != nil {
185
+ return nil, err
186
+ }
187
+
188
+ reader, err := uio.NewDagReader(ctx, dagnode, node.DAG)
189
+ if err != nil {
190
+ return nil, err
191
+ }
192
+
193
+ pr, pw := io.Pipe()
194
+ gw, err := gzip.NewWriterLevel(pw, compression)
195
+ if err != nil {
196
+ return nil, err
197
+ }
198
+ bufin := bufio.NewReader(reader)
199
+ go func() {
200
+ _, err := bufin.WriteTo(gw)
201
+ if err != nil {
202
+ log.Error("Fail to compress the stream")
203
+ }
204
+ gw.Close()
205
+ pw.Close()
206
+ }()
207
+
208
+ return pr, nil
209
+}