123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601 |
- #pragma once
- #include <string>
- #include <algorithm>
- #include <vector>
- #include <WinSock2.h>
- #pragma comment(lib, "ws2_32.lib")
- #include "HTTPTypes.h"
- #include "DNSMap.h"
- #include "IInputFiled.h"
- /******************************************************************************
- HTTP操作类
- 功能:
- 实现HTTP的操作
- 说明:
- 使用之前必须调用Init进行初始化。
- 自动管理Cookies的发送和保存。
- 如果中文出现乱码,请在调用Get、Post之前调用SetCodePage设置编码。
- 如需要封装好的HTTPS、异步HTTP、完成端口TCP等商业源码,请联系作者索取。
- 作者:
- 佳也 2623168833 jaye8090@qq.com
- 时间:
- 2013-4-8 到 2014-11-12
- ******************************************************************************/
- class CHTTP
- {
- public:
- CHTTP(void);
- ~CHTTP(void);
- /**************************************************************************
- 初始化
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int Init(void);
- //基本接口
- public:
- /**************************************************************************
- HTTP的GET操作
- 参数:
- strHTML 返回值。获取到的HTML内容。
- strURL URL地址
- strHeader 指定请求头信息,多个请求头用\r\n分隔。
- 若为空串,则使用默认的请求头。
- strWait 指定等待字符串,出现此字符串则中途停止接收。
- 因为中途没有编码转换,所以不要用中文。
- 若为空串,则不中途停止接收。
- bNeedHeader 是否需要响应头信息
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int Get(string & strHTML, string strURL
- , string strHeader = ""
- , string strWait = "", bool bNeedHeader = false);
- /**************************************************************************
- HTTP的POST操作
- 参数:
- strHTML 返回值。获取到的HTML内容。
- strURL URL地址
- strPostData POST数据
- strHeader 指定请求头信息,多个请求头用\r\n分隔。
- 若为空串,则使用默认的请求头。
- strWait 指定等待字符串,出现此字符串则中途停止接收。
- 因为中途没有编码转换,所以不要用中文。
- 若为空串,则不中途停止接收。
- bNeedHeader 是否需要响应头信息
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int Post(string & strHTML, string strURL, string strPostData
- , string strHeader = ""
- , string strWait = "", bool bNeedHeader = false);
- /**************************************************************************
- HTTP的POST操作
- 参数:
- strHTML 返回值。获取到的HTML内容。
- strURL URL地址
- strPostData POST数据
- strHeader 指定请求头信息,多个请求头用\r\n分隔。
- 若为空串,则使用默认的请求头。
- strWait 指定等待字符串,出现此字符串则中途停止接收。
- 因为中途没有编码转换,所以不要用中文。
- 若为空串,则不中途停止接收。
- bNeedHeader 是否需要响应头信息
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int PostFile(string & strHTML, string strURL, std::vector<CInputFiled*>& inputs
- , string strHeader = ""
- , string strWait = "", bool bNeedHeader = false);
- /**************************************************************************
- GET图片数据
- 参数:
- pchImgData 返回值。图片数据的内存地址。
- 此内存数据的有效期,到下次调用Get、Post、GetImg为止。
- 对象析构后,此内存将被释放。
- nImgSize 返回值。图片数据的大小。
- strURL URL地址
- strHeader 指定请求头信息,多个请求头用\r\n分隔。
- 若为空串,则使用默认的请求头。
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int GetImg(char * & pchImgData, int & nImgSize
- , string strURL, string strHeader = "");
- //高级接口
- public:
- /**************************************************************************
- 设置超时时间
- 参数:
- nConnTimeout 连接超时,毫秒。
- nSendTimeout 发送超时,毫秒。
- nRecvTimeout 接收超时,毫秒。
- **************************************************************************/
- void SetTimeout(int nConnTimeout, int nSendTimeout, int nRecvTimeout);
- /**************************************************************************
- 恢复上次设置的超时时间
- **************************************************************************/
- void SetTimeoutBack(void);
- /**************************************************************************
- 添加一个Cookie项
- 说明:
- 如果此Cookie项已经存在,则替换掉。
- 参数:
- strCookie 一个Cookie项,格式如下:
- "name=value; path=/; domain=host.com"
- path或domain属性可以没有。
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int AddCookie(string strCookie);
- /**************************************************************************
- 获取Cookies字符串
- 参数:
- bOnlyNameValue 是否只需要Cookie名和值属性,剔除path和domain属性。
- 返回:
- 当前Cookies字符串,格式为:
- bOnlyNameValue为false时:
- "name1=value1; path=/; domain=host.com;; name2=value2; path..."
- Cookie项的属性之间,用;分隔。Cookie项与项之间,用;;分隔。
- bOnlyNameValue为true时:
- "name1=value1; name2=value2; name3=value3;..."
- Cookie项与项之间,用;分隔。
- **************************************************************************/
- string GetCookies(bool bOnlyNameValue = false);
- /**************************************************************************
- 设置Cookies
- 参数:
- strCookies Cookies字符串,格式为:
- "name1=value1; name2=value2;...",或者
- "name1=value1; path=/; domain=.com;; name2=value2; ..."
- 不带path和domain属性时,Cookie项之间用;分隔。
- 带path和domain属性时,Cookie项之间用;;分隔。
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int SetCookies(string strCookies);
- /**************************************************************************
- 设置编码方式
- 参数:
- uiCodePage 编码方式。
- CP_ACP为常用的GB2312编码
- CP_UTF8为常用的UTF8编码
- **************************************************************************/
- void SetCodePage(UINT uiCodePage);
- /**************************************************************************
- 清除DNS缓存
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int ClearDNS(void);
- //内部操作
- private:
- /**************************************************************************
- 执行HTTP操作
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _Execute(void);
- /**************************************************************************
- 获取HTML字符串
- 参数:
- strHTML 返回值。获取到的HTML字符串。
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _GetHTMLStr(string & strHTML);
- /**************************************************************************
- 分解URL
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _ParseURL(void);
- /**************************************************************************
- 连接服务器
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _ConnServer(void);
- /**************************************************************************
- 发送数据
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _SendData(void);
- /**************************************************************************
- 接收数据
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _RecvData(void);
- /**************************************************************************
- 剔除响应数据的头部
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _RejectHeader(void);
- /**************************************************************************
- 提取响应数据的Cookies
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _GetResponseCookies(void);
- /**************************************************************************
- 接收响应数据
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _RecvResponseData(void);
- /**************************************************************************
- 一次一次接收数据
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _RecvEachData(void);
- /**************************************************************************
- 是否结束接收
- 返回:
- 结束接收返回true,否则返回false。
- **************************************************************************/
- bool _IsEndRecv(void);
- /**************************************************************************
- 获取响应数据正文长度
- **************************************************************************/
- void _GetBodyLen(void);
- /**************************************************************************
- 开始访问
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _StartVisit(void);
- /**************************************************************************
- 开始访问
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _StartVisitFile(void);
- /**************************************************************************
- 结束访问
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _EndVisit(void);
- /**************************************************************************
- 把数据转换成字符串
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _TransDataToStr(void);
- /**************************************************************************
- 把接收到的字符串编码转换
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _EncodeRecvStr(void);
- /**************************************************************************
- 检测等待字符串是否出现
- 返回:
- 出现了返回true,否则返回false。
- **************************************************************************/
- bool _CheckWaitStr(void);
- /**************************************************************************
- 编码POST数据
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _EncodePostData(void);
- /**************************************************************************
- 获取IP地址
- 参数:
- strIP 返回值。IP地址字符串。
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _GetIPStr(wstring & strIP);
- /**************************************************************************
- 编码转换
- 参数:
- strTrans 返回值。源字符串、目标字符串。
- uiDstCodePage 目标编码
- uiSrcCodePage 源编码
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _TransCodePage(string & strTrans
- , UINT uiDstCodePage, UINT uiSrcCodePage);
- /**************************************************************************
- 构造请求头
- 返回:
- 构造好的请求头。
- **************************************************************************/
- string _MakeHeader(void);
- /**************************************************************************
- 截取URL的协议部分
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _CutURLPtl(void);
- /**************************************************************************
- 截取URL的域名部分
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _CutURLDomain(void);
- /**************************************************************************
- 处理域名中包含端口号的情况
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _ProcessDomainPort(void);
- /**************************************************************************
- 截取URL的路径部分
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _CutURLPath(void);
- /**************************************************************************
- 生成Cookies串
- 返回:
- 用于HTTP请求的Cookies串
- **************************************************************************/
- string _MakeCookiesString(void);
- /**************************************************************************
- 判断这条Cookie是否匹配域名和路径属性
- 参数:
- sCookie 要判断的Cookie
- 返回:
- 匹配返回true,不匹配返回false。
- **************************************************************************/
- bool _IsCookieMatch(HTTP::SCookie const & sCookie);
- /**************************************************************************
- 截取字符串
- 参数:
- strSource 源字符串。空格会全部剔除。
- strHead 头定位字符串。空串,则代表从源字符串最前面开始截取。
- strTail 尾定位字符串。空串,则代表截取到源字符串最后面。
- 返回:
- 截取的字符串。
- **************************************************************************/
- string _CutStr(string strSource, string strHead, string strTail);
- /**************************************************************************
- 定位字符串
- 参数:
- nPos 返回值。字符串的起始位置。
- nLen 返回值。字符串的长度。
- strSourceLow 源字符串,全小写。
- strHeadLow 头定位字符串,全小写。
- strTailLow 尾定位字符串,全小写。
- 返回:
- 定位成功返回true,定位失败返回false。
- **************************************************************************/
- bool _PosStr(string::size_type & nPos, string::size_type & nLen,
- string strSourceLow, string strHeadLow, string strTailLow);
- /**************************************************************************
- 判断这条Cookie路径是否匹配
- 参数:
- strCookiePath 需要判断的Cookie路径
- 返回:
- 匹配返回true,不匹配返回false。
- **************************************************************************/
- bool _IsCookiePathMatch(string strCookiePath);
- /**************************************************************************
- 判断这条Cookie域名是否匹配
- 参数:
- strCookieDomain 需要判断的Cookie域名
- 返回:
- 匹配返回true,不匹配返回false。
- **************************************************************************/
- bool _IsCookieDomainMatch(string strCookieDomain);
- /**************************************************************************
- 判断这条Cookie路径的后面是否匹配,防止/a与/ab匹配的情况。
- 参数:
- strCookiePath 需要判断的Cookie路径
- 返回:
- 匹配返回true,不匹配返回false。
- **************************************************************************/
- bool _IsCookiePathMatchNext(string strCookiePath);
- /**************************************************************************
- 字符串替换
- 参数:
- strReplace 返回值。源字符串、替换后的字符串。
- strOld 要替换的字符串
- strNew 替换成的字符串
- **************************************************************************/
- void _ReplaceString(string & strReplace, string strOld, string strNew);
- /**************************************************************************
- 分解Cookie字符串
- 参数:
- sCookie 返回值。Cookie结构体。
- strCookie Cookie字符串
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _ParseCookieStr(HTTP::SCookie & sCookie, string strCookie);
- /**************************************************************************
- 添加一个Cookie项
- 参数:
- sCookie 一个Cookie项
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _AddCookie(HTTP::SCookie const & sCookie);
- /**************************************************************************
- 查找Cookie项是否已经存在Cookies表中
- 参数:
- sCookie Cookie项。
- 返回:
- 存在则返回Cookies表下标,不存在返回-1。
- **************************************************************************/
- int _FindCookie(HTTP::SCookie const & sCookie);
- /**************************************************************************
- 分割字符串
- 参数:
- listStr 返回值。分割后的字符串列表。
- strSrc 源字符串
- strSplit 分割符
- **************************************************************************/
- void _SplitStr(vector<string> & listStr, string strSrc, string strSplit);
- /**************************************************************************
- 小写字符串
- 参数:
- strLower 返回值。源字符串、转换成小写后的字符串。
- **************************************************************************/
- void _ToLower(string & strLower);
- /**************************************************************************
- 启动并创建套接字
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _StartupCreateSocket(void);
- /**************************************************************************
- 填写地址信息
- 参数:
- addr 返回值。地址信息。
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _FillAddrInfo(sockaddr_in & addr);
- /**************************************************************************
- 带超时的连接
- 参数:
- addr 地址信息
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _ConnWithTimeout(sockaddr_in const & addr);
- /**************************************************************************
- 使用select实现超时
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _SelectTimeout(void);
- /**************************************************************************
- 设置套接字的超时
- 返回:
- 成功返回0,失败返回错误码。
- **************************************************************************/
- int _SetSocketTimeout(void);
- //内部数据
- private:
- string m_strURL; //URL地址
- string m_strHeader; //请求头信息
- bool m_bPost; //是否需要POST数据
- string m_strPostData; //POST数据
- std::vector<CInputFiled*> *m_inputs; //post数据
- string m_strWait; //等待字符串
- bool m_bNeedHeader; //是否需要响应头信息
- UINT m_uiCodePage; //编码方式
- string m_strPtl; //协议
- string m_strDomain; //域名
- string m_strPath; //路径
- unsigned short m_nPort; //端口
- string::size_type m_nPtlTailPos; //URL协议尾部符号://的位置
- string::size_type m_nDomainTailPos; //URL域名尾部符号/的位置
- int m_nConnTimeout; //连接超时
- int m_nSendTimeout; //发送超时
- int m_nRecvTimeout; //接收超时
- int m_nConnTimeoutBak; //连接超时,备份
- int m_nSendTimeoutBak; //发送超时,备份
- int m_nRecvTimeoutBak; //接收超时,备份
- vector<HTTP::SCookie> m_listCookies; //Cookies表
- char * m_pchRecvData; //接收到的数据指针
- int m_nDataSize; //接收到的数据大小
- string m_strRecvData; //转换成字符串的数据
- int m_nHeaderLen; //响应头长度
- int m_nBodyLen; //正文长度
- static CDNSMap m_mapDNS; //DNS缓存表
- bool m_bStartup; //启动套接字是否成功
- SOCKET m_socket; //套接字
- };
|