From 387ed4a775bd35de54e8695757b41601357dda8e Mon Sep 17 00:00:00 2001 From: Cory Slep Date: Sun, 19 Aug 2018 22:52:24 +0200 Subject: [PATCH] Fix body delivery bytes being incorrectly copied --- CHANGELOG | 1 + pub/fed_test.go | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ pub/internal.go | 4 ++-- 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index d934afc..44c9d31 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ v0.2.1 2018-08-19 +* Request body is now correctly copied when sending federation messages. * Change RWType and FollowResponse to bool and uint8, respectively. * Update README with applications using the go-fed/activity library. * Update README with links to official implementation reports for go-fed. diff --git a/pub/fed_test.go b/pub/fed_test.go index 5b58a5e..92a207e 100644 --- a/pub/fed_test.go +++ b/pub/fed_test.go @@ -6616,3 +6616,55 @@ func TestIssue75(t *testing.T) { t.Fatalf("unexpected callback object: %s", err) } } + +func TestDelivery_Bytes(t *testing.T) { + app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t) + PreparePubberPostOutboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p) + resp := httptest.NewRecorder() + req := Sign(ActivityPubRequest(httptest.NewRequest("POST", testOutboxURI, bytes.NewBuffer(MustSerialize(testCreateNote))))) + socialCb.create = func(c context.Context, s *streams.Create) error { + return nil + } + gotHttpDo := 0 + var httpDeliveryRequest *http.Request + httpClient.do = func(req *http.Request) (*http.Response, error) { + gotHttpDo++ + if gotHttpDo == 1 { + actorResp := &http.Response{ + StatusCode: http.StatusOK, + Body: ioutil.NopCloser(bytes.NewBuffer(samActorJSON)), + } + return actorResp, nil + } else if gotHttpDo == 2 { + actorResp := &http.Response{ + StatusCode: http.StatusOK, + Body: ioutil.NopCloser(bytes.NewBuffer(sallyActorJSON)), + } + return actorResp, nil + } else if gotHttpDo == 3 { + httpDeliveryRequest = req + okResp := &http.Response{ + StatusCode: http.StatusOK, + Body: ioutil.NopCloser(bytes.NewBuffer([]byte{})), + } + return okResp, nil + } + return nil, nil + } + handled, err := p.PostOutbox(context.Background(), resp, req) + if err != nil { + t.Fatal(err) + } else if !handled { + t.Fatalf("expected handled, got !handled") + } else if gotHttpDo != 3 { + t.Fatalf("expected %d, got %d", 3, gotHttpDo) + } else if httpDeliveryRequest.Method != "POST" { + t.Fatalf("expected %s, got %s", "POST", httpDeliveryRequest.Method) + } else if deliveryBody, err := ioutil.ReadAll(httpDeliveryRequest.Body); err != nil { + t.Fatal(err) + } else if len(deliveryBody) == 0 { + t.Fatalf("empty delivery body") + } else if s := httpDeliveryRequest.URL.String(); s != samIRIInboxString { + t.Fatalf("expected %s, got %s", samIRIInboxString, s) + } +} diff --git a/pub/internal.go b/pub/internal.go index ee86a8e..ff41192 100644 --- a/pub/internal.go +++ b/pub/internal.go @@ -167,8 +167,8 @@ func (f *federator) dereferenceAsUser(boxIRI, fetchIRI *url.URL) (obj vocab.Obje // // creds is able to be nil. func postToOutbox(c HttpClient, b []byte, to *url.URL, agent string, creds *creds, clock Clock) error { - byteCopy := make([]byte, 0, len(b)) - copy(b, byteCopy) + byteCopy := make([]byte, len(b)) + copy(byteCopy, b) buf := bytes.NewBuffer(byteCopy) req, err := http.NewRequest("POST", to.String(), buf) if err != nil {