Skip to content

Commit

Permalink
Server Checker: check short URLs asynchronously
Browse files Browse the repository at this point in the history
  • Loading branch information
zenden2k committed Jan 17, 2025
1 parent d65a2ee commit 609d6ff
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 30 deletions.
2 changes: 2 additions & 0 deletions Source/Gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ set(SRC_LIST
../ServerListTool/ServersCheckerModel.cpp
../ServerListTool/Helpers.cpp
../ServerListTool/ServerListView.cpp
../ServerListTool/CheckShortUrlTask.cpp
)

set(RESOURCE_LIST "../Image Uploader.rc"
Expand Down Expand Up @@ -338,6 +339,7 @@ set(HEADER_LIST
../ServerListTool/ServersCheckerModel.h
../ServerListTool/Helpers.h
../ServerListTool/ServerListView.h
../ServerListTool/CheckShortUrlTask.h
../resource.h
)

Expand Down
68 changes: 68 additions & 0 deletions Source/ServerListTool/CheckShortUrlTask.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include "CheckShortUrlTask.h"

namespace ServersListTool {

CheckShortUrlTask::CheckShortUrlTask(std::shared_ptr<INetworkClientFactory> factory, std::string url, std::string shortUrl)
: factory_(std::move(factory))
, url_(std::move(url))
, shortUrl_(std::move(shortUrl))
{
}

void CheckShortUrlTask::run()
{
if (isCanceled_) {
onTaskFinished(this, false);
return;
}
isInProgress_ = true;
auto client = factory_->create();

client->setCurlOptionInt(CURLOPT_FOLLOWLOCATION, 0);

bool ok = false;
std::string targetUrl = url_;
int i = 0; //counter for limiting max redirects
if (!targetUrl.empty()) {
int responseCode = 0;

do {
if (isCanceled_) {
break;
}
client->setCurlOptionInt(CURLOPT_FOLLOWLOCATION, 0);
client->doGet(targetUrl);

responseCode = client->responseCode();
if (responseCode == 302 || responseCode == 301) {
targetUrl = client->getCurlInfoString(CURLINFO_REDIRECT_URL);
}

i++;
} while (i < 6 && !targetUrl.empty() && (responseCode == 302 || responseCode == 301) && targetUrl != shortUrl_);

if (!targetUrl.empty() && targetUrl == shortUrl_) {
ok = true;
}
}

isInProgress_ = false;
onTaskFinished(this, ok);
}

void CheckShortUrlTask::cancel()
{
isCanceled_ = true;
}

bool CheckShortUrlTask::isCanceled()
{
return isCanceled_;
}

bool CheckShortUrlTask::isInProgress()
{
return isInProgress_;
}

}
31 changes: 31 additions & 0 deletions Source/ServerListTool/CheckShortUrlTask.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include <atomic>
#include <string>
#include <memory>

#include <boost/signals2.hpp>

#include "Core/TaskDispatcher.h"
#include "Core/Network/INetworkClient.h"

namespace ServersListTool {

class CheckShortUrlTask : public CancellableTask {
public:
explicit CheckShortUrlTask(std::shared_ptr<INetworkClientFactory> factory, std::string url, std::string shortUrl);
void run() override;
void cancel() override;
bool isCanceled() override;
bool isInProgress() override;

boost::signals2::signal<void(CheckShortUrlTask*, bool)> onTaskFinished;

private:
std::atomic<bool> isCanceled_;
std::atomic<bool> isInProgress_;
std::shared_ptr<INetworkClientFactory> factory_;
std::string url_, shortUrl_;
};

}
2 changes: 1 addition & 1 deletion Source/ServerListTool/ServerListView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,6 @@ LRESULT CServerListView::OnListViewNMCustomDraw(int idCtrl, LPNMHDR pnmh, BOOL&
}

void CServerListView::onRowChanged(size_t index) {
RedrawItems(index, index);
PostMessage(LVM_REDRAWITEMS, index, index);
}
}
52 changes: 23 additions & 29 deletions Source/ServerListTool/ServersChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "ServerListTool/Helpers.h"
#include "Core/ServiceLocator.h"
#include "Core/TaskDispatcher.h"
#include "CheckShortUrlTask.h"

namespace ServersListTool {

Expand Down Expand Up @@ -131,6 +132,10 @@ void ServersChecker::stop() {
if (uploadSession_) {
uploadSession_->stop();
}
std::lock_guard<std::mutex> lk(scheduledTasksMutex_);
for (auto& task : scheduledTasks_) {
task->cancel();
}
}

bool ServersChecker::isRunning() const {
Expand Down Expand Up @@ -214,39 +219,28 @@ void ServersChecker::checkShortUrl(UploadTask* task) {
return;
}
UploadTaskUserData* userData = static_cast<UploadTaskUserData*>(task->userData());
ServerData& data = *model_->getDataByIndex(userData->rowIndex);

client->setCurlOptionInt(CURLOPT_FOLLOWLOCATION, 0);

bool ok = false;
std::string targetUrl = task->uploadResult()->directUrl;
int i = 0; //counter for limiting max redirects
if (!targetUrl.empty()) {
int responseCode = 0;

do {
client->setCurlOptionInt(CURLOPT_FOLLOWLOCATION, 0);
client->doGet(targetUrl);
ServerData* data = model_->getDataByIndex(userData->rowIndex);

responseCode = client->responseCode();
if (responseCode == 302 || responseCode == 301) {
targetUrl = client->getCurlInfoString(CURLINFO_REDIRECT_URL);
}

i++;
} while (i < 6 && !targetUrl.empty() && (responseCode == 302 || responseCode == 301) && targetUrl != urlTask->getUrl());

if (!targetUrl.empty() && targetUrl == urlTask->getUrl()) {
data.setStrMark("Good link");
//m_ListView.SetItemText(userData->rowIndex, 3, _T("Good link"));
ok = true;
auto networkClientFactory = ServiceLocator::instance()->networkClientFactory();
auto checkTask = std::make_shared<CheckShortUrlTask>(networkClientFactory, task->uploadResult()->directUrl, urlTask->getUrl());
checkTask->onTaskFinished.connect([this, rowIndex = userData->rowIndex, data](auto* task, bool ok) {
if (ok) {
data->setStrMark("Good link");
}
data->filesChecked++;
data->stars[0] = ok ? 5 : 0;
data->finished = true;
markServer(rowIndex);
std::lock_guard<std::mutex> lk(scheduledTasksMutex_);
auto it = std::remove_if(scheduledTasks_.begin(), scheduledTasks_.end(), [task](auto&& a) { return a.get() == task; });
scheduledTasks_.erase(it, scheduledTasks_.end());
});
{
std::lock_guard<std::mutex> lk(scheduledTasksMutex_);
scheduledTasks_.push_back(checkTask);
}

data.filesChecked++;
data.stars[0] = ok ? 5 : 0;
data.finished = true;
markServer(userData->rowIndex);
ServiceLocator::instance()->taskDispatcher()->postTask(checkTask);
}

void ServersChecker::onTaskFinished(UploadTask* task, bool ok) {
Expand Down
3 changes: 3 additions & 0 deletions Source/ServerListTool/ServersChecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class CFileDownloader;
namespace ServersListTool {

class ServersCheckerModel;
class CheckShortUrlTask;

struct UploadTaskUserData {
size_t rowIndex = 0;
Expand Down Expand Up @@ -58,6 +59,8 @@ class ServersChecker {
std::string srcFileHash_;
std::shared_ptr<INetworkClientFactory> networkClientFactory_;
std::atomic<int> linksToCheck_;
std::vector<std::shared_ptr<CheckShortUrlTask>> scheduledTasks_;
std::mutex scheduledTasksMutex_;
};
}
#endif

0 comments on commit 609d6ff

Please sign in to comment.