Skip to content

Commit

Permalink
Current version of Psi+ is 1.5.2035
Browse files Browse the repository at this point in the history
It is based on:
* psi: 8bf57027
* plugins: 7a65467
* psimedia: 478567e
* resources: e32ef4b
  • Loading branch information
tehnick committed Jul 8, 2024
1 parent bfea2c3 commit 787e78e
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 148 deletions.
121 changes: 60 additions & 61 deletions iris/src/xmpp/xmpp-im/httpfileupload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@

#include "xmpp_client.h"
#include "xmpp_serverinfomanager.h"
#include "xmpp_tasks.h"
#include "xmpp_xmlcommon.h"

#include <QList>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QPointer>

using namespace XMPP;

Expand Down Expand Up @@ -99,70 +99,69 @@ void HttpFileUpload::start()
if (featureOptions.isEmpty()) {
featureOptions << (QSet<QString>() << xmlns_v0_2_5) << (QSet<QString>() << xmlns_v0_3_1);
}
d->client->serverInfoManager()->queryServiceInfo(
auto query = d->client->serverInfoManager()->queryServiceInfo(
QLatin1String("store"), QLatin1String("file"), featureOptions,
QRegularExpression("^(upload|http|stor|file|dis|drive).*"), ServerInfoManager::SQ_CheckAllOnNoMatch,
[this](const QList<DiscoItem> &items) {
d->httpHosts.clear();
for (const auto &item : items) {
const QStringList &l = item.features().list();
XEP0363::version ver = XEP0363::vUnknown;
QString xmlns;
quint64 sizeLimit = 0;
if (l.contains(xmlns_v0_3_1)) {
ver = XEP0363::v0_3_1;
xmlns = xmlns_v0_3_1;
} else if (l.contains(xmlns_v0_2_5)) {
ver = XEP0363::v0_2_5;
xmlns = xmlns_v0_2_5;
QRegularExpression("^(upload|http|stor|file|dis|drive).*"), ServiceInfoQuery::CheckAllOnNoMatch);
connect(query, &ServiceInfoQuery::finished, this, [this](const QList<DiscoItem> &items) {
d->httpHosts.clear();
for (const auto &item : items) {
const QStringList &l = item.features().list();
XEP0363::version ver = XEP0363::vUnknown;
QString xmlns;
quint64 sizeLimit = 0;
if (l.contains(xmlns_v0_3_1)) {
ver = XEP0363::v0_3_1;
xmlns = xmlns_v0_3_1;
} else if (l.contains(xmlns_v0_2_5)) {
ver = XEP0363::v0_2_5;
xmlns = xmlns_v0_2_5;
}
if (ver != XEP0363::vUnknown) {
QVector<std::pair<HttpHost, int>> hosts;
const XData::Field field = item.registeredExtension(xmlns).getField(QLatin1String("max-file-size"));
if (field.isValid() && field.type() == XData::Field::Field_TextSingle)
sizeLimit = field.value().at(0).toULongLong();
HttpHost host;
host.ver = ver;
host.jid = item.jid();
host.sizeLimit = sizeLimit;
QVariant metaProps(d->client->serverInfoManager()->serviceMeta(host.jid, "httpprops"));
if (metaProps.isValid()) {
host.props = HostProps(metaProps.value<int>());
} else {
host.props = SecureGet | SecurePut;
if (ver == XEP0363::v0_3_1)
host.props |= NewestVer;
}
if (ver != XEP0363::vUnknown) {
QVector<std::pair<HttpHost, int>> hosts;
const XData::Field field = item.registeredExtension(xmlns).getField(QLatin1String("max-file-size"));
if (field.isValid() && field.type() == XData::Field::Field_TextSingle)
sizeLimit = field.value().at(0).toULongLong();
HttpHost host;
host.ver = ver;
host.jid = item.jid();
host.sizeLimit = sizeLimit;
QVariant metaProps(d->client->serverInfoManager()->serviceMeta(host.jid, "httpprops"));
if (metaProps.isValid()) {
host.props = HostProps(metaProps.value<int>());
} else {
host.props = SecureGet | SecurePut;
if (ver == XEP0363::v0_3_1)
host.props |= NewestVer;
}
int value = 0;
if (host.props & SecureGet)
value += 5;
if (host.props & SecurePut)
value += 5;
if (host.props & NewestVer)
value += 3;
if (host.props & Failure)
value -= 15;
if (!sizeLimit || d->fileSize < sizeLimit)
hosts.append({ host, value });

// no sorting in preference order. most preferred go first
std::sort(hosts.begin(), hosts.end(),
[](const auto &a, const auto &b) { return a.second > b.second; });
for (auto &hp : hosts) {
d->httpHosts.append(hp.first);
}
int value = 0;
if (host.props & SecureGet)
value += 5;
if (host.props & SecurePut)
value += 5;
if (host.props & NewestVer)
value += 3;
if (host.props & Failure)
value -= 15;
if (!sizeLimit || d->fileSize < sizeLimit)
hosts.append({ host, value });

// no sorting in preference order. most preferred go first
std::sort(hosts.begin(), hosts.end(), [](const auto &a, const auto &b) { return a.second > b.second; });
for (auto &hp : hosts) {
d->httpHosts.append(hp.first);
}
}
// d->currentHost = d->httpHosts.begin();
d->client->httpFileUploadManager()->setDiscoHosts(d->httpHosts);
if (d->httpHosts.isEmpty()) { // if empty as the last resort check all services
d->result.statusCode = HttpFileUpload::ErrorCode::NoUploadService;
d->result.statusString = "No suitable http upload services were found";
done(State::Error);
} else {
tryNextServer();
}
});
}
// d->currentHost = d->httpHosts.begin();
d->client->httpFileUploadManager()->setDiscoHosts(d->httpHosts);
if (d->httpHosts.isEmpty()) { // if empty as the last resort check all services
d->result.statusCode = HttpFileUpload::ErrorCode::NoUploadService;
d->result.statusString = "No suitable http upload services were found";
done(State::Error);
} else {
tryNextServer();
}
});
}

void HttpFileUpload::tryNextServer()
Expand Down
68 changes: 34 additions & 34 deletions iris/src/xmpp/xmpp-im/jingle-s5b.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -698,42 +698,42 @@ namespace XMPP { namespace Jingle { namespace S5B {

proxyDiscoveryInProgress = true;
QList<QSet<QString>> featureOptions = { { "http://jabber.org/protocol/bytestreams" } };
q->_pad->session()->manager()->client()->serverInfoManager()->queryServiceInfo(
auto query = q->_pad->session()->manager()->client()->serverInfoManager()->queryServiceInfo(
QStringLiteral("proxy"), QStringLiteral("bytestreams"), featureOptions,
QRegularExpression("proxy.*|socks.*|stream.*|s5b.*"), ServerInfoManager::SQ_CheckAllOnNoMatch,
[this](const QList<DiscoItem> &items) {
if (!proxyDiscoveryInProgress) { // check if new results are ever/still expected
// seems like we have successful connection via higher priority channel. so nobody cares
// about proxy
return;
}
auto m = static_cast<Manager *>(q->_pad->manager());
Jid userProxy = m->userProxy();

bool userProxyFound = !userProxy.isValid();
for (const auto &i : items) {
quint16 localPref = 0;
if (!userProxyFound && i.jid() == userProxy) {
localPref = 1;
userProxyFound = true;
continue;
}
Candidate c(q, i.jid(), generateCid(), localPref);
localCandidates.emplace(c.cid(), c);
qDebug("new local candidate: %s", qPrintable(c.toString()));
queryS5BProxy(i.jid(), c.cid());
}
if (!userProxyFound) {
Candidate c(q, userProxy, generateCid(), 1);
localCandidates.emplace(c.cid(), c);
qDebug("new local candidate: %s", qPrintable(c.toString()));
queryS5BProxy(userProxy, c.cid());
} else if (items.count() == 0) {
// seems like we don't have any proxy
proxyDiscoveryInProgress = false;
checkAndFinishNegotiation();
QRegularExpression("proxy.*|socks.*|stream.*|s5b.*"), ServiceInfoQuery::CheckAllOnNoMatch);
q->connect(query, &ServiceInfoQuery::finished, q, [this](const QList<DiscoItem> &items) {
if (!proxyDiscoveryInProgress) { // check if new results are ever/still expected
// seems like we have successful connection via higher priority channel. so nobody cares
// about proxy
return;
}
auto m = static_cast<Manager *>(q->_pad->manager());
Jid userProxy = m->userProxy();

bool userProxyFound = !userProxy.isValid();
for (const auto &i : items) {
quint16 localPref = 0;
if (!userProxyFound && i.jid() == userProxy) {
localPref = 1;
userProxyFound = true;
continue;
}
});
Candidate c(q, i.jid(), generateCid(), localPref);
localCandidates.emplace(c.cid(), c);
qDebug("new local candidate: %s", qPrintable(c.toString()));
queryS5BProxy(i.jid(), c.cid());
}
if (!userProxyFound) {
Candidate c(q, userProxy, generateCid(), 1);
localCandidates.emplace(c.cid(), c);
qDebug("new local candidate: %s", qPrintable(c.toString()));
queryS5BProxy(userProxy, c.cid());
} else if (items.count() == 0) {
// seems like we don't have any proxy
proxyDiscoveryInProgress = false;
checkAndFinishNegotiation();
}
});
}

void tryConnectToRemoteCandidate()
Expand Down
47 changes: 29 additions & 18 deletions iris/src/xmpp/xmpp-im/xmpp_serverinfomanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ void ServerInfoManager::queryServicesList()
jtitems->go(true);
}

void ServerInfoManager::finish(ServiceInfoQuery *q, const QList<DiscoItem> &items)
{
emit q->finished(items);
if (q->parent() == this) {
q->deleteLater();
}
}

void ServerInfoManager::checkPendingServiceQueries()
{
// if services list is not ready yet we have to exit. if it's failed we have to finish all pending queries
Expand All @@ -102,17 +110,18 @@ void ServerInfoManager::checkPendingServiceQueries()
const auto sqs = _serviceQueries;
_serviceQueries.clear();
for (const auto &q : sqs) {
q.callback(QList<DiscoItem>());
finish(q);
}
}
return;
}

// services list is ready here and we can start checking it and sending disco#info to not cached entries
auto sqIt = _serviceQueries.begin();
while (sqIt != _serviceQueries.end()) {
auto queryIt = _serviceQueries.begin();
while (queryIt != _serviceQueries.end()) {

// populate services to query for this service request
auto sqIt = *queryIt;
if (!sqIt->servicesToQueryDefined) {
sqIt->spareServicesToQuery.clear();
// grep all suitble service jids. moving forward preferred ones
Expand All @@ -122,7 +131,7 @@ void ServerInfoManager::checkPendingServiceQueries()
if (sqIt->nameHint.isValid()) {
if (!sqIt->nameHint.isValid() || sqIt->nameHint.match(si.key()).hasMatch()) {
sqIt->servicesToQuery.push_back(si.key());
} else if (sqIt->options & SQ_CheckAllOnNoMatch) {
} else if (sqIt->options & ServiceInfoQuery::CheckAllOnNoMatch) {
sqIt->spareServicesToQuery.push_back(si.key());
}
} else {
Expand All @@ -134,8 +143,8 @@ void ServerInfoManager::checkPendingServiceQueries()
sqIt->spareServicesToQuery.clear();
}
if (sqIt->servicesToQuery.empty()) {
sqIt->callback(QList<DiscoItem>());
_serviceQueries.erase(sqIt++);
finish(sqIt);
_serviceQueries.erase(queryIt++);
continue;
}
sqIt->servicesToQueryDefined = true;
Expand Down Expand Up @@ -169,7 +178,7 @@ void ServerInfoManager::checkPendingServiceQueries()
sqIt->features.constBegin(), sqIt->features.constEnd(), false,
[&si](bool a, const QSet<QString> &b) { return a || si->item.features().test(b); }))) {
sqIt->result.append(si->item);
if (sqIt->options & SQ_FinishOnFirstMatch) {
if (sqIt->options & ServiceInfoQuery::FinishOnFirstMatch) {
break;
}
}
Expand Down Expand Up @@ -210,20 +219,19 @@ void ServerInfoManager::checkPendingServiceQueries()
}

// if has at least one sufficient result
auto forceFinish = (!sqIt->result.isEmpty() && (sqIt->options & SQ_FinishOnFirstMatch)); // stop on first found
auto forceFinish = (!sqIt->result.isEmpty()
&& (sqIt->options & ServiceInfoQuery::FinishOnFirstMatch)); // stop on first found
// if nothing in progress then we have full result set or nothing found even in spare list
if (forceFinish || !hasInProgress) { // self explanatory
auto callback = std::move(sqIt->callback);
auto result = sqIt->result;
_serviceQueries.erase(sqIt++);
callback(result);
_serviceQueries.erase(queryIt++);
finish(sqIt, sqIt->result);
} else {
++sqIt;
++queryIt;
}
}
}

void ServerInfoManager::appendQuery(const ServiceQuery &q)
void ServerInfoManager::appendQuery(ServiceInfoQuery *q)
{
_serviceQueries.push_back(q);
if (_servicesListState == ST_InProgress) {
Expand All @@ -236,11 +244,14 @@ void ServerInfoManager::appendQuery(const ServiceQuery &q)
}
}

void ServerInfoManager::queryServiceInfo(const QString &category, const QString &type,
const QList<QSet<QString>> &features, const QRegularExpression &nameHint,
SQOptions options, std::function<void(const QList<DiscoItem> &items)> callback)
ServiceInfoQuery *ServerInfoManager::queryServiceInfo(const QString &category, const QString &type,
const QList<QSet<QString>> &features,
const QRegularExpression &nameHint,
ServiceInfoQuery::Options options)
{
appendQuery(ServiceQuery(type, category, features, nameHint, options, std::move(callback)));
auto query = new ServiceInfoQuery(type, category, features, nameHint, options, this);
appendQuery(query);
return query;
}

void ServerInfoManager::setServiceMeta(const Jid &service, const QString &key, const QVariant &value)
Expand Down
Loading

0 comments on commit 787e78e

Please sign in to comment.