func (adder *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() } dir := gopath.Dir(path) if dir != "." { if err := mfs.Mkdir(adder.mr, dir, true, false); err != nil { return err } } if err := mfs.PutNode(adder.mr, path, node); err != nil { return err } if !adder.Silent { return outputDagnode(adder.out, path, node) } return nil }
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 randNode() (*merkledag.Node, key.Key) { node := new(merkledag.Node) node.Data = make([]byte, 32) util.NewTimeSeededRand().Read(node.Data) k, _ := node.Key() return node, k }
//FromDAGNode creates Records from links of merkledag n and retuns it. //links must contain "Stamp" and "Thread" func FromDAGNode(self *peer.Self, n *merkledag.Node, sign []byte) (*Record, error) { r := &Record{ self: self, Stamp: time.Unix(0, 0), Sign: sign, Contents: make(map[string][]byte), } var err error r.Key, err = n.Key() if log.If(err) { return nil, err } for _, l := range n.Links { nn, err := r.self.GetLinkedNode(n, l.Name) if log.If(err) { return nil, err } r.Contents[l.Name] = nn.Data switch l.Name { case "thread": r.Thread = string(nn.Data) case "stamp": stamp := binary.BigEndian.Uint64(nn.Data) r.Stamp = time.Unix(0, int64(stamp)) } } if err := r.check(false); log.If(err) { return nil, err } return r, nil }
func randNode() (*mdag.Node, key.Key) { nd := new(mdag.Node) nd.Data = make([]byte, 32) util.NewTimeSeededRand().Read(nd.Data) k, _ := nd.Key() return nd, k }
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 (p *pinner) pinIndirectRecurse(ctx context.Context, node *mdag.Node) error { k, err := node.Key() if err != nil { return err } p.indirPin.Increment(k) return p.pinLinks(ctx, node) }
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 }
//NewList returns List obj. func NewList(self *peer.Self, key key.Key) (*List, error) { if key == "" { var err error n := merkledag.Node{} key, err = n.Key() if log.If(err) { return nil, err } } tl := &List{ self: self, key: key, } return tl, nil }
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 }
//AddDAGNode adds dagNode and returns key func (m *Self) AddDAGNode(dagNode *merkledag.Node, pin bool) (key.Key, error) { if err := m.ipfsNode.DAG.AddRecursive(dagNode); log.If(err) { return "", err } k, err := dagNode.Key() if log.If(err) { return "", err } log.Println("added DAG", k.B58String()) if pin { err = m.ipfsNode.Pinning.Pin(m.ctx, dagNode, true) } log.If(err) return k, err }
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) }
//New returns Thread obj. func New(self *peer.Self, name string, root key.Key) (*Thread, error) { if root == "" { var err error r := merkledag.Node{} root, err = r.Key() if log.If(err) { return nil, err } log.Println("root key", root) } t := &Thread{ self: self, name: name, root: root, } return t, nil }
func getOutput(dagnode *dag.Node) (*Object, error) { key, err := dagnode.Key() if err != nil { return nil, err } output := &Object{ Hash: key.B58String(), 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 (p *pinner) unpinLinks(ctx context.Context, node *mdag.Node) error { for _, l := range node.Links { node, err := l.GetNode(ctx, p.dserv) if err != nil { return err } k, err := node.Key() if err != nil { return err } p.indirPin.Decrement(k) err = p.unpinLinks(ctx, node) if err != nil { return err } } return nil }
// newRoot creates a new Root and starts up a republisher routine for it func NewRoot(parent context.Context, ds dag.DAGService, node *dag.Node, pf PubFunc) (*Root, error) { ndk, err := node.Key() if err != nil { return nil, err } var repub *Republisher if pf != nil { repub = NewRepublisher(parent, pf, time.Millisecond*300, time.Second*3) repub.setVal(ndk) go repub.Run() } root := &Root{ node: node, repub: repub, dserv: ds, } pbn, err := ft.FromBytes(node.Data()) if err != nil { log.Error("IPNS pointer was not unixfs node") return nil, err } switch pbn.GetType() { case ft.TDirectory: root.val = NewDirectory(parent, ndk.String(), node, root, ds) case ft.TFile, ft.TMetadata, ft.TRaw: fi, err := NewFile(ndk.String(), node, root, ds) if err != nil { return nil, err } root.val = fi default: panic("unrecognized! (NYI)") } return root, nil }
// Pin the given node, optionally recursive func (p *pinner) Pin(ctx context.Context, node *mdag.Node, recurse bool) error { p.lock.Lock() defer p.lock.Unlock() k, err := node.Key() if err != nil { return err } if recurse { if p.recursePin.HasKey(k) { return nil } if p.directPin.HasKey(k) { p.directPin.RemoveBlock(k) } // fetch entire graph err := mdag.FetchGraph(ctx, node, p.dserv) if err != nil { return err } p.recursePin.AddBlock(k) } else { if _, err := p.dserv.Get(ctx, k); err != nil { return err } if p.recursePin.HasKey(k) { return fmt.Errorf("%s already pinned recursively", k.B58String()) } p.directPin.AddBlock(k) } return 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 } } err = i.node.DAG.AddRecursive(newnode) if 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) }
func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) { // TODO(cryptix): move me to ServeHTTP and pass into all handlers ctx, cancel := context.WithCancel(i.node.Context()) defer cancel() rootPath, err := path.ParsePath(r.URL.Path) if err != nil { webError(w, "putHandler: ipfs path not valid", err, http.StatusBadRequest) return } rsegs := rootPath.Segments() if rsegs[0] == ipnsPathPrefix { webError(w, "putHandler: updating named entries not supported", errors.New("WritableGateway: ipns put not supported"), http.StatusBadRequest) return } var newnode *dag.Node if rsegs[len(rsegs)-1] == "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn" { newnode = uio.NewEmptyDirectory() } else { putNode, err := i.newDagFromReader(r.Body) if err != nil { webError(w, "putHandler: Could not create DAG from request", err, http.StatusInternalServerError) return } newnode = putNode } var newPath string if len(rsegs) > 1 { newPath = path.Join(rsegs[2:]) } var newkey key.Key rnode, err := core.Resolve(ctx, i.node, rootPath) switch ev := err.(type) { case path.ErrNoLink: // ev.Node < node where resolve failed // ev.Name < new link // but we need to patch from the root rnode, err := i.node.DAG.Get(ctx, key.B58KeyDecode(rsegs[1])) if err != nil { webError(w, "putHandler: Could not create DAG from request", err, http.StatusInternalServerError) return } e := dagutils.NewDagEditor(rnode, i.node.DAG) err = e.InsertNodeAtPath(ctx, newPath, newnode, uio.NewEmptyDirectory) if err != nil { webError(w, "putHandler: InsertNodeAtPath failed", err, http.StatusInternalServerError) return } nnode, err := e.Finalize(i.node.DAG) if err != nil { webError(w, "putHandler: could not get node", err, http.StatusInternalServerError) return } newkey, err = nnode.Key() if err != nil { webError(w, "putHandler: could not get key of edited node", err, http.StatusInternalServerError) return } case nil: // object set-data case rnode.Data = newnode.Data newkey, err = i.node.DAG.Add(rnode) if err != nil { nnk, _ := newnode.Key() rk, _ := rnode.Key() webError(w, fmt.Sprintf("putHandler: Could not add newnode(%q) to root(%q)", nnk.B58String(), rk.B58String()), err, http.StatusInternalServerError) return } default: log.Warningf("putHandler: unhandled resolve error %T", ev) webError(w, "could not resolve root DAG", ev, http.StatusInternalServerError) return } i.addUserHeaders(w) // ok, _now_ write user's headers. w.Header().Set("IPFS-Hash", newkey.String()) http.Redirect(w, r, gopath.Join(ipfsPathPrefix, newkey.String(), newPath), http.StatusCreated) }