C++ 如何调用带有句点的服务器请求,并在响应无效时再次发送该请求?

C++ 如何调用带有句点的服务器请求,并在响应无效时再次发送该请求?,c++,qt,c++11,network-programming,qt5,C++,Qt,C++11,Network Programming,Qt5,我正在为我的个人培训编写一个简单的web服务客户端。我决定用Qt来做。我使用的是5.7版。我设法克服了从服务器发送和接收请求的困难。但仍然存在一个问题 我在\u scanButton\u click()上有一个插槽,根据选中的单选按钮,它会向服务器调用一些请求。我的问题是如何在第一个请求之后向服务器发送另一个带句点的请求,这样我就可以检查响应代码是否有效,并且可以为它调用单独的窗口 这是我的主窗口.cpp #include "mainwindow.h" #include &q

我正在为我的个人培训编写一个简单的web服务客户端。我决定用Qt来做。我使用的是5.7版。我设法克服了从服务器发送和接收请求的困难。但仍然存在一个问题

我在\u scanButton\u click()上有一个插槽
,根据选中的单选按钮,它会向服务器调用一些请求。我的问题是如何在第一个请求之后向服务器发送另一个带句点的请求,这样我就可以检查响应代码是否有效,并且可以为它调用单独的窗口

这是我的主窗口.cpp

#include "mainwindow.h"
#include "networkmanager.h"
#include "commentdialog.h"
#include "rescanfiledialog.h"
#include "filebrowser.h"
#include "program_exceptions.h"
#include "overlaywidget.h"

#include <QMessageBox>
#include <regex>


MainWindow::MainWindow(QWidget* parent) :
    QMainWindow{parent} {
    ui.setupUi(this);

    ui.fileRadioButton->setFixedWidth(100);
    ui.urlRadioButton->setFixedWidth(100);
    ui.searchRadioButton->setFixedWidth(100);

    ui.stringFormater->setFixedSize(500, 30);
    ui.stringFormater->setPlaceholderText("No file selected");
    ui.uploadButton->setFixedHeight(30);

    ui.scanButton->setFixedSize(120, 50);
    ui.rescanButton->setFixedSize(120, 50);
    ui.commentButton->setFixedSize(120, 50);
}


void MainWindow::changeEvent(QEvent* e) {
    QMainWindow::changeEvent(e);

    switch (e->type()) {

        case QEvent::LanguageChange:
            ui.retranslateUi(this);
            break;

        default:
            break;
    }
}


void MainWindow::on_scanButton_clicked() {
    NetworkManager* network_manager{new NetworkManager};
    QString input_string = ui.stringFormater->text();

    try {

        if (ui.fileRadioButton->isChecked()) {

            if (std::regex_match(input_string.toStdString(), std::regex("^(.*/)([^/]*)$"))) {

                network_manager->scanFileRequest(input_string);

            } else {
                throw InvalidFilePathException();
            }

        } else if (ui.urlRadioButton->isChecked()) {

            if (std::regex_match(input_string.toStdString(),
                             std::regex("^(ht{2}ps?:\\/{2})?(w{3}\\.)?([^:\\/\\.\\s]+)\\.([^:\\/\\.\\s]+)$"))) {
                network_manager->scanUrlRequest(input_string);

            } else {
                throw InvalidUrlNameException();
            }

        } else if (ui.searchRadioButton->isChecked()) {

            if (!std::regex_match(input_string.toStdString(), std::regex("([^:\\/\\.\\s]+)\\.([^:\\/\\.\\s]+)$"))) {

                if (!std::regex_match(input_string.toStdString(), std::regex("^(([0-9]{1,3})\\.){3}([0-9]{1,3})$"))) {
                    throw InvalidIpAddressException();

                } else {
                    network_manager->retrieveIpReportRequest(input_string);
                }

                throw InvalidDomainNameException();

            } else {
                network_manager->retrieveDomainReportRequest(input_string);
            }
        }

    } catch (std::exception& ex) {
        QString exception_message{ex.what()};
        QMessageBox::warning(this, "Warning", exception_message);
    }

    ui.stringFormater->clear();
}


