首页 > 编程语言 >Qt开发程序用QProcess调用curl命令上传文件并获取响应的文件

Qt开发程序用QProcess调用curl命令上传文件并获取响应的文件

时间:2024-01-24 17:35:07浏览次数:34  
标签:文件 Qt CURLFORM QProcess str easy curl CURLOPT setopt

1.需求

做一个批量数字签名的工具,从一个文件夹内寻找所有的exe文件,然后复制到另外一个文件夹中,并且保存源文件的路径,将目标文件夹内的所有exe文件上传到公司的数字签名平台去做数字签名,并且返回接收后的文件;

尝试了libcurl的post请求,发现总是返回参数错误;

 

int HttpClient::PostFile(std::string strFile)
{
    std::string strurl = "http://10.1.13.228/sign";
    int iret = -1;

    struct curl_httppost *formpost = NULL;
    struct curl_httppost *lastptr = NULL;
    QFileInfo fileinfo(strFile.c_str());
    std::string strFilePath = fileinfo.absolutePath().toStdString();
    std::string strFileName = fileinfo.fileName().toStdString();
    QFile file(strFile.c_str());
    int filesize = file.size();
    QByteArray pBuffer = file.readAll();
    int buffsize = pBuffer.size();
    if (pBuffer.size() != fileinfo.size()) {
        printf("read file failed\n");
        
        return -iret;
    }
/*    */
    //curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "upfile", CURLFORM_FILE, strFile.c_str(), CURLFORM_CONTENTTYPE, "text/xml", CURLFORM_END);
    //curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "filename", CURLFORM_COPYCONTENTS, strFileName.c_str(), CURLFORM_END);
    //curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "action", CURLFORM_COPYCONTENTS, "upload", CURLFORM_END);
    CURL* curl = curl_easy_init();
    
    //curl_formadd(&formpost, &lastptr,
    //    CURLFORM_COPYNAME, "uploadfile",
    //    CURLFORM_FILE, strFilePath.c_str(),//imagepath
    //    CURLFORM_CONTENTTYPE, "multipart/form-data",
    //    CURLFORM_END);

    //curl_formadd(&formpost, &lastptr,
    //    CURLFORM_COPYNAME, "filename",
    //    CURLFORM_COPYCONTENTS, strFileName.c_str(),
    //    CURLFORM_END);
    
    if (curl)
    {
        /*curl_formadd(&formpost, &lastptr,
            CURLFORM_COPYNAME, "file",
            CURLFORM_BUFFER, strFileName.c_str(),
            CURLFORM_BUFFERPTR, pReadBuffer,
            CURLFORM_BUFFERLENGTH, fileinfo.size(),
            CURLFORM_CONTENTTYPE, "application/octet-stream",
            CURLFORM_END);*/
            /*curl_formadd(&formpost,
                &lastptr,
                CURLFORM_COPYNAME, "fileUpload",
                CURLFORM_FILE, strFile.c_str(),
                CURLFORM_END);*/
        curl_formadd(&formpost, &lastptr, CURLFORM_PTRNAME, "reqformat", CURLFORM_PTRCONTENTS, "plain", CURLFORM_END);

        curl_formadd(&formpost, &lastptr, CURLFORM_PTRNAME, "file", CURLFORM_PTRCONTENTS, pBuffer, CURLFORM_CONTENTSLENGTH, pBuffer.size(), CURLFORM_END);

        ///* Fill in the filename field */
        curl_formadd(&formpost,
            &lastptr,
            CURLFORM_COPYNAME, "filename",
            CURLFORM_COPYCONTENTS, strFileName.c_str(),
            CURLFORM_END);
        //curl_formadd(&formpost, &lastptr, CURLFORM_PTRNAME, "file", CURLFORM_FILE, strFile.c_str(), CURLFORM_END);
        /* Fill in the submit field too, even if this is rarely needed */
        curl_easy_setopt(curl, CURLOPT_POST, 1);
        curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
        //curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5); // 重定向次数
        ///curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);//设置301、302跳转跟随location

        curl_easy_setopt(curl, CURLOPT_URL, strurl.c_str());
        //curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
        curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);// 超时10秒

        if (0 == strncmp(strurl.c_str(), "https:", 6))
        {
            curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
        }
        struct curl_slist *headers = NULL;
        std::string strfiletext = "file:@" + strFile;
       
        headers = curl_slist_append(headers, "Content-Type:multipart/form-data");
        headers = curl_slist_append(headers, strfiletext.c_str());
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        char* raw_parame = "";
        //char* escap_param = curl_escape(raw_parame, strlen(raw_parame));
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, raw_parame);
        /* 长参数一定要设置CURLOPT_POSTFIELDSIZE,否则会截断 */
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(raw_parame));
        FILE *pagefile;
        //写入到文件
        QString strOutPath = fileinfo.absolutePath().toStdString().c_str();
        strOutPath+="/output/";
        QDir dir(strOutPath);
        if (!dir.exists())
        {
            dir.mkpath((strOutPath));
        }
        std::string strSigniturFile = fileinfo.absolutePath().toStdString() + "/output/" + strFileName;
        QFile Outputfileinfo(strSigniturFile.c_str());
        if (Outputfileinfo.exists())
        {
            Outputfileinfo.remove();
        }
        pagefile = fopen(strSigniturFile.c_str(), "wb");
        if (pagefile)
        {
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteFile);
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, pagefile);
            CURLcode res = curl_easy_perform(curl);
            if (res != CURLE_OK)
            {
                fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
            }
            fclose(pagefile);
            printf("************************************\n");
        }
        else {

            printf("XXXXXXXXXXXXXXXXXXXXXXXXXXXX\n");
        }
            
        if (curl)
        {
            curl_easy_cleanup(curl);
        }
        if (headers)
        {
        }
    }
    return iret;
}

