-
Change-Id: I87701996c8ba4b8d0fd689a7f1a4eee6ac858a13
Change-Id: I87701996c8ba4b8d0fd689a7f1a4eee6ac858a13
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
uri.h 8.33 KiB
/****************************************************************************
* Copyright (C) 2014-2021 Savoir-faire Linux Inc. *
* Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
* Author : Hugo Lefeuvre <hugo.lefeuvre@savoirfairelinux.com> *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#pragma once
#include "typedefs.h"
#include <memory>
#include <QStringList>
class URIPimpl;
class QDataStream;
/**
* @class URI A specialized string with multiple attributes
*
* Most of LibRingClient handle uri as strings, but more
* advanced algorithms need to access the various sections.
* This class implement a centralized and progressive URI
* parser to avoid having custom implementation peppered
* everywhere. This class doesn't attempt to produce perfect
* output. It has multiple tradeoff to be faster when
* accuracy has little value in the context of LibRingClient.
*
* Here is some example of common numbers/URIs:
* * 123
* * 123@192.168.123.123
* * 123@asterisk-server
* * <sip:123@192.168.123.123>
* * <sips:123@192.168.123.123>
* * <sips:888@192.168.48.213;transport=TLS>
* * <sip:c8oqz84zk7z@privacy.org>;tag=hyh8
* * 1 800 123-4567
* * 18001234567
*
* @ref http://tools.ietf.org/html/rfc5456#page-8
* @ref http://tools.ietf.org/html/rfc3986
* @ref http://tools.ietf.org/html/rfc3261
* @ref http://tools.ietf.org/html/rfc5630
*
* <code>
* From the RFC:
* foo://example.com:8042/over/there?name=ferret#nose
* \_/ \______________/\_________/ \_________/ \__/
* | | | | |
* scheme authority path query fragment
* | _____________________|__
* / \ / \
* urn:example:animal:ferret:nose
*
* authority = [ userinfo "@" ] host [ ":" port ]
* </code>
*
* "For example, the semicolon (";") and equals ("=") reserved characters are
* often used to delimit parameters and parameter values applicable to
* that segment. The comma (",") reserved character is often used for
* similar purposes. For example, one URI producer might use a segment
* such as "name;v=1.1" to indicate a reference to version 1.1 of
* "name", whereas another might use a segment such as "name,1.1" to
* indicate the same. "
*/
class LIB_EXPORT URI : public QString
{
public:
URI();
URI(const URI& other);
URI(const QString& other);
virtual ~URI();
// @enum SchemeType The very first part of the URI followed by a ':'
enum class SchemeType { SIP, SIPS, RING, NONE, COUNT__, UNRECOGNIZED };
Q_ENUMS(URI::SchemeType)
/**
* @enum Transport each known valid transport types
* Defined at http://tools.ietf.org/html/rfc3261#page-222
*/
enum class Transport {
NOT_SET, /*!< The transport have not been set directly in the URI */
TLS, /*!< Encrypted calls (capital) */
tls, /*!< Encrypted calls */
TCP, /*!< TCP (the default) (capital) */
tcp, /*!< TCP (the default) */
UDP, /*!< Without a connection (capital) */
udp, /*!< Without a connection */
SCTP, /*!< */
sctp, /*!< */
DTLS, /*!< */
dtls, /*!< */
COUNT__
};
Q_ENUMS(URI::Transport)
/**
* @enum Section flags associated with each logical sections of the URI
*
* Those sections can be packed into a block to be used to define the
* expected URI syntax
*
*/
enum class Section {
CHEVRONS = 0x1 << 0, /*!< <code><sips:888@192.168.48.213:5060;transport=TLS>
\_/ \_/
|_________________Chevrons_______________________|
</code>*/
SCHEME = 0x1 << 1, /*!< <code><sips:888@192.168.48.213:5060;transport=TLS>
\___/
|______Scheme|</code> */
USER_INFO = 0x1 << 2, /*!< <code><sips:888@192.168.48.213:5060;transport=TLS>
\___/
|_________Userinfo</code> */
HOSTNAME = 0x1 << 3, /*!< <code><sips:888@192.168.48.213:5060;transport=TLS>
\______________/
|_________Hostname</code> */
PORT = 0x1 << 4, /*!< <code><sips:888@192.168.48.213:5060;transport=TLS>
\____/
|_____Port</code> */
TRANSPORT = 0x1 << 5, /*!< <code><sips:888@192.168.48.213:5060;transport=TLS>
\_____________/
Transport________|</code> */
TAG = 0x1 << 6, /*!< <code><sips:888@192.168.48.213:5060;tag=b5c73d9ef>
\_____________/
Tag_________|</code> */
};
/**
* @enum ProtocolHint Expanded version of Account::Protocol
*
* This is used to make better choice when it come to choose an account or
* guess if the URI can be used with the current set et configured accounts.
*
* @warning This is an approximation. Those values are guessed using partial
* parsing (for performance) and are not definitive.
*/
enum class ProtocolHint {
RING, /* Start with "ring:" and 45 ASCII chars OR 40 ASCII chars */
IP, /* Match an IPv4 address */
SIP_HOST, /* Start with "sip:", has an @ and no "ring:" prefix */
SIP_OTHER, /* Start with "sip:" and doesn't fit in other categories */
RING_USERNAME, /* Anything that starts with "ring:" and isn't followed by 40 ASCII chars */
UNRECOGNIZED /* Anything that doesn't fit in other categories */
};
Q_ENUMS(URI::ProtocolHint)
// Getter
QString hostname() const;
QString userinfo() const;
bool hasHostname() const;
bool hasPort() const;
int port() const;
SchemeType schemeType() const;
ProtocolHint protocolHint() const;
// Setter
void setUserinfo(const QString& userinfo);
void setHostname(const QString& hostname);
void setPort(const QString& port);
void setSchemeType(SchemeType t);
// Converter
QString format(FlagPack<URI::Section> sections) const;
/**
* Helper function which returns a QString containing a uri formatted to include at minimum the
* SCHEME and USER_INFO, and also the HOSTNAME and PORT, if available.
*/
QString full() const;
URI& operator=(const URI&);
private:
std::unique_ptr<URIPimpl> pimpl_;
};
Q_DECLARE_METATYPE(URI)
Q_DECLARE_METATYPE(URI::ProtocolHint)
DECLARE_ENUM_FLAGS(URI::Section)
QDataStream& operator<<(QDataStream& stream, const URI::ProtocolHint& ph);