void MainWindow::on_fileRadioButton_clicked() {
    ui.stringFormater->setPlaceholderText("No file selected");
    ui.uploadButton->setText("Choose File");
    ui.scanButton->setText("Scan it!");
    ui.stringFormater->clear();
}

void MainWindow::on_urlRadioButton_clicked() {
    ui.stringFormater->setPlaceholderText("http://example.com");
    ui.uploadButton->setText("Enter URL");
    ui.scanButton->setText("Scan it!");
    ui.stringFormater->clear();
}

void MainWindow::on_searchRadioButton_clicked() {
    ui.stringFormater->setPlaceholderText("hash, URL, domain, IP address...");
    ui.uploadButton->setText("Enter Term");
    ui.scanButton->setText("Search it!");
    ui.stringFormater->clear();
}


void MainWindow::on_uploadButton_clicked() {
    if (ui.fileRadioButton->isChecked()) {
        FileBrowser* file_browser{new FileBrowser(this)};
        file_browser->exec();

        ui.stringFormater->setText(file_browser->getFilePath());
        file_browser->setFilePath("");
    }
}


void MainWindow::on_rescanButton_clicked() {
    RescanFileDialog* rescan_file_doalog{new RescanFileDialog(this)};
    rescan_file_doalog->exec();
}


void MainWindow::on_commentButton_clicked() {
    CommentDialog* comment_dialog{new CommentDialog(this)};
    comment_dialog->exec();
}
#包括“mainwindow.h”
#包括“networkmanager.h”
#包括“commentdialog.h”
#包括“rescanfiledialog.h”
#包括“filebrowser.h”
#包括“program_exceptions.h”
#包括“overlaywidget.h”
#包括
#包括
主窗口::主窗口(QWidget*父窗口):
QMainWindow{parent}{
ui.setupUi(这个);
ui.fileRadioButton->setFixedWidth(100);
ui.urlRadioButton->setFixedWidth(100);
ui.searchRadioButton->setFixedWidth(100);
ui.StringFormatter->setFixedSize(500,30);
ui.stringformatter->setplaceholder文本(“未选择文件”);
ui.上传按钮->设置固定高度(30);
ui.scanButton->setFixedSize(120,50);
ui.rescanButton->setFixedSize(120,50);
ui.commentButton->setFixedSize(120,50);
}
void主窗口::changeEvent(QEvent*e){
QMainWindow::changeEvent(e);
开关(e->type()){
案例QEvent::LanguageChange:
ui.重新翻译(本);
打破
违约:
打破
}
}
void main window::在_scanButton_clicked()上{
NetworkManager*网络管理器{new NetworkManager};
QString input_string=ui.stringformatter->text();
试一试{
如果(ui.fileRadioButton->isChecked()){
if(std::regex_匹配(input_string.toStdString(),std::regex(“^(.*/)([^/]*)$”){
网络\u管理器->扫描文件请求(输入\u字符串);
}否则{
抛出InvalidFilePathException();
}
}else if(ui.urlRadioButton->isChecked()){
如果(std::regex)匹配(input_string.toStdString(),
std::regex(“^(ht{2}ps?:\\/{2}”)(w{3}\\)?([^:\\/\\.\\s]+)\.([^:\\/\\.\\s]+)$”){
网络管理器->扫描请求(输入字符串);
}否则{
抛出InvalidUrlNameException();
}
}else if(ui.searchRadioButton->isChecked()){
如果(!std::regex_匹配(input_string.toStdString(),std::regex(([^:\/\\.\\s]+)\.([^:\/\\.\\s]+)$)){
如果(!std::regex_匹配(input_string.toStdString(),std::regex(^([0-9]{1,3})\\){3}([0-9]{1,3})$”){
抛出InvalidIpAddressException();
}否则{
网络管理器->检索预请求(输入字符串);
}
抛出InvalidDomainNameException();
}否则{
网络管理器->检索域报告请求(输入字符串);
}
}
}捕获(标准::异常和例外){
QString异常消息{ex.what()};
QMessageBox::警告(此“警告”,异常消息);
}
ui.stringformatter->clear();
}
void主窗口::在文件上单击RadioButton(){
ui.stringformatter->setplaceholder文本(“未选择文件”);
ui.uploadButton->setText(“选择文件”);
ui.scanButton->setText(“扫描它!”);
ui.stringformatter->clear();
}
void主窗口::在\u urlRadioButton上单击(){
ui.StringFormatter->SetPlaceholder文本(“http://example.com");
ui.uploadButton->setText(“输入URL”);
ui.scanButton->setText(“扫描它!”);
ui.stringformatter->clear();
}
void主窗口::在搜索RadioButton上单击(){
StringFormatter->SetPlaceholder文本(“哈希、URL、域、IP地址…”);
ui.uploadButton->setText(“输入术语”);
ui.scanButton->setText(“搜索它!”);
ui.stringformatter->clear();
}
void main window::在上传按钮时单击(){
如果(ui.fileRadioButton->isChecked()){
文件浏览器*文件浏览器{新文件浏览器(本)};
文件浏览器->exec();
stringformatter->setText(文件\浏览器->getFilePath());
文件浏览器->设置文件路径(“”);
}
}
void main window::在重新扫描按钮时单击(){
重新扫描文件对话框*重新扫描文件doalog{新建重新扫描文件对话框(此)};
重新扫描文件\u doalog->exec();
}
void main window::on_commentButton_clicked(){
CommentDialog*comment_dialog{new CommentDialog(this)};
注释对话框->exec();
}
网络经理来了

#ifndef NETWORKMANAGER_H
#define NETWORKMANAGER_H

#include <QtNetwork>


class NetworkManager : public QObject {

    Q_OBJECT

private:

    QString api_address{"https://www.virustotal.com/vtapi/v2"};
    QByteArray api_key{"API KEY HERE"};
    QNetworkAccessManager* network_manager{new QNetworkAccessManager(this)};

    static QJsonObject json_response;

public:

    explicit NetworkManager() {
        connect(network_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*)));
    }

    virtual ~NetworkManager() = default;

    void scanFileRequest(const QString&);
    void rescanFileRequest(const QString&);
    void retrieveFileReportRequest(const QString&);

    void scanUrlRequest(const QString&);
    void retrieveUrlReportRequest(const QString&);

    void retrieveIpReportRequest(const QString&);
    void retrieveDomainReportRequest(const QString&);
    void makeCommentRequest(const QString&, const QString&);

    const static QJsonObject getJsonResponse() {
        return json_response;
    }

private slots:

    void requestFinished(QNetworkReply*);
};


#endif // NETWORKMANAGER_H
\ifndef网络管理器\u H
#定义网络管理器
#包括
类网络管理器:公共QObject{
Q_对象
私人:
QString api_地址{”https://www.virustotal.com/vtapi/v2"};
QByteArray api_key{“api key HERE”};
QNetworkAccessManager*网络管理器{new QNetworkAccessManager(this)};
静态QJsonObject json_响应;
公众:
显式网络管理器(){
连接(网络管理器,信号(完成(QNetworkReply*)),此,插槽(请求完成(QNetworkReply*));
}
virtual~NetworkManager()=默认值;
无效扫描文件请求(常量QString&);
无效重新扫描文件请求(常量QString&);
void retrieveFileReportRequest(const QString&);
void scanUrlRequest(const QString&);
void retrieveUrlReportRequest(const QString&);
无效检索预请求(const QString&);
void retrieveDomainReportRequest(常量QString&);
void makeCommentRequest(常量QString&,常量QString&);
常量静态QJsonObject getJsonResponse(){
返回json_响应;
}
专用插槽:
无效请求完成(QNetworkReply*);
};
#endif//NETWORKMANAGER\u H
和networkmanager.cpp

#include "networkmanager.h"
#include "responses.h"
#include "status_codes.h"
#include "program_exceptions.h"

#include <QMessageBox>
#include <QTimer>


QJsonObject NetworkManager::json_response{};


void NetworkManager::scanFileRequest(const QString& absolute_file_path) {
    const QFileInfo file_info{absolute_file_path};
    QHttpMultiPart* multi_part{new QHttpMultiPart(QHttpMultiPart::FormDataType)};

    QHttpPart api_key_part{};
    api_key_part.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"apikey\""));
    api_key_part.setBody(api_key);

    QHttpPart file_part{};
    QMimeDatabase db{};
    QMimeType mime_message{db.mimeTypeForFile(file_info)};
    file_part.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(mime_message.name()));
    file_part.setHeader(QNetworkRequest::ContentDispositionHeader,
                    QVariant("form-data; name=\"file\"; filename=\"" + file_info.fileName() + "\""));

    QFile* file{new QFile(absolute_file_path)};

    try {

        if (!file->open(QIODevice::ReadOnly)) {
            throw FileDoesNotExistException();
        }

    } catch (std::exception& ex) {
        QMessageBox message_box{QMessageBox::Warning, "Warning", QObject::tr(ex.what()),
                            QMessageBox::NoButton, 0, Qt::FramelessWindowHint};

        message_box.exec();
    }

    file_part.setBodyDevice(file);
    file->setParent(multi_part);

    multi_part->append(api_key_part);
    multi_part->append(file_part);

    QNetworkRequest request{QUrl{api_address + "/file/scan"}};
    network_manager->post(request, multi_part);
}


void NetworkManager::rescanFileRequest(const QString& resource) {
    QUrlQuery query_set{};
    query_set.addQueryItem("apikey", api_key);
    query_set.addQueryItem("resource", resource);

    QUrl post_params{};
    post_params.setQuery(query_set);

    QByteArray post_data{post_params.toEncoded(QUrl::RemoveFragment)};
    post_data.remove(0, 1);

    QNetworkRequest request{QUrl{api_address + "/file/rescan"}};
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");

    network_manager->post(request, post_data);
}


void NetworkManager::retrieveFileReportRequest(const QString& resource) {
    QUrl url{api_address + "/file/report"};

    QUrlQuery query_set{};
    query_set.addQueryItem("apikey", api_key);
    query_set.addQueryItem("resource", resource);

    url.setQuery(query_set.query());
    QNetworkRequest request{url};

    network_manager->get(request);
}


void NetworkManager::scanUrlRequest(const QString& url) {
    QUrlQuery query_set{};
    query_set.addQueryItem("apikey", api_key);
    query_set.addQueryItem("url", url);

    QUrl post_params{};
    post_params.setQuery(query_set);

    QByteArray post_data{post_params.toEncoded(QUrl::RemoveFragment)};
    post_data.remove(0, 1);

    QNetworkRequest request{QUrl{api_address + "/url/scan"}};
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");

    network_manager->post(request, post_data);
}


void NetworkManager::retrieveUrlReportRequest(const QString& resource) {
    QUrlQuery query_set{};
    query_set.addQueryItem("apikey", api_key);
    query_set.addQueryItem("resource", resource);

    QUrl post_params{};
    post_params.setQuery(query_set);

    QByteArray post_data{post_params.toEncoded(QUrl::RemoveFragment)};
    post_data.remove(0, 1);

    QNetworkRequest request{QUrl{api_address + "/url/report"}};
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");

    network_manager->post(request, post_data);
}


void NetworkManager::retrieveIpReportRequest(const QString& ip) {
    QUrl url{api_address + "/ip-address/report"};

    QUrlQuery query_set{};
    query_set.addQueryItem("apikey", api_key);
    query_set.addQueryItem("ip", ip);

    url.setQuery(query_set.query());
    QNetworkRequest request{url};

    network_manager->get(request);
}


void NetworkManager::retrieveDomainReportRequest(const QString& domain) {
    QUrl url{api_address + "/domain/report"};

    QUrlQuery query_set{};
    query_set.addQueryItem("apikey", api_key);
    query_set.addQueryItem("domain", domain);

    url.setQuery(query_set.query());
    QNetworkRequest request{url};

    network_manager->get(request);
}


void NetworkManager::makeCommentRequest(const QString& resource, const QString& comment) {
    QUrlQuery query_set{};
    query_set.addQueryItem("apikey", api_key);
    query_set.addQueryItem("resource", resource);
    query_set.addQueryItem("comment", comment);

    QUrl post_params{};
    post_params.setQuery(query_set);

    QByteArray post_data{post_params.toEncoded(QUrl::RemoveFragment)};
    post_data.remove(0, 1);

    QNetworkRequest request{QUrl{api_address + "/comments/put"}};
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");

    network_manager->post(request, post_data);
}


void NetworkManager::requestFinished(QNetworkReply* reply) {
    try {
        http_status_code_t server_reply{static_cast<http_status_code_t>(
                                        reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt())};

        if (server_reply == OK) {
            QJsonObject json_object = QJsonDocument::fromJson(reply->readAll()).object();
            response_code_t response_code{static_cast<response_code_t>(json_object["response_code"].toInt())};
            std::string verbose_msg{json_object["verbose_msg"].toString().toStdString()};

            if (response_code == ITEM_IS_PRESENT) {
                json_response = json_object;
                qDebug() << json_response;

            } else if (response_code == ITEM_IS_STILL_IN_QUEUE) {
                throw RequestStillInQueueException(verbose_msg);

            } else if (response_code == ITEM_DOES_NOT_EXIST) {
                throw ItemDoesNotExistException(verbose_msg);

            } else {
                throw UnknownResponseCodeException();
            }

        } else if (server_reply == API_REQUEST_LIMIT_EXCEEDED) {
            throw PublicAPIRequestRateExceededException();

        } else if (server_reply == FORBIDDEN) {
            throw ForbiddenException();

        } else {
            throw UnknownHttpStatusCodeException();
        }

    } catch (std::exception& ex) {
        QMessageBox message_box{QMessageBox::Warning, "Warning", QObject::tr(ex.what()),
                            QMessageBox::NoButton, 0, Qt::FramelessWindowHint};

        message_box.exec();
    }
}
#包括“networkmanager.h”
#包括“responses.h”
#包括“状态代码.h”
#包括“program_exceptions.h”
#包括
#包括
QJsonObject NetworkManager::json_响应{};
void NetworkManager::scanFileRequest(const QString&
void NetworkManager::requestFinished(QNetworkReply* reply) {
try {
    http_status_code_t server_reply{static_cast<http_status_code_t>(
                                        reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt())};

    if (server_reply == OK) {
        QJsonObject json_object = QJsonDocument::fromJson(reply->readAll()).object();
        response_code_t response_code{static_cast<response_code_t>(json_object["response_code"].toInt())};
        std::string verbose_msg{json_object["verbose_msg"].toString().toStdString()};

        if (response_code == ITEM_IS_PRESENT) {
            qDebug() << json_object;

            if (verbose_msg == "Scan finished, information embedded") {

                auto antiviruses = json_object["scans"].toObject().keys();
                auto values = json_object["scans"].toObject();

                for (auto antivirus : antiviruses) {
                    qDebug() << antivirus;

                    auto keys = values.value(antivirus).toObject().keys();

                    for (auto key : keys) {
                        qDebug() << key << " : " << values.value(antivirus).toObject().value(key);
                    }
                }

                return;
            }

            QTimer::singleShot(15000, this, [=]{
                retrieveFileReportRequest(json_object["resource"].toString());
            });

        } else {
            qDebug() << json_object;
            QTimer::singleShot(15000, this, [=]{
                retrieveFileReportRequest(json_object["resource"].toString());
            });
        }

    } else if (server_reply == API_REQUEST_LIMIT_EXCEEDED) {
        throw PublicAPIRequestRateExceededException();

    } else if (server_reply == FORBIDDEN) {
        throw ForbiddenException();

    } else {
        throw UnknownHttpStatusCodeException();
    }

} catch (std::exception& ex) {
    QMessageBox message_box{QMessageBox::Warning, "Warning", QObject::tr(ex.what()),
                            QMessageBox::NoButton, 0, Qt::FramelessWindowHint};

    message_box.exec();
}