fixed issue with parsing the password in a amqp:// string
This commit is contained in:
parent
2bb1300bc0
commit
2a249ae7ea
|
|
@ -50,65 +50,82 @@ private:
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor to parse an address string
|
* Constructor to parse an address string
|
||||||
* The address should be in "amqp://
|
* The address should start with "amqp://
|
||||||
* @param address
|
* @param data
|
||||||
|
* @param size
|
||||||
* @throws std::runtime_error
|
* @throws std::runtime_error
|
||||||
*/
|
*/
|
||||||
Address(const char *address) : _vhost("/")
|
Address(const char *data, size_t size) : _vhost("/")
|
||||||
{
|
{
|
||||||
|
// position of the last byte
|
||||||
|
const char *last = data + size;
|
||||||
|
|
||||||
// must start with amqp://
|
// must start with amqp://
|
||||||
if (strncmp(address, "amqp://", 7) != 0) throw std::runtime_error("AMQP address should start with \"amqp://\"");
|
if (size < 7 || strncmp(data, "amqp://", 7) != 0) throw std::runtime_error("AMQP address should start with \"amqp://\"");
|
||||||
|
|
||||||
// begin of the string being parsed
|
// begin of the string was parsed
|
||||||
const char *begin = address + 7;
|
data += 7;
|
||||||
|
|
||||||
// do we have a '@' to split user-data and hostname?
|
// do we have a '@' to split user-data and hostname?
|
||||||
const char *at = strchr(begin, '@');
|
const char *at = (const char *)memchr(data, '@', last - data);
|
||||||
|
|
||||||
// do we have one?
|
// do we have one?
|
||||||
if (at != nullptr)
|
if (at != nullptr)
|
||||||
{
|
{
|
||||||
|
// size of the user:password
|
||||||
|
size_t loginsize = at - data;
|
||||||
|
|
||||||
// colon could split username and password
|
// colon could split username and password
|
||||||
const char *colon = (const char *)memchr(begin, ':', at - begin);
|
const char *colon = (const char *)memchr(data, ':', loginsize);
|
||||||
|
|
||||||
// assign the login
|
// assign the login
|
||||||
_login = Login(
|
_login = Login(
|
||||||
std::string(begin, colon ? colon - begin : at - begin),
|
std::string(data, colon ? colon - data : loginsize),
|
||||||
std::string(colon ? colon + 1 : "", colon ? at - colon - 1 : 0)
|
std::string(colon ? colon + 1 : "", colon ? at - colon - 1 : 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
// set begin to the start of the hostname
|
// set data to the start of the hostname
|
||||||
begin = at + 1;
|
data = at + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find out where the vhost is set (starts with a slash)
|
// find out where the vhost is set (starts with a slash)
|
||||||
const char *slash = strchr(begin, '/');
|
const char *slash = (const char *)memchr(data, '/', last - data);
|
||||||
|
|
||||||
// was a vhost set?
|
// was a vhost set?
|
||||||
if (slash != nullptr && slash[1]) _vhost = slash + 1;
|
if (slash != nullptr && last - data > 1) _vhost.assign(slash + 1, last - data - 1);
|
||||||
|
|
||||||
// the hostname is everything until the slash, check is portnumber was set
|
// the hostname is everything until the slash, check is portnumber was set
|
||||||
const char *colon = strchr(begin, ':');
|
const char *colon = (const char *)memchr(data, ':', last - data);
|
||||||
|
|
||||||
// was a portnumber specified (colon must appear before the slash of the vhost)
|
// was a portnumber specified (colon must appear before the slash of the vhost)
|
||||||
if (colon && (!slash || colon < slash))
|
if (colon && (!slash || colon < slash))
|
||||||
{
|
{
|
||||||
// a portnumber was set to
|
// a portnumber was set to
|
||||||
_hostname.assign(begin, colon - begin);
|
_hostname.assign(data, colon - data);
|
||||||
_port = atoi(colon + 1);
|
|
||||||
|
// calculate the port
|
||||||
|
_port = atoi(std::string(colon + 1, slash ? slash - colon - 1 : last - colon - 1).data());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// no portnumber was set
|
// no portnumber was set
|
||||||
_hostname.assign(begin, slash ? slash - begin : strlen(begin));
|
_hostname.assign(data, slash ? slash - data : last - data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor to parse an address string
|
||||||
|
* The address should start with "amqp://
|
||||||
|
* @param data
|
||||||
|
* @throws std::runtime_error
|
||||||
|
*/
|
||||||
|
Address(const char *data) : Address(data, strlen(data)) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor based on std::string
|
* Constructor based on std::string
|
||||||
* @param address
|
* @param address
|
||||||
*/
|
*/
|
||||||
Address(const std::string &address) : Address(address.data()) {}
|
Address(const std::string &address) : Address(address.data(), address.size()) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor based on already known properties
|
* Constructor based on already known properties
|
||||||
|
|
@ -117,14 +134,16 @@ public:
|
||||||
* @param login
|
* @param login
|
||||||
* @param vhost
|
* @param vhost
|
||||||
*/
|
*/
|
||||||
Address(std::string host, uint16_t port, Login login, std::string vhost) : _login(std::move(login)),
|
Address(std::string host, uint16_t port, Login login, std::string vhost) :
|
||||||
_hostname(std::move(host)),
|
_login(std::move(login)),
|
||||||
_port(port), _vhost(std::move(vhost)) {}
|
_hostname(std::move(host)),
|
||||||
|
_port(port),
|
||||||
|
_vhost(std::move(vhost)) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor
|
* Destructor
|
||||||
*/
|
*/
|
||||||
virtual ~Address() {}
|
virtual ~Address() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expose the login data
|
* Expose the login data
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
/**
|
||||||
|
* Address.cpp
|
||||||
|
*
|
||||||
|
* Test program to parse address strings
|
||||||
|
*
|
||||||
|
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||||
|
* @copyright 2017 Copernica BV
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies
|
||||||
|
*/
|
||||||
|
#include <amqpcpp.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main procedure
|
||||||
|
* @param argc
|
||||||
|
* @param argv
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int main(int argc, const char *argv[])
|
||||||
|
{
|
||||||
|
// iterate over the arguments
|
||||||
|
for (int i = 1; i < argc; ++i)
|
||||||
|
{
|
||||||
|
// parse address
|
||||||
|
AMQP::Address address(argv[i]);
|
||||||
|
|
||||||
|
// output all properties
|
||||||
|
std::cout << "user: " << address.login().user() << std::endl;
|
||||||
|
std::cout << "password: " << address.login().password() << std::endl;
|
||||||
|
std::cout << "hostname: " << address.hostname() << std::endl;
|
||||||
|
std::cout << "port: " << address.port() << std::endl;
|
||||||
|
std::cout << "vhost: " << address.vhost() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// done
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue