2018-06-26 15:33:51 +02:00
|
|
|
#include "common/NetworkRequest.hpp"
|
2018-01-19 22:45:33 +01:00
|
|
|
|
2019-08-20 20:27:16 +02:00
|
|
|
#include "common/NetworkPrivate.hpp"
|
2018-08-11 22:23:06 +02:00
|
|
|
#include "common/Outcome.hpp"
|
2019-08-03 11:20:19 +02:00
|
|
|
#include "common/Version.hpp"
|
2019-08-15 20:38:11 +02:00
|
|
|
#include "debug/AssertInGuiThread.hpp"
|
2018-07-07 13:08:57 +02:00
|
|
|
#include "providers/twitch/TwitchCommon.hpp"
|
|
|
|
#include "singletons/Paths.hpp"
|
2018-08-07 23:46:00 +02:00
|
|
|
#include "util/DebugCount.hpp"
|
2019-08-15 20:38:11 +02:00
|
|
|
#include "util/PostToThread.hpp"
|
2018-07-07 13:08:57 +02:00
|
|
|
|
2019-08-20 20:08:49 +02:00
|
|
|
#include <QDebug>
|
2018-07-07 13:08:57 +02:00
|
|
|
#include <QFile>
|
2018-08-10 18:56:17 +02:00
|
|
|
#include <QtConcurrent>
|
2020-11-21 16:20:10 +01:00
|
|
|
#include "common/QLogging.hpp"
|
2018-08-19 16:20:14 +02:00
|
|
|
|
2018-07-07 13:08:57 +02:00
|
|
|
#include <cassert>
|
2018-04-27 22:11:19 +02:00
|
|
|
|
2018-01-19 22:45:33 +01:00
|
|
|
namespace chatterino {
|
|
|
|
|
2018-08-06 21:17:03 +02:00
|
|
|
NetworkRequest::NetworkRequest(const std::string &url,
|
|
|
|
NetworkRequestType requestType)
|
2018-07-07 13:51:01 +02:00
|
|
|
: data(new NetworkData)
|
2018-01-19 22:45:33 +01:00
|
|
|
{
|
2018-07-07 13:51:01 +02:00
|
|
|
this->data->request_.setUrl(QUrl(QString::fromStdString(url)));
|
|
|
|
this->data->requestType_ = requestType;
|
2019-08-03 11:20:19 +02:00
|
|
|
|
|
|
|
this->initializeDefaultValues();
|
2018-01-19 22:45:33 +01:00
|
|
|
}
|
|
|
|
|
2018-07-07 13:08:57 +02:00
|
|
|
NetworkRequest::NetworkRequest(QUrl url, NetworkRequestType requestType)
|
2018-07-07 13:51:01 +02:00
|
|
|
: data(new NetworkData)
|
2018-01-19 22:45:33 +01:00
|
|
|
{
|
2018-07-07 13:51:01 +02:00
|
|
|
this->data->request_.setUrl(url);
|
|
|
|
this->data->requestType_ = requestType;
|
2019-08-03 11:20:19 +02:00
|
|
|
|
|
|
|
this->initializeDefaultValues();
|
2018-01-19 22:45:33 +01:00
|
|
|
}
|
|
|
|
|
2018-07-07 13:08:57 +02:00
|
|
|
NetworkRequest::~NetworkRequest()
|
2018-01-19 22:45:33 +01:00
|
|
|
{
|
2019-08-20 21:50:36 +02:00
|
|
|
//assert(!this->data || this->executed_);
|
2018-01-19 22:45:33 +01:00
|
|
|
}
|
|
|
|
|
2019-08-20 18:51:23 +02:00
|
|
|
NetworkRequest NetworkRequest::type(NetworkRequestType newRequestType) &&
|
|
|
|
{
|
|
|
|
this->data->requestType_ = newRequestType;
|
|
|
|
return std::move(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
NetworkRequest NetworkRequest::caller(const QObject *caller) &&
|
|
|
|
{
|
2019-08-20 23:30:39 +02:00
|
|
|
if (caller)
|
|
|
|
{
|
|
|
|
// Caller must be in gui thread
|
|
|
|
assert(caller->thread() == qApp->thread());
|
|
|
|
|
|
|
|
this->data->caller_ = const_cast<QObject *>(caller);
|
|
|
|
this->data->hasCaller_ = true;
|
|
|
|
}
|
2019-08-20 18:51:23 +02:00
|
|
|
return std::move(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
NetworkRequest NetworkRequest::onReplyCreated(NetworkReplyCreatedCallback cb) &&
|
|
|
|
{
|
|
|
|
this->data->onReplyCreated_ = cb;
|
|
|
|
return std::move(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
NetworkRequest NetworkRequest::onError(NetworkErrorCallback cb) &&
|
|
|
|
{
|
|
|
|
this->data->onError_ = cb;
|
|
|
|
return std::move(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
NetworkRequest NetworkRequest::onSuccess(NetworkSuccessCallback cb) &&
|
|
|
|
{
|
|
|
|
this->data->onSuccess_ = cb;
|
|
|
|
return std::move(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
NetworkRequest NetworkRequest::header(const char *headerName,
|
|
|
|
const char *value) &&
|
|
|
|
{
|
|
|
|
this->data->request_.setRawHeader(headerName, value);
|
|
|
|
return std::move(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
NetworkRequest NetworkRequest::header(const char *headerName,
|
|
|
|
const QByteArray &value) &&
|
|
|
|
{
|
|
|
|
this->data->request_.setRawHeader(headerName, value);
|
|
|
|
return std::move(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
NetworkRequest NetworkRequest::header(const char *headerName,
|
|
|
|
const QString &value) &&
|
|
|
|
{
|
|
|
|
this->data->request_.setRawHeader(headerName, value.toUtf8());
|
|
|
|
return std::move(*this);
|
|
|
|
}
|
|
|
|
|
2020-07-05 14:32:10 +02:00
|
|
|
NetworkRequest NetworkRequest::headerList(const QStringList &headers) &&
|
|
|
|
{
|
|
|
|
for (const QString &header : headers)
|
|
|
|
{
|
|
|
|
const QStringList thisHeader = header.trimmed().split(":");
|
|
|
|
if (thisHeader.size() == 2)
|
|
|
|
{
|
|
|
|
this->data->request_.setRawHeader(thisHeader[0].trimmed().toUtf8(),
|
|
|
|
thisHeader[1].trimmed().toUtf8());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return std::move(*this);
|
|
|
|
}
|
|
|
|
|
2019-08-20 18:51:23 +02:00
|
|
|
NetworkRequest NetworkRequest::timeout(int ms) &&
|
|
|
|
{
|
2019-08-20 20:08:49 +02:00
|
|
|
this->data->hasTimeout_ = true;
|
2020-12-26 12:42:39 +01:00
|
|
|
this->data->timeoutMS_ = ms;
|
2019-08-20 18:51:23 +02:00
|
|
|
return std::move(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
NetworkRequest NetworkRequest::concurrent() &&
|
|
|
|
{
|
2019-08-21 00:01:27 +02:00
|
|
|
this->data->executeConcurrently_ = true;
|
2019-08-20 18:51:23 +02:00
|
|
|
return std::move(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
NetworkRequest NetworkRequest::authorizeTwitchV5(const QString &clientID,
|
|
|
|
const QString &oauthToken) &&
|
|
|
|
{
|
2019-08-20 18:53:26 +02:00
|
|
|
// TODO: make two overloads, with and without oauth token
|
|
|
|
auto tmp = std::move(*this)
|
|
|
|
.header("Client-ID", clientID)
|
|
|
|
.header("Accept", "application/vnd.twitchtv.v5+json");
|
|
|
|
|
2019-08-20 18:51:23 +02:00
|
|
|
if (!oauthToken.isEmpty())
|
2019-08-20 18:53:26 +02:00
|
|
|
return std::move(tmp).header("Authorization", "OAuth " + oauthToken);
|
|
|
|
else
|
|
|
|
return tmp;
|
2019-08-20 18:51:23 +02:00
|
|
|
}
|
|
|
|
|
2019-09-19 18:26:38 +02:00
|
|
|
NetworkRequest NetworkRequest::multiPart(QHttpMultiPart *payload) &&
|
|
|
|
{
|
|
|
|
payload->setParent(this->data->lifetimeManager_);
|
|
|
|
this->data->multiPartPayload_ = payload;
|
|
|
|
return std::move(*this);
|
|
|
|
}
|
|
|
|
|
2019-08-20 18:51:23 +02:00
|
|
|
NetworkRequest NetworkRequest::payload(const QByteArray &payload) &&
|
|
|
|
{
|
|
|
|
this->data->payload_ = payload;
|
|
|
|
return std::move(*this);
|
|
|
|
}
|
|
|
|
|
2019-08-20 20:08:49 +02:00
|
|
|
NetworkRequest NetworkRequest::cache() &&
|
2019-08-20 18:51:23 +02:00
|
|
|
{
|
2019-08-21 00:01:27 +02:00
|
|
|
this->data->cache_ = true;
|
2019-08-20 18:51:23 +02:00
|
|
|
return std::move(*this);
|
|
|
|
}
|
|
|
|
|
2018-07-06 17:56:11 +02:00
|
|
|
void NetworkRequest::execute()
|
|
|
|
{
|
2018-07-07 13:08:57 +02:00
|
|
|
this->executed_ = true;
|
|
|
|
|
2019-08-20 20:08:49 +02:00
|
|
|
// Only allow caching for GET request
|
2019-08-21 00:01:27 +02:00
|
|
|
if (this->data->cache_ &&
|
2019-08-20 20:08:49 +02:00
|
|
|
this->data->requestType_ != NetworkRequestType::Get)
|
2018-10-21 13:43:02 +02:00
|
|
|
{
|
2020-11-21 16:20:10 +01:00
|
|
|
qCDebug(chatterinoCommon) << "Can only cache GET requests!";
|
2019-08-21 00:01:27 +02:00
|
|
|
this->data->cache_ = false;
|
2018-07-06 17:56:11 +02:00
|
|
|
}
|
|
|
|
|
2019-08-20 23:29:11 +02:00
|
|
|
// Can not have a caller and be concurrent at the same time.
|
2019-08-21 00:01:27 +02:00
|
|
|
assert(!(this->data->caller_ && this->data->executeConcurrently_));
|
2019-08-20 23:29:11 +02:00
|
|
|
|
2019-08-20 20:08:49 +02:00
|
|
|
load(std::move(this->data));
|
2018-09-20 13:37:20 +02:00
|
|
|
}
|
|
|
|
|
2019-08-03 11:20:19 +02:00
|
|
|
void NetworkRequest::initializeDefaultValues()
|
|
|
|
{
|
|
|
|
const auto userAgent = QString("chatterino/%1 (%2)")
|
|
|
|
.arg(CHATTERINO_VERSION, CHATTERINO_GIT_HASH)
|
|
|
|
.toUtf8();
|
|
|
|
|
|
|
|
this->data->request_.setRawHeader("User-Agent", userAgent);
|
|
|
|
}
|
|
|
|
|
2018-07-07 13:08:57 +02:00
|
|
|
// Helper creator functions
|
|
|
|
NetworkRequest NetworkRequest::twitchRequest(QUrl url)
|
2018-07-06 17:56:11 +02:00
|
|
|
{
|
2019-08-20 20:08:49 +02:00
|
|
|
return NetworkRequest(url).authorizeTwitchV5(getDefaultClientID());
|
2018-07-06 17:56:11 +02:00
|
|
|
}
|
|
|
|
|
2018-01-19 22:45:33 +01:00
|
|
|
} // namespace chatterino
|