发现总是包参数错误;

后来发现可以curl加命令参数的方式上传程序文件去签名;前提是电脑必须安装了curl,可以打开window程序cmd.exe,然后查看curl --version 查看本地电脑的curl版本;

#include "UploadFileThread.h"
#include <QProcess>
UploadFileThread::UploadFileThread()
{

}

UploadFileThread::~UploadFileThread()
{

}

void UploadFileThread::SetFiles(QMap<QString, QString> taskInfo)
{
    m_taskInfo = taskInfo;
    start();
}


void UploadFileThread::run()
{
    int s = 0;
    for (auto is = m_taskInfo.begin(); is != m_taskInfo.end(); is++)
    {
        QString strPath = is.key();
        strPath = strPath.replace("/", "\\");
        QStringList strParameter;
        //strParameter << "curl";
        strParameter << "-F";
        strParameter << "fd=sha256";
        strParameter << "-F";
        strParameter << ("file=@"+ strPath);
        strParameter << "-F";
        strParameter << "cert_type=EV";
        strParameter << "http://109.1.13.228";
        strParameter << "-k";
        strParameter << "-f";
        strParameter << "-o";
        strParameter << strPath;
        QProcess process(this);
        process.execute("curl", strParameter);
        process.waitForStarted();
        process.waitForFinished();
        s++;
        emit signalProgress(int(100.0*(s) / m_taskInfo.size()));
    }
  
}

 

标签:文件,Qt,CURLFORM,QProcess,str,easy,curl,CURLOPT,setopt
From: https://www.cnblogs.com/bclshuai/p/17985181

相关文章

  • ffmpeg-打开文件-avio_open_dir-avio_read_dir
    vio_open_diravio_read_dirCode#includevoiddir_function(void){ AVIOContext*ctx=NULL; //目录操作上下文 AVIODirEntry*entry=NULL; //目录项 av_log_set_level(AV_LOG_DEBUG); //设置日志等级 intret=avio_open_dir(&ctx,"./A",NULL); if(r......
  • BeautifulSoup和Cheerio库:解析QQ音频文件的完整教程
    在当今数字化的世界中,网络上充斥着各种各样的数据,而这些数据往往以各种不同的格式和结构存在。要从这些数据中获取有用的信息,我们就需要使用一些工具来解析和提取数据。BeautifulSoup和CheerioBeautifulSoup是Python中用于解析HTML和XML文档的库,而Cheerio是Node.js中类似的库。......
  • 配置日志文件达到一定大小自动压缩
    1工具的安装apt-getinstalllogrotate2修改配置文件在/etc/logrotate.d目录下创建一个新的logrotate的配置文件,touch myapp.conf在该配置文件中添加以下内容:/path/to/your/logfile{size10M#设置日志文件最大大小为10MBrotate5#保存5份日志文件comp......
  • QTableWidget指定某行某列只能输入数字
    主要通过给QTableWidget设置代理,即继承QItemDelegate类重写其中的方法实现,具体代码如下:1/**2*@fileNonNegativeNumberItemDelegate.h3*@brief非负整数校验代理4*@author禅元天道([email protected])5*@date2024-01-246*/7#ifndefNONNE......
  • python创建json文件并换行
     在Python中,您可以使用内置的json 模块创建和操作JSON文件。以下是如何创建一个JSON文件的步骤:1、Json格式JSON数据的书写格式是键(名称)/值对。JSON值可以是:字符串(在双引号中)、数组(在中括号中)、数字(整数或浮点数)、逻辑值(true或false)、对象(在大括号中)、null。JSON......
  • qt的信号和槽以及常见容器
    Qt的信号和槽机制是Qt的一项核心特性,也是其主要的编程模型之一。它通过一种事件驱动的方式,使得不同对象之间可以进行沟通、交互和协作。信号和槽是Qt中的两个重要的概念。信号是一个事件,当一个对象的内部状态发生变化时,它会发出一个信号。槽是一个响应函数,用来处理信号所表......
  • NetCore获取文件内容
    1、注入IWebHostEnvironmentprivateIWebHostEnvironment_hostEnvironment;publicFormBaseController(IWebHostEnvironmenthostEnvironment){_hostEnvironment=hostEnvironment;} 2、读取根目录下文件内容(Templates/Index.html)publicasyncTask<IActionRes......
  • Linux查看文件的命令有哪些?
    在Linux系统中,查看文件的命令常用的有五个,分别是:find命令、locate命令、whereis命令、which命令及type命令,接下来通过这篇文章为大家详细介绍一下这五个命令。Linux查看文件的五种命令1、findfind是最常见和最强大的查找命令,你可以用它找到任何你想找的文件。f......
  • nfs网络文件系统介绍_
    1NFS介绍1.1NFS概念描述 1.2NFS历史介绍1.3NFS在企业中的应用场景 1.4NFS服务挂载结构图解 1.5NFS在企业生产集群架构中的位置 ......
  • CentOS7&Windows10的hosts文件设置
    CentOS7的hosts文件设置打开hosts文件vim/etc/hosts添加如下内容[IP][映射名称]如:127.0.0.1www.haha.com重启设备,查看主机名修改成功rebootWindows10的hosts文件的设置找到windows的hosts文件C:\Windows\System32\drivers\etc打开hosts文件添加cen......