teleport/client/tp-player/thr_download.cpp

293 lines
8.4 KiB
C++
Raw Normal View History

2019-11-03 19:34:11 +00:00
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QNetworkCookie>
#include "thr_download.h"
#include "util.h"
#include "downloader.h"
#include "record_format.h"
//=================================================================
// ThrDownload
//=================================================================
ThrDownload::ThrDownload() {
m_need_stop = false;
m_have_tpr = false;
m_have_tpk = false;
m_have_tpd = nullptr;
m_need_tpk = false;
m_running = true;
}
ThrDownload::~ThrDownload() {
if(m_have_tpd)
delete[] m_have_tpd;
}
// tp-player.exe http://teleport.domain.com:7190/{sub/path/}tp_1491560510_ca67fceb75a78c9d/1234 (注意并不直接访问此URI实际上其并不存在)
// TP服务器地址(可能包含子路径哦,例如上例中的{sub/path/}部分)/session-id(用于判断当前授权用户)/录像会话编号
bool ThrDownload::init(const QString& local_data_path_base, const QString &res) {
m_data_path_base = local_data_path_base;
QString _tmp_res = res.toLower();
if(!_tmp_res.startsWith("http")) {
return false;
}
QStringList _uris = res.split('/');
if(_uris.size() < 3) {
return false;
}
m_sid = _uris[_uris.size()-2];
m_rid = _uris[_uris.size()-1];
m_url_base = res.left(res.length() - m_sid.length() - m_rid.length() - 2);
if(m_sid.length() == 0 || m_rid.length() == 0 || m_url_base.length() == 0)
return false;
return true;
}
void ThrDownload::stop() {
if(!m_running)
return;
// if(!isRunning())
// return;
m_need_stop = true;
wait();
qDebug("data thread stop() end.");
}
// tp-player.exe http://teleport.domain.com:7190/{sub/path/}tp_1491560510_ca67fceb75a78c9d/1234 (注意并不直接访问此URI实际上其并不存在)
// TP服务器地址(可能包含子路径哦,例如上例中的{sub/path/}部分)/session-id(用于判断当前授权用户)/录像会话编号
void ThrDownload::run() {
_run();
m_running = false;
qDebug("ThrDownload thread run() end.");
}
void ThrDownload::_run() {
// m_state = statDownloading;
if(!_download_tpr()) {
// m_state = statFailDone;
return;
}
m_have_tpr = true;
m_have_tpd = new bool[m_tpd_count];
for(uint32_t i = 0; i < m_tpd_count; ++i) {
m_have_tpd[i] = false;
}
if(m_need_tpk) {
if(!_download_tpk()) {
// m_state = statFailDone;
return;
}
m_have_tpk = true;
}
uint32_t file_idx = 0;
for(;;) {
if(m_need_stop)
break;
QString str_fidx;
str_fidx.sprintf("%d", file_idx+1);
QString tpd_fname = QString("%1/tp-rdp-%2.tpd").arg(m_data_path, str_fidx);
tpd_fname = QDir::toNativeSeparators(tpd_fname);
QString tmp_fname = QString("%1/tp-rdp-%2.tpd.downloading").arg(m_data_path, str_fidx);
tmp_fname = QDir::toNativeSeparators(tmp_fname);
QFileInfo fi_tmp(tmp_fname);
if(fi_tmp.isFile()) {
QFile::remove(tmp_fname);
}
QFileInfo fi_tpd(tpd_fname);
if(!fi_tpd.exists()) {
QString url = QString("%1/audit/get-file?act=read&type=rdp&rid=%2&f=tp-rdp-%3.tpd").arg(m_url_base, m_rid, str_fidx);
qDebug() << "URL : " << url;
qDebug() << "TPD : " << tmp_fname;
if(!_download_file(url, tmp_fname)) {
// m_state = statFailDone;
return;
}
if(!QFile::rename(tmp_fname, tpd_fname)) {
// m_state = statFailDone;
return;
}
}
m_have_tpd[file_idx] = true;
file_idx += 1;
if(file_idx >= m_tpd_count)
break;
}
// m_state = statSuccessDone;
}
bool ThrDownload::_download_tpr() {
QString url = QString("%1/audit/get-file?act=read&type=rdp&rid=%2&f=tp-rdp.tpr").arg(m_url_base, m_rid);
QByteArray data;
if(!_download_file(url, data))
return false;
if(data.size() != sizeof(TS_RECORD_HEADER)) {
qDebug("invalid header data. %d", data.size());
m_error = QString(LOCAL8BIT("录像信息文件数据错误!"));
return false;
}
TS_RECORD_HEADER* hdr = reinterpret_cast<TS_RECORD_HEADER*>(data.data());
// if(hdr->info.ver != 4) {
// qDebug() << "invaid .tpr file.";
// m_last_error = QString("%1 %2%3").arg(LOCAL8BIT("不支持的录像文件版本 "), QString(hdr->info.ver), LOCAL8BIT("\n\n此播放器支持录像文件版本 4。"));
// return false;
// }
// if(m_hdr.basic.width == 0 || m_hdr.basic.height == 0) {
// _notify_error(LOCAL8BIT("错误的录像信息,未记录窗口尺寸!"));
// return false;
// }
// if(m_hdr.info.dat_file_count == 0) {
// _notify_error(LOCAL8BIT("错误的录像信息,未记录数据文件数量!"));
// return false;
// }
// 下载得到的数据应该是一个TS_RECORD_HEADER解析此数据生成本地文件路径并保存之。
QDateTime timeUTC;
// timeUTC.setTimeSpec(Qt::UTC);
// timeUTC.setTime_t(m_hdr.basic.timestamp);
timeUTC.setSecsSinceEpoch(hdr->basic.timestamp);
QString strUTC = timeUTC.toString("yyyyMMdd-hhmmss");
QString strAcc(hdr->basic.acc_username);
int idx = strAcc.indexOf('\\');
if(-1 != idx) {
QString _domain = strAcc.left(idx);
QString _user = strAcc.right(strAcc.length() - idx - 1);
strAcc = _user + "@" + _domain;
}
QString strType;
if(hdr->info.type == TS_TPPR_TYPE_SSH) {
strType = "SSH";
}
else if(hdr->info.type == TS_TPPR_TYPE_RDP) {
strType = "RDP";
m_need_tpk = true;
}
else {
strType = "UNKNOWN";
}
// .../record/RDP-211-admin-user@domain-192.168.0.68-20191015-020243
m_data_path = QString("%1/%2-%3-%4-%5-%6-%7").arg(m_data_path_base, strType, m_rid, hdr->basic.user_username, strAcc, hdr->basic.host_ip, strUTC);
m_data_path = QDir::toNativeSeparators(m_data_path);
qDebug() << "PATH_BASE: " << m_data_path;
QDir dir;
dir.mkpath(m_data_path);
QFileInfo fi;
fi.setFile(m_data_path);
if(!fi.isDir()) {
qDebug("can not create folder to save downloaded file.");
return false;
}
QString filename = QString("%1/tp-rdp.tpr").arg(m_data_path);
filename = QDir::toNativeSeparators(filename);
qDebug() << "TPR: " << filename;
QFile f;
f.setFileName(filename);
if(!f.open(QIODevice::WriteOnly | QFile::Truncate)){
qDebug("open file for write failed.");
return false;
}
qint64 written = f.write(reinterpret_cast<const char*>(hdr), sizeof(TS_RECORD_HEADER));
f.flush();
f.close();
if(written != sizeof(TS_RECORD_HEADER)) {
qDebug("save header file failed.");
return false;
}
m_tpd_count = hdr->info.dat_file_count;
return true;
}
bool ThrDownload::_download_tpk() {
QString tpk_fname = QString("%1/tp-rdp.tpk").arg(m_data_path);
tpk_fname = QDir::toNativeSeparators(tpk_fname);
QString tmp_fname = QString("%1/tp-rdp.tpk.downloading").arg(m_data_path);
tmp_fname = QDir::toNativeSeparators(tmp_fname);
QFileInfo fi_tmp(tmp_fname);
if(fi_tmp.isFile()) {
QFile::remove(tmp_fname);
}
QFileInfo fi_tpk(tpk_fname);
if(!fi_tpk.exists()) {
QString url = QString("%1/audit/get-file?act=read&type=rdp&rid=%2&f=tp-rdp.tpk").arg(m_url_base, m_rid);
qDebug() << "TPK: " << tmp_fname;
if(!_download_file(url, tmp_fname))
return false;
if(!QFile::rename(tmp_fname, tpk_fname))
return false;
}
return true;
}
bool ThrDownload::_download_file(const QString& url, const QString filename) {
Downloader dl;
if(!dl.request(url, m_sid, filename)) {
qDebug() << "download failed.";
m_error = QString("%1").arg(LOCAL8BIT("下载文件失败!"));
return false;
}
return true;
}
bool ThrDownload::_download_file(const QString& url, QByteArray& data) {
Downloader dl;
if(!dl.request(url, m_sid, &data)) {
qDebug() << "download failed.";
m_error = QString("%1").arg(LOCAL8BIT("下载文件失败!"));
return false;
}
return true;
}
bool ThrDownload::is_tpd_downloaded(uint32_t file_idx) const {
if(!m_have_tpd)
return false;
if(file_idx >= m_tpd_count)
return false;
return m_have_tpd[file_idx];
}