1. 程式人生 > >Qt發起Http/Https請求

Qt發起Http/Https請求

我們 cati 查看 sch 變量 app font manage 下載

1. BurpSuite抓包

1.1 設置代理

burpsuite代理設置

技術分享圖片

瀏覽器代理設置(chrome),其他瀏覽器同理。

地址欄輸入 chrome://settings/

打開代理設置

技術分享圖片

設置代理端口

技術分享圖片

如果使用了代理插件,比如switchomega,可以這麽設置

技術分享圖片

這樣當選擇使用代理選項的時候,請求包的數據也會被burpsuite攔截到。


1.2 導入證書

瀏覽器地址欄輸入 http://burp/,如果有使用代理插件,建議先停用插件,待正確導入證書後開啟使用,後續不再有影響。

技術分享圖片

點擊CA Certificate,下載證書cacert.der

瀏覽器地址欄輸入chrome://settings/

技術分享圖片

選擇 “受信任的根證書頒發機構”,導入證書

技術分享圖片

下一步,選擇證書,導入成功。

1.3 攔截抓包

瀏覽器地址欄輸入地址訪問,www.baidu.com

intercept is off 攔截已關閉

intercept is on 攔截已開啟

技術分享圖片

可以看到請求包已經被我們攔截下來了。

選擇放行Forward或者點擊Intercept is on關閉攔截就會把數據包放行出去。

HTTP history中可以觀察到已經攔截到的請求地址

技術分享圖片

如果有過濾的需求,可點擊過濾

技術分享圖片

點擊鏈接,會顯示請求和響應等數據

技術分享圖片

下面自我發揮……


Qt發起http/https請求

1. 配置openssl

qt自身是不支持https的,如果想要使用https發起請求,要進行相關配置。

1.1 查看qt支持哪些協議

可以通過以下代碼查看使用的qt版本支持哪些協議。

pro文件設置

添加network支持,QT += network

查看qt支持哪些協議

#include <QNetworkAccessManager>

#include <QDebug>

QNetworkAccessManager *manager = new QNetworkAccessManager(this);

qDebug() << manager->supportedSchemes();

2 配置ssl
2.1 下載openssl
http://slproweb.com/products/Win32OpenSSL.html
選擇版本,就選擇這個版本了
技術分享圖片
2.2 下載後直接安裝,然後加入到系統環境變量(我的安裝目錄是D:\OpenSSL-Win32\bin)
2.3 配置qt支持https
LIBS += -L"D:/OpenSSL-Win32/lib" -llibeay32 
LIBS += -L"D:/OpenSSL-Win32/lib" -lssleay32
INCLUDEPATH += $$quote(D:/OpenSSL-Win32/include)
可以測試ssl是否配置成功或者查看ssl的錯誤提示。
#include <QSslSocket>
qDebug() <<"ssl:" << QSslSocket::sslLibraryBuildVersionString();
2.4 編寫程序
這裏不必要的業務邏輯就不在寫了,主要放上https請求的代碼,著重關註和http請求的不同點。

bool MainWindow::SendHttp()

{
    /*QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    qDebug() << manager->supportedSchemes();*/

    qDebug() <<"ssl:" << QSslSocket::sslLibraryBuildVersionString();

    QNetworkRequest request;
    QSslConfiguration config;

    QNetworkProxy proxy;
    proxy.setType(QNetworkProxy::HttpProxy);
    proxy.setHostName("127.0.0.1");
    proxy.setPort(8080);
    QNetworkProxy::setApplicationProxy(proxy);

	//url
	request.setUrl(QUrl(strWww));

    QSslConfiguration conf = request.sslConfiguration();
    config.setPeerVerifyMode(QSslSocket::VerifyNone);
    config.setProtocol(QSsl::TlsV1_0);
    request.setSslConfiguration(config);

    //header
    auto it = m_headerMap.begin();
    while(it != m_headerMap.end())
    {
        //qDebug() << it->second.m_skey.toLatin1() << it->second.m_sval.toLatin1() << ‘\n‘;
        request.setRawHeader(it->second.m_skey.toLatin1(), it->second.m_sval.toLatin1());
        ++it;
    }

    //nam
    QNetworkAccessManager qnam;
	qDebug() << qnam.supportedSchemes();

    // 開啟一個局部的事件循環,等待響應結束,退出
    QEventLoop loop;
    QTimer timer;
    //發出請求
    QNetworkReply *reply = qnam.get(request);
    QObject::connect(&qnam,SIGNAL(finished(QNetworkReply *)),&loop,SLOT(quit()));
    //請求結束並下載完成後,退出子事件循環
    QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    //超時退出
    QObject::connect(&timer,SIGNAL(timeout()),&loop,SLOT(quit()));
    //超時設置5秒鐘
    timer.start(5000);
    //開啟子事件循環
    loop.exec();
    //....

    if (reply->error() == QNetworkReply::NoError)
    {
        QVariant statusCodeV =
            reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

       if(statusCodeV.toInt() == 200
                                    /*這裏寫了這個readAll(),
                                     * 下面readAll()就取不出數據了
                                     * && !reply->readAll().isEmpty()
                                     */
        )
        {

           //寫入文件
           std::ofstream ofile;
           ofile.open("test.txt");
           if(ofile.fail())
           {
                qDebug() << "error ofile" << ‘\n‘;
           }
           //reply->readAll().isEmpty()
           ofile << reply->readAll().toStdString();
           ofile.flush();
           ofile.close();
        }
    }

	return true;
}

Qt發起Http/Https請求