CURL自动解压缩有时失败,请问怎么解决?

QQ551780977 2012-04-16 11:33:10
我在测试WWW.QQ.COM时,发现有时候CURL自动解压缩失败,直接返回GZIP数据,那位知道怎么解决?谢谢!
我不想自己写代码来解压缩!
...全文
265 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
QQ551780977 2012-04-16
  • 打赏
  • 举报
回复
上一个对CURL还没完成的C++封装类,希望能帮助到一些有需要的朋友。
注意,下面的代码会出现自动解压缩失败

#pragma once
#pragma comment(lib, "curl/libcurld.lib")
#include "curl/curl.h"
class CCurl
{

public:
CCurl()
{
_Init();
}
//全局初始化,只能用于主线程
static void GlobalInit()
{
curl_global_init(CURL_GLOBAL_ALL);
}
//全局资源清除,只能用于主线程
static void GlobalCleanup()
{
curl_global_cleanup();
}
void Close()
{
if( _GetHandle() )
{
curl_easy_cleanup(m_pCurl);
m_pCurl = NULL;
}
FreeHeaderListPtr();

}
//禁止重用
void SetForbidReuse(bool Flags = false)
{

curl_easy_setopt(m_pCurl, CURLOPT_FORBID_REUSE, Flags);
}
//重新连接
void SetFreshConnect(bool Flags = false)
{
curl_easy_setopt(m_pCurl, CURLOPT_FRESH_CONNECT, Flags);
}
public:
void HttpGet(const char *Url = NULL)
{
if( NULL != Url)
SetUrl(Url);
SetCutomRequest("GET");
}
void RemoveHttpHeader(bool Flags = false)
{
curl_easy_setopt(m_pCurl, CURLOPT_HTTPGET, Flags);
}
public:
void SetUrl(const char *Url)
{
curl_easy_setopt(m_pCurl, CURLOPT_URL, Url);
}
void AddRequestHeader(const char *Header)
{
m_pHeader = curl_slist_append(m_pHeader, Header);
}
void SetRequestHeader()
{
if(m_pHeader)
curl_easy_setopt(m_pCurl, CURLOPT_HTTPHEADER, m_pHeader);
}
void FreeHeaderListPtr()
{
if(m_pHeader)
{
curl_slist_free_all(m_pHeader);
}
}
public:
//设置一个长整形数,作为最大延续多少秒。
void SetTimeOut (long Size = 0)
{
curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT, Size);
}
void SetConnectTimeOut(long Size = 0)
{
curl_easy_setopt(m_pCurl, CURLOPT_CONNECTTIMEOUT, Size);
}
public:
int Exec()
{
SetRequestHeader();
int Code = curl_easy_perform(m_pCurl);
return Code;
}

public:
double GetResultFileSize()
{
double Size = 0;
curl_easy_getinfo(m_pCurl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &Size);
return Size;
}
public:
void SetCutomRequest(const char *RequestType = "GET")
{
curl_easy_setopt(m_pCurl, CURLOPT_CUSTOMREQUEST, RequestType);
}
//如果你想把一个头包含在输出中,设置这个选项为一个非零值。
void SetOutHeader(bool Flags = true)
{
curl_easy_setopt(m_pCurl, CURLOPT_HEADER, Flags);
}
// 如果你不想在输出中包含body部分,设置这个选项为一个零值。
void SetOutBody(bool Flags = true)
{
curl_easy_setopt(m_pCurl, CURLOPT_NOBODY, !Flags);
}
void SetOnGzip(bool Flags = false)
{
if(Flags)
curl_easy_setopt(m_pCurl, CURLOPT_ACCEPT_ENCODING, "gzip");

}
void SetTransferEncoding(bool Flags = false)
{
curl_easy_setopt(m_pCurl, CURLOPT_TRANSFER_ENCODING , Flags);
}
//传递一个你想指定的范围。它应该是"X-Y"格式,X或Y是被除外的。HTTP传送同样支持几个间隔,用逗句来分隔(X-Y,N-M)。
void SetRange(const char *Str)
{
curl_easy_setopt(m_pCurl, CURLOPT_RANGE , Str); //设置断点继传
}
//设置续传起始位置
void SetResumeFrom(long Start = 0)
{
curl_easy_setopt(m_pCurl, CURLOPT_RESUME_FROM, Start);
}
//如果你不会PHP为CURL传输显示一个进程条,设置这个选项为一个非零值。
void SetOnProgress (bool Flags = false)
{
curl_easy_setopt(m_pCurl, CURLOPT_NOPROGRESS, !Flags);
}
public: //设置HTTP头回调函数
void SetHeaderCallFunction(void *UserPtr = NULL, void *Function = NULL)
{
if(Function)
{
curl_easy_setopt(m_pCurl, CURLOPT_HEADERFUNCTION, Function);
curl_easy_setopt(m_pCurl, CURLOPT_HEADERDATA, UserPtr);
}

}
//当有数据可写时调用function参数中的回调函数
void SetWriteCallFunction(void *UserPtr = NULL, void *Function = NULL)
{
if(Function)
{
curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, Function);
curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, UserPtr);
}

}
//设置进度回调函数
void SetProgressCallFunction(void *UserPtr = NULL, void *Function = NULL)
{
if(Function)
{
curl_easy_setopt(m_pCurl, CURLOPT_NOPROGRESS, false);
curl_easy_setopt(m_pCurl, CURLOPT_PROGRESSFUNCTION, Function);
curl_easy_setopt(m_pCurl, CURLOPT_PROGRESSDATA, UserPtr);
}
}

