Bläddra i källkod

WINHTTP库封装示例。

JeffWang 3 år sedan
förälder
incheckning
c0de238820

BIN
WINHTTPS/HttpGetPostDemo.7z


+ 25 - 0
WINHTTPS/WINHTTPS-17.sln

@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.1.32328.378
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WINHTTPS", "WINHTTPS\WINHTTPS.vcxproj", "{6DBF8756-04C2-4D25-A1BC-9DD27F45D5FA}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{6DBF8756-04C2-4D25-A1BC-9DD27F45D5FA}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6DBF8756-04C2-4D25-A1BC-9DD27F45D5FA}.Debug|Win32.Build.0 = Debug|Win32
+		{6DBF8756-04C2-4D25-A1BC-9DD27F45D5FA}.Release|Win32.ActiveCfg = Release|Win32
+		{6DBF8756-04C2-4D25-A1BC-9DD27F45D5FA}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {BFF4D0F5-8E9B-45E8-98CE-5570F068AA27}
+	EndGlobalSection
+EndGlobal

+ 20 - 0
WINHTTPS/WINHTTPS.sln

@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WINHTTPS", "WINHTTPS\WINHTTPS.vcproj", "{6DBF8756-04C2-4D25-A1BC-9DD27F45D5FA}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{6DBF8756-04C2-4D25-A1BC-9DD27F45D5FA}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6DBF8756-04C2-4D25-A1BC-9DD27F45D5FA}.Debug|Win32.Build.0 = Debug|Win32
+		{6DBF8756-04C2-4D25-A1BC-9DD27F45D5FA}.Release|Win32.ActiveCfg = Release|Win32
+		{6DBF8756-04C2-4D25-A1BC-9DD27F45D5FA}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 295 - 0
WINHTTPS/WINHTTPS/HTTPDef.h

@@ -0,0 +1,295 @@
+#pragma once
+
+#ifndef _MSVC_LANG
+#define _MSVC_LANG 1997L
+#endif
+
+#define CRLF L"\r\n"
+#define CONTENT_LENGTH L"Content-Length: "
+#define CONTENT_TYPE L"Content-Type: "
+#define BOUNDARY L"----WebKitFormBoundary7MA4YWxkTrZu0gW"
+#define FORMDATAHEADER L"Content-Type:multipart/form-data;boundary="##BOUNDARY
+#define FORMURLENCODEDDATAHEADER L"Content-Type:application/x-www-form-urlencoded"
+#define FORMDATA_FILE_FORMAT L"------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"%s\"; %s=\"%s\"\r\nContent-Type: %s\r\n"
+/*
+e.g.
+------WebKitFormBoundary7MA4YWxkTrZu0gW
+Content-Disposition: form-data; name=filename
+filename=D:\1.jpg
+Content-Type:image/gif
+
+*/
+
+#define FORMDATA_TEXT_FORMAT L"------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"%s\";\r\n\r\n%s=\"%s\"\r\n"
+/*
+e.g.
+------WebKitFormBoundary7MA4YWxkTrZu0gW
+Content-Disposition: form-data; name=username
+
+username=superman
+
+*/
+
+#define FORMDATA_URLENCODED_FORMAT L"------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: application/x-www-form-urlencoded\r\nContent-Length=\"%d\";\r\n\r\n%s=\"%s\"\r\n"
+/*
+e.g.
+------WebKitFormBoundary7MA4YWxkTrZu0gW
+Content-Disposition: form-data; name=username
+
+username=superman
+
+*/
+
+typedef enum {
+	RTYPE_STRING,
+	RTYPE_BYTE
+}ResultType;
+
+typedef enum {
+	DTYPE_STRING,
+	DTYPE_BYTE,
+	DTYPE_PATH
+}PostDataType;
+
+typedef enum{
+	CTYPE_STRING,
+	CTYPE_COOKIE
+}ResultCookieType;
+
+typedef struct HTTPItem
+{
+#if _MSVC_LANG >= 201402L // C++14
+	std::string url;
+	std::string host;
+	std::string Method = "GET";
+	// 请求超时时间;
+	DWORD	Timeout=10000;
+	// 读写超时时间;
+	DWORD ReadWriteTimeout=30000;
+	// 连接鲜活标记;
+	BOOL KeepAlive=TRUE;
+	// 请求的标记头;
+	std::string Accept="text/html, application/xhtml+xml, */*";
+	// 请求返回类型;
+	std::string ContentType= "text/html";
+	// 客户端访问信息;
+	std::string UserAgent= "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)";
+	// 返回数据的编码;
+	std::string Encoding;
+	// Post的数据类型;
+	std::string PostDataType;
+	// Post请求时要发送的数据;
+	std::string PostData;
+	// Cookie对象集合;
+	std::string CookieCollection;
+	// 请求时的Cookie;
+	std::string Cookie;
+	// 来源地址,上次访问的地址;
+	std::string Referer;
+	// 证书绝对路径;
+	std::string CerPath;
+	// 设置代理对象;
+	WINHTTP_CURRENT_USER_IE_PROXY_CONFIG WebProxy;
+	// 是否设置全文小写;
+	BOOL isToLower=FALSE;
+	// 获取或设置要在HTTP 请求中使用的Date HTTP标头值;
+	SYSTEMTIME Date;
+	// 支持跳转页面,查询结果将是跳转后的页面;
+	BOOL AllowAutoRedirect=FALSE;
+	// 最大连接数;
+	DWORD ConnectionLimit;
+	// 代理服务器用户名;
+	std::string ProxyUserName;
+	// 代理服务器密码;
+	std::string ProxyPwd;
+	// 代理服务器IP;
+	std::string ProxyIP;
+	// 设置返回类型String和Byte;
+	std::string ResultType;
+	// HTTP请求头Header对象;
+	std::string Header;
+	// 获取或设置用于请求的 HTTP 版本。返回结果:用于请求的 HTTP 版本。默认为 System.Net.HttpVersion.Version11
+	HTTP_VERSION_INFO ProtocolVersion;
+	// 获取或设置一个 System.Boolean 值,该值确定是否使用 100-Continue 行为。如果 POST 请求需要 100-Continue 响应,则为 true;否则为 false。默认值为 true
+	BOOL Expect100Continue=FALSE;
+	// 设置509证书集合;
+	std::string ClentCertificates;
+	// 设置或获取Post参数编码,默认的为Default编码;
+	std::string PostEncoding;
+	// Cookie返回类型,默认的是只返回字符串类型;
+	std::string ResultCookieType;
+	// 获取或设置请求的身份验证信息
+	std::string ICredentials;
+	// 设置请求将跟随的重定向的最大数目
+	DWORD MaximumAutomaticRedirections;
+	// 获取和设置IfModifiedSince,默认为当前日期和时间;
+	tm IfModifiedSince;
+	// 是否重置request,response的值,默认不重置,当设置为True时request,response将被设置为Null;
+	bool IsReset=FALSE;
+	// 设置本地的出口IP和端口;
+	std::string IPEndPoint;
+#else
+	std::wstring m_strUrl;
+	std::wstring m_strHost;
+	std::wstring m_strDomain;
+	std::wstring m_strApiName;
+	DWORD m_dwPort;
+	int m_nScheme;//HTTP/HTTPS;
+	std::wstring m_strMethod; // GET/POST/HEAD/PUT……;
+	// 客户端访问信息;
+	std::wstring m_strUserAgent;
+	// 连接鲜活标记;
+	BOOL m_bKeepAlive;
+	// 请求的标记头;
+	std::wstring m_strAccept;
+	// 请求返回类型;
+	std::wstring m_strContentType;	
+
+#pragma region 超时值设置;
+	// 域名解析超时值,默认值为0,表示无穷大;
+	int	m_nResolveTimeout;
+	// 请求连接超时值,初始值为60秒;
+	int m_nConnectTimeout;
+	// 默认30秒;
+	int m_nSendTimeout;
+	// 默认30秒;
+	int m_nReceiveTimeout;
+	// 要求有效的ssl连接;
+	bool m_brequireValidSSL;
+#pragma endregion
+
+#pragma region 代理设置;	
+	// 代理服务器用户名;
+	std::wstring m_strProxyUserName;
+	// 代理服务器密码;
+	std::wstring m_strProxyPwd;
+	// 代理服务器列表;
+	std::wstring m_strProxyServerList;
+#pragma endregion
+
+#pragma region Cookie设置;
+	// Cookie对象集合;
+	std::wstring m_strCookieCollection;
+	// 请求时的Cookie;
+	std::wstring m_strCookies;
+#pragma endregion
+
+#pragma region 证书;
+
+#pragma endregion
+
+	
+	// 返回数据的编码;
+	std::wstring m_strEncoding;
+	// Post的数据类型;
+	std::wstring m_strPostDataType;
+	// Post请求时要发送的数据;
+	std::wstring m_strPostData;	
+	// 来源地址,上次访问的地址;
+	std::wstring m_strReferer;
+	// 证书绝对路径;
+	std::wstring m_strCerPath;
+	// 设置代理对象,不想使用IE默认配置就设置为Null,而且不要设置ProxyIp
+	WINHTTP_CURRENT_USER_IE_PROXY_CONFIG m_WebProxy;
+	// 是否设置全文小写;
+	BOOL m_bIsToLower;
+	// 获取或设置要在HTTP 请求中使用的Date HTTP标头值;
+	SYSTEMTIME m_Date;
+	// 支持跳转页面,查询结果将是跳转后的页面;
+	BOOL m_bAllowAutoRedirect;
+	// 最大连接数;
+	DWORD m_dwConnectionLimit;	
+	// 设置返回类型String和Byte;
+	std::string m_strResultType;
+	// HTTP请求头Header对象,多个头使用\r\n分隔;
+	std::wstring m_strHeader;
+	// 获取或设置用于请求的 HTTP 版本。返回结果:用于请求的 HTTP 版本。默认为 System.Net.HttpVersion.Version11
+	HTTP_VERSION_INFO m_ProtocolVersion;
+	// 获取或设置一个 System.Boolean 值,该值确定是否使用 100-Continue 行为。如果 POST 请求需要 100-Continue 响应,则为 true;否则为 false。默认值为 true
+	BOOL m_bExpect100Continue;
+	// 设置509证书集合;
+	std::wstring m_strClentCertificates;
+	// 设置或获取Post参数编码,默认的为Default编码;
+	std::wstring m_strPostEncoding;
+	// Cookie返回类型,默认的是只返回字符串类型;
+	std::wstring m_strResultCookieType;
+	// 获取或设置请求的身份验证信息
+	std::wstring m_strICredentials;
+	// 设置请求将跟随的重定向的最大数目
+	DWORD m_dwMaximumAutomaticRedirections;
+	// 获取和设置IfModifiedSince,默认为当前日期和时间;
+	SYSTEMTIME m_IfModifiedSince;
+	// 是否重置request,response的值,默认不重置,当设置为True时request,response将被设置为Null;
+	bool m_bIsReset;
+	// 设置本地的出口IP和端口;
+	std::wstring m_strIPEndPoint;
+	// 表单数据;
+	std::wstring m_strFormData;
+	// 查询参数;
+	std::wstring m_strQueryParams;
+
+	HTTPItem() {
+		// 默认请求类型GET;
+		m_strMethod = L"GET";
+		// 域名解析超时值,默认0秒表示无穷大;
+		m_nResolveTimeout = 0;
+		// 请求连接超时值60秒;
+		m_nConnectTimeout = 60000;
+		// 发送超时值,默认30秒;
+		m_nSendTimeout = 30000;
+		// 接收超时值,默认30秒;
+		m_nReceiveTimeout = 30000;
+		// 默认连接鲜活;
+		m_bKeepAlive = TRUE;
+		// 默认请求头值;
+		m_strAccept = L"text/html, application/xhtml+xml, */*";
+		// 默认返回类型;
+		m_strContentType = L"text/html";
+		// 默认客户端访问信息值;
+		m_strUserAgent = L"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)";
+		// 返回数据默认编码类型utf-8;
+
+		// 默认不转小写;
+		m_bIsToLower = FALSE;
+		// 默认不跳转;
+		m_bAllowAutoRedirect = FALSE;
+		// 默认不继续;
+		m_bExpect100Continue = FALSE;
+		m_bIsReset = FALSE;
+
+		m_ProtocolVersion.dwMajorVersion=1;
+		m_ProtocolVersion.dwMinorVersion=0;
+	}
+#endif
+}HTTPITEM, *LPHTTPITEM;
+
+
+
+typedef struct HTTPResult
+{
+	std::wstring m_strHeader;
+	// Http请求返回的Cookie;
+	std::wstring m_strCookie;
+	// Cookie对象集合;
+	std::wstring m_strCookieCollection;
+	// 返回的Http内容;
+	std::wstring m_strHtml;
+	// 返回状态说明;
+	std::wstring m_strStatusDescription;
+	// 返回的状态码;
+	DWORD m_dwStatusCode;
+	// 最后访问的URL;
+	std::wstring m_strResponseUri;
+	// 获取重定向的URL;
+	std::wstring m_strRedirectUrl;
+	std::wstring m_strCharset;
+	DWORD m_dwByteCount;
+	std::wstring m_strLocation;
+
+	std::string m_strResponseData;
+
+	HTTPResult()
+	{
+	}
+
+}HTTPRESULT, *LPHTTPRESULT ;

+ 944 - 0
WINHTTPS/WINHTTPS/HTTPHelper - 副本 (2).cpp

