nats.go
nats.go copied to clipboard
Error message required when invalid message subject is given.
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).
I will take a look.
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.
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
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)
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.
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.
Pedantic mode will catch these but will slow things down for sure.