loader.go 1.04 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
package loader

import (
	"bytes"
	"io"

	"github.com/ipfs/go-graphsync/ipldbridge"
	gsmsg "github.com/ipfs/go-graphsync/message"
	ipld "github.com/ipld/go-ipld-prime"
)

// ResponseSender sends responses over the network
type ResponseSender interface {
	SendResponse(
		requestID gsmsg.GraphSyncRequestID,
		link ipld.Link,
		data []byte,
	)
}

// WrapLoader wraps a given loader with an interceptor that sends loaded
// blocks out to the network with the given response sender.
func WrapLoader(loader ipldbridge.Loader,
	requestID gsmsg.GraphSyncRequestID,
	responseSender ResponseSender) ipldbridge.Loader {
	return func(lnk ipld.Link, lnkCtx ipldbridge.LinkContext) (io.Reader, error) {
		result, err := loader(lnk, lnkCtx)
		var data []byte
		var blockBuffer bytes.Buffer
		if err == nil {
			_, err = io.Copy(&blockBuffer, result)
			if err == nil {
				result = &blockBuffer
				data = blockBuffer.Bytes()
			}
		}
		responseSender.SendResponse(requestID, lnk, data)
38 39 40
		if data == nil {
			err = ipldbridge.ErrDoNotFollow()
		}
41 42 43
		return result, err
	}
}