美文网首页
libcurl封装http请求工具类

libcurl封装http请求工具类

作者: 何亮hook_8285 | 来源:发表于2021-10-03 01:28 被阅读0次

curl是什么

用URL传输数据的命令行工具和库,支持以下协议:DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP,IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMTP, SMTPS,TELNET,TFTP等

curl函数

curl_easy_init() 用于初始化会话对象

curl_easy_cleanup() 关闭会话对象

curl_easy_setopt() 设置会话请求参数

curl_easy_perform() 执行会话

curl_easy_getinfo() 获取响应信息

封装C++工具类

httputils.h

//
// Created by heliang on 2021/10/2.
//

#ifndef HTTPUTILS_H
#define HTTPUTILS_H
#include <iostream>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <map>
#include <curl/curl.h>



using namespace std;

/**
 * 响应体按字节存储
 *
 */
struct MemoryStruct {
    //字节大小
    char *memory;
    //字节数组大小
    size_t size;
};


/**
 * http工具类
 */
class HttpUtils {
public:
    HttpUtils();
    ~HttpUtils();
    //GET请求
    string Get(string url);
    //Post fordata请求
    string Post(string url,map<string,string> formData);

    //Post request body
    string PostBody(string url,string body);

    /**
     *上传文件
     * @param url
     * @param fileName 文件表单名称 等于 <input type="file" name="file">
     * @param filePath 文件目录  等于 type="file" 选择的文件
     * @param paramFormData formdate表单参数
     * @return
     */
    string PostFile(string url, string fileName,string filePath,map<string,string> paramFormData);

    //PUt request body
    string PutBody(string url,string body);

    //Patch
    string PatchBody(string url,string body);

    //Delete
    string Delete(string url);

    /**
     * 下载文件
     * @param url
     * @return
     */
    MemoryStruct DownloadFile(string url);

    //响应体回调方法
    static  size_t CallbackResponse(char *data, size_t size, size_t nmemb, string  * buffer) ;
    //读取数据
    static size_t CallbackRead(char *data,size_t size, size_t nmemb,string  * buffer);

    //字节处理响应体
    static  size_t CallbackResponseByte(void *contents, size_t size, size_t nmemb, void *userp);
};



#endif //HTTPUTILS_H

HttpUtils.cpp

//
// Created by heliang on 2021/10/2.
//

#include "httputils.h"




HttpUtils::HttpUtils() {
    curl_global_init(CURL_GLOBAL_ALL);
}



/**
 * GET 请求
 *
 * @param url
 * @return
 */
string HttpUtils::Get(string url) {

    string response;
    //初始化一个会话
    CURL *curl=curl_easy_init();
    //get请求
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
    //设置请求地址
    curl_easy_setopt(curl,CURLOPT_URL,url.c_str());
    //设置响应的回调函数
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HttpUtils::CallbackResponse);
    //设置响应结果写到那个变量
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
    //执行请求结构
    CURLcode  res= curl_easy_perform(curl);
    //关闭会话
    curl_easy_cleanup(curl);
    return response;
}



/**
 * post 请求
 * @param url 请求地址
 * @param formData 请求参数
 * @return
 */
string HttpUtils::Post(string url, map<string, string> formData) {

    string response;
    //初始化一个会话
    CURL *curl=curl_easy_init();
    //设置请求地址
    curl_easy_setopt(curl,CURLOPT_URL,url.c_str());
    //设置响应的回调函数
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HttpUtils::CallbackResponse);
    //设置响应结果写到那个变量
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

    string formPost;
    map<string, string>::iterator iter;
    int total=formData.size();
    int curCount=0;
    for(iter=formData.begin();iter!=formData.end();iter++){
           string key=iter->first;
           string value=iter->second;
        formPost.append(key+"="+value);
        if(curCount!=total-1){
            formPost.append("&");
        }
        curCount++;

    }
    //post
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS,formPost.c_str());
    //执行请求结构
    CURLcode  res= curl_easy_perform(curl);
    //关闭会话
    curl_easy_cleanup(curl);
    return response;

}