public:
//设置自动跳转
void SetOnAutoReferer(bool Flags = false)
{
curl_easy_setopt(m_pCurl, CURLOPT_AUTOREFERER, Flags);
}
//如果你想CURL报告每一件意外的事情,设置这个选项为一个非零值。
void SetOnVerbose(bool Flags = false)
{
curl_easy_setopt(m_pCurl, CURLOPT_VERBOSE, Flags);
}

void SetErrorBuffer(const char *Buf)
{
//curl_easy_setopt(m_pCurl, CURLOPT_ERRORBUFFER, Buf);
}

//多线程传输时设置FALSE是安全的
void SetOnSignal(bool Flags = false)
{
curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, !Flags); //设置线程安全
}

//如果你想在发生错误(HTTP代码返回大于等于300)时,不显示,设置这个选项为非零值。默认行为是返回一个正常页,忽略代码。
void SetFailOnError(bool Flags = false)
{
curl_easy_setopt(m_pCurl, CURLOPT_FAILONERROR, Flags);
}
public:
//void GetVersion();

private:
void _Init()
{
m_pHeader = NULL;
m_pCurl = curl_easy_init();
SetOnSignal(false);
SetFailOnError(true);
}

bool _GetHandle()
{
if( m_pCurl )
{
return true;
}
else
{
return false;
}
}

private:
CURL *m_pCurl;
curl_slist *m_pHeader;
};
size_t OnHeader(char *Buffer, size_t Size, size_t Nmemb, FILE *UserPtr)
{
return 0;
}

size_t OnWriteData(char *Buffer, size_t Size, size_t Nmemb, FILE *UserPtr)
{
if(UserPtr)
{
return fwrite(Buffer, Size, Nmemb, UserPtr);
}
else
return Size * Nmemb;
}

size_t OnProgress(void *UserPtr, double DownTotal, double DownNow,
double UploadTotal, double UploadNow )
{
printf("%g/%g\n",DownNow,DownTotal);
return 0;
}
int main()
{

const char *url = "http://www.qq.com";
CCurl::GlobalInit();
CCurl http;
http.SetTimeOut(20);
http.HttpGet(url);
http.SetOnVerbose(true);
http.SetOutHeader(false);
http.SetOutBody(false);
printf("\n%d\n\n",http.Exec());
http.SetForbidReuse(true);


http.AddRequestHeader("Cache-Control: no-cache");
//http.AddRequestHeader("Accept-Encoding: gzip");
http.AddRequestHeader("User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
//http.SetTransferEncoding(false);
http.SetOutHeader(false);
http.SetOutBody(true);
char filename[100] = {0};
srand(time(0));
sprintf(filename,"%d.html",rand()%1000);
FILE *pfile = fopen(filename,"ab+");
http.SetWriteCallFunction(pfile,OnWriteData);
http.SetProgressCallFunction(NULL, OnProgress);
printf("\n%d\n\n",http.Exec());
fclose(pfile);
http.SetForbidReuse(true);
http.Close();

CCurl::GlobalCleanup();

return 0;
}

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