Fix publish props not being passed to v5 msg callback for QoS 2 msgs.

Closes #1432. Thanks to Magnus Galåen.
pull/1473/head
Roger A. Light 6 years ago
parent 4db1e80410
commit 093c8f90f5

@ -2,6 +2,10 @@ Broker:
- Various fixes for `allow_zero_length_clientid` config, where this option was
not being set correctly. Closes #1429.
Client library:
- Fix publish properties not being passed to on_message_v5 callback for QoS 2
messages. Closes #1432.
1.6.7 - 20190925
================

@ -152,13 +152,13 @@ int handle__publish(struct mosquitto *mosq)
mosquitto_property_free_all(&properties);
return rc;
case 2:
message->properties = properties;
util__decrement_receive_quota(mosq);
rc = send__pubrec(mosq, message->msg.mid, 0);
pthread_mutex_lock(&mosq->msgs_in.mutex);
message->state = mosq_ms_wait_for_pubrel;
message__queue(mosq, message, mosq_md_in);
pthread_mutex_unlock(&mosq->msgs_in.mutex);
mosquitto_property_free_all(&properties);
return rc;
default:
message__cleanup(&message);

@ -114,7 +114,7 @@ int handle__pubrel(struct mosquitto_db *db, struct mosquitto *mosq)
}
if(mosq->on_message_v5){
mosq->in_callback = true;
mosq->on_message_v5(mosq, mosq->userdata, &message->msg, properties);
mosq->on_message_v5(mosq, mosq->userdata, &message->msg, message->properties);
mosq->in_callback = false;
}
pthread_mutex_unlock(&mosq->callback_mutex);

@ -0,0 +1,58 @@
#!/usr/bin/env python3
# Check whether the v5 message callback gets the properties
from mosq_test_helper import *
port = mosq_test.get_lib_port()
rc = 1
keepalive = 60
connect_packet = mosq_test.gen_connect("prop-test", keepalive=keepalive, proto_ver=5)
connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_CONTENT_TYPE, "plain/text")
props += mqtt5_props.gen_string_prop(mqtt5_props.PROP_RESPONSE_TOPIC, "msg/123")
publish_packet = mosq_test.gen_publish("prop/test", qos=0, payload="message", proto_ver=5, properties=props)
ok_packet = mosq_test.gen_publish("ok", qos=0, payload="ok", proto_ver=5)
disconnect_packet = mosq_test.gen_disconnect(proto_ver=5)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.settimeout(10)
sock.bind(('', port))
sock.listen(5)
client_args = sys.argv[1:]
env = dict(os.environ)
env['LD_LIBRARY_PATH'] = '../../lib:../../lib/cpp'
try:
pp = env['PYTHONPATH']
except KeyError:
pp = ''
env['PYTHONPATH'] = '../../lib/python:'+pp
client = mosq_test.start_client(filename=sys.argv[1].replace('/', '-'), cmd=client_args, env=env, port=port)
try:
(conn, address) = sock.accept()
conn.settimeout(10)
if mosq_test.expect_packet(conn, "connect", connect_packet):
conn.send(connack_packet)
conn.send(publish_packet)
if mosq_test.expect_packet(conn, "ok", ok_packet):
rc = 0
conn.close()
finally:
client.terminate()
client.wait()
if rc:
(stdo, stde) = client.communicate()
print(stde)
sock.close()
exit(rc)

@ -0,0 +1,62 @@
#!/usr/bin/env python3
# Check whether the v5 message callback gets the properties
from mosq_test_helper import *
port = mosq_test.get_lib_port()
rc = 1
keepalive = 60
connect_packet = mosq_test.gen_connect("prop-test", keepalive=keepalive, proto_ver=5)
connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
mid = 1
props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_CONTENT_TYPE, "plain/text")
props += mqtt5_props.gen_string_prop(mqtt5_props.PROP_RESPONSE_TOPIC, "msg/123")
publish_packet = mosq_test.gen_publish("prop/test", mid=mid, qos=1, payload="message", proto_ver=5, properties=props)
puback_packet = mosq_test.gen_puback(mid=mid, proto_ver=5)
ok_packet = mosq_test.gen_publish("ok", qos=0, payload="ok", proto_ver=5)
disconnect_packet = mosq_test.gen_disconnect(proto_ver=5)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.settimeout(10)
sock.bind(('', port))
sock.listen(5)
client_args = sys.argv[1:]
env = dict(os.environ)
env['LD_LIBRARY_PATH'] = '../../lib:../../lib/cpp'
try:
pp = env['PYTHONPATH']
except KeyError:
pp = ''
env['PYTHONPATH'] = '../../lib/python:'+pp
client = mosq_test.start_client(filename=sys.argv[1].replace('/', '-'), cmd=client_args, env=env, port=port)
try:
(conn, address) = sock.accept()
conn.settimeout(10)
if mosq_test.expect_packet(conn, "connect", connect_packet):
conn.send(connack_packet)
conn.send(publish_packet)
if mosq_test.expect_packet(conn, "puback", puback_packet):
if mosq_test.expect_packet(conn, "ok", ok_packet):
rc = 0
conn.close()
finally:
client.terminate()
client.wait()
if rc:
(stdo, stde) = client.communicate()
print(stde)
sock.close()
exit(rc)

