nats.go icon indicating copy to clipboard operation
nats.go copied to clipboard

Error message required when invalid message subject is given.

Open goFrendiAsgard opened this issue 5 years ago • 7 comments

From the documentation, it is stated that

Subject names: Subject names, including reply subject (INBOX) names, are case-sensitive and must be non-empty alphanumeric strings with no embedded whitespace, and optionally token-delimited using the dot character (.), e.g.:

FOO, BAR, foo.bar, foo.BAR, FOO.BAR and FOO.BAR.BAZ are all valid subject names

FOO. BAR, foo. .bar andfoo..bar are not valid subject names

Unluckily, this is exactly what I did two days ago. No error message was thrown, so I was unaware of this problem. However, I observed a strange behaviour. Whenever I fire a message (with invalid subject), it was also consumed by subscriber that should not get the message.

Here is my code:

package main

import (
	"fmt"
	nats "github.com/nats-io/nats.go"
	"time"
)

func main() {
	nc, _ := nats.Connect(nats.DefaultURL)

	nc.Subscribe("*.get /foo", func(m *nats.Msg) {
		fmt.Printf("Received a message from foo: %s\n", string(m.Data))
	})

	nc.Subscribe("*.get /bar", func(m *nats.Msg) {
		fmt.Printf("Received a message from bar: %s\n", string(m.Data))
	})

	nc.Publish("ID.get /foo", []byte("foo-message"))
	nc.Publish("ID.get /bar", []byte("bar-message"))

	time.Sleep(3 * time.Second)
}

And this is what I get:

Received a message from bar: foo-message
Received a message from bar: bar-message
Received a message from foo: foo-message
Received a message from foo: bar-message

I know, it is already stated in the documentation. But I guess it is going to be better if we get an error message when doing something unintended.

Let me know if this is possible or not (or if you want my help).

goFrendiAsgard avatar Jun 01 '19 09:06 goFrendiAsgard

I will take a look.

derekcollison avatar Jun 07 '19 18:06 derekcollison

The queue name in the protocol is optional, in this case, once the protocol line is put together, server/client.go:1568 splitArg will interpret the protocol message as: *.get /foo 1 and *.get /bar 2, so /foo and /bar as are understood as queue names.

aricart avatar Jun 14 '19 15:06 aricart

Thinking maybe we could do some extra checking when Pedantic is enabled in the client, not sure want to have it by default for Publish for example as validating the subject could slightly affect performance, for Subscribe maybe ok though

wallyqs avatar Jun 14 '19 15:06 wallyqs

Pedantic would require the client has the right checks. And in cases where the subject is dynamically generated the error still will happen. Likely the fix is to add placeholders for subscription queue and publish replysub that do nothing but enforce a known number of expected tokens.

(main issue is any check on a particular client doesn't solve on the server)

aricart avatar Jun 14 '19 15:06 aricart

sounds like some options:

  • clients should check before hand, this has 0 performance consequences
  • server can check if there are > 2 elements on subscribe, which only catches the "foo bar" "baz blat" subject + queue name situations (as Alberto is saying)
  • server can check on publish, but again use performance would be affected
  • we should add an example specifically like this to the doc

I vote for slowly updating clients as they come out, and adding the "more than 2" check to the server on subscribe. Also, adding something to doc. I don't think we should add to every publish.

sasbury avatar Jun 14 '19 17:06 sasbury

I added https://github.com/nats-io/nats.java/issues/243 to the java client. I am worried about fixing before a major update because this will add an exception where there wasn't one before. If someone happens to be using "hello world" successfully i do'nt want to break their code.

sasbury avatar Jun 17 '19 23:06 sasbury

Pedantic mode will catch these but will slow things down for sure.

derekcollison avatar Jun 17 '19 23:06 derekcollison