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;
}
网友评论