Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.27.0
require (
github.com/alanshaw/dag-json-gen v0.0.9
github.com/fil-forge/automobile v0.0.1
github.com/fil-forge/ucantone v0.0.0-20260827134420-25cf8340b9a1
github.com/fil-forge/ucantone v0.0.0-20260924160040-c31dec73d9b3
github.com/filecoin-project/go-data-segment v0.0.1
github.com/filecoin-project/go-fil-commcid v0.3.1
github.com/filecoin-project/go-fil-commp-hashhash v0.4.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ github.com/alanshaw/dag-json-gen v0.0.9 h1:q59Ra1mQB6HnFGI1ilFxsZvF1CqGN0XDlUWq1
github.com/alanshaw/dag-json-gen v0.0.9/go.mod h1:v1YBZcS4B355MqxtyQr+fGNbEhm0CzHd+gOqOO/MZ+I=
github.com/fil-forge/automobile v0.0.1 h1:9xB3yc4l5b9EdRJSJcNwudgBFNHoMPEAdcb7GfobLhA=
github.com/fil-forge/automobile v0.0.1/go.mod h1:TsO7jlO8ykJZY5tF8j4GsUcu3F02lEzxO7ULoB61hRA=
github.com/fil-forge/ucantone v0.0.0-20260827134420-25cf8340b9a1 h1:Tzy3lZ7+LAyVK4+qyWM97UMOtnXx05Wdn+rcTDLdBDE=
github.com/fil-forge/ucantone v0.0.0-20260827134420-25cf8340b9a1/go.mod h1:aX35jlUs3hnWAhigjO8z9kMPiYnkW3XOW8iVoJyz7cg=
github.com/fil-forge/ucantone v0.0.0-20260924160040-c31dec73d9b3 h1:Ta5ODMWR9mM4zMfRp/K1unAKvnt7f5dhehRA+YHiv7w=
github.com/fil-forge/ucantone v0.0.0-20260924160040-c31dec73d9b3/go.mod h1:aX35jlUs3hnWAhigjO8z9kMPiYnkW3XOW8iVoJyz7cg=
github.com/filecoin-project/go-data-segment v0.0.1 h1:1wmDxOG4ubWQm3ZC1XI5nCon5qgSq7Ra3Rb6Dbu10Gs=
github.com/filecoin-project/go-data-segment v0.0.1/go.mod h1:H0/NKbsRxmRFBcLibmABv+yFNHdmtl5AyplYLnb0Zv4=
github.com/filecoin-project/go-fil-commcid v0.3.1 h1:4EfxpHSlvtkOqa9weG2Yt5kxFmPib2xU7Uc9Lbqk7fs=
Expand Down
49 changes: 49 additions & 0 deletions ucan/retrieval/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,57 @@ func TestClient(t *testing.T) {

require.Equal(t, 1, httpClient.Transport.(*countingTransport).count)
})

t.Run("the request carries the caller's context", func(t *testing.T) {
alice := testutil.RandomIssuer(t)
serviceURL, service := startTestServer(t, func(req execution.Request, res execution.Response) error {
return res.SetSuccess(datamodel.Map{})
})

type key struct{}
var got any
httpClient := &http.Client{Transport: roundTripFunc(func(r *http.Request) (*http.Response, error) {
got = r.Context().Value(key{})
return http.DefaultTransport.RoundTrip(r)
})}
client, err := retrieval.NewClient(serviceURL, retrieval.WithHTTPClient(httpClient))
require.NoError(t, err)

inv, err := contentRetrieve.Invoke(alice, alice.DID(), &datamodel.Map{}, invocation.WithAudience(service.DID()))
require.NoError(t, err)

ctx := context.WithValue(t.Context(), key{}, "caller")
res, err := client.Execute(execution.NewRequest(ctx, inv))
require.NoError(t, err)
if hc, ok := res.Metadata().(*retrieval.HTTPHeaderResponseContainer); ok && hc.Body != nil {
require.NoError(t, hc.Body.Close())
}
require.Equal(t, "caller", got)
})

t.Run("a canceled context aborts the request", func(t *testing.T) {
alice := testutil.RandomIssuer(t)
serviceURL, service := startTestServer(t, func(req execution.Request, res execution.Response) error {
t.Error("the request reached the server")
return res.SetSuccess(datamodel.Map{})
})
client, err := retrieval.NewClient(serviceURL)
require.NoError(t, err)

inv, err := contentRetrieve.Invoke(alice, alice.DID(), &datamodel.Map{}, invocation.WithAudience(service.DID()))
require.NoError(t, err)

ctx, cancel := context.WithCancel(t.Context())
cancel()
_, err = client.Execute(execution.NewRequest(ctx, inv))
require.ErrorIs(t, err, context.Canceled)
})
}

type roundTripFunc func(*http.Request) (*http.Response, error)

func (f roundTripFunc) RoundTrip(r *http.Request) (*http.Response, error) { return f(r) }

type recordingListener struct {
encoded ucan.Container
decoded ucan.Container
Expand Down
18 changes: 11 additions & 7 deletions ucan/retrieval/transport.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package retrieval

import (
"context"
"fmt"
"io"
"net/http"
Expand Down Expand Up @@ -91,24 +92,27 @@ type HTTPHeaderOutboundCodec struct{}

var _ transport.OutboundCodec[*http.Request, *http.Response] = (*HTTPHeaderOutboundCodec)(nil)

func (h *HTTPHeaderOutboundCodec) Encode(c ucan.Container) (*http.Request, error) {
func (h *HTTPHeaderOutboundCodec) Encode(ctx context.Context, c ucan.Container) (*http.Request, error) {
method := http.MethodGet
headers := http.Header{}
var body io.ReadCloser
var body io.Reader
if hc, ok := c.(*HTTPHeaderRequestContainer); ok {
if hc.Method != "" {
method = hc.Method
}
if hc.Header != nil {
headers = hc.Header
}
body = hc.Body
if hc.Body != nil {
body = hc.Body
}
}
req := &http.Request{
Method: method,
Body: body,
Header: headers,
// The URL is the transport's to set.
req, err := http.NewRequestWithContext(ctx, method, "", body)
if err != nil {
return nil, fmt.Errorf("creating request: %w", err)
}
req.Header = headers
ctBytes, err := container.Encode(container.Base64Gzip, c)
if err != nil {
return nil, fmt.Errorf("encoding container: %w", err)
Expand Down
Loading