@@ -0,0 +1,944 @@
+#include "StdAfx.h"
+#include "HTTPHelper.h"
+
+HTTPHelper::HTTPHelper(void):m_hSession(NULL),m_hConnect(NULL),m_hRequest(NULL),m_nRetryTimes(3)
+{
+}
+
+HTTPHelper::~HTTPHelper(void)
+{
+}
+
+bool HTTPHelper::UrlParse(std::wstring strUrl)
+{
+	int nPos = 0;
+	std::wstring strSub;
+	if (strUrl.size()) m_strUrl = strUrl;
+	wchar_t* magic[] = { L"https://", L"http://", NULL };
+	if ( m_strUrl.find(magic[0]) != std::wstring::npos || m_strUrl.find(magic[1]) != std::wstring::npos ) {
+		if (m_strUrl.find(magic[0]) != std::wstring::npos) {
+			m_dwPort = 443;
+			m_nScheme=INTERNET_SCHEME_HTTPS;
+			strSub = m_strUrl.substr(8);			
+		} else {
+			m_dwPort = 80;
+			m_nScheme=INTERNET_SCHEME_HTTP;
+			strSub = m_strUrl.substr(7);
+		}
+
+		if ( (nPos = strSub.find(L"/")) != std::wstring::npos ) {
+			m_strDomain = strSub.substr(0, nPos);
+			m_strApiName = strSub.substr(nPos);
+		} else {
+			m_strDomain = strSub;
+			m_strApiName = L"/";
+		}
+
+		if ( (nPos = m_strDomain.find(L":")) != std::wstring::npos ) {
+			m_strHost = m_strDomain.substr(0, nPos);
+			m_dwPort = _wtol(m_strDomain.substr(nPos+1).c_str());
+		} else {
+			m_strHost = m_strDomain;
+		}
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+bool HTTPHelper::GetHtml(HTTPITEM &item, HTTPRESULT &result)
+{
+	if ( !SendRequest(item,result) )
+		return false;
+
+	return true;
+}
+
+BOOL HTTPHelper::_OpenHTTP()
+{
+	DWORD dwError(0);
+	if ( m_hSession == NULL ) {
+		// 创建会话;
+		m_hSession = WinHttpOpen(
+			m_strUserAgent.c_str(),
+			WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
+			WINHTTP_NO_PROXY_NAME, 
+			WINHTTP_NO_PROXY_BYPASS,
+			0);
+
+		if ( m_hSession == NULL ) {
+			dwError = GetLastError();
+			return FALSE;
+		}
+
+		// 设置超时值;
+		if ( !_SetTimeout() ) {
+			return FALSE;
+		}
+
+		// 连接服务器;
+		m_hConnect = WinHttpConnect(m_hSession, m_strHost.c_str(), m_dwPort, 0);
+		if ( m_hConnect == NULL) {
+			dwError = GetLastError();
+			return FALSE;
+		}
+
+		std::wstring strObjctName = m_strApiName;
+		if ( m_strQueryParams.size() ) {
+			strObjctName.append(L"?");
+			strObjctName.append(m_strQueryParams);
+		}
+
+		// 请求类型:是否是https;
+		DWORD dwOpenRequestFlag = (m_nScheme == INTERNET_SCHEME_HTTPS) ? WINHTTP_FLAG_SECURE : 0;
+		m_hRequest = WinHttpOpenRequest(m_hConnect, 
+			m_strMethod.c_str(), 
+			strObjctName.c_str(),
+			NULL,
+			WINHTTP_NO_REFERER,
+			WINHTTP_DEFAULT_ACCEPT_TYPES,
+			dwOpenRequestFlag);
+
+		if ( m_hRequest == NULL ) {
+			dwError = GetLastError();
+			return FALSE;
+		}
+
+		// 如果是https,那么客户端就很容易受到无效证书的影响,现在接受任何事情都是最容易的
+		if ( m_brequireValidSSL && m_nScheme == INTERNET_SCHEME_HTTPS ) {
+			DWORD dwOps = SECURITY_FLAG_IGNORE_CERT_CN_INVALID
+				| SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
+				| SECURITY_FLAG_IGNORE_UNKNOWN_CA
+				| SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
+			WinHttpSetOption(m_hRequest, WINHTTP_OPTION_SECURITY_FLAGS, &dwOps, sizeof(DWORD));
+		}
+	}
+
+	return TRUE;
+}
+
+BOOL HTTPHelper::_SendRequestData()
+{
+	DWORD dwError(0);
+	BOOL bGetResponseSucceed=FALSE;
+	while ( !bGetResponseSucceed && m_nRetryTimes-- > 0 )
+	{
+		// 是否有请求头;
+		if ( !_SetRequestHeaders() ) {
+			continue;
+		}
+
+		// 是否有Cookie;
+		if ( !_SetCookies() ) {
+			continue;
+		}
+
+		// 是否有代理服务器;
+		if ( !_SetProxy() ) {
+			continue;
+		}
+
+		// 是否关闭自动重定向;
+		if ( !_SetAutoRedirect() ) {
+			continue;
+		}
+
+		// 发送请求;
+		bool bSendRequestSucceed = false;
+		//if (::WinHttpSendRequest(m_hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, NULL, (LPVOID)m_strPostData.c_str(), m_strPostData.size()*sizeof(wchar_t), m_strPostData.size()*sizeof(wchar_t), NULL))
+		if (::WinHttpSendRequest(m_hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, NULL, WINHTTP_NO_REQUEST_DATA, 0, _GetSendRequestSize(), NULL))
+		{
+			bSendRequestSucceed = true;
+		}
+		else
+		{
+			// 从IE设置中查询代理信息,如果有代理,设置代理;
+			WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig;
+			memset(&proxyConfig, 0, sizeof(proxyConfig));
+			if (::WinHttpGetIEProxyConfigForCurrentUser(&proxyConfig))
+			{
+				if (proxyConfig.lpszAutoConfigUrl != NULL)
+				{
+					WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions;
+					memset(&autoProxyOptions, 0, sizeof(autoProxyOptions));
+					autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL;
+					autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP;
+					autoProxyOptions.lpszAutoConfigUrl = proxyConfig.lpszAutoConfigUrl;
+					autoProxyOptions.fAutoLogonIfChallenged = TRUE;
+					autoProxyOptions.dwReserved = 0;
+					autoProxyOptions.lpvReserved = NULL;
+
+					WINHTTP_PROXY_INFO proxyInfo;
+					memset(&proxyInfo, 0, sizeof(proxyInfo));
+
+					if (::WinHttpGetProxyForUrl(m_hSession, m_strUrl.c_str(), &autoProxyOptions, &proxyInfo))
+					{
+						if (::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo)))
+						{
+							if (::WinHttpSendRequest(m_hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, NULL))
+							{
+								bSendRequestSucceed = true;
+							}
+						}
+						if (proxyInfo.lpszProxy != NULL)
+						{
+							::GlobalFree(proxyInfo.lpszProxy);
+						}
+						if (proxyInfo.lpszProxyBypass != NULL)
+						{
+							::GlobalFree(proxyInfo.lpszProxyBypass);
+						}
+					}
+					else
+					{
+						dwError = ::GetLastError();
+					}
+				}
+				else if (proxyConfig.lpszProxy != NULL)
+				{
+					WINHTTP_PROXY_INFO proxyInfo;
+					memset(&proxyInfo, 0, sizeof(proxyInfo));
+					proxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
+					wchar_t szProxy[MAX_PATH] = L"";
+					wcscpy_s(szProxy, MAX_PATH, proxyConfig.lpszProxy);
+					proxyInfo.lpszProxy = szProxy;
+
+					if (proxyConfig.lpszProxyBypass != NULL)
+					{
+						wchar_t szProxyBypass[MAX_PATH] = L"";
+						wcscpy_s(szProxyBypass, MAX_PATH, proxyConfig.lpszProxyBypass);
+						proxyInfo.lpszProxyBypass = szProxyBypass;
+					}
+
+					if (!::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo)))
+					{
+						dwError = ::GetLastError();
+					}
+				}
+
+				if (proxyConfig.lpszAutoConfigUrl != NULL)
+				{
+					::GlobalFree(proxyConfig.lpszAutoConfigUrl);
+				}
+				if (proxyConfig.lpszProxy != NULL)
+				{
+					::GlobalFree(proxyConfig.lpszProxy);
+				}
+				if (proxyConfig.lpszProxyBypass != NULL)
+				{
+					::GlobalFree(proxyConfig.lpszProxyBypass);
+				}
+			}
+			else
+			{
+				dwError = ::GetLastError();
+			}
+		}
+
+		if (bSendRequestSucceed)
+		{
+			// 有FormData数据要上传;
+			if ( m_strFormData.size() != 0 )
+			{
+				DWORD dwWritten = 0;
+				if (!::WinHttpWriteData(m_hRequest, m_strFormData.c_str(), m_strFormData.size()*sizeof(wchar_t), &dwWritten))
+				{
+					dwError = ::GetLastError();
+					continue;
+				}
+			}
+
+			// 有PostData数据要上传;
+			if ( m_strPostData.size() != 0 )
+			{
+				DWORD dwWritten = 0;
+				if (!::WinHttpWriteData(m_hRequest, m_strPostData.c_str(), m_strPostData.size()*sizeof(wchar_t), &dwWritten))
+				{
+					dwError = ::GetLastError();
+					continue;
+				}
+			}
+		}
+
+		bGetResponseSucceed = TRUE;
+	}	
+
+	return bGetResponseSucceed;
+}
+
+BOOL HTTPHelper::_ReceiveResponse(std::wstring &strHeaer, DWORD &dwStatusCode, std::string &strResponseData)
+{
+	DWORD dwError(0);
+	if (::WinHttpReceiveResponse(m_hRequest, NULL))
+	{
+		DWORD dwSize = 0;
+		BOOL bResult = FALSE;
+		// 获取返回头;
+		bResult = ::WinHttpQueryHeaders(m_hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &dwSize, WINHTTP_NO_HEADER_INDEX);
+		if (bResult || (!bResult && (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)))
+		{
+			if ( dwSize < K0 )
+			{
+				wchar_t szHeader[K0] = {0};
+				if (::WinHttpQueryHeaders(m_hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, szHeader, &dwSize, WINHTTP_NO_HEADER_INDEX))
+				{
+					strHeaer.assign(szHeader);
+				}
+			}
+			else if ( dwSize < K1 )
+			{
+				wchar_t szHeader[K1] = {0};
+				if (::WinHttpQueryHeaders(m_hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, szHeader, &dwSize, WINHTTP_NO_HEADER_INDEX))
+				{
+					strHeaer.assign(szHeader);
+				}
+			}			
+		}
+
+		dwSize = 0;
+		bResult = ::WinHttpQueryHeaders(m_hRequest, WINHTTP_QUERY_STATUS_CODE, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &dwSize, WINHTTP_NO_HEADER_INDEX); 
+		if (bResult || (!bResult && (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)))
+		{
+			wchar_t szStatusCode[MAX_PATH] = {0};
+			if (::WinHttpQueryHeaders(m_hRequest, WINHTTP_QUERY_STATUS_CODE, WINHTTP_HEADER_NAME_BY_INDEX, szStatusCode, &dwSize, WINHTTP_NO_HEADER_INDEX))
+			{
+				dwStatusCode = _wtol(szStatusCode);
+			}
+		}
+
+
+		do
+		{
+			dwSize = 0;
+			if (::WinHttpQueryDataAvailable(m_hRequest, &dwSize))
+			{
+				//SetProgress(iCurrentBufferSize);
+				DWORD dwRead = 0;
+				BYTE szReadData[K1] = {0};	// 每次读取1K;
+				if (::WinHttpReadData(m_hRequest, szReadData, K1, &dwRead))
+				{
+					strResponseData.append(szReadData, dwRead);
+				}
+			} else {
+				dwError = ::GetLastError();
+			}
+		}
+		while (dwSize > 0);
+		//SetProgress(iCurrentBufferSize);
+	}
+	else
+	{
+		dwError = ::GetLastError();
+	}
+
+	return TRUE;
+}
+
+bool HTTPHelper::SendRequest(HTTPITEM &item,HTTPRESULT &httpResult)
+{
+	DWORD dwError = -1;
+	if ( m_hSession == NULL ) {
+		if (!_OpenHTTP())
+			return false;
+
+		bool bGetResponseSucceed=false;
+		while ( !bGetResponseSucceed && m_nRetryTimes-- > 0 )
+		{
+			// 是否有请求头;
+			if ( !_SetRequestHeaders() ) {
+				continue;
+			}
+
+			// 是否有Cookie;
+			if ( !_SetCookies() ) {
+				continue;
+			}
+
+			// 是否有代理服务器;
+			if ( !_SetProxy() ) {
+				continue;
+			}
+
+			// 是否关闭自动重定向;
+			if ( !_SetAutoRedirect() ) {
+				continue;
+			}
+
+			// 发送请求;
+			bool bSendRequestSucceed = false;
+			//if (::WinHttpSendRequest(m_hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, NULL, (LPVOID)m_strPostData.c_str(), m_strPostData.size()*sizeof(wchar_t), m_strPostData.size()*sizeof(wchar_t), NULL))
+			if (::WinHttpSendRequest(m_hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, NULL, WINHTTP_NO_REQUEST_DATA, 0, _GetSendRequestSize(), NULL))
+			{
+				bSendRequestSucceed = true;
+			}
+			else
+			{
+				// 从IE设置中查询代理信息,如果有代理,设置代理;
+				WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig;
+				memset(&proxyConfig, 0, sizeof(proxyConfig));
+				if (::WinHttpGetIEProxyConfigForCurrentUser(&proxyConfig))
+				{
+					if (proxyConfig.lpszAutoConfigUrl != NULL)
+					{
+						WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions;
+						memset(&autoProxyOptions, 0, sizeof(autoProxyOptions));
+						autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL;
+						autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP;
+						autoProxyOptions.lpszAutoConfigUrl = proxyConfig.lpszAutoConfigUrl;
+						autoProxyOptions.fAutoLogonIfChallenged = TRUE;
+						autoProxyOptions.dwReserved = 0;
+						autoProxyOptions.lpvReserved = NULL;
+
+						WINHTTP_PROXY_INFO proxyInfo;
+						memset(&proxyInfo, 0, sizeof(proxyInfo));
+
+						if (::WinHttpGetProxyForUrl(m_hSession, m_strUrl.c_str(), &autoProxyOptions, &proxyInfo))
+						{
+							if (::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo)))
+							{
+								if (::WinHttpSendRequest(m_hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, NULL))
+								{
+									bSendRequestSucceed = true;
+								}
+							}
+							if (proxyInfo.lpszProxy != NULL)
+							{
+								::GlobalFree(proxyInfo.lpszProxy);
+							}
+							if (proxyInfo.lpszProxyBypass != NULL)
+							{
+								::GlobalFree(proxyInfo.lpszProxyBypass);
+							}
+						}
+						else
+						{
+							dwError = ::GetLastError();
+						}
+					}
+					else if (proxyConfig.lpszProxy != NULL)
+					{
+						WINHTTP_PROXY_INFO proxyInfo;
+						memset(&proxyInfo, 0, sizeof(proxyInfo));
+						proxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
+						wchar_t szProxy[MAX_PATH] = L"";
+						wcscpy_s(szProxy, MAX_PATH, proxyConfig.lpszProxy);
+						proxyInfo.lpszProxy = szProxy;
+
+						if (proxyConfig.lpszProxyBypass != NULL)
+						{
+							wchar_t szProxyBypass[MAX_PATH] = L"";
+							wcscpy_s(szProxyBypass, MAX_PATH, proxyConfig.lpszProxyBypass);
+							proxyInfo.lpszProxyBypass = szProxyBypass;
+						}
+
+						if (!::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo)))
+						{
+							dwError = ::GetLastError();
+						}
+					}
+
+					if (proxyConfig.lpszAutoConfigUrl != NULL)
+					{
+						::GlobalFree(proxyConfig.lpszAutoConfigUrl);
+					}
+					if (proxyConfig.lpszProxy != NULL)
+					{
+						::GlobalFree(proxyConfig.lpszProxy);
+					}
+					if (proxyConfig.lpszProxyBypass != NULL)
+					{
+						::GlobalFree(proxyConfig.lpszProxyBypass);
+					}
+				}
+				else
+				{
+					dwError = ::GetLastError();
+				}
+			}
+
+			if (bSendRequestSucceed)
+			{
+				// 有FormData数据要上传;
+				if ( m_strFormData.size() != 0 )
+				{
+					DWORD dwWritten = 0;
+					if (!::WinHttpWriteData(m_hRequest, m_strFormData.c_str(), m_strFormData.size()*sizeof(wchar_t), &dwWritten))
+					{
+						dwError = ::GetLastError();
+					}
+				}
+
+				// 有PostData数据要上传;
+				if ( m_strPostData.size() != 0 )
+				{
+					DWORD dwWritten = 0;
+					if (!::WinHttpWriteData(m_hRequest, m_strPostData.c_str(), m_strPostData.size()*sizeof(wchar_t), &dwWritten))
+					{
+						dwError = ::GetLastError();
+					}
+				}
+
+				if (::WinHttpReceiveResponse(m_hRequest, NULL))
+				{
+					DWORD dwSize = 0;
+					BOOL bResult = FALSE;
+					// 获取返回头;
+					bResult = ::WinHttpQueryHeaders(m_hRequest,
+						WINHTTP_QUERY_RAW_HEADERS_CRLF,
+						WINHTTP_HEADER_NAME_BY_INDEX,
+						NULL,
+						&dwSize,
+						WINHTTP_NO_HEADER_INDEX);
+
+					if (bResult || (!bResult && (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)))
+					{
+						wchar_t *szHeader = new wchar_t[dwSize];
+						if (szHeader != NULL)
+						{
+							memset(szHeader, 0, dwSize* sizeof(wchar_t));
+							if (::WinHttpQueryHeaders(m_hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, szHeader, &dwSize, WINHTTP_NO_HEADER_INDEX))
+							{
+								httpResult.m_strHeader.assign(szHeader);
+							}
+							delete[] szHeader;
+						}
+					}
+
+					dwSize = 0;
+					bResult = ::WinHttpQueryHeaders(m_hRequest,
+						WINHTTP_QUERY_STATUS_CODE,
+						WINHTTP_HEADER_NAME_BY_INDEX,
+						NULL,
+						&dwSize,
+						WINHTTP_NO_HEADER_INDEX);
+					if (bResult || (!bResult && (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)))
+					{
+						wchar_t *szStatusCode = new wchar_t[dwSize];
+						if (szStatusCode != NULL)
+						{
+							memset(szStatusCode, 0, dwSize* sizeof(wchar_t));
+							if (::WinHttpQueryHeaders(m_hRequest,
+								WINHTTP_QUERY_STATUS_CODE,
+								WINHTTP_HEADER_NAME_BY_INDEX,
+								szStatusCode,
+								&dwSize,
+								WINHTTP_NO_HEADER_INDEX))
+							{
+								httpResult.m_dwStatusCode = _wtol(szStatusCode);
+							}
+							delete[] szStatusCode;
+						}
+					}
+
+					unsigned int iMaxBufferSize = 8912;
+					unsigned int iCurrentBufferSize = 0;
+					if (httpResult.m_pResponseData != NULL)
+					{
+						delete[] httpResult.m_pResponseData;
+						httpResult.m_pResponseData = NULL;
+					}
+					httpResult.m_pResponseData = new BYTE[iMaxBufferSize];
+					if (httpResult.m_pResponseData == NULL)
+					{
+						//bRetVal = false;
+						break;
+					}
+					memset(httpResult.m_pResponseData, 0, iMaxBufferSize);
+					do
+					{
+						dwSize = 0;
+						if (::WinHttpQueryDataAvailable(m_hRequest, &dwSize))
+						{
+							//SetProgress(iCurrentBufferSize);
+							BYTE *pResponse = new BYTE[dwSize + 1];
+							if (pResponse != NULL)
+							{
+								memset(pResponse, 0, (dwSize + 1)*sizeof(BYTE));
+								DWORD dwRead = 0;
+								if (::WinHttpReadData(m_hRequest, pResponse, dwSize, &dwRead))
+								{
+									if (dwRead + iCurrentBufferSize > iMaxBufferSize)
+									{
+										BYTE *pOldBuffer = httpResult.m_pResponseData;
+										httpResult.m_pResponseData = new BYTE[iMaxBufferSize * 2];
+										if (httpResult.m_pResponseData == NULL)
+										{
+											httpResult.m_pResponseData = pOldBuffer;
+											//bRetVal = false;
+											break;
+										}
+										iMaxBufferSize *= 2;
+										memset(httpResult.m_pResponseData, 0, iMaxBufferSize);
+										memcpy(httpResult.m_pResponseData, pOldBuffer, iCurrentBufferSize);
+										delete[] pOldBuffer;
+									}
+									memcpy(httpResult.m_pResponseData + iCurrentBufferSize, pResponse, dwRead);
+									iCurrentBufferSize += dwRead;
+								}
+								delete[] pResponse;
+							}
+						}
+						else
+						{
+							dwError = ::GetLastError();
+						}
+					}
+					while (dwSize > 0);
+					//SetProgress(iCurrentBufferSize);
+					httpResult.m_dwResponseSize = iCurrentBufferSize;
+
+					/*
+					UINT codePage = CP_ACP;
+					DWORD dwFlag = MB_PRECOMPOSED;
+					if (_wcsnicmp(m_responseCharset.c_str(), L"utf-8", 5) == 0)
+					{
+					codePage = CP_UTF8;
+					dwFlag = 0;
+					}
+					int iLength = ::MultiByteToWideChar(codePage, dwFlag, (LPCSTR)m_pResponse, m_responseByteCountReceived + 1, NULL, 0);
+					if (iLength <= 0)
+					{
+					// Use CP_ACP if UTF-8 fail
+					codePage = CP_ACP;
+					dwFlag = MB_PRECOMPOSED;
+					iLength = ::MultiByteToWideChar(codePage, dwFlag, (LPCSTR)m_pResponse, m_responseByteCountReceived + 1, NULL, 0);
+					}
+					if (iLength > 0)
+					{
+					wchar_t *wideChar = new wchar_t[iLength];
+					if (wideChar != NULL)
+					{
+					memset(wideChar, 0, iLength * sizeof(wchar_t));
+					iLength = ::MultiByteToWideChar(codePage, dwFlag, (LPCSTR)m_pResponse, m_responseByteCountReceived + 1, wideChar, iLength);
+					if (iLength > 0)
+					{
+					m_responseContent = wideChar;
+					}
+					delete[] wideChar;
+					}
+					}*/
+					bGetResponseSucceed = true;
+
+					/*
+					// If the resposne html web page size is less than 200, retry.
+					if (verb == L"GET" && !disableAutoRedirect)
+					{
+					wstring regExp = L"{<html>}";
+					vector<wstring> result;
+					if (ParseRegExp(regExp, false, 1, m_responseContent, result) && result.size() > 0)
+					{
+					regExp = L"{</html>}";
+					if (!ParseRegExp(regExp, false, 1, m_responseContent, result) || result.size() <= 0)
+					{
+					m_dwLastError = ERROR_INVALID_DATA;
+					bGetReponseSucceed = false;
+					}
+					}
+					}*/
+				}
+				else
+				{
+					dwError = ::GetLastError();
+				}
+			}
+
+		}
+	}
+
+	return true;
+}
+
+bool HTTPHelper::SetCer(HTTPITEM &item)
+{
+	return true;
+}
+
+BOOL HTTPHelper::_SetTimeout()
+{
+	if ( m_hSession == NULL )
+		return FALSE;
+
+	BOOL bRet = WinHttpSetTimeouts(m_hSession, m_nResolveTimeout, m_nConnectTimeout, m_nSendTimeout, m_nReceiveTimeout);
+	if ( !bRet ) {
+		DWORD dwError = GetLastError();
+	}
+
+	return bRet;
+}
+
+BOOL HTTPHelper::_SetRequestHeaders()
+{
+	if ( m_hRequest == NULL )
+		return FALSE;
+
+	if ( m_strHeader.size() > 0 ) {
+		if ( !WinHttpAddRequestHeaders(m_hRequest, m_strHeader.c_str(), m_strHeader.size(), WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON) ) {
+			DWORD dwError = GetLastError();
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+void HTTPHelper::_SetContentLength()
+{
+	int nPos = m_strHeader.find(CONTENT_LENGTH);
+	if ( nPos != std::wstring::npos) {
+		// 删除原有的请求头;
+		int nPos2 = m_strHeader.find(L"\r\n",nPos);
+		if ( nPos2 !=std::wstring::npos )
+			m_strHeader.erase(nPos, nPos2-nPos+2);
+		else
+			m_strHeader.erase(nPos);
+	}
+
+	wchar_t szContentLenght[MAX_PATH] = {0};
+	swprintf_s(szContentLenght, L"%s%d", CONTENT_LENGTH, m_strFormData.size());
+
+	// 添加Form表单头;
+	m_strHeader.append(szContentLenght);
+	m_strHeader.append(CRLF);
+}
+
+DWORD HTTPHelper::_GetSendRequestSize()
+{
+	DWORD dwSize(0);
+	if ( m_strPostData.size())
+		dwSize = m_strPostData.size()*sizeof(wchar_t);
+	else if ( m_strFormData.size())
+		dwSize = m_strFormData.size()*sizeof(wchar_t);
+
+	return dwSize;
+}
+
+BOOL HTTPHelper::_SetCookies()
+{
+	if ( m_hRequest == NULL )
+		return FALSE;
+
+	if ( m_strCookies.size() > 0 ) {
+		std::wstring cookies = L"Cookie: ";
+		cookies += m_strCookies;
+		if (!::WinHttpAddRequestHeaders(m_hRequest, cookies.c_str(), cookies.size(), WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON)) {
+			DWORD dwError = ::GetLastError();
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+BOOL HTTPHelper::_SetProxy()
+{
+	if ( m_hRequest == NULL )
+		return FALSE;
+
+	if ( m_strProxyServerList.size() ) {
+		WINHTTP_PROXY_INFO proxyInfo;
+		memset(&proxyInfo, 0, sizeof(proxyInfo));
+
+		proxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
+		wchar_t szProxy[MAX_PATH] = L"";
+		wcscpy_s(szProxy, MAX_PATH, m_strProxyServerList.c_str());
+		proxyInfo.lpszProxy = szProxy;
+
+		DWORD dwError(0);
+		if (!::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo))) {
+			dwError = ::GetLastError();
+			return FALSE;
+		}
+
+		if (m_strProxyUserName.size() > 0) {
+			if (!::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_PROXY_USERNAME, (LPVOID)m_strProxyUserName.c_str(), m_strProxyUserName.size() * sizeof(wchar_t))) {
+				dwError = ::GetLastError();
+				return FALSE;
+			}
+
+			if (m_strProxyPwd.size() > 0) {
+				if (!::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_PROXY_PASSWORD, (LPVOID)m_strProxyPwd.c_str(), m_strProxyPwd.size() * sizeof(wchar_t))) {
+					dwError = ::GetLastError();
+					return FALSE;
+				}
+			}
+		}
+	}
+
+	return TRUE;
+}
+
+BOOL HTTPHelper::_SetAutoRedirect()
+{
+	if ( !m_bAllowAutoRedirect ) {
+		DWORD dwDisableFeature = WINHTTP_DISABLE_REDIRECTS;
+		if (!::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_DISABLE_FEATURE, &dwDisableFeature, sizeof(dwDisableFeature))) {
+			DWORD dwError = ::GetLastError();
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+void HTTPHelper::SetContentType(std::wstring strContentType)
+{
+	int nPos = m_strHeader.find(CONTENT_TYPE);
+	if ( nPos != std::wstring::npos) {
+		// 删除原有的请求头;
+		int nPos2 = m_strHeader.find(L"\r\n",nPos);
+		if ( nPos2 !=std::wstring::npos )
+			m_strHeader.erase(nPos, nPos2-nPos+2);
+		else
+			m_strHeader.erase(nPos);
+	}
+	// 添加Form表单头;
+	m_strHeader.append(strContentType);
+	m_strHeader.append(CRLF);
+}
+
+void HTTPHelper::AddQueryParams(std::wstring strName, std::wstring strValue)
+{
+	if ( m_strQueryParams.size() )
+		m_strQueryParams.append(L"&");
+
+	m_strQueryParams.append(strName);
+	m_strQueryParams.append(L"=");
+	m_strQueryParams.append(strValue);
+}
+
+void HTTPHelper::AddFormDataHeader() 
+{
+	if ( m_strHeader.find(FORMDATAHEADER) == std::wstring::npos ) {
+		int nPos = m_strHeader.find(L"Content-Type:");
+		if ( nPos != std::wstring::npos) {
+			// 删除原有的请求头;
+			int nPos2 = m_strHeader.find(L"\r\n",nPos);
+			if ( nPos2 !=std::wstring::npos )
+				m_strHeader.erase(nPos, nPos2-nPos+2);
+			else
+				m_strHeader.erase(nPos);
+		}
+		// 添加Form表单头;
+		m_strHeader.append(FORMDATAHEADER);
+		m_strHeader.append(CRLF);
+	}
+
+	// 清空FormatData;
+	m_strFormData.clear();
+}
+
+void HTTPHelper::AddFormUrlEncodedDataHeader() 
+{
+	if ( m_strHeader.find(FORMURLENCODEDDATAHEADER) == std::wstring::npos ) {
+		int nPos = m_strHeader.find(L"Content-Type:");
+		if ( nPos != std::wstring::npos) {
+			// 删除原有的请求头;
+			int nPos2 = m_strHeader.find(L"\r\n",nPos);
+			if ( nPos2 !=std::wstring::npos )
+				m_strHeader.erase(nPos, nPos2-nPos+2);
+			else
+				m_strHeader.erase(nPos);
+		}
+		// 添加Form表单头;
+		m_strHeader.append(FORMURLENCODEDDATAHEADER);
+		m_strHeader.append(CRLF);
+	}
+
+	// 清空FormatData;
+	m_strFormData.clear();
+}
+
+void HTTPHelper::AddBodyFormDataText(std::wstring strName, std::wstring strValue)
+{
+	AddFormDataHeader();//放到外头,只调用一次就好;
+	int nSize = wcslen(FORMDATA_TEXT_FORMAT) + strName.size() + strValue.size();
+	if ( nSize < K0 ) {
+		wchar_t szFormData[K0] = {0};
+		swprintf_s(szFormData, FORMDATA_TEXT_FORMAT, strName.c_str(), strName.c_str(), strValue.c_str());
+		m_strFormData.append(szFormData);
+	}
+	else if ( nSize < K1 ) {
+		wchar_t szFormData[K1] = {0};
+		swprintf_s(szFormData, FORMDATA_TEXT_FORMAT, strName.c_str(), strName.c_str(), strValue.c_str());
+		m_strFormData.append(szFormData);
+	}
+	else if ( nSize < K2 ) {
+		wchar_t szFormData[K2] = {0};
+		swprintf_s(szFormData, FORMDATA_TEXT_FORMAT, strName.c_str(), strName.c_str(), strValue.c_str());
+		m_strFormData.append(szFormData);
+	}
+	else if ( nSize < K4 ) {
+		wchar_t szFormData[K4] = {0};
+		swprintf_s(szFormData, FORMDATA_TEXT_FORMAT, strName.c_str(), strName.c_str(), strValue.c_str());
+		m_strFormData.append(szFormData);
+	}
+	else if ( nSize < K8 ) {
+		wchar_t szFormData[K8] = {0};
+		swprintf_s(szFormData, FORMDATA_TEXT_FORMAT, strName.c_str(), strName.c_str(), strValue.c_str());
+		m_strFormData.append(szFormData);
+	} else {
+
+	}
+}
+
+void HTTPHelper::AddBodyFormDataFile(std::wstring strName, std::wstring strFilePath, std::wstring strContentType)
+{
+	AddFormDataHeader();//放到外头,只调用一次就好;
+	int nSize = wcslen(FORMDATA_FILE_FORMAT) + strName.size() + strFilePath.size() + strContentType.size();
+	if ( nSize < K0 ) {
+		wchar_t szFormData[K0] = {0};
+		swprintf_s(szFormData, FORMDATA_FILE_FORMAT, strName.c_str(), strName.c_str(), strFilePath.c_str(), strContentType.c_str());
+		m_strFormData.append(szFormData);
+	}
+	else if ( nSize < K1 ) {
+		wchar_t szFormData[K1] = {0};
+		swprintf_s(szFormData, FORMDATA_FILE_FORMAT, strName.c_str(), strName.c_str(), strFilePath.c_str(), strContentType.c_str());
+		m_strFormData.append(szFormData);
+	}
+	else if ( nSize < K2 ) {
+		wchar_t szFormData[K2] = {0};
+		swprintf_s(szFormData, FORMDATA_FILE_FORMAT, strName.c_str(), strName.c_str(), strFilePath.c_str(), strContentType.c_str());
+		m_strFormData.append(szFormData);
+	}
+	else if ( nSize < K4 ) {
+		wchar_t szFormData[K4] = {0};
+		swprintf_s(szFormData, FORMDATA_FILE_FORMAT, strName.c_str(), strName.c_str(), strFilePath.c_str(), strContentType.c_str());
+		m_strFormData.append(szFormData);
+	}
+	else if ( nSize < K8 ) {
+		wchar_t szFormData[K8] = {0};
+		swprintf_s(szFormData, FORMDATA_FILE_FORMAT, strName.c_str(), strName.c_str(), strFilePath.c_str(), strContentType.c_str());
+		m_strFormData.append(szFormData);
+	} else {
+
+	}
+}
+
+void HTTPHelper::AddBodyFormUrlEncodedData(std::wstring strName, std::wstring strValue)
+{
+	AddFormUrlEncodedDataHeader();//放到外头,只调用一次就好;
+	if ( m_strFormData.size() )
+		m_strFormData.append(L"&");
+
+	m_strFormData.append(strName);
+	m_strFormData.append(L"=");
+	m_strFormData.append(strValue);
+	// 重新计算长度;
+	_SetContentLength();
+}
+
+void HTTPHelper::AddBodyRawData(std::wstring strRawData, std::wstring strContentType/* = */)
+{
+	m_strPostData = strRawData;
+	// 代替ContentType
+	strRawData = CONTENT_TYPE;
+	strRawData.append(strContentType);
+	strRawData.append(CRLF);
+	SetContentType(strRawData);
+}
+
+void HTTPHelper::AddBodyBinary(std::wstring strFilePath)
+{
+
+}

+ 541 - 0
WINHTTPS/WINHTTPS/HTTPHelper - 副本.cpp

@@ -0,0 +1,541 @@
+#include "StdAfx.h"
+#include "HTTPHelper.h"
+
+HTTPHelper::HTTPHelper(void):m_hSession(NULL),m_hConnect(NULL),m_hRequest(NULL),m_nRetryTimes(3)
+{
+}
+
+HTTPHelper::~HTTPHelper(void)
+{
+}
+
+bool HTTPHelper::UrlParse(std::wstring strUrl)
+{
+	int nPos = 0;
+	m_strUrl = strUrl;
+	std::wstring strSub;
+	wchar_t* magic[] = { L"https://", L"http://", NULL };
+	if ( m_strUrl.find(magic[0]) != std::wstring::npos || m_strUrl.find(magic[1]) != std::wstring::npos ) {
+		if (m_strUrl.find(magic[0]) != std::wstring::npos) {
+			m_dwPort = 443;
+			m_brequireValidSSL=TRUE;
+			strSub = m_strUrl.substr(8);
+			
+		} else {
+			m_dwPort = 80;
+			m_brequireValidSSL=FALSE;
+			strSub = m_strUrl.substr(7);
+		}
+
+		if ( (nPos = strSub.find(L"/")) != std::wstring::npos ) {
+			m_strDomain = strSub.substr(0, nPos);
+			m_strParam = strSub.substr(nPos);
+		} else {
+			m_strDomain = strSub;
+			m_strParam = L"/";
+		}
+
+		if ( (nPos = m_strDomain.find(L":")) != std::wstring::npos ) {
+			m_strHost = m_strDomain.substr(0, nPos);
+			m_dwPort = _wtol(m_strDomain.substr(nPos+1).c_str());
+		} else {
+			m_strHost = m_strDomain;
+		}
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+bool HTTPHelper::GetHtml(HTTPITEM &item, HTTPRESULT &result)
+{
+	if ( !SendRequest(item,result) )
+		return false;
+
+	return true;
+}
+
+bool HTTPHelper::SendRequest(HTTPITEM &item,HTTPRESULT &httpResult)
+{
+	DWORD dwError = -1;
+	if ( m_hSession == NULL ) {
+		// 创建会话;
+		m_hSession = WinHttpOpen(
+			item.m_strUserAgent.c_str(),
+			WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
+			WINHTTP_NO_PROXY_NAME, 
+			WINHTTP_NO_PROXY_BYPASS,
+			0);
+
+		if ( m_hSession == NULL ) {
+			dwError = GetLastError();
+			return false;
+		}
+
+		// 设置超时值;
+		if ( !WinHttpSetTimeouts(m_hSession, item.m_nResolveTimeout, item.m_nConnectTimeout, item.m_nSendTimeout, item.m_nReceiveTimeout) ) {
+			dwError = GetLastError();
+			return false;
+		}
+
+#pragma region 解析url;
+		URL_COMPONENTS urlComp;
+		DWORD dwUrlLen = 0;
+
+		// 初始化URL_COMPONENTS结构体.
+		ZeroMemory(&urlComp, sizeof(urlComp));
+		urlComp.dwStructSize = sizeof(urlComp);
+
+		// Set required component lengths to non-zero 
+		// so that they are cracked.
+		urlComp.dwSchemeLength    = (DWORD)-1;
+		urlComp.dwHostNameLength  = (DWORD)-1;
+		urlComp.dwUrlPathLength   = (DWORD)-1;
+		urlComp.dwExtraInfoLength = (DWORD)-1;
+
+		// Crack the URL.
+		if (!WinHttpCrackUrl(item.m_strUrl.c_str(), item.m_strUrl.size(), 0, &urlComp)) {
+			dwError = GetLastError();
+			return false;
+		}
+#pragma endregion
+
+		// 连接服务器;
+		m_hConnect = WinHttpConnect(m_hSession, urlComp.lpszHostName, urlComp.nPort, 0);
+		if ( m_hConnect == NULL) {
+			dwError = GetLastError();
+			return false;
+		}
+
+		// 请求类型:是否是https;
+		DWORD dwOpenRequestFlag = (urlComp.nScheme == INTERNET_SCHEME_HTTPS) ? WINHTTP_FLAG_SECURE : 0;
+		m_hRequest = WinHttpOpenRequest(m_hConnect, 
+			item.m_strMethod.c_str(), 
+			urlComp.lpszUrlPath,NULL,
+			WINHTTP_NO_REFERER,
+			WINHTTP_DEFAULT_ACCEPT_TYPES,
+			dwOpenRequestFlag);
+
+		if ( m_hRequest == NULL ) {
+			dwError = GetLastError();
+			return false;
+		}
+
+		// 如果是https,那么客户端就很容易受到无效证书的影响,现在接受任何事情都是最容易的
+		if ( item.m_brequireValidSSL && urlComp.nScheme == INTERNET_SCHEME_HTTPS ) {
+			DWORD dwOps = SECURITY_FLAG_IGNORE_CERT_CN_INVALID
+				| SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
+				| SECURITY_FLAG_IGNORE_UNKNOWN_CA;
+			WinHttpSetOption(m_hRequest, WINHTTP_OPTION_SECURITY_FLAGS, &dwOps, sizeof(DWORD));
+		}
+
+		bool bGetResponseSucceed=false;
+		while ( !bGetResponseSucceed && m_nRetryTimes-- > 0 )
+		{
+			// 是否有请求头;
+			if ( item.m_strHeader.size() > 0 )
+			{
+				if (!WinHttpAddRequestHeaders(m_hRequest, item.m_strHeader.c_str(), item.m_strHeader.size(), WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON))
+				{
+					continue;
+					dwError = GetLastError();
+				}
+			}
+
+			// 是否有Cookie;
+			if ( item.m_strCookies.size() > 0 )
+			{
+				std::wstring cookies = L"Cookie: ";
+				cookies += item.m_strCookies;
+				if (!::WinHttpAddRequestHeaders(m_hRequest, cookies.c_str(), cookies.size(), WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON))
+				{
+					dwError = ::GetLastError();
+					continue;
+				}
+			}
+
+			// 是否有代理服务器;
+			if ( item.m_strProxyServerList.size() > 0 )
+			{
+				WINHTTP_PROXY_INFO proxyInfo;
+				memset(&proxyInfo, 0, sizeof(proxyInfo));
+
+				proxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
+				wchar_t szProxy[MAX_PATH] = L"";
+				wcscpy_s(szProxy, MAX_PATH, item.m_strProxyServerList.c_str());
+				proxyInfo.lpszProxy = szProxy;
+
+				if (!::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo)))
+				{
+					dwError = ::GetLastError();
+					continue;
+				}
+
+				if (item.m_strProxyUserName.size() > 0)
+				{
+					if (!::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_PROXY_USERNAME, (LPVOID)item.m_strProxyUserName.c_str(), item.m_strProxyUserName.size() * sizeof(wchar_t)))
+					{
+						dwError = ::GetLastError();
+						continue;
+					}
+
+					if (item.m_strProxyPwd.size() > 0)
+					{
+						if (!::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_PROXY_PASSWORD, (LPVOID)item.m_strProxyPwd.c_str(), item.m_strProxyPwd.size() * sizeof(wchar_t)))
+						{
+							dwError = ::GetLastError();
+							continue;
+						}
+					}
+				}
+			}
+
+			// 是否关闭自动重定向;
+			if ( !item.m_bAllowAutoRedirect )
+			{
+				DWORD dwDisableFeature = WINHTTP_DISABLE_REDIRECTS;
+				if (!::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_DISABLE_FEATURE, &dwDisableFeature, sizeof(dwDisableFeature)))
+				{
+					dwError = ::GetLastError();
+					continue;
+				}
+			}
+
+			// 发送请求;
+			bool bSendRequestSucceed = false;
+			if (::WinHttpSendRequest(m_hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, NULL))
+			{
+				bSendRequestSucceed = true;
+			}
+			else
+			{
+				// 从IE设置中查询代理信息,如果有代理,设置代理;
+				WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig;
+				memset(&proxyConfig, 0, sizeof(proxyConfig));
+				if (::WinHttpGetIEProxyConfigForCurrentUser(&proxyConfig))
+				{
+					if (proxyConfig.lpszAutoConfigUrl != NULL)
+					{
+						WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions;
+						memset(&autoProxyOptions, 0, sizeof(autoProxyOptions));
+						autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL;
+						autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP;
+						autoProxyOptions.lpszAutoConfigUrl = proxyConfig.lpszAutoConfigUrl;
+						autoProxyOptions.fAutoLogonIfChallenged = TRUE;
+						autoProxyOptions.dwReserved = 0;
+						autoProxyOptions.lpvReserved = NULL;
+
+						WINHTTP_PROXY_INFO proxyInfo;
+						memset(&proxyInfo, 0, sizeof(proxyInfo));
+
+						if (::WinHttpGetProxyForUrl(m_hSession, item.m_strUrl.c_str(), &autoProxyOptions, &proxyInfo))
+						{
+							if (::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo)))
+							{
+								if (::WinHttpSendRequest(m_hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, NULL))
+								{
+									bSendRequestSucceed = true;
+								}
+							}
+							if (proxyInfo.lpszProxy != NULL)
+							{
+								::GlobalFree(proxyInfo.lpszProxy);
+							}
+							if (proxyInfo.lpszProxyBypass != NULL)
+							{
+								::GlobalFree(proxyInfo.lpszProxyBypass);
+							}
+						}
+						else
+						{
+							dwError = ::GetLastError();
+						}
+					}
+					else if (proxyConfig.lpszProxy != NULL)
+					{
+						WINHTTP_PROXY_INFO proxyInfo;
+						memset(&proxyInfo, 0, sizeof(proxyInfo));
+						proxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
+						wchar_t szProxy[MAX_PATH] = L"";
+						wcscpy_s(szProxy, MAX_PATH, proxyConfig.lpszProxy);
+						proxyInfo.lpszProxy = szProxy;
+
+						if (proxyConfig.lpszProxyBypass != NULL)
+						{
+							wchar_t szProxyBypass[MAX_PATH] = L"";
+							wcscpy_s(szProxyBypass, MAX_PATH, proxyConfig.lpszProxyBypass);
+							proxyInfo.lpszProxyBypass = szProxyBypass;
+						}
+
+						if (!::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo)))
+						{
+							dwError = ::GetLastError();
+						}
+					}
+
+					if (proxyConfig.lpszAutoConfigUrl != NULL)
+					{
+						::GlobalFree(proxyConfig.lpszAutoConfigUrl);
+					}
+					if (proxyConfig.lpszProxy != NULL)
+					{
+						::GlobalFree(proxyConfig.lpszProxy);
+					}
+					if (proxyConfig.lpszProxyBypass != NULL)
+					{
+						::GlobalFree(proxyConfig.lpszProxyBypass);
+					}
+				}
+				else
+				{
+					dwError = ::GetLastError();
+				}
+			}
+
+			if (bSendRequestSucceed)
+			{
+				// 有要上传的数据;
+				/*if (m_pDataToSend != NULL)
+				{
+				DWORD dwWritten = 0;
+				if (!::WinHttpWriteData(m_hRequest,
+				m_pDataToSend,
+				m_dataToSendSize,
+				&dwWritten))
+				{
+				dwError = ::GetLastError();
+				}
+				}*/
+
+				if (::WinHttpReceiveResponse(m_hRequest, NULL))
+				{
+					DWORD dwSize = 0;
+					BOOL bResult = FALSE;
+					// 获取返回头;
+					bResult = ::WinHttpQueryHeaders(m_hRequest,
+						WINHTTP_QUERY_RAW_HEADERS_CRLF,
+						WINHTTP_HEADER_NAME_BY_INDEX,
+						NULL,
+						&dwSize,
+						WINHTTP_NO_HEADER_INDEX);
+
+					if (bResult || (!bResult && (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)))
+					{
+						wchar_t *szHeader = new wchar_t[dwSize];
+						if (szHeader != NULL)
+						{
+							memset(szHeader, 0, dwSize* sizeof(wchar_t));
+							if (::WinHttpQueryHeaders(m_hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, szHeader, &dwSize, WINHTTP_NO_HEADER_INDEX))
+							{
+								httpResult.m_strHeader.assign(szHeader);
+								std::vector<std::wstring> result;
+								std::wstring regExp = L"";
+								/*
+								if (!m_bForceCharset)
+								{
+								regExp = L"charset={[A-Za-z0-9\\-_]+}";
+								if (ParseRegExp(regExp, false, 1, m_responseHeader, result) && result.size() > 0)
+								{
+								httpResult.Charset = result[0];
+								}
+								}
+								regExp = L"Content-Length: {[0-9]+}";
+								if (ParseRegExp(regExp, false, 1, m_responseHeader, result) && result.size() > 0)
+								{
+								httpResult.dwByteCount = (unsigned int)_wtoi(result[0].c_str());
+								}
+								regExp = L"Location: {[0-9]+}";
+								if (ParseRegExp(regExp, false, 1, m_responseHeader, result) && result.size() > 0)
+								{
+								httpResult.Location = result[0];
+								}
+								regExp = L"Set-Cookie:\\b*{.+?}\\n";
+								if (ParseRegExp(regExp, false, 1, m_responseHeader, result) && result.size() > 0)
+								{
+								for (vector<wstring>::size_type i = 0; i < result.size(); i++)
+								{
+								httpResult.Cookie += result[i];
+								if (i != result.size() - 1)
+								{
+								httpResult.Cookie += L"; ";
+								}
+								}
+								httpResult.Cookie = Trim(httpResult.Cookie, L" ");
+								if (httpResult.Cookie.size() > 0 && httpResult.Cookie[httpResult.Cookie.size() - 1] != L';')
+								{
+								httpResult.Cookie += L";";
+								}
+								}*/
+							}
+							delete[] szHeader;
+						}
+					}
+
+					dwSize = 0;
+					bResult = ::WinHttpQueryHeaders(m_hRequest,
+						WINHTTP_QUERY_STATUS_CODE,
+						WINHTTP_HEADER_NAME_BY_INDEX,
+						NULL,
+						&dwSize,
+						WINHTTP_NO_HEADER_INDEX);
+					if (bResult || (!bResult && (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)))
+					{
+						wchar_t *szStatusCode = new wchar_t[dwSize];
+						if (szStatusCode != NULL)
+						{
+							memset(szStatusCode, 0, dwSize* sizeof(wchar_t));
+							if (::WinHttpQueryHeaders(m_hRequest,
+								WINHTTP_QUERY_STATUS_CODE,
+								WINHTTP_HEADER_NAME_BY_INDEX,
+								szStatusCode,
+								&dwSize,
+								WINHTTP_NO_HEADER_INDEX))
+							{
+								httpResult.m_dwStatusCode = _wtol(szStatusCode);
+							}
+							delete[] szStatusCode;
+						}
+					}
+
+					unsigned int iMaxBufferSize = 8912;
+					unsigned int iCurrentBufferSize = 0;
+					if (httpResult.m_pResponseData != NULL)
+					{
+						delete[] httpResult.m_pResponseData;
+						httpResult.m_pResponseData = NULL;
+					}
+					httpResult.m_pResponseData = new BYTE[iMaxBufferSize];
+					if (httpResult.m_pResponseData == NULL)
+					{
+						//bRetVal = false;
+						break;
+					}
+					memset(httpResult.m_pResponseData, 0, iMaxBufferSize);
+					do
+					{
+						dwSize = 0;
+						if (::WinHttpQueryDataAvailable(m_hRequest, &dwSize))
+						{
+							//SetProgress(iCurrentBufferSize);
+							BYTE *pResponse = new BYTE[dwSize + 1];
+							if (pResponse != NULL)
+							{
+								memset(pResponse, 0, (dwSize + 1)*sizeof(BYTE));
+								DWORD dwRead = 0;
+								if (::WinHttpReadData(m_hRequest, pResponse, dwSize, &dwRead))
+								{
+									if (dwRead + iCurrentBufferSize > iMaxBufferSize)
+									{
+										BYTE *pOldBuffer = httpResult.m_pResponseData;
+										httpResult.m_pResponseData = new BYTE[iMaxBufferSize * 2];
+										if (httpResult.m_pResponseData == NULL)
+										{
+											httpResult.m_pResponseData = pOldBuffer;
+											//bRetVal = false;
+											break;
+										}
+										iMaxBufferSize *= 2;
+										memset(httpResult.m_pResponseData, 0, iMaxBufferSize);
+										memcpy(httpResult.m_pResponseData, pOldBuffer, iCurrentBufferSize);
+										delete[] pOldBuffer;
+									}
+									memcpy(httpResult.m_pResponseData + iCurrentBufferSize, pResponse, dwRead);
+									iCurrentBufferSize += dwRead;
+								}
+								delete[] pResponse;
+							}
+						}
+						else
+						{
+							dwError = ::GetLastError();
+						}
+					}
+					while (dwSize > 0);
+					//SetProgress(iCurrentBufferSize);
+					httpResult.m_dwResponseSize = iCurrentBufferSize;
+
+					/*
+					UINT codePage = CP_ACP;
+					DWORD dwFlag = MB_PRECOMPOSED;
+					if (_wcsnicmp(m_responseCharset.c_str(), L"utf-8", 5) == 0)
+					{
+					codePage = CP_UTF8;
+					dwFlag = 0;
+					}
+					int iLength = ::MultiByteToWideChar(codePage, dwFlag, (LPCSTR)m_pResponse, m_responseByteCountReceived + 1, NULL, 0);
+					if (iLength <= 0)
+					{
+					// Use CP_ACP if UTF-8 fail
+					codePage = CP_ACP;
+					dwFlag = MB_PRECOMPOSED;
+					iLength = ::MultiByteToWideChar(codePage, dwFlag, (LPCSTR)m_pResponse, m_responseByteCountReceived + 1, NULL, 0);
+					}
+					if (iLength > 0)
+					{
+					wchar_t *wideChar = new wchar_t[iLength];
+					if (wideChar != NULL)
+					{
+					memset(wideChar, 0, iLength * sizeof(wchar_t));
+					iLength = ::MultiByteToWideChar(codePage, dwFlag, (LPCSTR)m_pResponse, m_responseByteCountReceived + 1, wideChar, iLength);
+					if (iLength > 0)
+					{
+					m_responseContent = wideChar;
+					}
+					delete[] wideChar;
+					}
+					}*/
+					bGetResponseSucceed = true;
+
+					/*
+					// If the resposne html web page size is less than 200, retry.
+					if (verb == L"GET" && !disableAutoRedirect)
+					{
+					wstring regExp = L"{<html>}";
+					vector<wstring> result;
+					if (ParseRegExp(regExp, false, 1, m_responseContent, result) && result.size() > 0)
+					{
+					regExp = L"{</html>}";
+					if (!ParseRegExp(regExp, false, 1, m_responseContent, result) || result.size() <= 0)
+					{
+					m_dwLastError = ERROR_INVALID_DATA;
+					bGetReponseSucceed = false;
+					}
+					}
+					}*/
+				}
+				else
+				{
+					dwError = ::GetLastError();
+				}
+			}
+
+		}
+	}
+
+	return true;
+}
+
+bool HTTPHelper::SetCer(HTTPITEM &item)
+{
+	return true;
+}
+
+bool HTTPHelper::SetTimeout(int nResolveTimeout /* = 0 */, int nConnectTimeout /* = 30000 */, int nSendTimeout /* = 30000 */, int nReceiveTimeout /* = 30000 */)
+{
+	if ( m_hSession == NULL )
+		return false;
+
+	BOOL bRet = WinHttpSetTimeouts(m_hSession, nResolveTimeout, nConnectTimeout, nSendTimeout, nReceiveTimeout);
+	if ( !bRet )
+	{
+		DWORD dwError = GetLastError();
+	}
+
+	return bRet;
+}
+
+bool HTTPHelper::SetUserAgent(std::string strAgent/* = */)
+{
+	return true;
+}