//发送Post body请求
string HttpUtils::PostBody(string url, string body) {
    string response;
    CURL *curl=curl_easy_init();
    //设置请求地址
    curl_easy_setopt(curl,CURLOPT_URL,url.c_str());
    curl_easy_setopt(curl, CURLOPT_POST, 1L);
    //设置响应的回调函数
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HttpUtils::CallbackResponse);
    //设置响应结果写到那个变量
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

    //post内容
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.size());

    curl_slist* headerList = NULL;
    headerList = curl_slist_append(headerList, "Content-Type:application/json");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER,
                     headerList);

    //执行请求结构
    CURLcode  res= curl_easy_perform(curl);
    //关闭curl对象
    curl_easy_cleanup(curl);
    curl_slist_free_all(headerList);
    return response;
}

//PUt request body
string HttpUtils::PutBody(string url, string body) {
    string response;
    CURL *curl=curl_easy_init();
    //设置请求地址
    curl_easy_setopt(curl,CURLOPT_URL,url.c_str());
    curl_easy_setopt(curl, CURLOPT_PUT, 1L);
    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, HttpUtils::CallbackRead);
    curl_easy_setopt(curl, CURLOPT_READDATA, &body);
    //设置数据大小
    curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, body.size());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HttpUtils::CallbackResponse);
    //设置响应结果写到那个变量
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

    curl_slist* headerList = NULL;
    headerList = curl_slist_append(headerList, "Content-Type:application/json");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER,
                     headerList);

    //执行请求结构
    CURLcode  res= curl_easy_perform(curl);
    //关闭curl对象
    curl_easy_cleanup(curl);
    curl_slist_free_all(headerList);
    return response;
}


/**
 * Patch 请求
 * @param url
 * @param body
 * @return
 */
string HttpUtils::PatchBody(string url, string body) {
    string response;
    CURL *curl=curl_easy_init();
    //设置请求地址
    curl_easy_setopt(curl,CURLOPT_URL,url.c_str());
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PATCH");
    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, HttpUtils::CallbackRead);
    curl_easy_setopt(curl, CURLOPT_READDATA, &body);
    //设置数据大小
    curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, body.size());

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HttpUtils::CallbackResponse);
    //设置响应结果写到那个变量
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

    curl_slist* headerList = NULL;
    headerList = curl_slist_append(headerList, "Content-Type:application/json");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER,
                     headerList);

    //执行请求结构
    CURLcode  res= curl_easy_perform(curl);
    //关闭curl对象
    curl_easy_cleanup(curl);
    curl_slist_free_all(headerList);
    return response;
}



HttpUtils::~HttpUtils() {
    curl_global_cleanup();
}

/**
 * delete 请求
 * @param url
 * @return
 */
string HttpUtils::Delete(string url) {
    string response;
    CURL *curl=curl_easy_init();
    //设置请求地址
    curl_easy_setopt(curl,CURLOPT_URL,url.c_str());
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HttpUtils::CallbackResponse);
    //设置响应结果写到那个变量
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

    //执行请求结构
    CURLcode  res= curl_easy_perform(curl);
    //关闭curl对象
    curl_easy_cleanup(curl);
    return response;
}


/**
 *上传文件 ,遵守RFC1738协议
 * @param url
 * @param fileName 文件表单名称 等于 <input type="file" name="file">
 * @param filePath 文件目录  等于 type="file" 选择的文件
 * @param paramFormData formdate表单参数
 * @return
 */
string HttpUtils::PostFile(string url, string fileName,string filePath,map<string,string> paramFormData) {
    string response;

    struct curl_httppost *formpost = NULL;
    struct curl_httppost *lastptr = NULL;
    struct curl_slist *headerlist = NULL;

    //文件名称
    curl_formadd(&formpost,
                 &lastptr,
                 CURLFORM_COPYNAME, fileName.c_str(),
                 CURLFORM_FILE,filePath.c_str(),
                 CURLFORM_END);


    //设置表单元素
    if(!paramFormData.empty()){
        map<string,string>::iterator  iter;
        for(iter=paramFormData.begin();iter!=paramFormData.end();iter++){
            string key=iter->first;
            string value=iter->second;
            curl_formadd(&formpost,
                         &lastptr,
                         CURLFORM_COPYNAME, key.c_str(),
                         CURLFORM_COPYCONTENTS,value.c_str(),
                         CURLFORM_END);
        }
    }


    /* 设置表单发送执行 */
    curl_formadd(&formpost,
                 &lastptr,
                 CURLFORM_COPYNAME, "submit",
                 CURLFORM_COPYCONTENTS, "send",
                 CURLFORM_END);


    headerlist = curl_slist_append(headerlist, "Expect:");

    CURL *curl=curl_easy_init();

    //设置自定义header
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);

    //设置表单参数
    curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);

    //设置请求地址
    curl_easy_setopt(curl,CURLOPT_URL,url.c_str());

    //设置返回结果回调函数
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HttpUtils::CallbackResponse);
    //设置响应结果写到那个变量
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

    //执行请求结构
    CURLcode  res= curl_easy_perform(curl);

    //关闭curl对象
    curl_easy_cleanup(curl);
    curl_formfree(formpost);
    curl_slist_free_all(headerlist);
    return response;
}


