From f82653f70932a0be28cf3202345be41fa4ae579d Mon Sep 17 00:00:00 2001 From: Cory Slep Date: Fri, 3 Aug 2018 22:30:53 +0200 Subject: [PATCH] Don't do an Activity's side effects more than once If a federated Activity has been seen before, skip handling its side effects. --- pub/fed.go | 13 ++++++++----- pub/fed_test.go | 16 ++++++++++++---- pub/internal.go | 5 ++++- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/pub/fed.go b/pub/fed.go index 51dd5dd..215c592 100644 --- a/pub/fed.go +++ b/pub/fed.go @@ -205,15 +205,18 @@ func (f *federator) PostInbox(c context.Context, w http.ResponseWriter, r *http. if err = f.FederateAPI.Unblocked(c, iris); err != nil { return true, err } - if err = f.getPostInboxResolver(c, r.URL).Deserialize(m); err != nil { + if err := f.addToInboxIfNew(c, r, m, func() error { + if err = f.getPostInboxResolver(c, r.URL).Deserialize(m); err != nil { + return err + } + return nil + }); err != nil { if err == errObjectRequired || err == errTargetRequired { w.WriteHeader(http.StatusBadRequest) return true, nil + } else { + return true, err } - return true, err - } - if err := f.addToInbox(c, r, m); err != nil { - return true, err } if err := f.inboxForwarding(c, m); err != nil { return true, err diff --git a/pub/fed_test.go b/pub/fed_test.go index 15818a0..8e9ea91 100644 --- a/pub/fed_test.go +++ b/pub/fed_test.go @@ -1989,10 +1989,14 @@ func TestPostInbox_RequiresObject(t *testing.T) { }, }, } - _, _, fedApp, _, _, _, _, p := NewPubberTest(t) + app, _, fedApp, _, _, _, _, p := NewPubberTest(t) fedApp.unblocked = func(c context.Context, actorIRIs []*url.URL) error { return nil } + app.MockFederateApp.getInbox = func(c context.Context, r *http.Request, rw RWType) (vocab.OrderedCollectionType, error) { + inbox := &vocab.OrderedCollection{} + return inbox, nil + } for _, test := range tests { t.Logf("Running table test case %q", test.name) resp := httptest.NewRecorder() @@ -2036,10 +2040,14 @@ func TestPostInbox_RequiresTarget(t *testing.T) { }, }, } - _, _, fedApp, _, _, _, _, p := NewPubberTest(t) + app, _, fedApp, _, _, _, _, p := NewPubberTest(t) fedApp.unblocked = func(c context.Context, actorIRIs []*url.URL) error { return nil } + app.MockFederateApp.getInbox = func(c context.Context, r *http.Request, rw RWType) (vocab.OrderedCollectionType, error) { + inbox := &vocab.OrderedCollection{} + return inbox, nil + } for _, test := range tests { t.Logf("Running table test case %q", test.name) resp := httptest.NewRecorder() @@ -2080,8 +2088,8 @@ func TestPostInbox_DoesNotAddToInboxIfDuplicate(t *testing.T) { t.Fatal(err) } else if !handled { t.Fatalf("expected handled, got !handled") - } else if gotSet != 1 { - t.Fatalf("expected %d, got %d", 1, gotSet) + } else if gotSet != 0 { + t.Fatalf("expected %d, got %d", 0, gotSet) } } diff --git a/pub/internal.go b/pub/internal.go index 4da0c6b..9fc1f22 100644 --- a/pub/internal.go +++ b/pub/internal.go @@ -1763,7 +1763,7 @@ func (f *federator) addToOutbox(c context.Context, r *http.Request, m map[string return f.App.Set(c, outbox) } -func (f *federator) addToInbox(c context.Context, r *http.Request, m map[string]interface{}) error { +func (f *federator) addToInboxIfNew(c context.Context, r *http.Request, m map[string]interface{}, callback func() error) error { inbox, err := f.App.GetInbox(c, r, ReadWrite) if err != nil { return err @@ -1780,6 +1780,9 @@ func (f *federator) addToInbox(c context.Context, r *http.Request, m map[string] return fmt.Errorf("activity missing id") } if !iriSet[activity.GetId().String()] { + if err := callback(); err != nil { + return err + } inbox.PrependOrderedItemsIRI(activity.GetId()) return f.App.Set(c, inbox) }