@ -0,0 +1,66 @@
#!/usr/bin/env python3
# Check whether the v5 message callback gets the properties
from mosq_test_helper import *
port = mosq_test.get_lib_port()
rc = 1
keepalive = 60
connect_packet = mosq_test.gen_connect("prop-test", keepalive=keepalive, proto_ver=5)
connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
mid = 1
props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_CONTENT_TYPE, "plain/text")
props += mqtt5_props.gen_string_prop(mqtt5_props.PROP_RESPONSE_TOPIC, "msg/123")
publish_packet = mosq_test.gen_publish("prop/test", mid=mid, qos=2, payload="message", proto_ver=5, properties=props)
pubrec_packet = mosq_test.gen_pubrec(mid=mid, proto_ver=5)
pubrel_packet = mosq_test.gen_pubrel(mid=mid, proto_ver=5)
pubcomp_packet = mosq_test.gen_pubcomp(mid=mid, proto_ver=5)
ok_packet = mosq_test.gen_publish("ok", qos=0, payload="ok", proto_ver=5)
disconnect_packet = mosq_test.gen_disconnect(proto_ver=5)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.settimeout(10)
sock.bind(('', port))
sock.listen(5)
client_args = sys.argv[1:]
env = dict(os.environ)
env['LD_LIBRARY_PATH'] = '../../lib:../../lib/cpp'
try:
pp = env['PYTHONPATH']
except KeyError:
pp = ''
env['PYTHONPATH'] = '../../lib/python:'+pp
client = mosq_test.start_client(filename=sys.argv[1].replace('/', '-'), cmd=client_args, env=env, port=port)
try:
(conn, address) = sock.accept()
conn.settimeout(10)
if mosq_test.expect_packet(conn, "connect", connect_packet):
conn.send(connack_packet)
conn.send(publish_packet)
if mosq_test.expect_packet(conn, "pubrec", pubrec_packet):
conn.send(pubrel_packet)
if mosq_test.expect_packet(conn, "pubcomp", pubcomp_packet):
if mosq_test.expect_packet(conn, "ok", ok_packet):
rc = 0
conn.close()
finally:
client.terminate()
client.wait()
if rc:
(stdo, stde) = client.communicate()
print(stde)
sock.close()
exit(rc)

@ -68,6 +68,9 @@ endif
./11-prop-oversize-packet.py $@/11-prop-oversize-packet.test
./11-prop-send-content-type.py $@/11-prop-send-content-type.test
./11-prop-send-payload-format.py $@/11-prop-send-payload-format.test
./11-prop-recv-qos0.py $@/11-prop-recv-qos0.test
./11-prop-recv-qos1.py $@/11-prop-recv-qos1.test
./11-prop-recv-qos2.py $@/11-prop-recv-qos2.test
clean :
$(MAKE) -C c clean

@ -0,0 +1,81 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mosquitto.h>
#include <mqtt_protocol.h>
static int run = -1;
static int sent_mid = -1;
void on_connect(struct mosquitto *mosq, void *obj, int rc)
{
int rc2;
mosquitto_property *proplist = NULL;
if(rc){
exit(1);
}
}
void on_message_v5(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg, const mosquitto_property *properties)
{
int rc;
char *str;
if(properties){
if(mosquitto_property_read_string(properties, MQTT_PROP_CONTENT_TYPE, &str, false)){
rc = strcmp(str, "plain/text");
free(str);
if(rc == 0){
if(mosquitto_property_read_string(properties, MQTT_PROP_RESPONSE_TOPIC, &str, false)){
rc = strcmp(str, "msg/123");
free(str);
if(rc == 0){
if(msg->qos == 0){
mosquitto_publish(mosq, NULL, "ok", 2, "ok", 0, 0);
return;
}
}
}
}
}
}
/* No matching message, so quit with an error */
exit(1);
}
void on_publish(struct mosquitto *mosq, void *obj, int mid)
{
run = 0;
}
int main(int argc, char *argv[])
{
int rc;
int tmp;
struct mosquitto *mosq;
int port = atoi(argv[1]);
mosquitto_lib_init();
mosq = mosquitto_new("prop-test", true, NULL);
mosquitto_connect_callback_set(mosq, on_connect);
mosquitto_message_v5_callback_set(mosq, on_message_v5);
mosquitto_int_option(mosq, MOSQ_OPT_PROTOCOL_VERSION, MQTT_PROTOCOL_V5);
rc = mosquitto_connect(mosq, "localhost", port, 60);
while(run == -1){
rc = mosquitto_loop(mosq, -1, 1);
}
mosquitto_lib_cleanup();
return run;
}

