[go: nahoru, domu]

Skip to content

Commit

Permalink
Gateway PUT Overwrite: Fix for PUT on empty dir; added test
Browse files Browse the repository at this point in the history
The previous commit would fail when an empty directory was
specified. This commit checks if the empty directory is
specified, and will return an empty directory as it did
previously. Also added a test case which verifies that a
PUT to an existing file for a given DAG will overwrite
its contents and return the correct new DAG.

License: MIT
Signed-off-by: Tom O'Donnell <todonnel91@gmail.com>
  • Loading branch information
te0d committed Aug 4, 2017
1 parent 65edf7f commit d6e7d9d
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 40 deletions.
85 changes: 45 additions & 40 deletions core/corehttp/gateway_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,63 +417,68 @@ func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) {
return
}

rnode, err := i.node.DAG.Get(ctx, c)
if err != nil {
webError(w, "putHandler: Could not create DAG from request", err, http.StatusInternalServerError)
return
}

pbnd, ok := rnode.(*dag.ProtoNode)
if !ok {
webError(w, "Cannot read non protobuf nodes through gateway", dag.ErrNotProtobuf, http.StatusBadRequest)
return
}

e := dagutils.NewDagEditor(pbnd, i.node.DAG)

tnode, err := core.Resolve(ctx, i.node.Namesys, i.node.Resolver, rootPath)
switch ev := err.(type) {
case path.ErrNoLink:
err = e.InsertNodeAtPath(ctx, newPath, newnode, ft.EmptyDirNode)
if rsegs[len(rsegs)-1] == "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn" && newPath == "" {
// Empty directory with no path specified will return empty directory.
newcid = c;
} else {
rnode, err := i.node.DAG.Get(ctx, c)
if err != nil {
webError(w, "putHandler: InsertNodeAtPath failed", err, http.StatusInternalServerError)
webError(w, "putHandler: Could not create DAG from request", err, http.StatusInternalServerError)
return
}
case nil:
pbtnd, ok := tnode.(*dag.ProtoNode)

pbnd, ok := rnode.(*dag.ProtoNode)
if !ok {
webError(w, "Cannot read non protobuf nodes through gateway", dag.ErrNotProtobuf, http.StatusBadRequest)
return
}

pbnewnode, ok := newnode.(*dag.ProtoNode)
if !ok {
webError(w, "Cannot read non protobuf nodes through gateway", dag.ErrNotProtobuf, http.StatusBadRequest)
e := dagutils.NewDagEditor(pbnd, i.node.DAG)

tnode, err := core.Resolve(ctx, i.node.Namesys, i.node.Resolver, rootPath)
switch ev := err.(type) {
case path.ErrNoLink:
err = e.InsertNodeAtPath(ctx, newPath, newnode, ft.EmptyDirNode)
if err != nil {
webError(w, "putHandler: InsertNodeAtPath failed", err, http.StatusInternalServerError)
return
}
case nil:
pbtnd, ok := tnode.(*dag.ProtoNode)
if !ok {
webError(w, "Cannot read non protobuf nodes through gateway", dag.ErrNotProtobuf, http.StatusBadRequest)
return
}

pbnewnode, ok := newnode.(*dag.ProtoNode)
if !ok {
webError(w, "Cannot read non protobuf nodes through gateway", dag.ErrNotProtobuf, http.StatusBadRequest)
return
}

// object set-data case
pbtnd.SetData(pbnewnode.Data())

err = e.InsertNodeAtPath(ctx, newPath, pbtnd, ft.EmptyDirNode)
if err != nil {
webError(w, "putHandler: InsertNodeAtPath failed", err, http.StatusInternalServerError)
return
}
default:
log.Warningf("putHandler: unhandled resolve error %T", ev)
webError(w, "could not resolve root DAG", ev, http.StatusInternalServerError)
return
}

// object set-data case
pbtnd.SetData(pbnewnode.Data())

err = e.InsertNodeAtPath(ctx, newPath, pbtnd, ft.EmptyDirNode)
nnode, err := e.Finalize(i.node.DAG)
if err != nil {
webError(w, "putHandler: InsertNodeAtPath failed", err, http.StatusInternalServerError)
webError(w, "putHandler: could not get node", err, http.StatusInternalServerError)
return
}
default:
log.Warningf("putHandler: unhandled resolve error %T", ev)
webError(w, "could not resolve root DAG", ev, http.StatusInternalServerError)
return
}

nnode, err := e.Finalize(i.node.DAG)
if err != nil {
webError(w, "putHandler: could not get node", err, http.StatusInternalServerError)
return
newcid = nnode.Cid()
}

newcid = nnode.Cid()

i.addUserHeaders(w) // ok, _now_ write user's headers.
w.Header().Set("IPFS-Hash", newcid.String())
http.Redirect(w, r, gopath.Join(ipfsPathPrefix, newcid.String(), newPath), http.StatusCreated)
Expand Down
19 changes: 19 additions & 0 deletions test/sharness/t0111-gateway-writeable.sh
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,25 @@ test_expect_success "We can HTTP GET file just updated" '
test_cmp infile2 outfile2
'


test_expect_success "HTTP PUT file to overwrite existing file" '
echo "nonrandom" >infile3 &&
URL="http://localhost:$port/ipfs/$HASH/test/test.txt" &&
echo "PUT $URL" &&
curl -svX PUT --data-binary @infile3 "$URL" 2>curl_put3.out &&
grep "HTTP/1.1 201 Created" curl_put3.out &&
LOCATION=$(grep Location curl_put3.out) &&
HASH=$(expr "$LOCATION" : "< Location: /ipfs/\(.*\)/test/test.txt")
'


test_expect_success "We can HTTP GET file just updated" '
URL="http://localhost:$port/ipfs/$HASH/test/test.txt" &&
echo "GET $URL" &&
curl -svo outfile3 "$URL" 2>curl_get3.out &&
test_cmp infile3 outfile3
'

test_kill_ipfs_daemon

test_done

0 comments on commit d6e7d9d

Please sign in to comment.