github.com/storacha/go-ucanto@v0.7.2/transport/car/request/request.go (about)

     1  package request
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  
     7  	"github.com/storacha/go-ucanto/core/car"
     8  	"github.com/storacha/go-ucanto/core/dag/blockstore"
     9  	"github.com/storacha/go-ucanto/core/ipld"
    10  	"github.com/storacha/go-ucanto/core/message"
    11  	"github.com/storacha/go-ucanto/transport"
    12  	uhttp "github.com/storacha/go-ucanto/transport/http"
    13  )
    14  
    15  const ContentType = car.ContentType
    16  
    17  func Encode(message message.AgentMessage) (transport.HTTPRequest, error) {
    18  	headers := http.Header{}
    19  	headers.Add("Content-Type", car.ContentType)
    20  	// signal that we want to receive a CAR file in the response
    21  	headers.Add("Accept", car.ContentType)
    22  	reader := car.Encode([]ipld.Link{message.Root().Link()}, message.Blocks())
    23  	return uhttp.NewRequest(reader, headers), nil
    24  }
    25  
    26  func Decode(req transport.HTTPRequest) (message.AgentMessage, error) {
    27  	roots, blocks, err := car.Decode(req.Body())
    28  	if err != nil {
    29  		return nil, fmt.Errorf("decoding CAR: %w", err)
    30  	}
    31  	if len(roots) != 1 {
    32  		return nil, fmt.Errorf("unexpected number of roots: %d, expected: 1", len(roots))
    33  	}
    34  	bstore, err := blockstore.NewBlockReader(blockstore.WithBlocksIterator(blocks))
    35  	if err != nil {
    36  		return nil, fmt.Errorf("creating blockstore: %w", err)
    37  	}
    38  	return message.NewMessage(roots[0], bstore)
    39  }