+ 53 - 0
WINHTTPS/WINHTTPS/HTTPHelper - 副本.h

@@ -0,0 +1,53 @@
+#pragma once
+#include "HTTPDef.h"
+
+class HTTPHelper: protected HTTPITEM
+{
+	HINTERNET m_hSession;
+	HINTERNET m_hConnect;
+	HINTERNET m_hRequest;
+
+	UINT m_nRetryTimes;
+public:
+	HTTPHelper(void);
+	~HTTPHelper(void);
+
+public:
+	bool UrlParse(std::wstring strUrl);
+
+public:
+	bool GetHtml(HTTPITEM &item, HTTPRESULT &result);
+	bool SendRequest(HTTPITEM &item, HTTPRESULT &result);
+
+public:
+	// 设置Post的数据;
+	bool SetPostData(HTTPITEM &item);
+	// 设置表单数据;
+	bool SetFormData();
+	// 设置url;
+	inline void SetUrl(std::wstring url) {m_strUrl = url;};
+	// 设置方法;
+	inline void SetMethod(std::wstring strMethon=L"GET") { m_strMethod = strMethon;};
+	// 设置证书;
+	bool SetCer(HTTPITEM &item);
+	// 设置证书;
+	bool SetCerList(HTTPITEM &item);
+	// 设置自动重定向;
+	inline void SetAutoRedirect(bool bAutoRedirect=false) { m_bAllowAutoRedirect = bAutoRedirect;};	
+	// 设置Cookie;
+	inline void SetCookie(std::string strCookies){ m_strCookies = strCookies; };
+	// 设置用户代理;
+	inline void SetUserAgent(std::string strAgent="Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)") { m_strUserAgent = strAgent;};
+	// 设置代理;
+	inline void SetProxy(std::string strProxyServerList, std::string strProxyUserName="", std::string strProxyPwd="") {
+		m_strProxyPwd = strProxyPwd;
+		m_strProxyUserName = strProxyUserName;
+		m_strProxyServerList = strProxyServerList;
+	};
+	// 设置超时值;
+	inline void SetTimeout(int nResolveTimeout = 0, int nConnectTimeout = 30000, int nSendTimeout = 30000, int nReceiveTimeout = 30000)
+	{
+
+	};
+	// 设置请求头;
+};

