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
58 changes: 57 additions & 1 deletion commands/s3/cbor_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

64 changes: 64 additions & 0 deletions commands/s3/codec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package s3_test

import (
"bytes"
"fmt"
"reflect"
"strings"
"testing"
Expand Down Expand Up @@ -68,6 +69,69 @@ func TestRequestRoundTrip(t *testing.T) {
}
}

// TestRequestBodyRoundTrip covers the optional body: carried when set, in
// both codecs, and absent from the encoding when not, so a request without
// one encodes exactly as it did before the field existed.
func TestRequestBodyRoundTrip(t *testing.T) {
in := &s3.Request{
Method: "POST",
Headers: map[string]string{"host": "region.s3.fil.one"},
URL: "https://region.s3.fil.one/bucket?delete",
Body: []byte("<Delete><Object><Key>k</Key><VersionId>v</VersionId></Object></Delete>"),
}

var cb bytes.Buffer
require.NoError(t, in.MarshalCBOR(&cb))
var outCBOR s3.Request
require.NoError(t, outCBOR.UnmarshalCBOR(bytes.NewReader(cb.Bytes())))
require.Equal(t, *in, outCBOR)

var jb bytes.Buffer
require.NoError(t, in.MarshalDagJSON(&jb))
var outJSON s3.Request
require.NoError(t, outJSON.UnmarshalDagJSON(bytes.NewReader(jb.Bytes())))
require.Equal(t, *in, outJSON)

// The limit holds the largest valid DeleteObjects document, which XML
// escaping takes well past the codecs' usual 2 MiB: a thousand distinct
// keys of 1021 ampersands and a three-digit suffix is over 5 MB.
var big strings.Builder
big.WriteString("<Delete>")
for i := range 1000 {
fmt.Fprintf(&big, "<Object><Key>%s%03d</Key><VersionId>v</VersionId></Object>", strings.Repeat("&amp;", 1021), i)
}
big.WriteString("</Delete>")
require.Greater(t, big.Len(), 5_000_000)
in.Body = []byte(big.String())
cb.Reset()
require.NoError(t, in.MarshalCBOR(&cb))
require.NoError(t, outCBOR.UnmarshalCBOR(bytes.NewReader(cb.Bytes())))
require.Equal(t, in.Body, outCBOR.Body)
jb.Reset()
require.NoError(t, in.MarshalDagJSON(&jb))
require.NoError(t, outJSON.UnmarshalDagJSON(bytes.NewReader(jb.Bytes())))
require.Equal(t, in.Body, outJSON.Body)

// Over the limit, both encoders refuse.
in.Body = make([]byte, 8<<20+1)
cb.Reset()
require.Error(t, in.MarshalCBOR(&cb))
jb.Reset()
require.Error(t, in.MarshalDagJSON(&jb))

// Without a body neither encoding names the field.
bare := &s3.Request{Method: "GET", Headers: map[string]string{"host": "h"}, URL: "https://h/b/k"}
cb.Reset()
require.NoError(t, bare.MarshalCBOR(&cb))
require.NotContains(t, cb.String(), "body")
jb.Reset()
require.NoError(t, bare.MarshalDagJSON(&jb))
require.NotContains(t, jb.String(), "body")
var outBare s3.Request
require.NoError(t, outBare.UnmarshalCBOR(bytes.NewReader(cb.Bytes())))
require.Nil(t, outBare.Body)
}

func TestAuthorizeOKRoundTrip(t *testing.T) {
access := did.MustParse("did:key:z6MkjFRxLLGdBqQSLkZbVnuwUFiomK8eGBkPtim9ETvP7vec")
delCid := mustCid(t, "bafyreienos3cw7hcga5vwani3pberioe2qscnz5jk2um5jajo4v7bwmvvm")
Expand Down
45 changes: 44 additions & 1 deletion commands/s3/json_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions commands/s3/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ type Request struct {
Method string `cborgen:"method" dagjsongen:"method"`
Headers map[string]string `cborgen:"headers" dagjsongen:"headers"`
URL string `cborgen:"url" dagjsongen:"url"`
// Body is the request body, carried only for the operations whose body
// decides what the request needs authorized (Hilt names them); every
// other request is sent without one. It is bound to the signature by
// the authorizer before it is read. The limit holds the largest valid
// DeleteObjects document: a thousand entries of a kilobyte key expanded
// up to sixfold by XML escaping, a version id as long, and the
// conditional fields, about 7.3 MB.
Body []byte `cborgen:"body,omitempty,maxlen=8388608" dagjsongen:"body,omitempty,maxlen=8388608"`
}

// VerificationKey is a SigV4/SigV4a derived signing key returned by Hilt so
Expand Down
Loading