/**
 * 下载文件
 * @param url
 * @return
 */
MemoryStruct HttpUtils::DownloadFile(string url) {

    //存储响应结构体
    struct MemoryStruct chunk;

    //分配空间大小
    chunk.memory = (char *)malloc(1);
    chunk.size = 0;

    //开始一次会话
    CURL *curl=curl_easy_init();
    //设置请求地址
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    //设置响应的回调方法
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HttpUtils::CallbackResponseByte);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &chunk);


    //执行请求结构
    CURLcode  res= curl_easy_perform(curl);
    //操作成功
    if(CURLE_OK==res){
        //获取文件大小
        curl_off_t val;
        curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD_T, &val);
        cout << "file size=" << val << endl;

        //总下载时间:
        curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME_T, &val);
        cout << "total time=" << val << endl;

        //平均下载速度
        curl_easy_getinfo(curl, CURLINFO_SPEED_DOWNLOAD_T, &val);
        cout << "down =" << val / 1024 << endl;

        //获取响应体 CONTENT_TYPE
        char *contentType;
        curl_easy_getinfo(curl,CURLINFO_CONTENT_TYPE,&contentType);
        cout << contentType << endl;

        //获取响应状态码
        long responseCode;
        curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&responseCode);
        cout << "response code = " << responseCode << endl;


    }
    //关闭会话
    curl_easy_cleanup(curl);
    return chunk;
}



/**
 * 响应时回调方法
 * @param data 响应体字节数据
 * @param size  被写入的每个元素的大小,以字节为单位。
 * @param nmemb 这是元素的个数,每个元素的大小为 size 字节。
 * @param buffer 传递的指针
 * @return
 */
size_t HttpUtils::CallbackResponse(char *data, size_t size, size_t nmemb, string  *buffer) {
    size_t realsize = size * nmemb;
    if (buffer != NULL) {
        buffer->append(data,realsize);
    }

    return realsize;
}


/**
 * 读取内容回调方法
 * @param data 响应体字节数据
 * @param size 被写入的每个元素的大小,以字节为单位。
 * @param nmemb 这是元素的个数,每个元素的大小为 size 字节。
 * @param buffer 传递的指针
 * @return
 */
size_t HttpUtils::CallbackRead(char *data, size_t size, size_t nmemb, string *buffer) {
    size_t copy_size = buffer->size();
    std::memcpy(data, buffer->c_str(), copy_size);
    return copy_size;
}

/**
 * 字节处理响应体
 * @param contents 响应体字节数据
 * @param size 被写入的每个元素的大小,以字节为单位。
 * @param nmemb 这是元素的个数,每个元素的大小为 size 字节。
 * @param userp 传递的指针
 * @return 
 */
size_t HttpUtils::CallbackResponseByte(void *contents, size_t size, size_t nmemb, void *userp) {
    size_t realsize = size * nmemb;
    struct MemoryStruct *mem = (struct MemoryStruct *)userp;

    char *ptr = (char *)realloc(mem->memory, mem->size + realsize + 1);
    if(!ptr) {
        printf("not enough memory (realloc returned NULL)\n");
        return 0;
    }

    mem->memory = ptr;
    memcpy(&(mem->memory[mem->size]), contents, realsize);
    mem->size += realsize;
    mem->memory[mem->size] = 0;

    return realsize;
}

相关文章

网友评论

      本文标题:libcurl封装http请求工具类

      本文链接:https://www.haomeiwen.com/subject/glamnltx.html