summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--librabbitmq/amqp.h2
-rw-r--r--librabbitmq/amqp_url.c37
-rw-r--r--tests/test_parse_url.c111
-rw-r--r--tools/common.c68
4 files changed, 149 insertions, 69 deletions
diff --git a/librabbitmq/amqp.h b/librabbitmq/amqp.h
index d1bfe4e..825e9ff 100644
--- a/librabbitmq/amqp.h
+++ b/librabbitmq/amqp.h
@@ -124,6 +124,7 @@ struct iovec;
# define AMQP_CALL
#endif
+#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
@@ -569,6 +570,7 @@ struct amqp_connection_info {
char *host;
char *vhost;
int port;
+ bool ssl;
};
AMQP_PUBLIC_FUNCTION
diff --git a/librabbitmq/amqp_url.c b/librabbitmq/amqp_url.c
index 277b5a6..72a4126 100644
--- a/librabbitmq/amqp_url.c
+++ b/librabbitmq/amqp_url.c
@@ -52,6 +52,7 @@ void amqp_default_connection_info(struct amqp_connection_info *ci)
ci->host = "localhost";
ci->port = 5672;
ci->vhost = "/";
+ ci->ssl = false;
}
/* Scan for the next delimiter, handling percent-encodings on the way. */
@@ -116,11 +117,16 @@ int amqp_parse_url(char *url, struct amqp_connection_info *parsed)
char *port = NULL;
/* check the prefix */
- if (strncmp(url, "amqp://", 7)) {
+ if (!strncmp(url, "amqp://", 7)) {
+ /* do nothing */
+ } else if (!strncmp(url, "amqps://", 8)) {
+ parsed->port = 5671;
+ parsed->ssl = true;
+ } else {
goto out;
}
- host = start = url += 7;
+ host = start = url += (parsed->ssl ? 8 : 7);
delim = find_delim(&url, 1);
if (delim == ':') {
@@ -135,9 +141,8 @@ int amqp_parse_url(char *url, struct amqp_connection_info *parsed)
/* What might have been the host and port were in fact
the username and password */
parsed->user = host;
- if (port) {
+ if (port)
parsed->password = port;
- }
port = NULL;
host = start = url;
@@ -147,16 +152,14 @@ int amqp_parse_url(char *url, struct amqp_connection_info *parsed)
if (delim == '[') {
/* IPv6 address. The bracket should be the first
character in the host. */
- if (host != start || *host != 0) {
+ if (host != start || *host != 0)
goto out;
- }
start = url;
delim = find_delim(&url, 0);
- if (delim != ']') {
+ if (delim != ']')
goto out;
- }
parsed->host = start;
start = url;
@@ -164,14 +167,13 @@ int amqp_parse_url(char *url, struct amqp_connection_info *parsed)
/* Closing bracket should be the last character in the
host. */
- if (*start != 0) {
+ if (*start != 0)
goto out;
- }
- } else {
+ }
+ else {
/* If we haven't seen the host yet, this is it. */
- if (*host != 0) {
+ if (*host != 0)
parsed->host = host;
- }
}
if (delim == ':') {
@@ -183,9 +185,8 @@ int amqp_parse_url(char *url, struct amqp_connection_info *parsed)
char *end;
long portnum = strtol(port, &end, 10);
- if (port == end || *end != 0 || portnum < 0 || portnum > 65535) {
+ if (port == end || *end != 0 || portnum < 0 || portnum > 65535)
goto out;
- }
parsed->port = portnum;
}
@@ -194,13 +195,13 @@ int amqp_parse_url(char *url, struct amqp_connection_info *parsed)
start = url;
delim = find_delim(&url, 1);
- if (delim != 0) {
+ if (delim != 0)
goto out;
- }
parsed->vhost = start;
res = 0;
- } else if (delim == 0) {
+ }
+ else if (delim == 0) {
res = 0;
}
diff --git a/tests/test_parse_url.c b/tests/test_parse_url.c
index b816cd8..241cf8c 100644
--- a/tests/test_parse_url.c
+++ b/tests/test_parse_url.c
@@ -111,62 +111,143 @@ int main(void)
{
/* From the spec */
parse_success("amqp://user:pass@host:10000/vhost", "user", "pass",
- "host", 10000, "vhost");
+ "host", 10000, "vhost");
+ parse_success("amqps://user:pass@host:10000/vhost", "user", "pass",
+ "host", 10000, "vhost");
+
parse_success("amqp://user%61:%61pass@ho%61st:10000/v%2fhost",
- "usera", "apass", "hoast", 10000, "v/host");
+ "usera", "apass", "hoast", 10000, "v/host");
+ parse_success("amqps://user%61:%61pass@ho%61st:10000/v%2fhost",
+ "usera", "apass", "hoast", 10000, "v/host");
+
parse_success("amqp://", "guest", "guest", "localhost", 5672, "/");
+ parse_success("amqps://", "guest", "guest", "localhost", 5671, "/");
+
parse_success("amqp://:@/", "", "", "localhost", 5672, "");
+ parse_success("amqps://:@/", "", "", "localhost", 5671, "");
+
parse_success("amqp://user@", "user", "guest", "localhost", 5672, "/");
+ parse_success("amqps://user@", "user", "guest", "localhost", 5671, "/");
+
parse_success("amqp://user:pass@", "user", "pass",
- "localhost", 5672, "/");
+ "localhost", 5672, "/");
+ parse_success("amqps://user:pass@", "user", "pass",
+ "localhost", 5671, "/");
+
parse_success("amqp://host", "guest", "guest", "host", 5672, "/");
+ parse_success("amqps://host", "guest", "guest", "host", 5671, "/");
+
parse_success("amqp://:10000", "guest", "guest", "localhost", 10000,
- "/");
+ "/");
+ parse_success("amqps://:10000", "guest", "guest", "localhost", 10000,
+ "/");
+
parse_success("amqp:///vhost", "guest", "guest", "localhost", 5672,
- "vhost");
+ "vhost");
+ parse_success("amqps:///vhost", "guest", "guest", "localhost", 5671,
+ "vhost");
+
parse_success("amqp://host/", "guest", "guest", "host", 5672, "");
+ parse_success("amqps://host/", "guest", "guest", "host", 5671, "");
+
parse_success("amqp://host/%2f", "guest", "guest", "host", 5672, "/");
+ parse_success("amqps://host/%2f", "guest", "guest", "host", 5671, "/");
+
parse_success("amqp://[::1]", "guest", "guest", "::1", 5672, "/");
+ parse_success("amqps://[::1]", "guest", "guest", "::1", 5671, "/");
/* Various other success cases */
parse_success("amqp://host:100", "guest", "guest", "host", 100, "/");
+ parse_success("amqps://host:100", "guest", "guest", "host", 100, "/");
+
parse_success("amqp://[::1]:100", "guest", "guest", "::1", 100, "/");
+ parse_success("amqps://[::1]:100", "guest", "guest", "::1", 100, "/");
parse_success("amqp://host/blah", "guest", "guest",
- "host", 5672, "blah");
+ "host", 5672, "blah");
+ parse_success("amqps://host/blah", "guest", "guest",
+ "host", 5671, "blah");
+
parse_success("amqp://host:100/blah", "guest", "guest",
- "host", 100, "blah");
+ "host", 100, "blah");
+ parse_success("amqps://host:100/blah", "guest", "guest",
+ "host", 100, "blah");
+
parse_success("amqp://:100/blah", "guest", "guest",
- "localhost", 100, "blah");
+ "localhost", 100, "blah");
+ parse_success("amqps://:100/blah", "guest", "guest",
+ "localhost", 100, "blah");
+
parse_success("amqp://[::1]/blah", "guest", "guest",
- "::1", 5672, "blah");
+ "::1", 5672, "blah");
+ parse_success("amqps://[::1]/blah", "guest", "guest",
+ "::1", 5671, "blah");
+
parse_success("amqp://[::1]:100/blah", "guest", "guest",
- "::1", 100, "blah");
+ "::1", 100, "blah");
+ parse_success("amqps://[::1]:100/blah", "guest", "guest",
+ "::1", 100, "blah");
parse_success("amqp://user:pass@host", "user", "pass",
- "host", 5672, "/");
+ "host", 5672, "/");
+ parse_success("amqps://user:pass@host", "user", "pass",
+ "host", 5671, "/");
+
parse_success("amqp://user:pass@host:100", "user", "pass",
- "host", 100, "/");
+ "host", 100, "/");
+ parse_success("amqps://user:pass@host:100", "user", "pass",
+ "host", 100, "/");
+
parse_success("amqp://user:pass@:100", "user", "pass",
- "localhost", 100, "/");
+ "localhost", 100, "/");
+ parse_success("amqps://user:pass@:100", "user", "pass",
+ "localhost", 100, "/");
+
parse_success("amqp://user:pass@[::1]", "user", "pass",
- "::1", 5672, "/");
+ "::1", 5672, "/");
+ parse_success("amqps://user:pass@[::1]", "user", "pass",
+ "::1", 5671, "/");
+
parse_success("amqp://user:pass@[::1]:100", "user", "pass",
- "::1", 100, "/");
+ "::1", 100, "/");
+ parse_success("amqps://user:pass@[::1]:100", "user", "pass",
+ "::1", 100, "/");
/* Various failure cases */
parse_fail("http://www.rabbitmq.com");
+
parse_fail("amqp://foo:bar:baz");
+ parse_fail("amqps://foo:bar:baz");
+
+ parse_fail("amqp://foo[::1]");
+ parse_fail("amqps://foo[::1]");
+
parse_fail("amqp://foo[::1]");
+ parse_fail("amqps://foo[::1]");
+
parse_fail("amqp://foo:[::1]");
+ parse_fail("amqps://foo:[::1]");
+
parse_fail("amqp://[::1]foo");
+ parse_fail("amqps://[::1]foo");
+
parse_fail("amqp://foo:1000xyz");
+ parse_fail("amqps://foo:1000xyz");
+
parse_fail("amqp://foo:1000000");
+ parse_fail("amqps://foo:1000000");
+
parse_fail("amqp://foo/bar/baz");
+ parse_fail("amqps://foo/bar/baz");
parse_fail("amqp://foo%1");
+ parse_fail("amqps://foo%1");
+
parse_fail("amqp://foo%1x");
+ parse_fail("amqps://foo%1x");
+
parse_fail("amqp://foo%xy");
+ parse_fail("amqps://foo%xy");
return 0;
}
diff --git a/tools/common.c b/tools/common.c
index 43b74be..b0f534c 100644
--- a/tools/common.c
+++ b/tools/common.c
@@ -236,10 +236,9 @@ static void init_connection_info(struct amqp_connection_info *ci)
if (amqp_server) {
char *colon;
- if (ci->host) {
+ if (ci->host)
die("both --server and --url options specify"
" server host");
- }
/* parse the server string into a hostname and a port */
colon = strchr(amqp_server, ':');
@@ -252,86 +251,83 @@ static void init_connection_info(struct amqp_connection_info *ci)
--url now allows connection options to be
specificied concisely. */
fprintf(stderr, "Specifying the port number with"
- " --server is deprecated\n");
+ " --server is deprecated\n");
host_len = colon - amqp_server;
ci->host = malloc(host_len + 1);
memcpy(ci->host, amqp_server, host_len);
ci->host[host_len] = 0;
- if (ci->port >= 0) {
+ if (ci->port >= 0)
die("both --server and --url options specify"
" server port");
- }
- if (amqp_port >= 0) {
+ if (amqp_port >= 0)
die("both --server and --port options specify"
" server port");
- }
ci->port = strtol(colon+1, &port_end, 10);
if (ci->port < 0
|| ci->port > 65535
|| port_end == colon+1
- || *port_end != 0) {
+ || *port_end != 0)
die("bad server port number in '%s'",
amqp_server);
- }
+ }
+
+ if (amqp_ssl && !ci->ssl) {
+ die("the --ssl option specifies an SSL connection"
+ " but the --server option does not");
}
}
if (amqp_port >= 0) {
- if (ci->port >= 0) {
+ if (ci->port >= 0)
die("both --port and --url options specify"
" server port");
- }
ci->port = amqp_port;
}
if (amqp_username) {
- if (ci->user) {
+ if (ci->user)
die("both --username and --url options specify"
" AMQP username");
- }
ci->user = amqp_username;
}
if (amqp_password) {
- if (ci->password) {
+ if (ci->password)
die("both --password and --url options specify"
" AMQP password");
- }
ci->password = amqp_password;
}
if (amqp_vhost) {
- if (ci->vhost) {
+ if (ci->vhost)
die("both --vhost and --url options specify"
" AMQP vhost");
- }
ci->vhost = amqp_vhost;
}
+ if (amqp_ssl) {
+ ci->ssl = true;
+ }
+
amqp_default_connection_info(&defaults);
- if (!ci->user) {
+ if (!ci->user)
ci->user = defaults.user;
- }
- if (!ci->password) {
+ if (!ci->password)
ci->password = defaults.password;
- }
- if (!ci->host) {
+ if (!ci->host)
ci->host = defaults.host;
- }
- if (ci->port < 0) {
+ if (ci->port < 0)
ci->port = defaults.port;
- }
- if (!ci->vhost) {
+ if (!ci->vhost)
ci->vhost = defaults.vhost;
- }
}
amqp_connection_state_t make_connection(void)
@@ -342,24 +338,24 @@ amqp_connection_state_t make_connection(void)
init_connection_info(&ci);
conn = amqp_new_connection();
+ if (ci.ssl) {
#ifdef WITH_SSL
- if (amqp_ssl) {
s = amqp_open_ssl_socket(conn, ci.host, ci.port, amqp_cacert,
- amqp_key, amqp_cert);
- } else
+ amqp_key, amqp_cert);
+#else
+ die("librabbitmq was not built with SSL/TLS support");
#endif
- {
+ } else {
s = amqp_open_socket(ci.host, ci.port);
amqp_set_sockfd(conn, s);
}
die_amqp_error(s, "opening socket to %s:%d", ci.host, ci.port);
die_rpc(amqp_login(conn, ci.vhost, 0, 131072, 0,
- AMQP_SASL_METHOD_PLAIN,
- ci.user, ci.password),
- "logging in to AMQP server");
- if (!amqp_channel_open(conn, 1)) {
+ AMQP_SASL_METHOD_PLAIN,
+ ci.user, ci.password),
+ "logging in to AMQP server");
+ if (!amqp_channel_open(conn, 1))
die_rpc(amqp_get_rpc_reply(conn), "opening channel");
- }
return conn;
}