+ 682 - 0
WINHTTPS/WINHTTPS/HTTPHelper.cpp

@@ -0,0 +1,682 @@
+#include "StdAfx.h"
+#include "HTTPHelper.h"
+
+HTTPHelper::HTTPHelper(void):m_hSession(NULL),m_hConnect(NULL),m_hRequest(NULL),m_nRetryTimes(3)
+{
+}
+
+HTTPHelper::~HTTPHelper(void)
+{
+}
+
+bool HTTPHelper::UrlParse(std::wstring strUrl)
+{
+	int nPos = 0;
+	std::wstring strSub;
+	if (strUrl.size()) m_strUrl = strUrl;
+	wchar_t* magic[] = { L"https://", L"http://", NULL };
+	if ( m_strUrl.find(magic[0]) != std::wstring::npos || m_strUrl.find(magic[1]) != std::wstring::npos ) {
+		if (m_strUrl.find(magic[0]) != std::wstring::npos) {
+			m_dwPort = 443;
+			m_nScheme=INTERNET_SCHEME_HTTPS;
+			strSub = m_strUrl.substr(8);			
+		} else {
+			m_dwPort = 80;
+			m_nScheme=INTERNET_SCHEME_HTTP;
+			strSub = m_strUrl.substr(7);
+		}
+
+		if ( (nPos = strSub.find(L"/")) != std::wstring::npos ) {
+			m_strDomain = strSub.substr(0, nPos);
+			m_strApiName = strSub.substr(nPos);
+		} else {
+			m_strDomain = strSub;
+			m_strApiName = L"/";
+		}
+
+		if ( (nPos = m_strDomain.find(L":")) != std::wstring::npos ) {
+			m_strHost = m_strDomain.substr(0, nPos);
+			m_dwPort = _wtol(m_strDomain.substr(nPos+1).c_str());
+		} else {
+			m_strHost = m_strDomain;
+		}
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+bool HTTPHelper::GetHtml(HTTPITEM &item, HTTPRESULT &result)
+{
+	if ( !SendRequest(item,result) )
+		return false;
+
+	return true;
+}
+
+BOOL HTTPHelper::_OpenHTTP()
+{
+	DWORD dwError(0);
+	if ( m_hSession == NULL ) {
+		// 创建会话;
+		m_hSession = WinHttpOpen(
+			m_strUserAgent.c_str(),
+			WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
+			WINHTTP_NO_PROXY_NAME, 
+			WINHTTP_NO_PROXY_BYPASS,
+			0);
+
+		if ( m_hSession == NULL ) {
+			dwError = GetLastError();
+			return FALSE;
+		}
+
+		// 设置超时值;
+		if ( !_SetTimeout() ) {
+			return FALSE;
+		}
+
+		// 连接服务器;
+		m_hConnect = WinHttpConnect(m_hSession, m_strHost.c_str(), m_dwPort, 0);
+		if ( m_hConnect == NULL) {
+			dwError = GetLastError();
+			return FALSE;
+		}
+
+		std::wstring strObjctName = m_strApiName;
+		if ( m_strQueryParams.size() ) {
+			strObjctName.append(L"?");
+			strObjctName.append(m_strQueryParams);
+		}
+
+		// 请求类型:是否是https;
+		DWORD dwOpenRequestFlag = (m_nScheme == INTERNET_SCHEME_HTTPS) ? WINHTTP_FLAG_SECURE : 0;
+		m_hRequest = WinHttpOpenRequest(m_hConnect, 
+			m_strMethod.c_str(), 
+			strObjctName.c_str(),
+			NULL,
+			WINHTTP_NO_REFERER,
+			WINHTTP_DEFAULT_ACCEPT_TYPES,
+			dwOpenRequestFlag);
+
+		if ( m_hRequest == NULL ) {
+			dwError = GetLastError();
+			return FALSE;
+		}
+
+		// 如果是https,那么客户端就很容易受到无效证书的影响,现在接受任何事情都是最容易的
+		if ( m_brequireValidSSL && m_nScheme == INTERNET_SCHEME_HTTPS ) {
+			DWORD dwOps = SECURITY_FLAG_IGNORE_CERT_CN_INVALID
+				| SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
+				| SECURITY_FLAG_IGNORE_UNKNOWN_CA
+				| SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
+			WinHttpSetOption(m_hRequest, WINHTTP_OPTION_SECURITY_FLAGS, &dwOps, sizeof(DWORD));
+		}
+	}
+
+	return TRUE;
+}
+
+BOOL HTTPHelper::_SendRequestData()
+{
+	DWORD dwError(0);
+	BOOL bGetResponseSucceed=FALSE;
+	while ( !bGetResponseSucceed && m_nRetryTimes-- > 0 )
+	{
+		// 是否有请求头;
+		if ( !_SetRequestHeaders() ) {
+			continue;
+		}
+
+		// 是否有Cookie;
+		if ( !_SetCookies() ) {
+			continue;
+		}
+
+		// 是否有代理服务器;
+		if ( !_SetProxy() ) {
+			continue;
+		}
+
+		// 是否关闭自动重定向;
+		if ( !_SetAutoRedirect() ) {
+			continue;
+		}
+
+		// 发送请求;
+		bool bSendRequestSucceed = false;
+		//if (::WinHttpSendRequest(m_hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, NULL, (LPVOID)m_strPostData.c_str(), m_strPostData.size()*sizeof(wchar_t), m_strPostData.size()*sizeof(wchar_t), NULL))
+		//if (::WinHttpSendRequest(m_hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, NULL, WINHTTP_NO_REQUEST_DATA, 0, _GetSendRequestSize(), NULL))
+		if (::WinHttpSendRequest(m_hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, NULL, WINHTTP_NO_REQUEST_DATA, 0, 0, NULL)) // 这里不设置长度,就在Header Content-Length设置;
+		{
+			bSendRequestSucceed = true;
+		}
+		else
+		{
+			// 从IE设置中查询代理信息,如果有代理,设置代理;
+			WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig;
+			memset(&proxyConfig, 0, sizeof(proxyConfig));
+			if (::WinHttpGetIEProxyConfigForCurrentUser(&proxyConfig))
+			{
+				if (proxyConfig.lpszAutoConfigUrl != NULL)
+				{
+					WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions;
+					memset(&autoProxyOptions, 0, sizeof(autoProxyOptions));
+					autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL;
+					autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP;
+					autoProxyOptions.lpszAutoConfigUrl = proxyConfig.lpszAutoConfigUrl;
+					autoProxyOptions.fAutoLogonIfChallenged = TRUE;
+					autoProxyOptions.dwReserved = 0;
+					autoProxyOptions.lpvReserved = NULL;
+
+					WINHTTP_PROXY_INFO proxyInfo;
+					memset(&proxyInfo, 0, sizeof(proxyInfo));
+
+					if (::WinHttpGetProxyForUrl(m_hSession, m_strUrl.c_str(), &autoProxyOptions, &proxyInfo))
+					{
+						if (::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo)))
+						{
+							if (::WinHttpSendRequest(m_hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, NULL))
+							{
+								bSendRequestSucceed = true;
+							}
+						}
+						if (proxyInfo.lpszProxy != NULL)
+						{
+							::GlobalFree(proxyInfo.lpszProxy);
+						}
+						if (proxyInfo.lpszProxyBypass != NULL)
+						{
+							::GlobalFree(proxyInfo.lpszProxyBypass);
+						}
+					}
+					else
+					{
+						dwError = ::GetLastError();
+					}
+				}
+				else if (proxyConfig.lpszProxy != NULL)
+				{
+					WINHTTP_PROXY_INFO proxyInfo;
+					memset(&proxyInfo, 0, sizeof(proxyInfo));
+					proxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
+					wchar_t szProxy[MAX_PATH] = L"";
+					wcscpy_s(szProxy, MAX_PATH, proxyConfig.lpszProxy);
+					proxyInfo.lpszProxy = szProxy;
+
+					if (proxyConfig.lpszProxyBypass != NULL)
+					{
+						wchar_t szProxyBypass[MAX_PATH] = L"";
+						wcscpy_s(szProxyBypass, MAX_PATH, proxyConfig.lpszProxyBypass);
+						proxyInfo.lpszProxyBypass = szProxyBypass;
+					}
+
+					if (!::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo)))
+					{
+						dwError = ::GetLastError();
+					}
+				}
+
+				if (proxyConfig.lpszAutoConfigUrl != NULL)
+				{
+					::GlobalFree(proxyConfig.lpszAutoConfigUrl);
+				}
+				if (proxyConfig.lpszProxy != NULL)
+				{
+					::GlobalFree(proxyConfig.lpszProxy);
+				}
+				if (proxyConfig.lpszProxyBypass != NULL)
+				{
+					::GlobalFree(proxyConfig.lpszProxyBypass);
+				}
+			}
+			else
+			{
+				dwError = ::GetLastError();
+			}
+		}
+
+		if (bSendRequestSucceed)
+		{
+			// 有FormData数据要上传;
+			if ( m_strFormData.size() != 0 )
+			{
+				DWORD dwWritten = 0;
+				if (!::WinHttpWriteData(m_hRequest, m_strFormData.c_str(), m_strFormData.size()*sizeof(wchar_t), &dwWritten))
+				{
+					dwError = ::GetLastError();
+					continue;
+				}
+			}
+
+			// 有PostData数据要上传;
+			if ( m_strPostData.size() != 0 )
+			{
+				DWORD dwWritten = 0;
+				if (!::WinHttpWriteData(m_hRequest, m_strPostData.c_str(), m_strPostData.size()*sizeof(wchar_t), &dwWritten))
+				{
+					dwError = ::GetLastError();
+					continue;
+				}
+			}
+		}
+
+		bGetResponseSucceed = TRUE;
+	}	
+
+	return bGetResponseSucceed;
+}
+
+BOOL HTTPHelper::_ReceiveResponse(std::wstring &strHeaer, DWORD &dwStatusCode, std::string &strResponseData)
+{
+	DWORD dwError(0);
+	if (::WinHttpReceiveResponse(m_hRequest, NULL))
+	{
+		DWORD dwSize = 0;
+		BOOL bResult = FALSE;
+		// 获取返回头大小;
+		bResult = ::WinHttpQueryHeaders(m_hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &dwSize, WINHTTP_NO_HEADER_INDEX);
+		if (bResult || (!bResult && (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)))
+		{
+			if ( dwSize/2 < K0 )
+			{
+				wchar_t szHeader[K0] = {0};
+				if (::WinHttpQueryHeaders(m_hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, szHeader, &dwSize, WINHTTP_NO_HEADER_INDEX))
+				{
+					strHeaer.assign(szHeader);
+				}
+			}
+			else if ( dwSize/2 < K1 )
+			{
+				wchar_t szHeader[K1] = {0};
+				if (::WinHttpQueryHeaders(m_hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, szHeader, &dwSize, WINHTTP_NO_HEADER_INDEX))
+				{
+					strHeaer.assign(szHeader);
+				}
+			}
+			else if ( dwSize/2 < K2 )
+			{
+				wchar_t szHeader[K2] = {0};
+				if (::WinHttpQueryHeaders(m_hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, szHeader, &dwSize, WINHTTP_NO_HEADER_INDEX))
+				{
+					strHeaer.assign(szHeader);
+				}
+			}	
+		}
+
+		dwSize = 0;
+		bResult = ::WinHttpQueryHeaders(m_hRequest, WINHTTP_QUERY_STATUS_CODE, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &dwSize, WINHTTP_NO_HEADER_INDEX); 
+		if (bResult || (!bResult && (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)))
+		{
+			wchar_t szStatusCode[MAX_PATH] = {0};
+			if (::WinHttpQueryHeaders(m_hRequest, WINHTTP_QUERY_STATUS_CODE, WINHTTP_HEADER_NAME_BY_INDEX, szStatusCode, &dwSize, WINHTTP_NO_HEADER_INDEX))
+			{
+				dwStatusCode = _wtol(szStatusCode);
+			}
+		}
+		
+		if ( dwStatusCode != 200 )
+			return FALSE;
+
+		do
+		{
+			dwSize = 0;
+			if (WinHttpQueryDataAvailable(m_hRequest, &dwSize))
+			{
+				if (dwSize==0)
+					break;
+				//SetProgress(iCurrentBufferSize);
+				DWORD dwNumberOfBytesRead = 0;
+				BYTE szReadData[K1] = {0};	// 每次读取1K;
+				if (::WinHttpReadData(m_hRequest, szReadData, K1, &dwNumberOfBytesRead))
+				{
+					strResponseData.append((char*)szReadData, dwNumberOfBytesRead);
+				}
+			} else {
+				dwError = ::GetLastError();
+			}
+		}
+		while (dwSize > 0);
+		//SetProgress(iCurrentBufferSize);
+	}
+	else
+	{
+		dwError = ::GetLastError();
+	}
+
+	return TRUE;
+}
+
+bool HTTPHelper::SendRequest(HTTPITEM &item,HTTPRESULT &httpResult)
+{
+	if (!_OpenHTTP())
+		return false;
+
+	if (!_SendRequestData())
+		return false;
+
+	if (!_ReceiveResponse(httpResult.m_strHeader, httpResult.m_dwStatusCode, httpResult.m_strResponseData))
+		return false;
+
+	return true;
+}
+
+bool HTTPHelper::SetCer(HTTPITEM &item)
+{
+	return true;
+}
+
+BOOL HTTPHelper::_SetTimeout()
+{
+	if ( m_hSession == NULL )
+		return FALSE;
+
+	BOOL bRet = WinHttpSetTimeouts(m_hSession, m_nResolveTimeout, m_nConnectTimeout, m_nSendTimeout, m_nReceiveTimeout);
+	if ( !bRet ) {
+		DWORD dwError = GetLastError();
+	}
+
+	return bRet;
+}
+
+BOOL HTTPHelper::_SetRequestHeaders()
+{
+	if ( m_hRequest == NULL )
+		return FALSE;
+
+	if ( m_strHeader.size() > 0 ) {
+#if 1 // WinHttpSendRequest里不设置数据长度,这里必须设置;
+		wchar_t szContentLength[MAX_PATH] = {0};
+		swprintf_s(szContentLength, L"%s%d\r\n", CONTENT_LENGTH, _GetSendRequestSize());
+		m_strHeader.append(szContentLength);
+#endif
+		if ( !WinHttpAddRequestHeaders(m_hRequest, m_strHeader.c_str(), m_strHeader.size(), WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON) ) {
+			DWORD dwError = GetLastError();
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+void HTTPHelper::_SetContentLength()
+{
+	int nPos = m_strHeader.find(CONTENT_LENGTH);
+	if ( nPos != std::wstring::npos) {
+		// 删除原有的请求头;
+		int nPos2 = m_strHeader.find(L"\r\n",nPos);
+		if ( nPos2 !=std::wstring::npos )
+			m_strHeader.erase(nPos, nPos2-nPos+2);
+		else
+			m_strHeader.erase(nPos);
+	}
+
+	wchar_t szContentLenght[MAX_PATH] = {0};
+	swprintf_s(szContentLenght, L"%s%d", CONTENT_LENGTH, m_strFormData.size());
+
+	// 添加Form表单头;
+	m_strHeader.append(szContentLenght);
+	m_strHeader.append(CRLF);
+}
+
+DWORD HTTPHelper::_GetSendRequestSize()
+{
+	DWORD dwSize(0);
+	if ( m_strPostData.size())
+		dwSize = m_strPostData.size()*sizeof(wchar_t);
+	else if ( m_strFormData.size())
+		dwSize = m_strFormData.size()*sizeof(wchar_t);
+
+	return dwSize;
+}
+
+BOOL HTTPHelper::_SetCookies()
+{
+	if ( m_hRequest == NULL )
+		return FALSE;
+
+	if ( m_strCookies.size() > 0 ) {
+		std::wstring cookies = L"Cookie: ";
+		cookies += m_strCookies;
+		if (!::WinHttpAddRequestHeaders(m_hRequest, cookies.c_str(), cookies.size(), WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON)) {
+			DWORD dwError = ::GetLastError();
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+BOOL HTTPHelper::_SetProxy()
+{
+	if ( m_hRequest == NULL )
+		return FALSE;
+
+	if ( m_strProxyServerList.size() ) {
+		WINHTTP_PROXY_INFO proxyInfo;
+		memset(&proxyInfo, 0, sizeof(proxyInfo));
+
+		proxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
+		wchar_t szProxy[MAX_PATH] = L"";
+		wcscpy_s(szProxy, MAX_PATH, m_strProxyServerList.c_str());
+		proxyInfo.lpszProxy = szProxy;
+
+		DWORD dwError(0);
+		if (!::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo))) {
+			dwError = ::GetLastError();
+			return FALSE;
+		}
+
+		if (m_strProxyUserName.size() > 0) {
+			if (!::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_PROXY_USERNAME, (LPVOID)m_strProxyUserName.c_str(), m_strProxyUserName.size() * sizeof(wchar_t))) {
+				dwError = ::GetLastError();
+				return FALSE;
+			}
+
+			if (m_strProxyPwd.size() > 0) {
+				if (!::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_PROXY_PASSWORD, (LPVOID)m_strProxyPwd.c_str(), m_strProxyPwd.size() * sizeof(wchar_t))) {
+					dwError = ::GetLastError();
+					return FALSE;
+				}
+			}
+		}
+	}
+
+	return TRUE;
+}
+
+BOOL HTTPHelper::_SetAutoRedirect()
+{
+	if ( !m_bAllowAutoRedirect ) {
+		DWORD dwDisableFeature = WINHTTP_DISABLE_REDIRECTS;
+		if (!::WinHttpSetOption(m_hRequest, WINHTTP_OPTION_DISABLE_FEATURE, &dwDisableFeature, sizeof(dwDisableFeature))) {
+			DWORD dwError = ::GetLastError();
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+void HTTPHelper::SetContentType(std::wstring strContentType)
+{
+	int nPos = m_strHeader.find(CONTENT_TYPE);
+	if ( nPos != std::wstring::npos) {
+		// 删除原有的请求头;
+		int nPos2 = m_strHeader.find(L"\r\n",nPos);
+		if ( nPos2 !=std::wstring::npos )
+			m_strHeader.erase(nPos, nPos2-nPos+2);
+		else
+			m_strHeader.erase(nPos);
+	}
+	// 添加Form表单头;
+	m_strHeader.append(strContentType);
+	m_strHeader.append(CRLF);
+}
+
+void HTTPHelper::AddQueryParams(std::wstring strName, std::wstring strValue)
+{
+	if ( m_strQueryParams.size() )
+		m_strQueryParams.append(L"&");
+
+	m_strQueryParams.append(strName);
+	m_strQueryParams.append(L"=");
+	m_strQueryParams.append(strValue);
+}
+
+void HTTPHelper::AddFormDataHeader() 
+{
+	if ( m_strHeader.find(FORMDATAHEADER) == std::wstring::npos ) {
+		int nPos = m_strHeader.find(L"Content-Type:");
+		if ( nPos != std::wstring::npos) {
+			// 删除原有的请求头;
+			int nPos2 = m_strHeader.find(L"\r\n",nPos);
+			if ( nPos2 !=std::wstring::npos )
+				m_strHeader.erase(nPos, nPos2-nPos+2);
+			else
+				m_strHeader.erase(nPos);
+		}
+		// 添加Form表单头;
+		m_strHeader.append(FORMDATAHEADER);
+		m_strHeader.append(CRLF);
+	}
+
+	// 清空FormatData;
+	m_strFormData.clear();
+}
+
+void HTTPHelper::AddFormUrlEncodedDataHeader() 
+{
+	if ( m_strHeader.find(FORMURLENCODEDDATAHEADER) == std::wstring::npos ) {
+		int nPos = m_strHeader.find(L"Content-Type:");
+		if ( nPos != std::wstring::npos) {
+			// 删除原有的请求头;
+			int nPos2 = m_strHeader.find(L"\r\n",nPos);
+			if ( nPos2 !=std::wstring::npos )
+				m_strHeader.erase(nPos, nPos2-nPos+2);
+			else
+				m_strHeader.erase(nPos);
+		}
+		// 添加Form表单头;
+		m_strHeader.append(FORMURLENCODEDDATAHEADER);
+		m_strHeader.append(CRLF);
+	}
+
+	// 清空FormatData;
+	m_strFormData.clear();
+}
+
+void HTTPHelper::AddBodyFormDataText(std::wstring strName, std::wstring strValue)
+{
+	AddFormDataHeader();//放到外头,只调用一次就好;
+	int nSize = wcslen(FORMDATA_TEXT_FORMAT) + strName.size() + strValue.size();
+	if ( nSize < K0 ) {
+		wchar_t szFormData[K0] = {0};
+		swprintf_s(szFormData, FORMDATA_TEXT_FORMAT, strName.c_str(), strName.c_str(), strValue.c_str());
+		m_strFormData.append(szFormData);
+	}
+	else if ( nSize < K1 ) {
+		wchar_t szFormData[K1] = {0};
+		swprintf_s(szFormData, FORMDATA_TEXT_FORMAT, strName.c_str(), strName.c_str(), strValue.c_str());
+		m_strFormData.append(szFormData);
+	}
+	else if ( nSize < K2 ) {
+		wchar_t szFormData[K2] = {0};
+		swprintf_s(szFormData, FORMDATA_TEXT_FORMAT, strName.c_str(), strName.c_str(), strValue.c_str());
+		m_strFormData.append(szFormData);
+	}
+	else if ( nSize < K4 ) {
+		wchar_t szFormData[K4] = {0};
+		swprintf_s(szFormData, FORMDATA_TEXT_FORMAT, strName.c_str(), strName.c_str(), strValue.c_str());
+		m_strFormData.append(szFormData);
+	}
+	else if ( nSize < K8 ) {
+		wchar_t szFormData[K8] = {0};
+		swprintf_s(szFormData, FORMDATA_TEXT_FORMAT, strName.c_str(), strName.c_str(), strValue.c_str());
+		m_strFormData.append(szFormData);
+	} else {
+
+	}
+}
+
+void HTTPHelper::AddBodyFormDataFile(std::wstring strName, std::wstring strFilePath, std::wstring strContentType)
+{
+	AddFormDataHeader();//放到外头,只调用一次就好;
+	int nSize = wcslen(FORMDATA_FILE_FORMAT) + strName.size() + strFilePath.size() + strContentType.size();
+	if ( nSize < K0 ) {
+		wchar_t szFormData[K0] = {0};
+		swprintf_s(szFormData, FORMDATA_FILE_FORMAT, strName.c_str(), strName.c_str(), strFilePath.c_str(), strContentType.c_str());
+		m_strFormData.append(szFormData);
+	}
+	else if ( nSize < K1 ) {
+		wchar_t szFormData[K1] = {0};
+		swprintf_s(szFormData, FORMDATA_FILE_FORMAT, strName.c_str(), strName.c_str(), strFilePath.c_str(), strContentType.c_str());
+		m_strFormData.append(szFormData);
+	}
+	else if ( nSize < K2 ) {
+		wchar_t szFormData[K2] = {0};
+		swprintf_s(szFormData, FORMDATA_FILE_FORMAT, strName.c_str(), strName.c_str(), strFilePath.c_str(), strContentType.c_str());
+		m_strFormData.append(szFormData);
+	}
+	else if ( nSize < K4 ) {
+		wchar_t szFormData[K4] = {0};
+		swprintf_s(szFormData, FORMDATA_FILE_FORMAT, strName.c_str(), strName.c_str(), strFilePath.c_str(), strContentType.c_str());
+		m_strFormData.append(szFormData);
+	}
+	else if ( nSize < K8 ) {
+		wchar_t szFormData[K8] = {0};
+		swprintf_s(szFormData, FORMDATA_FILE_FORMAT, strName.c_str(), strName.c_str(), strFilePath.c_str(), strContentType.c_str());
+		m_strFormData.append(szFormData);
+	} else {
+
+	}
+}
+
+void HTTPHelper::AddBodyFormUrlEncodedData(std::wstring strName, std::wstring strValue)
+{
+	AddFormUrlEncodedDataHeader();//放到外头,只调用一次就好;
+	if ( m_strFormData.size() )
+		m_strFormData.append(L"&");
+
+	m_strFormData.append(strName);
+	m_strFormData.append(L"=");
+	m_strFormData.append(strValue);
+	// 重新计算长度;
+	_SetContentLength();
+}
+
+void HTTPHelper::AddBodyRawData(std::wstring strRawData, std::wstring strContentType/* = */)
+{
+	m_strPostData = strRawData;
+	// 代替ContentType
+	strRawData = CONTENT_TYPE;
+	strRawData.append(strContentType);
+	strRawData.append(CRLF);
+	SetContentType(strRawData);
+}
+
+void HTTPHelper::AddBodyBinary(std::wstring strFilePath)
+{
+
+}
+
+void HTTPHelper::AddRequestHeaders(std::wstring strName, std::wstring strValue) 
+{
+	// 先判断是否存在;
+	int nPos = m_strHeader.find(strName+L": ");
+	if ( nPos != std::wstring::npos) {
+		// 删除原有的请求头;
+		int nPos2 = m_strHeader.find(L"\r\n",nPos);
+		if ( nPos2 !=std::wstring::npos )
+			m_strHeader.erase(nPos, nPos2-nPos+2);
+		else
+			m_strHeader.erase(nPos);
+	}
+
+	// 添加Form表单头;
+	m_strHeader.append(strName);
+	m_strHeader.append(L": ");
+	m_strHeader.append(strValue);
+	m_strHeader.append(L"\r\n");
+};

+ 86 - 0
WINHTTPS/WINHTTPS/HTTPHelper.h

@@ -0,0 +1,86 @@
+#pragma once
+#include "HTTPDef.h"
+
+
+class HTTPHelper: protected HTTPITEM
+{
+	HINTERNET m_hSession;
+	HINTERNET m_hConnect;
+	HINTERNET m_hRequest;
+
+	UINT m_nRetryTimes;
+public:
+	HTTPHelper(void);
+	~HTTPHelper(void);
+
+private:	
+	BOOL _SetProxy();
+	BOOL _SetCookies();
+	BOOL _SetTimeout();
+	BOOL _SetAutoRedirect();
+	BOOL _SetRequestHeaders();
+	void _SetContentLength();
+	DWORD _GetSendRequestSize();
+	BOOL _OpenHTTP();
+	BOOL _SendRequestData();
+	BOOL _ReceiveResponse(std::wstring &strHeaer, DWORD &dwStatusCode, std::string &strResponseData);
+	
+public:
+	bool UrlParse(std::wstring strUrl=L"");
+	bool GetHtml(HTTPITEM &item, HTTPRESULT &result);
+	bool SendRequest(HTTPITEM &item, HTTPRESULT &result);
+
+public:
+	void SetContentType(std::wstring strContentType);
+	// 添加查询参数;
+	void AddQueryParams(std::wstring strName, std::wstring strValue);
+	
+#pragma region Body类型,只能使用其中一种方式
+	void AddFormDataHeader();
+	void AddFormUrlEncodedDataHeader();
+	// 设置Body:得先调用AddFormDataHeader、AddFormUrlEncodedDataHeader;
+	void AddBodyFormDataText(std::wstring strName, std::wstring strValue);
+	void AddBodyFormDataFile(std::wstring strName, std::wstring strFilePath, std::wstring strContentType=L"image/gif");
+	void AddBodyFormUrlEncodedData(std::wstring strName, std::wstring strValue);
+	// 原始数据,需要在请求头指定数据类型,如json、xml格式内容;
+	void AddBodyRawData(std::wstring strRawData, std::wstring strContentType=L"*/*");
+	// 上传二进制,需要指定文件名;
+	void AddBodyBinary(std::wstring strFilePath);
+#pragma endregion
+	// 设置Post的数据;
+	void SetPostData(std::wstring strPostData) {m_strPostData = strPostData;};
+	// 设置表单数据;
+	void SetFormData(std::wstring strFormData) {m_strFormData = strFormData;};
+	// 设置上传的文件;
+	void SetUploadFile(std::wstring strFileName);
+	// 设置url;
+	void SetUrl(std::wstring strUrl) {UrlParse(strUrl);};
+	// 设置方法;
+	void SetMethod(std::wstring strMethon=L"GET") { m_strMethod = strMethon;};
+	// 设置证书;
+	bool SetCer(HTTPITEM &item);
+	// 设置证书;
+	bool SetCerList(HTTPITEM &item);
+	// 设置自动重定向;
+	inline void SetAutoRedirect(bool bAutoRedirect=false) { m_bAllowAutoRedirect = bAutoRedirect;};	
+	// 设置Cookie;
+	inline void SetCookies(std::wstring strCookies){ m_strCookies = strCookies; };
+	// 设置用户代理;
+	inline void SetUserAgent(std::wstring strAgent=L"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)") { m_strUserAgent = strAgent;};
+	// 设置代理;
+	inline void SetProxy(std::wstring strProxyServerList, std::wstring strProxyUserName=L"", std::wstring strProxyPwd=L"") {
+		m_strProxyPwd = strProxyPwd;
+		m_strProxyUserName = strProxyUserName;
+		m_strProxyServerList = strProxyServerList;
+	};
+
+	// 设置超时值;
+	inline void SetTimeout(int nResolveTimeout = 0, int nConnectTimeout = 30000, int nSendTimeout = 30000, int nReceiveTimeout = 30000) {
+		m_nResolveTimeout = nResolveTimeout;
+		m_nConnectTimeout = nConnectTimeout;
+		m_nSendTimeout = m_nSendTimeout;
+		m_nReceiveTimeout = m_nReceiveTimeout;
+	};
+	// 设置请求头;
+	void AddRequestHeaders(std::wstring strName, std::wstring strValue);
+};

+ 29 - 0
WINHTTPS/WINHTTPS/ReadMe.txt

@@ -0,0 +1,29 @@
+========================================================================
+    控制台应用程序:WINHTTPS 项目概述
+========================================================================
+
+应用程序向导已为您创建了此 WINHTTPS 应用程序。
+
+本文件概要介绍组成 WINHTTPS 应用程序的
+的每个文件的内容。
+
+
+WINHTTPS.vcproj
+    这是使用应用程序向导生成的 VC++ 项目的主项目文件,
+    其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
+
+WINHTTPS.cpp
+    这是主应用程序源文件。
+
+/////////////////////////////////////////////////////////////////////////////
+其他标准文件:
+
+StdAfx.h, StdAfx.cpp
+    这些文件用于生成名为 WINHTTPS.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。
+
+/////////////////////////////////////////////////////////////////////////////
+其他注释:
+
+应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。
+
+/////////////////////////////////////////////////////////////////////////////

+ 230 - 0
WINHTTPS/WINHTTPS/WINHTTPS.cpp

@@ -0,0 +1,230 @@
+// WINHTTPS.cpp : 定义控制台应用程序的入口点。
+//
+
+#include "stdafx.h"
+#include "HTTPDef.h"
+#include "HTTPHelper.h"
+
+
+void test_get()
+{
+	HTTPITEM itme;
+	HTTPRESULT result;
+
+	HTTPHelper hhelper;
+	hhelper.SetMethod(L"POST");
+	//hhelper.AddRequestHeaders(L"Cache-Control", L"no-cache");
+	hhelper.AddRequestHeaders(L"User-Agent", L"Moka_Factory/1.0.01");
+	//hhelper.AddRequestHeaders(L"Accept", L"*/*");
+	//hhelper.AddRequestHeaders(L"Accept-Encoding", L"gzip, deflate, br");
+	hhelper.AddRequestHeaders(L"Connection", L"keep-alive");
+	//hhelper.SetUrl(L"http://huizhou.idmanage.qhmoka.com/IDManage/getid.do?devicetype=SCBC_RT2851M&sn=DGG75095762111001764&order=DGG7509576");
+	hhelper.SetUrl(L"http://huizhou.idmanage.qhmoka.com/IDManage/getid.do");
+	hhelper.AddQueryParams(L"devicetype", L"SCBC_RT2851M");
+	hhelper.AddQueryParams(L"sn", L"DGG75095762111001764");
+	hhelper.AddQueryParams(L"order", L"DGG7509576");
+	hhelper.GetHtml(itme,result);
+
+	wprintf(L"ResponseHeader=%s\r\n",result.m_strHeader.c_str());
+	wprintf(L"StatusCode=%ld\r\n", result.m_dwStatusCode);
+
+	if (result.m_dwStatusCode == 200)
+		printf("ResponseData=%s\r\n",result.m_strResponseData.c_str());
+
+	system("pause");
+}
+
+void test_post()
+{
+	HTTPITEM itme;
+	HTTPRESULT result;
+
+	HTTPHelper hhelper;
+	hhelper.SetMethod(L"POST");
+	//hhelper.AddRequestHeaders(L"Cache-Control", L"no-cache");
+	hhelper.AddRequestHeaders(L"User-Agent", L"Moka_Factory/1.0.01");
+	//hhelper.AddRequestHeaders(L"Accept", L"*/*");
+#pragma region 造成Post时返回分块编码的原因是:Accept-Encoding中gzip造成数据压缩传输了.
+	//hhelper.AddRequestHeaders(L"Accept-Encoding", L"gzip, deflate, br");
+	//hhelper.AddRequestHeaders(L"Connection", L"keep-alive");//持续连接,会产生分块编码(Transfer-Encoding: chunked)
+	hhelper.AddRequestHeaders(L"Connection", L"close"); //关闭,也一样会产生会分块编码(Transfer-Encoding: chunked)
+	//hhelper.AddRequestHeaders(L"Transfer-Encoding", L""); //关闭,也一样会产生会分块编码(Transfer-Encoding: chunked)
+#pragma endregion
+	//content-encoding
+	//hhelper.AddRequestHeaders(L"Content-Encoding", L"UTF-8"); // POST时才需要用到;
+	hhelper.AddRequestHeaders(L"Content-Type", L"application/json;charset=utf8"); // POST时才需要用到;
+	//hhelper.AddRequestHeaders(L"Content-Length", L"755"); // POST时才需要用到
+	hhelper.SetUrl(L"http://test.scbc.qhmoka.com/scbc-server/clientType/getMessage.do");
+	//hhelper.SetPostData(L"{\"bid\":\"TEST_WJF\",\"mac\":\"04-D4-C4-EE-6B-CD\"}");
+	hhelper.AddBodyRawData(L"{\"bid\":\"TEST_WJF\",\"mac\":\"04-D4-C4-EE-6B-CD\"}", L"application/json");
+	hhelper.GetHtml(itme,result);
+
+	wprintf(L"ResponseHeader=%s\r\n",result.m_strHeader.c_str());
+	wprintf(L"StatusCode=%ld\r\n", result.m_dwStatusCode);
+
+	if (result.m_dwStatusCode == 200)
+		printf("ResponseData=%s\r\n",result.m_strResponseData.c_str());
+
+	system("pause");
+
+	int a = 0;
+}
+
+void test_download()
+{
+
+}
+
+void test_putfile()
+{
+
+}
+
+int _tmain(int argc, _TCHAR* argv[])
+{
+	test_get();
+	test_post();
+
+	HTTPITEM itme;
+	HINTERNET hSession = NULL;
+	HINTERNET hConnect = NULL;
+	HINTERNET hRequest = NULL;
+
+	URL_COMPONENTS urlComp;
+	// Initialize the URL_COMPONENTS structure.
+	ZeroMemory(&urlComp, sizeof(urlComp));
+	urlComp.dwStructSize = sizeof(urlComp);
+
+	// Set required component lengths to non-zero 
+	// so that they are cracked.
+	urlComp.dwSchemeLength    = (DWORD)-1;
+	urlComp.dwHostNameLength  = (DWORD)-1;
+	urlComp.dwUrlPathLength   = (DWORD)-1;
+	urlComp.dwExtraInfoLength = (DWORD)-1;
+
+	//std::wstring url = L"http://search.msn.com/results.asp?RS=CHECKED&FORM=MSNH&v=1&q=wininet";
+	std::wstring url = L"https://test.scbc.qhmoka.com/scbc-server/clientType/getMessage";
+	if (::WinHttpCrackUrl(url.c_str(), url.size(), ICU_REJECT_USERPWD, &urlComp))
+	{
+	}
+
+	//1. 初始化一个WinHTTP-session句柄,参数1为此句柄的名称
+	hSession = WinHttpOpen(L"idm-interface", NULL, NULL, NULL, NULL);
+	if (hSession == NULL) {
+		std::cout<<"Error:Open session failed: "<<GetLastError()<<std::endl;
+		return -1;
+	}
+
+	// http://test.scbc.qhmoka.com/scbc-server/clientType/getMessage.do
+	//2. 通过上述句柄连接到服务器,需要指定服务器IP和端口号。若连接成功,返回的hConnect句柄不为NULL
+	hConnect = WinHttpConnect(hSession, L"test.scbc.qhmoka.com", (INTERNET_PORT)urlComp.nPort, 0);
+	if (hConnect == NULL) {
+		std::cout << "Error:Connect failed: " << GetLastError()<<std::endl;
+		return -1;
+	}
+
+	//3. 通过hConnect句柄创建一个hRequest句柄,用于发送数据与读取从服务器返回的数据。
+	hRequest = WinHttpOpenRequest(hConnect, L"Post", L"scbc-server/clientType/getMessage.do", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
+	//其中参数2表示请求方式,此处为Post;参数3:给定Post的具体地址,如这里的具体地址为http://192.168.50.112/getServiceInfo
+	if (hRequest == NULL) {
+		std::cout << "Error:OpenRequest failed: " << GetLastError() << std::endl;
+		return -1;
+	}
+
+	//4-1. 向服务器发送post数据
+	//(1) 指定发送的数据内容
+	std::string data = "{\"bid\":\"Testdddd11111\",\"mac\":\"18-87-D5-E2-9A-55\",\"version\":\"\",\"clientType\":\"\"}"; 
+	const void *ss = (const char *)data.c_str();
+
+	//(2) 发送请求
+	BOOL bResults;
+	bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, const_cast<void*>(ss), data.length(), data.length(), 0);
+	if (!bResults){
+		std::cout << "Error:SendRequest failed: " << GetLastError() << std::endl;
+		return -1;
+	}
+	else{
+		//(3) 发送请求成功则准备接受服务器的response。注意:在使用 WinHttpQueryDataAvailable和WinHttpReadData前必须使用WinHttpReceiveResponse才能access服务器返回的数据
+		bResults = WinHttpReceiveResponse(hRequest, NULL);
+	}
+
+	//4-2. 获取服务器返回数据的header信息。这一步我用来获取返回数据的数据类型。
+	LPVOID lpHeaderBuffer = NULL;
+	DWORD dwSize = 0;   
+	if (bResults)
+	{
+		//(1) 获取header的长度
+		WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF,
+			WINHTTP_HEADER_NAME_BY_INDEX, NULL,
+			&dwSize, WINHTTP_NO_HEADER_INDEX);
+
+		//(2) 根据header的长度为buffer申请内存空间
+		if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+		{
+			lpHeaderBuffer = new WCHAR[dwSize / sizeof(WCHAR)];
+
+			//(3) 使用WinHttpQueryHeaders获取header信息
+			bResults = WinHttpQueryHeaders(hRequest,
+				WINHTTP_QUERY_RAW_HEADERS_CRLF,
+				WINHTTP_HEADER_NAME_BY_INDEX,
+				lpHeaderBuffer, &dwSize,
+				WINHTTP_NO_HEADER_INDEX);
+		}
+	}
+	printf("Header contents: \n%S", lpHeaderBuffer);
+
+	//解析上述header信息会发现服务器返回数据的charset为uft-8。这意味着后面需要对获取到的raw data进行宽字符转换。一开始由于没有意识到需要进行转换所以得到的数据都是乱码。
+	//出现乱码的原因是:HTTP在传输过程中是二值的,它并没有text或者是unicode的概念。HTTP使用7bit的ASCII码作为HTTP headers,但是内容是任意的二值数据,需要根据header中指定的编码方式来描述它(通常是Content-Type header).
+	//因此当你接收到原始的HTTP数据时,先将其保存到char[] buffer中,然后利用WinHttpQueryHearders()获取HTTP头,得到内容的Content-Type,这样你就知道数据到底是啥类型的了,是ASCII还是Unicode或者其他。
+	//一旦你知道了具体的编码方式,你就可以通过MultiByteToWideChar()将其转换成合适编码的字符,存入wchar_t[]中。
+	//关于乱码的解决方案请看4-4
+
+	//4-3. 获取服务器返回数据
+	LPSTR pszOutBuffer = NULL;
+	DWORD dwDownloaded = 0;         //实际收取的字符数
+	wchar_t *pwText = NULL;
+	if (bResults)
+	{
+		do
+		{
+			//(1) 获取返回数据的大小(以字节为单位)
+			dwSize = 0;
+			if (!WinHttpQueryDataAvailable(hRequest, &dwSize)){
+				std::cout << "Error:WinHttpQueryDataAvailable failed:" << GetLastError() << std::endl;
+				break;
+			}           
+			if (!dwSize)    break;  //数据大小为0                
+
+			//(2) 根据返回数据的长度为buffer申请内存空间
+			pszOutBuffer = new char[dwSize + 1];
+			if (!pszOutBuffer){
+				std::cout<<"Out of memory."<<std::endl;
+				break;
+			}
+			ZeroMemory(pszOutBuffer, dwSize + 1);       //将buffer置0
+
+			//(3) 通过WinHttpReadData读取服务器的返回数据
+			if (!WinHttpReadData(hRequest,pszOutBuffer, dwSize, &dwDownloaded)){
+				std::cout << "Error:WinHttpQueryDataAvailable failed:" << GetLastError() << std::endl;
+			}
+			if (!dwDownloaded)
+				break;
+
+		} while (dwSize > 0);
+
+		//4-4. 将返回数据转换成UTF8
+		DWORD dwNum = MultiByteToWideChar(CP_ACP, 0, pszOutBuffer, -1, NULL, 0);    //返回原始ASCII码的字符数目       
+		pwText = new wchar_t[dwNum];                                                //根据ASCII码的字符数分配UTF8的空间
+		MultiByteToWideChar(CP_UTF8, 0, pszOutBuffer, -1, pwText, dwNum);           //将ASCII码转换成UTF8
+		printf("Received contents: \n%S", pwText);
+	}
+
+
+	//5. 依次关闭request,connect,session句柄
+	if (hRequest) WinHttpCloseHandle(hRequest);
+	if (hConnect) WinHttpCloseHandle(hConnect);
+	if (hSession) WinHttpCloseHandle(hSession);
+
+	return 0;
+}
+

+ 237 - 0
WINHTTPS/WINHTTPS/WINHTTPS.vcproj

@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="gb2312"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="WINHTTPS"
+	ProjectGUID="{6DBF8756-04C2-4D25-A1BC-9DD27F45D5FA}"
+	RootNamespace="WINHTTPS"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Ô´Îļþ"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\HTTPHelper.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\WINHTTPS.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Í·Îļþ"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\HTTPDef.h"
+				>
+			</File>
+			<File
+				RelativePath=".\HTTPHelper.h"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.h"
+				>
+			</File>
+			<File
+				RelativePath=".\targetver.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="×ÊÔ´Îļþ"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+		<File
+			RelativePath=".\ReadMe.txt"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

+ 109 - 0
WINHTTPS/WINHTTPS/WINHTTPS.vcxproj

@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>17.0</VCProjectVersion>
+    <ProjectGuid>{6DBF8756-04C2-4D25-A1BC-9DD27F45D5FA}</ProjectGuid>
+    <RootNamespace>WINHTTPS</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v143</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v143</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>17.0.32203.90</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir>$(Configuration)\</IntDir>
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir>$(Configuration)\</IntDir>
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="HTTPItem.cpp" />
+    <ClCompile Include="stdafx.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="WINHTTPS.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="HTTPItem.h" />
+    <ClInclude Include="stdafx.h" />
+    <ClInclude Include="targetver.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 42 - 0
WINHTTPS/WINHTTPS/WINHTTPS.vcxproj.filters

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="源文件">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="头文件">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="资源文件">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="HTTPItem.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="stdafx.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="WINHTTPS.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="HTTPItem.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="stdafx.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="targetver.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+</Project>

+ 130 - 0
WINHTTPS/WINHTTPS/stdafx.cpp

@@ -0,0 +1,130 @@
+// stdafx.cpp : 只包括标准包含文件的源文件
+// WINHTTPS.pch 将作为预编译头
+// stdafx.obj 将包含预编译类型信息
+
+#include "stdafx.h"
+
+// TODO: 在 STDAFX.H 中
+// 引用任何所需的附加头文件,而不是在此文件中引用
+std::string w2c(LPCWSTR wcs)
+{
+	if (wcs)
+	{
+		// 格式化前设置语言区域;
+#ifdef UNICODE
+		std::wstring old_locale;
+#else
+		std::string old_locale;
+#endif
+		TCHAR *pLocalName = _tsetlocale(LC_CTYPE, NULL);
+		if (pLocalName != NULL)
+			old_locale = pLocalName;
+		else
+			old_locale = _T("C");
+		_tsetlocale(LC_CTYPE, _T("chs"));//设定中文;
+
+#define LC_FREE _tsetlocale(LC_CTYPE, old_locale.c_str()); 
+
+		// 计算待转换的字节数
+		size_t count = wcstombs(NULL, wcs, 0);
+		if (count == -1)
+		{// 转换失败,count=-1;
+			LC_FREE;
+			return std::string();
+		}
+
+		if (count <= K1) // 1k;
+		{
+			char szValue[K1] = { 0 };
+			wcstombs(szValue, wcs, count);
+			LC_FREE;
+			return std::string(szValue);
+		}
+		else if (count <= K2) // 2k;
+		{
+			char szValue[K2] = { 0 };
+			wcstombs(szValue, wcs, count);
+			LC_FREE;
+			return std::string(szValue);
+		}
+		else if (count <= K4)	// 4k;
+		{
+			char szValue[K4] = { 0 };
+			wcstombs(szValue, wcs, count);
+			LC_FREE;
+			return std::string(szValue);
+		}
+		else if (count <= K8)	// 8k;
+		{
+			char szValue[K8] = { 0 };
+			wcstombs(szValue, wcs, count);
+			LC_FREE;
+			return std::string(szValue);
+		}
+		else
+		{// 超过8k;
+			char *pData = new char[count];
+			if ( pData )
+			{
+				memset(pData, 0, count);
+				wcstombs(pData, wcs, count);
+				
+				std::string val(pData);
+				delete []pData;
+				LC_FREE;
+
+				return val;
+			}
+		}
+
+		LC_FREE;
+	}
+	
+	return std::string();		
+}
+
+std::wstring c2w(LPCSTR mbs)
+{
+	if (mbs)
+	{
+		// 计算待转换的字节数
+		size_t count = mbstowcs(NULL, mbs, 0);
+		if (count <= K1) // 1k;
+		{
+			wchar_t szValue[K1] = { 0 };
+			mbstowcs(szValue, mbs, count);
+			return std::wstring(szValue);
+		}
+		else if (count <= K2) // 2k;
+		{
+			wchar_t szValue[K2] = { 0 };
+			mbstowcs(szValue, mbs, count);
+			return std::wstring(szValue);
+		}
+		else if (count <= K4)	// 4k;
+		{
+			wchar_t szValue[K4] = { 0 };
+			mbstowcs(szValue, mbs, count);
+			return std::wstring(szValue);
+		}
+		else if (count <= K8)	// 8k;
+		{
+			wchar_t szValue[K8] = { 0 };
+			mbstowcs(szValue, mbs, count);
+			return std::wstring(szValue);
+		}
+		else
+		{// 超过8k;
+			wchar_t *pData = new wchar_t[count];
+			memset(pData, 0, sizeof(wchar_t)*count);
+			mbstowcs(pData, mbs, count);
+
+			std::wstring val(pData);
+			delete []pData;
+
+			return val;
+		}
+	}
+	
+	return std::wstring();
+}

+ 32 - 0
WINHTTPS/WINHTTPS/stdafx.h

@@ -0,0 +1,32 @@
+// stdafx.h : 标准系统包含文件的包含文件,
+// 或是经常使用但不常更改的
+// 特定于项目的包含文件
+//
+
+#pragma once
+
+#include "targetver.h"
+
+#include <stdio.h>
+#include <tchar.h>
+
+#include <stdlib.h>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#pragma region WINHTTP模块头文件
+#include <windows.h>
+#include <winhttp.h>
+#pragma comment(lib, "winhttp.lib")
+#pragma endregion
+
+#define K0 256
+#define K1 1024
+#define K2 2048
+#define K4 4096
+#define K8 8192
+std::string w2c(LPCWSTR wcs);
+std::wstring c2w(LPCSTR mbs);
+
+// TODO: 在此处引用程序需要的其他头文件

+ 13 - 0
WINHTTPS/WINHTTPS/targetver.h

@@ -0,0 +1,13 @@
+#pragma once
+
+// 以下宏定义要求的最低平台。要求的最低平台
+// 是具有运行应用程序所需功能的 Windows、Internet Explorer 等产品的
+// 最早版本。通过在指定版本及更低版本的平台上启用所有可用的功能,宏可以
+// 正常工作。
+
+// 如果必须要针对低于以下指定版本的平台,请修改下列定义。
+// 有关不同平台对应值的最新信息,请参考 MSDN。
+#ifndef _WIN32_WINNT            // 指定要求的最低平台是 Windows Vista。
+#define _WIN32_WINNT 0x0600     // 将此值更改为相应的值,以适用于 Windows 的其他版本。
+#endif
+

+ 137 - 0
WINHTTPS/WinHttp简介.txt

@@ -0,0 +1,137 @@
+Windows HTTP服务(WinHTTP)
+目的
+Microsoft Windows HTTP服务(WinHTTP)为开发人员提供了HTTP客户端应用程序编程接口(API),通过HTTP协议向其他HTTP服务器发送请求。
+
+适用范围
+
+WinHTTP支持桌面客户端应用程序,Windows服务和基于Windows服务器的应用程序。
+
+因为.NET Framework应用程序应该使用System.net类中的网络设施,所以不建议在Microsoft .NET Framework上构建WinHTTP。
+
+
+开发人员
+
+WinHTTP提供适用于基于Active Server Pages(ASP)的应用程序的C / C ++应用程序编程接口(API)和组件对象模型(COM)自动化组件。
+
+对HTTP协议的基本了解对于使用任一接口很重要。
+
+
+运行时要求
+
+WinHTTP 5.1提供5.0版本的改进。有关新功能的更多信息,请参阅WinHTTP 5.1中的新功能。
+
+WinHTTP 5.1现在是以下系统的操作系统组件:
+
+
+Windows Server 2003系列 
+Windows XP SP1 
+Windows 2000 SP3(数据中心服务器除外) 
+重要随着WinHTTP版本5.1的发布,WinHTTP 5.0下载不可用。Microsoft已从MSDN中删除WinHTTP 5.0 SDK下载,并于2004年10月1日终止了5.0版的产品支持。
+
+
+关于WinHTTP
+Microsoft Windows HTTP服务(WinHTTP)为开发人员提供了HTTP / 1.1 Internet协议的服务器支持的高级接口。WinHTTP旨在主要用于与HTTP服务器进行通信的服务器应用程序在基于服务器的场景中。
+
+WinINet是一种较旧的技术,被设计为用于交互式桌面应用程序(如Microsoft Internet Explorer,Microsoft Office和Microsoft Money)的HTTP客户端平台。WinINet会显示一些用户界面,例如收集用户凭据。然而,WinHTTP以编程方式处理这些操作。需要HTTP客户端服务的服务器应用程序应使用WinHTTP而不是WinINet。有关更多信息,请参阅将WinINet应用程序移植到WinHTTP。
+
+WinHTTP也被设计用于系统服务和基于HTTP的客户端应用程序。WinHTTP比WinInet更安全可靠。但是,需要FTP或Gopher协议功能,cookie持久性,缓存,自动凭证对话框处理,Internet Explorer兼容性或下级平台支持的单用户应用程序应考虑使用WinInet。
+
+该接口可以通过使用WinHTTP应用程序编程接口(API)或使用IWinHttpRequest和IWinHttpRequestEvents接口从C / C ++访问。也可以通过WinHTTP对象从脚本和Microsoft Visual Basic访问WinHTTP。有关各个功能的更多信息和说明,请参阅特定语言的WinHTTP函数参考。
+
+应用程序(如C#或ASP.NET应用程序)应考虑托管的.NET Framework类。有关使用.NET Framework网络类的更多信息,请参阅MSDN库中的“访问Internet”主题:“.NET开发”>“.NET Framework SDK”>“.NET Framework”>“使用。 .NET框架“。
+
+注意除了异步完成回调之外,WinHTTP不可重入。也就是说,当线程有一个等待WinHTTP功能之一的调用,如WinHttpSendRequest,WinHttoReceiveResponse,WinHttpQueryDataAvailable,WinHttpSendData或WinHttpWriteData时,它不能再次调用WinHTTP直到第一个调用完成。可能发生第二次调用的一种情况如下:如果应用程序将异步过程调用(APC)排队到调用WinHTTP的线程中,并且如果WinHTTP在内部执行警报等待,则APC将有机会运行。现在如果APC例程也可以调用WinHTTP,它重新输入WinHTTP API,WinHTTP的内部状态可能会被破坏。
+
+WinHTTP 5.1特性
+
+在WinHTTP 5.1版中添加了以下功能:
+
+IPv6支持。 
+AutoProxy功能。 
+HTTP / 1.0协议,包括对keep-alive(持久)连接和会话cookie的支持。 
+HTTP / 1.1分组转移支持HTTP响应。 
+在会话之间保持活跃的匿名连接池。 
+安全套接字层(SSL)功能,包括客户端证书。支持的SSL协议包括以下内容:SSL 2.0,SSL 3.0和传输层安全性(TLS)1.0。
+支持服务器和代理身份验证,包括对Microsoft Passport 1.4和Negotiate / Kerberos包的集成支持。 
+自动处理重定向,除非被禁止。 
+脚本化界面除了API。 
+跟踪设备来帮助解决问题。 
+WinHTTP不支持多个WinINet功能,包括URL缓存和持久性Cookie,自动转发,自动拨号,离线支持,文件传输协议(FTP)和Gopher协议。
+
+有关版本5.1中引入的更改的更多信息,请参阅WinHTTP 5.1中的新增功能。
+
+
+WinHTTP入门
+
+
+有关WinHTTP的更多信息,请参阅以下主题:
+
+WinHTTP版本描述了在不同平台上运行的两个版本的WinHTTP,版本5.0和版本5.1。 
+WinHTTP 5.1中的新功能介绍了最新版本的WinHTTP中的更改和新增功能。 
+网络术语描述了与一般的网络和特定的HTTP协议有关的有用的概念和术语。 
+选择一个WinHTTP接口描述了C / C ++ API和WinHTTP的COM接口。 
+WinHTTP安全注意事项描述使用WinHTTP时要注意的安全问题。 
+将WinINet应用程序移植到WinHTTP中,介绍如何修改现有的WinINet应用程序以使用WinHTTP API。 
+
+WinHTTP功能
+WinHTTP提供以下功能:
+
+
+
+WinHttpAddRequestHeaders 
+向HTTP请求句柄添加一个或多个HTTP请求标头。 
+WinHttpCheckPlatform 
+确定WinHTTP是否支持当前平台。 
+WinHttpCloseHandle 
+关闭单个HINTERNET句柄。 
+WinHttpConnect 
+指定HTTP请求的初始目标服务器。 
+WinHttpCrackUrl 
+将URL分为其组成部分,例如主机名和路径。 
+WinHttpCreateUrl 
+从组件部分创建URL,例如主机名和路径。 
+WinHttpDetectAutoProxyConfigUrl 
+查找代理自动配置(PAC)文件的URL。此功能报告PAC文件的URL,但不下载该文件。
+WinHttpGetDefaultProxyConfiguration 
+从注册表中检索默认的WinHTTP代理配置。 
+WinHTTPGetIEProxyConfigForCurrentUser 
+获取当前用户的Internet Explorer(IE)代理配置。 
+WinHttpGetProxyForUrl 
+检索指定URL的代理信息。 
+WinHttpOpen 
+初始化应用程序对WinHTTP功能的使用。 
+WinHttpOpenRequest 
+创建HTTP请求句柄。 
+WinHttpQueryAuthSchemes 
+返回服务器支持的授权方案。 
+WinHttpQueryDataAvailable 
+返回使用WinHttpReadData立即可以读取的数据的字节数。 
+WinHttpQueryHeaders 
+检索与HTTP请求相关联的头信息。 
+WinHttpQueryOption 
+在指定的句柄上查询Internet选项。 
+WinHttpReadData 
+从WinHttpOpenRequest函数打开的句柄中读取数据。 
+WinHttpReceiveResponse 
+结束由WinHttpSendRequest启动的HTTP请求。 
+WinHttpSendRequest 
+将指定的请求发送到HTTP服务器。 
+WinHttpSetCredentials 
+将所需的授权凭证传递给服务器。 
+WinHttpSetDefaultProxyConfiguration 
+在注册表中设置默认的WinHTTP代理配置。 
+WinHttpSetOption 
+设置Internet选项。 
+WinHttpSetStatusCallback 
+设置WinHTTP可以在操作过程中进行调用的回调函数。 
+WinHttpSetTimeouts 
+设置涉及HTTP事务的各种超时。 
+WinHttpTimeFromSystemTime 
+根据HTTP版本1.0规范格式化日期和时间。 
+WinHttpTimeToSystemTime 
+获取HTTP时间/日期字符串并将其转换为SYSTEMTIME结构。 
+WinHttpWriteData 
+将请求数据写入HTTP服务器。 
+————————————————
+版权声明:本文为CSDN博主「零点零一」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
+原文链接:https://blog.csdn.net/thanklife/article/details/70909661

BIN
WINHTTPS/winhttp.zip