func (rw *RefWriter) writeRefsSingle(n *dag.Node) (int, error) { nkey, err := n.Key() if err != nil { return 0, err } if rw.skip(nkey) { return 0, nil } count := 0 for _, l := range n.Links { lk := key.Key(l.Hash) if rw.skip(lk) { continue } if err := rw.WriteEdge(nkey, lk, l.Name); err != nil { return count, err } count++ } return count, nil }
func (rw *RefWriter) writeRefsRecursive(n *dag.Node) (int, error) { nkey, err := n.Key() if err != nil { return 0, err } var count int for i, ng := range rw.DAG.GetDAG(rw.Ctx, n) { lk := key.Key(n.Links[i].Hash) if rw.skip(lk) { continue } if err := rw.WriteEdge(nkey, lk, n.Links[i].Name); err != nil { return count, err } nd, err := ng.Get(rw.Ctx) if err != nil { return count, err } c, err := rw.writeRefsRecursive(nd) count += c if err != nil { return count, err } } return count, nil }
func Diff(ctx context.Context, ds dag.DAGService, a, b *dag.Node) []*Change { if len(a.Links) == 0 && len(b.Links) == 0 { ak, _ := a.Key() bk, _ := b.Key() return []*Change{ &Change{ Type: Mod, Before: ak, After: bk, }, } } var out []*Change clean_a := a.Copy() clean_b := b.Copy() // strip out unchanged stuff for _, lnk := range a.Links { l, err := b.GetNodeLink(lnk.Name) if err == nil { if bytes.Equal(l.Hash, lnk.Hash) { // no change... ignore it } else { anode, _ := lnk.GetNode(ctx, ds) bnode, _ := l.GetNode(ctx, ds) sub := Diff(ctx, ds, anode, bnode) for _, subc := range sub { subc.Path = path.Join(lnk.Name, subc.Path) out = append(out, subc) } } clean_a.RemoveNodeLink(l.Name) clean_b.RemoveNodeLink(l.Name) } } for _, lnk := range clean_a.Links { out = append(out, &Change{ Type: Remove, Path: lnk.Name, Before: key.Key(lnk.Hash), }) } for _, lnk := range clean_b.Links { out = append(out, &Change{ Type: Add, Path: lnk.Name, After: key.Key(lnk.Hash), }) } return out }
func (t *traversal) shouldSkip(n *mdag.Node) (bool, error) { if t.opts.SkipDuplicates { k, err := n.Key() if err != nil { return true, err } if _, found := t.seen[string(k)]; found { return true, nil } t.seen[string(k)] = struct{}{} } return false, nil }
func (params *adder) addNode(node *dag.Node, path string) error { // patch it into the root if path == "" { key, err := node.Key() if err != nil { return err } path = key.Pretty() } if err := params.editor.InsertNodeAtPath(params.ctx, path, node, newDirNode); err != nil { return err } return outputDagnode(params.out, path, node) }
func getOutput(dagnode *dag.Node) (*Object, error) { key, err := dagnode.Key() if err != nil { return nil, err } output := &Object{ Hash: key.Pretty(), Links: make([]Link, len(dagnode.Links)), } for i, link := range dagnode.Links { output.Links[i] = Link{ Name: link.Name, Hash: link.Hash.B58String(), Size: link.Size, } } return output, nil }
func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) { // TODO(cryptix): either ask mildred about the flow of this or rewrite it webErrorWithCode(w, "Sorry, PUT is bugged right now, closing request", errors.New("handler disabled"), http.StatusInternalServerError) return urlPath := r.URL.Path pathext := urlPath[5:] var err error if urlPath == ipfsPathPrefix+"QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn/" { i.putEmptyDirHandler(w, r) return } var newnode *dag.Node if pathext[len(pathext)-1] == '/' { newnode = uio.NewEmptyDirectory() } else { newnode, err = i.newDagFromReader(r.Body) if err != nil { webError(w, "Could not create DAG from request", err, http.StatusInternalServerError) return } } ctx, cancel := context.WithCancel(i.node.Context()) defer cancel() ipfsNode, err := core.Resolve(ctx, i.node, path.Path(urlPath)) if err != nil { // FIXME HTTP error code webError(w, "Could not resolve name", err, http.StatusInternalServerError) return } k, err := ipfsNode.Key() if err != nil { webError(w, "Could not get key from resolved node", err, http.StatusInternalServerError) return } h, components, err := path.SplitAbsPath(path.FromKey(k)) if err != nil { webError(w, "Could not split path", err, http.StatusInternalServerError) return } if len(components) < 1 { err = fmt.Errorf("Cannot override existing object") webError(w, "http gateway", err, http.StatusBadRequest) return } tctx, cancel := context.WithTimeout(ctx, time.Minute) defer cancel() // TODO(cryptix): could this be core.Resolve() too? rootnd, err := i.node.Resolver.DAG.Get(tctx, key.Key(h)) if err != nil { webError(w, "Could not resolve root object", err, http.StatusBadRequest) return } // resolving path components into merkledag nodes. if a component does not // resolve, create empty directories (which will be linked and populated below.) pathNodes, err := i.node.Resolver.ResolveLinks(tctx, rootnd, components[:len(components)-1]) if _, ok := err.(path.ErrNoLink); ok { // Create empty directories, links will be made further down the code for len(pathNodes) < len(components) { pathNodes = append(pathNodes, uio.NewDirectory(i.node.DAG).GetNode()) } } else if err != nil { webError(w, "Could not resolve parent object", err, http.StatusBadRequest) return } for i := len(pathNodes) - 1; i >= 0; i-- { newnode, err = pathNodes[i].UpdateNodeLink(components[i], newnode) if err != nil { webError(w, "Could not update node links", err, http.StatusInternalServerError) return } } if err := i.node.DAG.AddRecursive(newnode); err != nil { webError(w, "Could not add recursively new node", err, http.StatusInternalServerError) return } // Redirect to new path key, err := newnode.Key() if err != nil { webError(w, "Could not get key of new node", err, http.StatusInternalServerError) return } i.addUserHeaders(w) // ok, _now_ write user's headers. w.Header().Set("IPFS-Hash", key.String()) http.Redirect(w, r, ipfsPathPrefix+key.String()+"/"+strings.Join(components, "/"), http.StatusCreated) }