The question has happened because I need to put something into the target topic field which will not match anything. The first and obvious try was giving mosquitto_subscribe() an empty string. Server responded with QoS=128 (rejected by broker).
But looking into MQTT specification I see
All Topic Names and Topic Filters MUST be at least one character long
and it does NOT define client or server behavior if empty string is provided.
Do I understand properly that at the protocol and API level the behavior is undefined, and application calling subscription must check for null string before calling?
If it is true (by the requirement of the standard) then it is strange because empty string can be checked at all levels - in application, in client code and in server/broker code, and the most correct behavior - from my point of view, is what I observe - server returning error through standard mechanism (callback). Empty string is a valid special case for any string, and it must be explicitly defined in the standard.
You are correct to state that topics and topic filters must be at least one character long. On handling errors, the protocol spec states the below:
Unless stated otherwise, if either the Server or Client encounters a protocol violation, it MUST close the Network Connection on which it received that Control Packet which caused the protocol violation
This is clear behaviour, not undefined.
That means, in my opinion, that the broker you are using does not comply to the specification. I’ve checked Mosquitto and it disconnects the client as it should be doing.
The Mosquitto library should be denying the ability to send subscribe messages with empty strings, I’ve fixed that for future versions.
What would be the future behavior? Error code returned - which one?
Can you explain why is this and what is the reason behind. Let me explain the case: my application takes topic name from the config file, and this config file may contain any string, including empty one. Even more, it is logical that empty string for subscription would not subscribe to anything, therefore I just leave string in config file empty if I do not want subscription. The way it works like now with my broker it responds with QoS=128 (subscription failed), but mosquitto_subscribe() itself returns success. Why are we limiting client in its subscription freedom while, if server/broker does not support empty string, let it do this way return failed subscription error code, and it will be final response from broker, and not local error code from the library.
Returning MOSQ_ERR_INVAL, to indicate invalid input.
You’d have to ask the protocol designers for the original reason. I can see that a zero length topic doesn’t make a whole lot of sense though.
The point is that this behaviour is an absolute requirement of the spec. As it stands, the behaviour of mosquitto_subscribe() in this case is non-compliant with the spec. It must not send subscribe messages with zero length topics. The behaviour of the broker you are using is also non-compliant, it must not accept subscribe messages with zero length topics. Used anywhere else this behaviour will result in the client being disconnected.
To write your argument in another way, you’re effectively saying that the way you want to check whether a string is empty or not is to send it as part of a subscribe packet to the broker, have that broker check that it’s empty and deny the subscription request in another network packet to you, which you then have to parse. I’d suggest that using strlen() is more efficient…
I the light of the weight of the protocol, this is major reason
I am using this as reference, would it be possible to put comment that “sub” can not be an empty string causing this specific behavior you described.
Roger, I am kind of surprised not to see this zero string limitation for the publishing. What do you think? Seems to be valid to publish into the topic identified by the empty string!
I’m going to keep on saying this Topics cannot be zero length. If you have a broker that accepts this, they do not comply with the MQTT protocol. If your client allows you to send zero length topics, they do not comply with the MQTT protocol. If this is code you’ve written yourself, you should fix it. If it’s code from other people, you should tell them.
There is a slight caveat to that. In MQTT v5.0, it is possible to set up topic aliases. This means on publish number one, you include your topic and an alias integer. Say topic='Eugeny', alias=1. On subsequent publishes, you can set topic to be an empty string as long as you also provide the alias, so topic='' and alias=1. This is not publishing to an empty topic - the broker will use the previously defined topic for that alias, so Eugeny. If you publish a zero length topic without an alias, that is a protocol error and your client must be disconnected. If you publish with a zero length topic with an alias that hasn’t been previously defined, that is also a protocol error.