mirror of
https://github.com/curl/curl.git
synced 2026-01-18 17:21:26 +01:00
@@ -1953,6 +1953,7 @@ curl_add_if("IPNS" NOT CURL_DISABLE_IPFS)
|
||||
curl_add_if("RTSP" NOT CURL_DISABLE_RTSP)
|
||||
curl_add_if("RTMP" USE_LIBRTMP)
|
||||
curl_add_if("MQTT" NOT CURL_DISABLE_MQTT)
|
||||
curl_add_if("MQTTS" NOT CURL_DISABLE_MQTT AND _ssl_enabled)
|
||||
curl_add_if("WS" NOT CURL_DISABLE_WEBSOCKETS)
|
||||
curl_add_if("WSS" NOT CURL_DISABLE_WEBSOCKETS AND _ssl_enabled)
|
||||
if(_items)
|
||||
|
||||
@@ -5424,6 +5424,9 @@ if test "$CURL_DISABLE_GOPHER" != "1"; then
|
||||
fi
|
||||
if test "$CURL_DISABLE_MQTT" != "1"; then
|
||||
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS MQTT"
|
||||
if test "$SSL_ENABLED" = "1"; then
|
||||
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS MQTTS"
|
||||
fi
|
||||
fi
|
||||
if test "$CURL_DISABLE_POP3" != "1"; then
|
||||
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS POP3"
|
||||
|
||||
@@ -21,7 +21,7 @@ The curl project produces two products:
|
||||
### libcurl
|
||||
|
||||
A client-side URL transfer library, supporting DICT, FILE, FTP, FTPS, GOPHER,
|
||||
GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, POP3, POP3S, RTMP,
|
||||
GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTMP,
|
||||
RTMPS, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS.
|
||||
|
||||
libcurl supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading,
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
**curl** is a tool for transferring data from or to a server using URLs. It
|
||||
supports these protocols: DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS,
|
||||
IMAP, IMAPS, LDAP, LDAPS, MQTT, POP3, POP3S, RTMP, RTMPS, RTSP, SCP, SFTP,
|
||||
SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS.
|
||||
IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTMP, RTMPS, RTSP, SCP,
|
||||
SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS.
|
||||
|
||||
curl is powered by libcurl for all transfer-related features. See
|
||||
*libcurl(3)* for details.
|
||||
|
||||
@@ -12,6 +12,10 @@ A plain "GET" subscribes to the topic and prints all published messages.
|
||||
|
||||
Doing a "POST" publishes the post data to the topic and exits.
|
||||
|
||||
## TLS protection
|
||||
|
||||
Use `mqtts://` to do MQTT over TLS: MQTTS.
|
||||
|
||||
### Subscribing
|
||||
|
||||
Command usage:
|
||||
|
||||
@@ -51,6 +51,8 @@ CURLPROTO_IMAP
|
||||
CURLPROTO_IMAPS
|
||||
CURLPROTO_LDAP
|
||||
CURLPROTO_LDAPS
|
||||
CURLPROTO_MQTT
|
||||
CURLPROTO_MQTTS
|
||||
CURLPROTO_POP3
|
||||
CURLPROTO_POP3S
|
||||
CURLPROTO_RTMP
|
||||
|
||||
@@ -42,8 +42,8 @@ set, it returns error.
|
||||
These are the available protocols:
|
||||
|
||||
DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS,
|
||||
MQTT, POP3, POP3S, RTMP, RTMPE, RTMPS, RTMPT, RTMPTE, RTMPTS, RTSP, SCP, SFTP,
|
||||
SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS, WSS
|
||||
MQTT, MQTTS, POP3, POP3S, RTMP, RTMPE, RTMPS, RTMPT, RTMPTE, RTMPTS, RTSP,
|
||||
SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS, WSS
|
||||
|
||||
You can set "ALL" as a short-cut to enable all protocols. Note that by setting
|
||||
all, you may enable protocols that were not supported the day you write this
|
||||
|
||||
@@ -58,6 +58,8 @@ CURLPROTO_IMAP
|
||||
CURLPROTO_IMAPS
|
||||
CURLPROTO_LDAP
|
||||
CURLPROTO_LDAPS
|
||||
CURLPROTO_MQTT
|
||||
CURLPROTO_MQTTS
|
||||
CURLPROTO_POP3
|
||||
CURLPROTO_POP3S
|
||||
CURLPROTO_RTMP
|
||||
|
||||
@@ -46,8 +46,8 @@ By default libcurl allows HTTP, HTTPS, FTP and FTPS on redirects (since
|
||||
These are the available protocols:
|
||||
|
||||
DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS,
|
||||
MQTT, POP3, POP3S, RTMP, RTMPE, RTMPS, RTMPT, RTMPTE, RTMPTS, RTSP, SCP, SFTP,
|
||||
SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS, WSS
|
||||
MQTT, MQTTS, POP3, POP3S, RTMP, RTMPE, RTMPS, RTMPT, RTMPTE, RTMPTS, RTSP,
|
||||
SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS, WSS
|
||||
|
||||
You can set "ALL" as a short-cut to enable all protocols. Note that by setting
|
||||
all, you may enable protocols that were not supported the day you write this
|
||||
|
||||
@@ -968,6 +968,7 @@ CURLPROTO_IMAPS 7.20.0
|
||||
CURLPROTO_LDAP 7.19.4
|
||||
CURLPROTO_LDAPS 7.19.4
|
||||
CURLPROTO_MQTT 7.71.0
|
||||
CURLPROTO_MQTTS 8.19.0
|
||||
CURLPROTO_POP3 7.20.0
|
||||
CURLPROTO_POP3S 7.20.0
|
||||
CURLPROTO_RTMP 7.21.0
|
||||
|
||||
@@ -184,6 +184,7 @@ Available substitute variables include:
|
||||
- `%IMAPPORT` - Port number of the IMAP server
|
||||
- `%LOGDIR` - Log directory relative to %PWD
|
||||
- `%MQTTPORT` - Port number of the MQTT server
|
||||
- `%MQTTSPORT` - Port number of the MQTTS server
|
||||
- `%NOLISTENPORT` - Port number where no service is listening
|
||||
- `%POP36PORT` - IPv6 port number of the POP3 server
|
||||
- `%POP3PORT` - Port number of the POP3 server
|
||||
|
||||
@@ -1100,6 +1100,7 @@ typedef CURLSTScode (*curl_hstswrite_callback)(CURL *easy,
|
||||
#define CURLPROTO_SMBS (1L << 27)
|
||||
#define CURLPROTO_MQTT (1L << 28)
|
||||
#define CURLPROTO_GOPHERS (1L << 29)
|
||||
#define CURLPROTO_MQTTS (1L << 30)
|
||||
#define CURLPROTO_ALL (~0L) /* enable everything */
|
||||
|
||||
/* long may be 32 or 64 bits, but we should never depend on anything else
|
||||
|
||||
46
lib/mqtt.c
46
lib/mqtt.c
@@ -36,6 +36,8 @@
|
||||
#include "url.h"
|
||||
#include "escape.h"
|
||||
#include "rand.h"
|
||||
#include "cfilters.h"
|
||||
#include "connect.h"
|
||||
|
||||
/* first byte is command.
|
||||
second byte is for flags. */
|
||||
@@ -934,6 +936,50 @@ static CURLcode mqtt_doing(struct Curl_easy *data, bool *done)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef USE_SSL
|
||||
|
||||
static CURLcode mqtts_connecting(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
CURLcode result;
|
||||
|
||||
result = Curl_conn_connect(data, FIRSTSOCKET, TRUE, done);
|
||||
if(result)
|
||||
connclose(conn, "Failed TLS connection");
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* MQTTS protocol handler.
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_mqtts = {
|
||||
"mqtts", /* scheme */
|
||||
mqtt_setup_conn, /* setup_connection */
|
||||
mqtt_do, /* do_it */
|
||||
mqtt_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
ZERO_NULL, /* connect_it */
|
||||
mqtts_connecting, /* connecting */
|
||||
mqtt_doing, /* doing */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
mqtt_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
ZERO_NULL, /* follow */
|
||||
PORT_MQTTS, /* defport */
|
||||
CURLPROTO_MQTTS, /* protocol */
|
||||
CURLPROTO_MQTT, /* family */
|
||||
PROTOPT_SSL /* flags */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MQTT protocol handler.
|
||||
*/
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
***************************************************************************/
|
||||
#ifndef CURL_DISABLE_MQTT
|
||||
extern const struct Curl_handler Curl_handler_mqtt;
|
||||
#ifdef USE_SSL
|
||||
extern const struct Curl_handler Curl_handler_mqtts;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_MQTT_H */
|
||||
|
||||
@@ -1423,7 +1423,12 @@ const struct Curl_handler *Curl_getn_scheme_handler(const char *scheme,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
NULL, NULL,
|
||||
#if defined(USE_SSL) && !defined(CURL_DISABLE_MQTT)
|
||||
&Curl_handler_mqtts,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
NULL,
|
||||
#if defined(USE_SSL) && !defined(CURL_DISABLE_GOPHER)
|
||||
&Curl_handler_gophers,
|
||||
#else
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#define PORT_RTMPS PORT_HTTPS
|
||||
#define PORT_GOPHER 70
|
||||
#define PORT_MQTT 1883
|
||||
#define PORT_MQTTS 8883
|
||||
|
||||
struct curl_trc_featt;
|
||||
|
||||
|
||||
@@ -341,6 +341,9 @@ static const char * const supported_protocols[] = {
|
||||
#ifndef CURL_DISABLE_MQTT
|
||||
"mqtt",
|
||||
#endif
|
||||
#if defined(USE_SSL) && !defined(CURL_DISABLE_MQTT)
|
||||
"mqtts",
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_POP3
|
||||
"pop3",
|
||||
#endif
|
||||
|
||||
@@ -51,6 +51,7 @@ static const struct detail scheme[] = {
|
||||
" ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \\\n"
|
||||
" (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))" },
|
||||
{ "mqtt", "#ifndef CURL_DISABLE_MQTT" },
|
||||
{ "mqtts", "#if defined(USE_SSL) && !defined(CURL_DISABLE_MQTT)" },
|
||||
{ "pop3", "#ifndef CURL_DISABLE_POP3" },
|
||||
{ "pop3s", "#if defined(USE_SSL) && !defined(CURL_DISABLE_POP3)" },
|
||||
{ "rtmp", "#ifdef USE_LIBRTMP" },
|
||||
|
||||
@@ -218,6 +218,8 @@ test1620 test1621 test1622 \
|
||||
\
|
||||
test1630 test1631 test1632 test1633 test1634 test1635 test1636 \
|
||||
\
|
||||
test1640 \
|
||||
\
|
||||
test1650 test1651 test1652 test1653 test1654 test1655 test1656 test1657 \
|
||||
test1658 \
|
||||
test1660 test1661 test1662 test1663 test1664 test1665 \
|
||||
|
||||
54
tests/data/test1640
Normal file
54
tests/data/test1640
Normal file
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
MQTT
|
||||
MQTT SUBSCRIBE
|
||||
MQTTS
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
# Server-side
|
||||
<reply>
|
||||
<data nocheck="yes">
|
||||
hello
|
||||
</data>
|
||||
<datacheck hex="yes">
|
||||
00 04 31 31 39 30 68 65 6c 6c 6f 5b 4c 46 5d 0a
|
||||
</datacheck>
|
||||
</reply>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<features>
|
||||
mqtts
|
||||
</features>
|
||||
<server>
|
||||
mqtts
|
||||
</server>
|
||||
<name>
|
||||
MQTTS SUBSCRIBE
|
||||
</name>
|
||||
<command option="binary-trace">
|
||||
mqtts://%HOSTIP:%MQTTSPORT/topic --insecure
|
||||
</command>
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
# These are hexadecimal protocol dumps from the client
|
||||
# Strip out the random part of the client id from the CONNECT message
|
||||
# before comparison
|
||||
<strippart>
|
||||
s/^(.* 00044d5154540402003c000c6375726c).*/$1/
|
||||
</strippart>
|
||||
<protocol>
|
||||
client CONNECT 18 00044d5154540402003c000c6375726c
|
||||
server CONNACK 2 20020000
|
||||
client SUBSCRIBE a 00010005746f70696300
|
||||
server SUBACK 3 9003000100
|
||||
server PUBLISH d 300d0005746f70696368656c6c6f0a
|
||||
server DISCONNECT 0 e000
|
||||
</protocol>
|
||||
</verify>
|
||||
</testcase>
|
||||
@@ -125,7 +125,7 @@ sub servername_str {
|
||||
|
||||
$proto = uc($proto) if($proto);
|
||||
die "unsupported protocol: '$proto'" unless($proto &&
|
||||
($proto =~ /^(((DNS|FTP|HTTP|HTTP\/2|HTTP\/3|IMAP|POP3|GOPHER|SMTP|HTTPS-MTLS)S?)|(TFTP|SFTP|SOCKS|SSH|RTSP|HTTPTLS|DICT|SMB|SMBS|TELNET|MQTT))$/));
|
||||
($proto =~ /^(((DNS|FTP|HTTP|HTTP\/2|HTTP\/3|IMAP|POP3|GOPHER|SMTP|HTTPS-MTLS)S?)|(TFTP|SFTP|SOCKS|SSH|RTSP|HTTPTLS|DICT|SMB|SMBS|TELNET|MQTT|MQTTS))$/));
|
||||
|
||||
$ipver = (not $ipver) ? 'ipv4' : lc($ipver);
|
||||
die "unsupported IP version: '$ipver'" unless($ipver &&
|
||||
|
||||
@@ -237,8 +237,8 @@ sub init_serverpidfile_hash {
|
||||
}
|
||||
}
|
||||
for my $proto (('tftp', 'sftp', 'socks', 'ssh', 'rtsp', 'httptls',
|
||||
'dict', 'smb', 'smbs', 'telnet', 'mqtt', 'https-mtls',
|
||||
'dns')) {
|
||||
'dict', 'smb', 'smbs', 'telnet', 'mqtt', 'mqtts',
|
||||
'https-mtls', 'dns')) {
|
||||
for my $ipvnum ((4, 6)) {
|
||||
for my $idnum ((1, 2)) {
|
||||
my $serv = servername_id($proto, $ipvnum, $idnum);
|
||||
@@ -1030,6 +1030,7 @@ my %protofunc = ('http' => \&verifyhttp,
|
||||
'pop3s' => \&verifyftp,
|
||||
'imaps' => \&verifyftp,
|
||||
'mqtt' => \&verifypid,
|
||||
'mqtts' => \&verifypid,
|
||||
'smtps' => \&verifyftp,
|
||||
'tftp' => \&verifyftp,
|
||||
'ssh' => \&verifyssh,
|
||||
@@ -1329,6 +1330,9 @@ sub runhttpsserver {
|
||||
if($proto eq "gophers") {
|
||||
$flags .= "--connect " . protoport("gopher");
|
||||
}
|
||||
elsif($proto eq "mqtts") {
|
||||
$flags .= "--connect " . protoport("mqtt");
|
||||
}
|
||||
elsif(!$proxy) {
|
||||
$flags .= "--connect " . protoport("http");
|
||||
}
|
||||
@@ -2955,6 +2959,36 @@ sub startservers {
|
||||
$run{'mqtt'}="$pid $pid2";
|
||||
}
|
||||
}
|
||||
elsif($what eq "mqtts" ) {
|
||||
if(!$stunnel) {
|
||||
# we cannot run mqtts tests without stunnel
|
||||
return ("no stunnel", 4);
|
||||
}
|
||||
if($run{'mqtt'} &&
|
||||
!responsive_mqtt_server("mqtt", "", $verbose)) {
|
||||
if(stopserver('mqtt')) {
|
||||
return ("failed stopping unresponsive MQTT server", 3);
|
||||
}
|
||||
}
|
||||
if(!$run{'mqtt'}) {
|
||||
($serr, $pid, $pid2, $PORT{"mqtt"}) = runmqttserver("", $verbose);
|
||||
if($pid <= 0) {
|
||||
return ("failed starting mqtt server", $serr);
|
||||
}
|
||||
logmsg sprintf("* pid mqtt => %d %d\n", $pid, $pid2) if($verbose);
|
||||
$run{'mqtt'}="$pid $pid2";
|
||||
}
|
||||
if(!$run{$what}) {
|
||||
($serr, $pid, $pid2, $PORT{$what}) =
|
||||
runhttpsserver($verbose, $what, "", $certfile);
|
||||
if($pid <= 0) {
|
||||
return ("failed starting MQTTS server (stunnel)", $serr);
|
||||
}
|
||||
logmsg sprintf("* pid $what => %d %d\n", $pid, $pid2)
|
||||
if($verbose);
|
||||
$run{$what}="$pid $pid2";
|
||||
}
|
||||
}
|
||||
elsif($what eq "http-unix") {
|
||||
if($run{'http-unix'} &&
|
||||
!responsive_http_server("http", $verbose, "unix", $HTTPUNIXPATH)) {
|
||||
@@ -3094,7 +3128,7 @@ sub subvariables {
|
||||
'HTTP2', 'HTTP2TLS',
|
||||
'HTTP3',
|
||||
'IMAP', 'IMAP6', 'IMAPS',
|
||||
'MQTT',
|
||||
'MQTT', 'MQTTS',
|
||||
'NOLISTEN',
|
||||
'POP3', 'POP36', 'POP3S',
|
||||
'RTSP', 'RTSP6',
|
||||
|
||||
Reference in New Issue
Block a user