230 lines
5.6 KiB
C++
230 lines
5.6 KiB
C++
/**
|
|
* Class describing initial connection setup
|
|
*
|
|
* This frame is sent by the server to the client, right after the connection
|
|
* is opened. It contains the initial connection properties, and the protocol
|
|
* number.
|
|
*
|
|
* @copyright 2014 - 2023 Copernica BV
|
|
*/
|
|
|
|
/**
|
|
* Dependencies
|
|
*/
|
|
#include "programname.h"
|
|
#include "platformname.h"
|
|
|
|
/**
|
|
* Set up namespace
|
|
*/
|
|
namespace AMQP {
|
|
|
|
/**
|
|
* Class implementation
|
|
*/
|
|
class ConnectionStartFrame : public ConnectionFrame
|
|
{
|
|
private:
|
|
/**
|
|
* Major AMQP version number
|
|
* @var uint8_t
|
|
*/
|
|
uint8_t _major;
|
|
|
|
/**
|
|
* Minor AMQP version number
|
|
* @var uint8_t
|
|
*/
|
|
uint8_t _minor;
|
|
|
|
/**
|
|
* Additional server properties
|
|
* @note: exact properties are not specified
|
|
* and are implementation-dependent
|
|
* @var Table
|
|
*/
|
|
Table _properties;
|
|
|
|
/**
|
|
* Available security mechanisms
|
|
* @var LongString
|
|
*/
|
|
LongString _mechanisms;
|
|
|
|
/**
|
|
* Available message locales
|
|
* @var LongString
|
|
*/
|
|
LongString _locales;
|
|
|
|
protected:
|
|
/**
|
|
* Encode a frame on a string buffer
|
|
*
|
|
* @param buffer buffer to write frame to
|
|
*/
|
|
virtual void fill(OutBuffer& buffer) const override
|
|
{
|
|
// call base
|
|
ConnectionFrame::fill(buffer);
|
|
|
|
// encode all fields
|
|
buffer.add(_major);
|
|
buffer.add(_minor);
|
|
_properties.fill(buffer);
|
|
_mechanisms.fill(buffer);
|
|
_locales.fill(buffer);
|
|
}
|
|
|
|
public:
|
|
/**
|
|
* Client-side constructer for a connection start frame
|
|
*
|
|
* @param major major protocol version
|
|
* @param minor minor protocol version
|
|
* @param properties server properties
|
|
* @param mechanisms available security mechanisms
|
|
* @param locales available locales
|
|
*/
|
|
ConnectionStartFrame(uint8_t major, uint8_t minor, const Table& properties, const std::string& mechanisms, const std::string& locales) :
|
|
ConnectionFrame((uint32_t)(properties.size() + mechanisms.length() + locales.length() + 10)), // 4 for each longstring (size-uint32), 2 major/minor
|
|
_major(major),
|
|
_minor(minor),
|
|
_properties(properties),
|
|
_mechanisms(mechanisms),
|
|
_locales(locales)
|
|
{}
|
|
|
|
/**
|
|
* Construct a connection start frame from a received frame
|
|
*
|
|
* @param frame received frame
|
|
*/
|
|
ConnectionStartFrame(ReceivedFrame &frame) :
|
|
ConnectionFrame(frame),
|
|
_major(frame.nextUint8()),
|
|
_minor(frame.nextUint8()),
|
|
_properties(frame),
|
|
_mechanisms(frame),
|
|
_locales(frame)
|
|
{}
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
virtual ~ConnectionStartFrame() {}
|
|
|
|
/**
|
|
* Method id
|
|
* @return uint16_t
|
|
*/
|
|
virtual uint16_t methodID() const override
|
|
{
|
|
return 10;
|
|
}
|
|
|
|
/**
|
|
* Major AMQP version number
|
|
* @return uint8_t
|
|
*/
|
|
uint8_t majorVersion() const
|
|
{
|
|
return _major;
|
|
}
|
|
|
|
/**
|
|
* Minor AMQP version number
|
|
* @return uint8_t
|
|
*/
|
|
uint8_t minorVersion() const
|
|
{
|
|
return _minor;
|
|
}
|
|
|
|
/**
|
|
* Additional server properties
|
|
* @note: exact properties are not specified
|
|
* and are implementation-dependent
|
|
*
|
|
* @return Table
|
|
*/
|
|
const Table& properties() const
|
|
{
|
|
return _properties;
|
|
}
|
|
|
|
/**
|
|
* The capabilities of the connection
|
|
* @return Table
|
|
*/
|
|
const Table& capabilities() const
|
|
{
|
|
// retrieve the capabilities
|
|
return _properties.get("capabilities");
|
|
}
|
|
|
|
/**
|
|
* Available security mechanisms
|
|
* @return string
|
|
*/
|
|
const std::string &mechanisms() const
|
|
{
|
|
return _mechanisms;
|
|
}
|
|
|
|
/**
|
|
* Available message locales
|
|
* @return string
|
|
*/
|
|
const std::string &locales() const
|
|
{
|
|
return _locales;
|
|
}
|
|
|
|
/**
|
|
* Process the connection start frame
|
|
* @param connection
|
|
* @return bool
|
|
* @internal
|
|
*/
|
|
virtual bool process(ConnectionImpl *connection) override
|
|
{
|
|
// the client properties
|
|
Table properties;
|
|
|
|
// move connection to handshake mode
|
|
connection->setProtocolOk(_properties, properties);
|
|
|
|
// the capabilities
|
|
Table capabilities;
|
|
|
|
// we want a special treatment for authentication failures
|
|
capabilities["authentication_failure_close"] = true;
|
|
|
|
// when the server cancels a consumer (for example because a queue is delete, or the node on which the
|
|
// queue lives dies, we want to receive a notification that the consumer is no longer alive)
|
|
capabilities["consumer_cancel_notify"] = true;
|
|
|
|
// fill the peer properties
|
|
if (!properties.contains("product")) properties["product"] = ProgramName();
|
|
if (!properties.contains("version")) properties["version"] = "Unknown";
|
|
if (!properties.contains("platform")) properties["platform"] = PlatformName();
|
|
if (!properties.contains("copyright")) properties["copyright"] = "Copernica AMQP-CPP library :: Copyright 2015-2023 Copernica BV";
|
|
if (!properties.contains("information")) properties["information"] = "https://github.com/CopernicaMarketingSoftware/AMQP-CPP";
|
|
if (!properties.contains("capabilities")) properties["capabilities"] = capabilities;
|
|
|
|
// send back a connection start ok frame
|
|
connection->send(ConnectionStartOKFrame(properties, "PLAIN", connection->login().saslPlain(), "en_US"));
|
|
|
|
// done
|
|
return true;
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* end namespace
|
|
*/
|
|
}
|
|
|