@ -0,0 +1,81 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mosquitto.h>
#include <mqtt_protocol.h>
static int run = -1;
static int sent_mid = -1;
void on_connect(struct mosquitto *mosq, void *obj, int rc)
{
int rc2;
mosquitto_property *proplist = NULL;
if(rc){
exit(1);
}
}
void on_message_v5(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg, const mosquitto_property *properties)
{
int rc;
char *str;
if(properties){
if(mosquitto_property_read_string(properties, MQTT_PROP_CONTENT_TYPE, &str, false)){
rc = strcmp(str, "plain/text");
free(str);
if(rc == 0){
if(mosquitto_property_read_string(properties, MQTT_PROP_RESPONSE_TOPIC, &str, false)){
rc = strcmp(str, "msg/123");
free(str);
if(rc == 0){
if(msg->qos == 1){
mosquitto_publish(mosq, NULL, "ok", 2, "ok", 0, 0);
return;
}
}
}
}
}
}
/* No matching message, so quit with an error */
exit(1);
}
void on_publish(struct mosquitto *mosq, void *obj, int mid)
{
run = 0;
}
int main(int argc, char *argv[])
{
int rc;
int tmp;
struct mosquitto *mosq;
int port = atoi(argv[1]);
mosquitto_lib_init();
mosq = mosquitto_new("prop-test", true, NULL);
mosquitto_connect_callback_set(mosq, on_connect);
mosquitto_message_v5_callback_set(mosq, on_message_v5);
mosquitto_int_option(mosq, MOSQ_OPT_PROTOCOL_VERSION, MQTT_PROTOCOL_V5);
rc = mosquitto_connect(mosq, "localhost", port, 60);
while(run == -1){
rc = mosquitto_loop(mosq, -1, 1);
}
mosquitto_lib_cleanup();
return run;
}

@ -0,0 +1,82 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mosquitto.h>
#include <mqtt_protocol.h>
static int run = -1;
static int sent_mid = -1;
void on_connect(struct mosquitto *mosq, void *obj, int rc)
{
int rc2;
mosquitto_property *proplist = NULL;
if(rc){
exit(1);
}
}
void on_message_v5(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg, const mosquitto_property *properties)
{
int rc;
char *str;
if(properties){
if(mosquitto_property_read_string(properties, MQTT_PROP_CONTENT_TYPE, &str, false)){
rc = strcmp(str, "plain/text");
free(str);
if(rc == 0){
if(mosquitto_property_read_string(properties, MQTT_PROP_RESPONSE_TOPIC, &str, false)){
rc = strcmp(str, "msg/123");
free(str);
if(rc == 0){
if(msg->qos == 2){
mosquitto_publish(mosq, NULL, "ok", 2, "ok", 0, 0);
return;
}
}
}
}
}
}
/* No matching message, so quit with an error */
exit(1);
}
void on_publish(struct mosquitto *mosq, void *obj, int mid)
{
run = 0;
}
int main(int argc, char *argv[])
{
int rc;
int tmp;
struct mosquitto *mosq;
int port = atoi(argv[1]);
mosquitto_lib_init();
mosq = mosquitto_new("prop-test", true, NULL);
mosquitto_connect_callback_set(mosq, on_connect);
mosquitto_message_v5_callback_set(mosq, on_message_v5);
mosquitto_int_option(mosq, MOSQ_OPT_PROTOCOL_VERSION, MQTT_PROTOCOL_V5);
rc = mosquitto_connect(mosq, "localhost", port, 60);
while(run == -1){
rc = mosquitto_loop(mosq, -1, 1);
}
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return run;
}

@ -46,6 +46,9 @@ SRC = \
08-ssl-fake-cacert.c \
09-util-topic-tokenise.c \
11-prop-oversize-packet.c \
11-prop-recv-qos0.c \
11-prop-recv-qos1.c \
11-prop-recv-qos2.c \
11-prop-send-payload-format.c \
11-prop-send-content-type.c

Loading…
Cancel
Save