Skip to content
This repository has been archived by the owner on Jun 27, 2023. It is now read-only.

Commit

Permalink
Merge pull request #80 from ipfs/fix/gateway-workaround
Browse files Browse the repository at this point in the history
fix(dagreader): remove a buggy workaround for a gateway issue
  • Loading branch information
Stebalien authored Jan 6, 2020
2 parents 0faf573 + d1f8577 commit da35b26
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 12 deletions.
21 changes: 9 additions & 12 deletions io/dagreader.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ var (
ErrIsDir = errors.New("this dag node is a directory")
ErrCantReadSymlinks = errors.New("cannot currently read symlinks")
ErrUnkownNodeType = errors.New("unknown node type")
ErrSeekNotSupported = errors.New("file does not support seeking")
)

// TODO: Rename the `DagReader` interface, this doesn't read *any* DAG, just
Expand Down Expand Up @@ -345,7 +346,7 @@ func (dr *dagReader) Seek(offset int64, whence int) (int64, error) {
switch whence {
case io.SeekStart:
if offset < 0 {
return -1, errors.New("invalid offset")
return dr.offset, errors.New("invalid offset")
}

if offset == dr.offset {
Expand All @@ -359,6 +360,11 @@ func (dr *dagReader) Seek(offset int64, whence int) (int64, error) {
// Seek from the beginning of the DAG.
dr.resetPosition()

// Shortcut seeking to the beginning, we're already there.
if offset == 0 {
return 0, nil
}

// Use the internal reader's context to fetch the child node promises
// (see `ipld.NavigableIPLDNode.FetchChild` for details).
dr.dagWalker.SetContext(dr.ctx)
Expand Down Expand Up @@ -388,7 +394,7 @@ func (dr *dagReader) Seek(offset int64, whence int) (int64, error) {
// If there aren't enough size hints don't seek
// (see the `io.EOF` handling error comment below).
if fsNode.NumChildren() != len(node.Links()) {
return io.EOF
return ErrSeekNotSupported
}

// Internal nodes have no data, so just iterate through the
Expand Down Expand Up @@ -445,16 +451,6 @@ func (dr *dagReader) Seek(offset int64, whence int) (int64, error) {
}
})

if err == io.EOF {
// TODO: Taken from https://github.com/ipfs/go-ipfs/pull/4320,
// check if still valid.
// Return negative number if we can't figure out the file size. Using io.EOF
// for this seems to be good(-enough) solution as it's only returned by
// precalcNextBuf when we step out of file range.
// This is needed for gateway to function properly
return -1, nil
}

if err != nil {
return 0, err
}
Expand Down Expand Up @@ -484,6 +480,7 @@ func (dr *dagReader) Seek(offset int64, whence int) (int64, error) {
// in the `SeekStart` case.
func (dr *dagReader) resetPosition() {
dr.currentNodeData = nil
dr.offset = 0

dr.dagWalker = ipld.NewWalker(dr.ctx, ipld.NewNavigableIPLDNode(dr.rootNode, dr.serv))
// TODO: This could be avoided (along with storing the `dr.rootNode` and
Expand Down
65 changes: 65 additions & 0 deletions io/dagreader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,71 @@ func TestSeekAndRead(t *testing.T) {
}
}

func TestSeekWithoutBlocksizes(t *testing.T) {
dserv := testu.GetDAGServ()
ctx, closer := context.WithCancel(context.Background())
defer closer()

inbuf := make([]byte, 1024)

for i := 0; i < 256; i++ {
inbuf[i*4] = byte(i)
}

inbuf[1023] = 1 // force the reader to be 1024 bytes
node := testu.GetNode(t, dserv, inbuf, testu.UseProtoBufLeaves)

// remove the blocksizes
pbnode := node.Copy().(*mdag.ProtoNode)
fsnode, err := unixfs.FSNodeFromBytes(pbnode.Data())
if err != nil {
t.Fatal(err)
}
fsnode.RemoveAllBlockSizes()
newData, err := fsnode.GetBytes()
if err != nil {
t.Fatal(err)
}
pbnode.SetData(newData)
err = dserv.Add(ctx, pbnode)
if err != nil {
t.Fatal(err)
}
node = pbnode

reader, err := NewDagReader(ctx, node, dserv)
if err != nil {
t.Fatal(err)
}

_, err = reader.Seek(-4, io.SeekEnd)
if err == nil {
t.Fatal("seeking shouldn't work without blocksizes")
}

_, err = reader.Seek(4, io.SeekStart)
if err == nil {
t.Fatal("seeking shouldn't work without blocksizes")
}

_, err = reader.Seek(4, io.SeekCurrent)
if err == nil {
t.Fatal("seeking shouldn't work without blocksizes")
}

// Seeking to the current position or the end should still work.

_, err = reader.Seek(0, io.SeekCurrent)
if err != nil {
t.Fatal(err)
}

_, err = reader.Seek(0, io.SeekStart)
if err != nil {
t.Fatal(err)
}
}

func TestRelativeSeek(t *testing.T) {
dserv := testu.GetDAGServ()
ctx, closer := context.WithCancel(context.Background())
Expand Down

0 comments on commit da35b26

Please sign in to comment.