aboutsummaryrefslogtreecommitdiff
path: root/lib/connection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/connection.cpp')
-rw-r--r--lib/connection.cpp49
1 files changed, 32 insertions, 17 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp
index 4c068b8f..783e12c0 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -82,8 +82,9 @@ class Connection::Private
// separately; specifically, we should keep objects for Invite and
// Leave state of the same room if the two happen to co-exist.
QHash<QPair<QString, bool>, Room*> roomMap;
- // Mapping from aliases to room ids, as per the last sync
- QHash<QString, QString> roomAliasMap;
+ /// Mapping from serverparts to alias/room id mappings,
+ /// as of the last sync
+ QHash<QString, QHash<QString, QString>> roomAliasMap;
QVector<QString> roomIdsToForget;
QVector<Room*> firstTimeRooms;
QVector<QString> pendingStateRoomIds;
@@ -158,20 +159,31 @@ Connection::~Connection()
stopSync();
}
-void Connection::resolveServer(const QString& mxidOrDomain)
+static const auto ServerPartRegEx = QStringLiteral(
+ "(\\[[^]]+\\]|[^:@]+)" // Either IPv6 address or hostname/IPv4 address
+ "(?::(\\d{1,5}))?" // Optional port
+);
+
+QString serverPart(const QString& mxId)
{
- // At this point we may have something as complex as
- // @username:[IPv6:address]:port, or as simple as a plain domain name.
+ static auto re = "^[@!#$+].+?:(" // Localpart and colon
+ % ServerPartRegEx % ")$";
+ static QRegularExpression parser(re,
+ QRegularExpression::UseUnicodePropertiesOption); // Because Asian digits
+ return parser.match(mxId).captured(1);
+}
- // Try to parse as an FQID; if there's no @ part, assume it's a domain name.
- QRegularExpression parser(
+void Connection::resolveServer(const QString& mxidOrDomain)
+{
+ // mxIdOrDomain may be something as complex as
+ // @username:[IPv6:address]:port, or as simple as a plain serverpart.
+ static QRegularExpression parser(
"^(@.+?:)?" // Optional username (allow everything for compatibility)
- "(\\[[^]]+\\]|[^:@]+)" // Either IPv6 address or hostname/IPv4 address
- "(:\\d{1,5})?$", // Optional port
- QRegularExpression::UseUnicodePropertiesOption); // Because asian digits
+ % ServerPartRegEx % '$',
+ QRegularExpression::UseUnicodePropertiesOption); // Because Asian digits
auto match = parser.match(mxidOrDomain);
- QUrl maybeBaseUrl = QUrl::fromUserInput(match.captured(2));
+ auto maybeBaseUrl = QUrl::fromUserInput(match.captured(2));
maybeBaseUrl.setScheme("https"); // Instead of the Qt-default "http"
if (!match.hasMatch() || !maybeBaseUrl.isValid())
{
@@ -883,33 +895,36 @@ Room* Connection::room(const QString& roomId, JoinStates states) const
Room* Connection::roomByAlias(const QString& roomAlias, JoinStates states) const
{
- const auto id = d->roomAliasMap.value(roomAlias);
+ const auto id =
+ d->roomAliasMap.value(serverPart(roomAlias)).value(roomAlias);
if (!id.isEmpty())
return room(id, states);
+
qCWarning(MAIN) << "Room for alias" << roomAlias
<< "is not found under account" << userId();
return nullptr;
}
void Connection::updateRoomAliases(const QString& roomId,
+ const QString& aliasServer,
const QStringList& previousRoomAliases,
const QStringList& roomAliases)
{
+ auto& aliasMap = d->roomAliasMap[aliasServer]; // Allocate if necessary
for (const auto& a: previousRoomAliases)
- if (d->roomAliasMap.remove(a) == 0)
+ if (aliasMap.remove(a) == 0)
qCWarning(MAIN) << "Alias" << a << "is not found (already deleted?)";
for (const auto& a: roomAliases)
{
- auto& mappedId = d->roomAliasMap[a];
+ auto& mappedId = aliasMap[a];
if (!mappedId.isEmpty())
{
if (mappedId == roomId)
- qCDebug(MAIN) << "Alias" << a << "is already mapped to room"
+ qCDebug(MAIN) << "Alias" << a << "is already mapped to"
<< roomId;
else
- qCWarning(MAIN) << "Alias" << a
- << "will be force-remapped from room"
+ qCWarning(MAIN) << "Alias" << a << "will be force-remapped from"
<< mappedId << "to" << roomId;
}
mappedId = roomId;