From eae3ffa859739aa7dc761dfd491e8b661c4ef2d6 Mon Sep 17 00:00:00 2001 From: Matthias Hanel Date: Tue, 23 Aug 2022 16:22:46 -0700 Subject: [PATCH] [FIXED] Service import response invoking svc import (#3393) past processing the import response, c.pa was not reset to the appropriate state, which lead to an unintended recursion Signed-off-by: Matthias Hanel --- server/accounts.go | 7 ++++++ server/accounts_test.go | 53 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/server/accounts.go b/server/accounts.go index 8c68d874..c8dd2045 100644 --- a/server/accounts.go +++ b/server/accounts.go @@ -2141,8 +2141,15 @@ func (a *Account) processServiceImportResponse(sub *subscription, c *client, _ * } a.mu.RUnlock() + old := c.pa.subject + if c.kind == CLIENT || c.kind == LEAF { + // reset state to prior to service invocation (code to reset c.pa.subject to old may not be necessary) + c.pa.subject = []byte(si.to) + } + // Send for normal processing. c.processServiceImport(si, a, msg) + c.pa.subject = old } // Will create the response prefix for fast generation of responses. diff --git a/server/accounts_test.go b/server/accounts_test.go index f9bc8623..30479f87 100644 --- a/server/accounts_test.go +++ b/server/accounts_test.go @@ -3524,3 +3524,56 @@ func TestAccountUserSubPermsWithQueueGroups(t *testing.T) { // Expect no msgs. checkSubsPending(t, qsub, 0) } + +func TestAccountImportCycle(t *testing.T) { + cf := createConfFile(t, []byte(` + port: -1 + accounts: { + CP: { + users: [ + {user: cp, password: cp}, + ], + exports: [ + {service: "q1.>", response_type: Singleton}, + {service: "q2.>", response_type: Singleton}, + ], + }, + A: { + users: [ + {user: a, password: a}, + ], + imports: [ + {service: {account: CP, subject: "q1.>"}}, + {service: {account: CP, subject: "q2.>"}}, + ] + }, + } + `)) + defer removeFile(t, cf) + s, _ := RunServerWithConfig(cf) + defer s.Shutdown() + ncCp, err := nats.Connect(s.ClientURL(), nats.UserInfo("cp", "cp")) + require_NoError(t, err) + defer ncCp.Close() + ncA, err := nats.Connect(s.ClientURL(), nats.UserInfo("a", "a")) + require_NoError(t, err) + defer ncA.Close() + // setup reply + subCp, err := ncCp.SubscribeSync("q1.>") + require_NoError(t, err) + // setup requestor and send reply + ib := "q2.inbox" + subAResp, err := ncA.SubscribeSync(ib) + require_NoError(t, err) + // send request + err = ncA.PublishRequest("q1.a", ib, []byte("test")) + require_NoError(t, err) + // reply + mReq, err := subCp.NextMsg(time.Second) + require_NoError(t, err) + err = mReq.Respond([]byte("reply")) + require_NoError(t, err) + mRep, err := subAResp.NextMsg(time.Second) + require_NoError(t, err) + require_Contains(t, string(mRep.Data), "reply") +}