LosaDev source snapshot 2019

This commit is contained in:
LosaDev committed 2026-11-07 13:30:45 +07:00
commit c198676e97
20588 files changed
+8812878

No files matched your search

+26
View File
@@ -0,0 +1,26 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LS_HTTP", "LS_HTTP\LS_HTTP.vcxproj", "{6011AA87-DD99-46AB-BFD4-3DB1C23E08FF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Dbg_GA|Win32 = Dbg_GA|Win32
Debug|Win32 = Debug|Win32
Rel_GA|Win32 = Rel_GA|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6011AA87-DD99-46AB-BFD4-3DB1C23E08FF}.Dbg_GA|Win32.ActiveCfg = Dbg_GA|Win32
{6011AA87-DD99-46AB-BFD4-3DB1C23E08FF}.Dbg_GA|Win32.Build.0 = Dbg_GA|Win32
{6011AA87-DD99-46AB-BFD4-3DB1C23E08FF}.Debug|Win32.ActiveCfg = Debug|Win32
{6011AA87-DD99-46AB-BFD4-3DB1C23E08FF}.Debug|Win32.Build.0 = Debug|Win32
{6011AA87-DD99-46AB-BFD4-3DB1C23E08FF}.Rel_GA|Win32.ActiveCfg = Rel_GA|Win32
{6011AA87-DD99-46AB-BFD4-3DB1C23E08FF}.Rel_GA|Win32.Build.0 = Rel_GA|Win32
{6011AA87-DD99-46AB-BFD4-3DB1C23E08FF}.Release|Win32.ActiveCfg = Release|Win32
{6011AA87-DD99-46AB-BFD4-3DB1C23E08FF}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
+178
View File
@@ -0,0 +1,178 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Dbg_GA|Win32">
<Configuration>Dbg_GA</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Rel_GA|Win32">
<Configuration>Rel_GA</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{6011AA87-DD99-46AB-BFD4-3DB1C23E08FF}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>LS_HTTP</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Dbg_GA|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Rel_GA|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Dbg_GA|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Rel_GA|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 Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetName>$(ProjectName)D</TargetName>
<OutDir>../../lib/</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Dbg_GA|Win32'">
<TargetName>LS_HTTP_ClientD</TargetName>
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>../../lib/</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Rel_GA|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<TargetName>LS_HTTP_Client</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../include/</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PostBuildEvent>
<Command>copy "$(TargetDir)\$(TargetName)$(TargetExt)" "$(TargetDir)\..\..\lib\$(TargetName)$(TargetExt)"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Dbg_GA|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;USE_GA;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../include/</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PostBuildEvent>
<Command>copy "$(TargetDir)\$(TargetName)$(TargetExt)" "$(TargetDir)\..\..\lib\$(TargetName)$(TargetExt)"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>../include/</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PostBuildEvent>
<Command>copy "$(TargetDir)\$(TargetName)$(TargetExt)" "$(TargetDir)\..\..\lib\$(TargetName)$(TargetExt)"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Rel_GA|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;USE_GA;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<AdditionalIncludeDirectories>../include/</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PostBuildEvent>
<Command>copy "$(TargetDir)\$(TargetName)$(TargetExt)" "$(TargetDir)\..\..\lib\$(TargetName)$(TargetExt)"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="ioHTTP.cpp" />
<ClCompile Include="stdafx.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\atlrx.h" />
<ClInclude Include="..\include\RegExp.h" />
<ClInclude Include="..\include\StringProcess.h" />
<ClInclude Include="..\include\WinHttpClient.h" />
<ClInclude Include="ioHTTP.h" />
<ClInclude Include="stdafx.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,51 @@
<?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;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="include">
<UniqueIdentifier>{74af3440-f95c-46b7-8c25-e3ae982f2f29}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="ioHTTP.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="..\include\atlrx.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\include\RegExp.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\include\StringProcess.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\include\WinHttpClient.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="ioHTTP.h">
<Filter>헤더 파일</Filter>
</ClInclude>
</ItemGroup>
</Project>
+27
View File
@@ -0,0 +1,27 @@
========================================================================
정적 라이브러리 : LS_HTTP 프로젝트 개요
========================================================================
응용 프로그램 마법사에서 이 LS_HTTP 라이브러리 프로젝트를 만들었습니다.
프로젝트에 대해 소스 파일은 만들어지지 않았습니다.
LS_HTTP.vcxproj
응용 프로그램 마법사를 사용하여 생성한 VC++ 프로젝트의 기본 프로젝트 파일입니다.
파일을 생성한 Visual C++ 버전에 대한 정보와 응용 프로그램 마법사를 사용하여 선택한 플랫폼,
구성 및 프로젝트 기능에 대한 정보가 포함되어 있습니다.
LS_HTTP.vcxproj.filters
응용 프로그램 마법사를 사용하여 생성된 VC++ 프로젝트의 필터 파일입니다.
이 파일에는 프로젝트의 파일과 필터 간의 연결 정보가 들어 있습니다.
이러한 연결은 특정 노드에서 유사한 확장명으로 그룹화된 파일을 표시하기 위해 IDE에서
사용됩니다. 예를 들어 ".cpp" 파일은 "소스 파일" 필터와 연결되어 있습니다.
/////////////////////////////////////////////////////////////////////////////
기타 참고:
응용 프로그램 마법사에서 사용하는 "TODO:" 주석은 사용자가 추가하거나 사용자 지정해야 하는
소스 코드 부분을 나타냅니다.
/////////////////////////////////////////////////////////////////////////////
+135
View File
@@ -0,0 +1,135 @@
#include "stdafx.h"
#include "WinHttpClient.h"
#include "ioHTTP.h"
ioHTTP::ioHTTP(void)
{
Init();
}
ioHTTP::~ioHTTP(void)
{
Destroy();
}
void ioHTTP::Init()
{
}
void ioHTTP::Destroy()
{
}
#if !defined( USE_GA )
DWORD Ansi2Wide(const char * szANSI, wchar_t* szWide, int iWideLen)
{
int iRet = MultiByteToWideChar( GetACP(),
0,
szANSI,
-1,
szWide,
iWideLen);
return (iRet);
}
DWORD Wide2Ansi(const wchar_t* szWide, char * szANSI, int iAnsiLen)
{
ZeroMemory(szANSI, iAnsiLen);
int iRet = WideCharToMultiByte(CP_ACP, 0, szWide, -1, szANSI, iAnsiLen, NULL, NULL);
return iRet;
}
#endif
DWORD Wide2Utf8(const wchar_t* szWide, char * szANSI, int iAnsiLen)
{
ZeroMemory(szANSI, iAnsiLen);
int iRet = WideCharToMultiByte(CP_UTF8, 0, szWide, -1, szANSI, iAnsiLen, NULL, NULL);
return iRet;
}
BOOL ioHTTP::GetResultData(const CHAR* URL, const char* POST, char* result, const int length)
{
WinHttpClient wHTTP;
wstring wURL;
wURL = CA2W(URL);
wstring verb = CA2W(POST);
wHTTP.UpdateUrl(wURL);
int postLen = strlen(POST);
//// Set post data.
if( strcmp("GET",POST) != 0) //post ¹æ½ÄÀ϶§
{
verb = L"POST";
wHTTP.SetAdditionalDataToSend((BYTE *)POST, postLen);
wchar_t szSize[50] = L"";
swprintf_s(szSize, L"%d", postLen);
wstring headers = L"Content-Length: ";
headers += szSize;
headers += L"\r\nContent-Type: application/x-www-form-urlencoded\r\n";
wHTTP.SetAdditionalRequestHeaders(headers);
}
else
verb = L"GET";
if(!wHTTP.SendHttpRequest(verb))
return FALSE;
wstring responseHeader = wHTTP.GetResponseHeader();
wstring responseContent = wHTTP.GetResponseContent();
Wide2Utf8( responseContent.c_str(), result, length );
return TRUE;
}
BOOL ioHTTP::GetResultData(const CHAR* URL, const char* POST, char* HEADER, char* result, const int length)
{
WinHttpClient wHTTP;
wstring wURL, wHeader;
wURL = CA2W(URL);
wHeader = CA2W(HEADER);
wstring verb = CA2W(POST);
wHTTP.UpdateUrl(wURL);
int postLen = strlen(POST)+2;
//// Set post data.
if( strcmp("GET",POST) != 0) //post ¹æ½ÄÀ϶§
{
verb = L"POST";
wHTTP.SetAdditionalDataToSend((BYTE *)POST, postLen);
wchar_t szSize[50] = L"";
swprintf_s(szSize, L"%d", postLen);
wstring headers = wHeader;
headers += L"\r\n";
headers += L"Content-Length: ";
headers += szSize;
headers += L"\r\n";
wHTTP.SetAdditionalRequestHeaders(headers);
}
else
verb = L"GET";
if(!wHTTP.SendHttpRequest(verb))
return FALSE;
wstring responseHeader = wHTTP.GetResponseHeader();
wstring responseContent = wHTTP.GetResponseContent();
Wide2Utf8( responseContent.c_str(), result, length );
return TRUE;
}
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include <string>
class ioHTTP
{
public:
ioHTTP(void);
~ioHTTP(void);
void Init();
void Destroy();
public:
BOOL GetResultData(const CHAR* URL, const char* POST, char* result, const int length);
BOOL GetResultData(const CHAR* URL, const char* POST, char* HEADER, char* result, const int length);
};
+183
View File
@@ -0,0 +1,183 @@
// Test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "WinHttpClient.h"
void SimpleGetTest(void)
{
// Set URL.
WinHttpClient client(L"http://www.codeproject.com/");
// Send http request, a GET request by default.
client.SendHttpRequest();
// The response header.
wstring httpResponseHeader = client.GetResponseHeader();
// The response content.
wstring httpResponseContent = client.GetResponseContent();
}
void SimplePostTest(void)
{
WinHttpClient client(L"http://www.codeproject.com/");
// Set post data.
string data = "title=A_NEW_THREAD&content=This_is_a_new_thread.";
client.SetAdditionalDataToSend((BYTE *)data.c_str(), data.size());
// Set request headers.
wchar_t szSize[50] = L"";
swprintf_s(szSize, L"%d", data.size());
wstring headers = L"Content-Length: ";
headers += szSize;
headers += L"\r\nContent-Type: application/x-www-form-urlencoded\r\n";
client.SetAdditionalRequestHeaders(headers);
// Send http post request.
client.SendHttpRequest(L"POST");
wstring httpResponseHeader = client.GetResponseHeader();
wstring httpResponseContent = client.GetResponseContent();
}
// Progress - finished percentage.
bool ProgressProc(double progress)
{
wprintf(L"Current progress: %-.1f%%\r\n", progress);
return true;
}
void ProgressTest(void)
{
// Set URL and call back function.
WinHttpClient client(L"http://www.codeproject.com/", ProgressProc);
client.SendHttpRequest();
wstring httpResponseHeader = client.GetResponseHeader();
wstring httpResponseContent = client.GetResponseContent();
}
void UserAgentTest(void)
{
WinHttpClient client(L"http://www.codeproject.com/");
// Set the user agent to the same as IE8.
client.SetUserAgent(L"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; InfoPath.2; CIBA; MS-RTC LM 8)");
client.SendHttpRequest();
wstring httpResponseHeader = client.GetResponseHeader();
wstring httpResponseContent = client.GetResponseContent();
}
void ProxyTest(void)
{
WinHttpClient client(L"http://www.codeproject.com/");
// Set the proxy to 192.168.0.1 with port 8080.
client.SetProxy(L"192.168.0.1:8080");
client.SendHttpRequest();
wstring httpResponseHeader = client.GetResponseHeader();
wstring httpResponseContent = client.GetResponseContent();
}
void CookiesTest(void)
{
WinHttpClient client(L"http://www.codeproject.com/");
// Set the cookies to send.
client.SetAdditionalRequestCookies(L"username=jack");
client.SendHttpRequest();
// Get the response cookies.
wstring httpResponseCookies = client.GetResponseCookies();
wstring httpResponseHeader = client.GetResponseHeader();
wstring httpResponseContent = client.GetResponseContent();
}
void HttpsTest(void)
{
WinHttpClient client(L"https://www.google.com/");
// Accept any certificate while performing HTTPS request.
client.SetRequireValidSslCertificates(false);
// Get the response cookies.
wstring httpResponseCookies = client.GetResponseCookies();
wstring httpResponseHeader = client.GetResponseHeader();
wstring httpResponseContent = client.GetResponseContent();
}
void MultipleRequestsTest(void)
{
WinHttpClient client(L"http://www.google.com/");
client.SendHttpRequest();
wstring httpResponseHeader = client.GetResponseHeader();
wstring httpResponseContent = client.GetResponseContent();
// Update the url.
client.UpdateUrl(L"http://www.microsoft.com/");
client.SendHttpRequest();
httpResponseHeader = client.GetResponseHeader();
httpResponseContent = client.GetResponseContent();
}
void CompleteTest(void)
{
// 1. Get the initial cookie.
WinHttpClient getClient(L"http://www.codeproject.com/script/Membership/LogOn.aspx");
getClient.SetAdditionalRequestHeaders(L"Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\r\nAccept-Language: en-us\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; QQPinyin 730; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; InfoPath.2; CIBA; MS-RTC LM 8)\r\nAccept-Encoding: gzip, deflate\r\nProxy-Connection: Keep-Alive\r\nHost: www.codeproject.com\r\n");
if (!getClient.SendHttpRequest())
{
return;
}
// 2. Post data to get the authentication cookie.
WinHttpClient postClient(L"http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fscript%2fMembership%2fLogOn.aspx");
// Post data.
// Change this to your Codeproject username and password.
wstring username = L"YourCodeProjectUsername";
wstring password = L"YourPassword";
postClient.SetAdditionalRequestCookies(getClient.GetResponseCookies());
string data = "FormName=MenuBarForm&Email=";
data += (char *)_bstr_t(username.c_str());
data += "&Password=";
data += (char *)_bstr_t(password.c_str());
data += "&RememberMeCheck=1";
postClient.SetAdditionalDataToSend((BYTE *)data.c_str(), data.size());
// Post headers.
wstring headers = L"Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\r\nReferer: http://www.codeproject.com/script/Membership/LogOn.aspx\r\nAccept-Language: en-us\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; QQPinyin 730; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; InfoPath.2; CIBA; MS-RTC LM 8)\r\nContent-Type: application/x-www-form-urlencoded\r\nHost: www.codeproject.com\r\nContent-Length: %d\r\nProxy-Connection: Keep-Alive\r\nPragma: no-cache\r\n";
wchar_t szHeaders[MAX_PATH * 10] = L"";
swprintf_s(szHeaders, MAX_PATH * 10, headers.c_str(), data.size());
postClient.SetAdditionalRequestHeaders(szHeaders);
if (!postClient.SendHttpRequest(L"POST", true))
{
return;
}
// 3. Finally get the zip file.
WinHttpClient downloadClient(L"http://www.codeproject.com/KB/IP/win_HTTP_wrapper/WinHttpClient_Src.zip");
downloadClient.SetUserAgent(L"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; InfoPath.2; CIBA; MS-RTC LM 8)");
// Sending this cookie make server believe you have already logged in.
downloadClient.SetAdditionalRequestCookies(postClient.GetResponseCookies());
if (!downloadClient.SendHttpRequest())
{
return;
}
downloadClient.SaveResponseToFile(L"C:\\WinHttpClient_Src.zip");
}
int _tmain(int /*argc*/, _TCHAR** /*argv*/)
{
CompleteTest();
return 0;
}
+8
View File
@@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// Test.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
+16
View File
@@ -0,0 +1,16 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <string>
typedef std::basic_string<TCHAR> tstring;
// TODO: reference additional headers your program requires here
+13
View File
@@ -0,0 +1,13 @@
#pragma once
// The following macros define the minimum required platform. The minimum required platform
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
// your application. The macros work by enabling all features available on platform versions up to and
// including the version specified.
// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows.
#endif
Binary file not shown.
+146
View File
@@ -0,0 +1,146 @@
/**
* Copyright 2008-2009 Cheng Shi. All rights reserved.
* Email: [email protected]
*/
#ifndef REGEXP_H
#define REGEXP_H
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#pragma warning(push)
#pragma warning(disable: 6385 6011 4127)
#include "atlrx.h"
#pragma warning(pop)
/*
* Parameters
* [in] regExp: Value of type string which is the input regular expression.
* [in] caseSensitive: Value of type bool which indicate whether the parse is case sensitive.
* [in] groupCount: Value of type int which is the group count of the regular expression.
* [in] source: Value of type string reference which is the source to parse.
* [out] result: Value of type vecotr of strings which is the output of the parse.
* [in] allowDuplicate: Value of type bool which indicates whether duplicate items are added to the output result.
*
* Return Value
* Returns true if the function succeeds, or false otherwise.
*
* Remarks
* The output result is devided into groups. User should get the groups according to the group count. For example:
* 1. RegExp = L"{ab}", source = L"abcabe", then result = L"ab", L"ab".
* 2. RegExp = L"{ab}{cd}", source = L"abcdeabecd", then result = L"ab", L"cd", L"ab", L"cd".
*/
inline bool ParseRegExp(const wstring &regExp, bool caseSensitive, int groupCount, const wstring &source, vector<wstring> &result, bool allowDuplicate = false)
{
result.clear();
if (regExp.size() <= 0)
{
return false;
}
if (groupCount <= 0)
{
return false;
}
if (source.size() <= 0)
{
return false;
}
CAtlRegExp<CAtlRECharTraitsW> re;
REParseError error = re.Parse(regExp.c_str(), caseSensitive);
if (error != REPARSE_ERROR_OK)
{
return false;
}
wchar_t *pSource = new wchar_t[source.size()+1];
wchar_t *pSourceEnd = pSource + source.size();
if (pSource == NULL)
{
return false;
}
wcscpy_s(pSource, source.size()+1, source.c_str());
BOOL bSucceed = TRUE;
CAtlREMatchContext<CAtlRECharTraitsW> mc;
const wchar_t *pFrom = pSource;
const wchar_t *pTo = NULL;
while (bSucceed)
{
bSucceed = re.Match(pFrom, &mc, &pTo);
if (bSucceed)
{
const wchar_t *pStart = NULL;
const wchar_t *pEnd = NULL;
vector<wstring> tempMatch;
for (int i = 0; i < groupCount; i++)
{
mc.GetMatch(i, &pStart, &pEnd);
if (pStart != NULL && pEnd != NULL)
{
wstring match(pStart, pEnd-pStart);
tempMatch.push_back(match);
}
else
{
break;
}
}
bool bAdd = true;
if (!allowDuplicate)
{
// Check whether this match already exists in the vector.
for (vector<wstring>::iterator it = result.begin(); it != result.end();)
{
bool bEqual = true;
for (vector<wstring>::iterator tempMatchIt = tempMatch.begin(); tempMatchIt != tempMatch.end(); tempMatchIt++, it++)
{
bool bGroupEqual = true;
if (caseSensitive)
{
bGroupEqual = (wcscmp(it->c_str(), tempMatchIt->c_str()) == 0);
}
else
{
bGroupEqual = (_wcsicmp(it->c_str(), tempMatchIt->c_str()) == 0);
}
if (!bGroupEqual)
{
bEqual = false;
}
}
if (bEqual)
{
bAdd = false;
break;
}
}
}
if (bAdd)
{
for (vector<wstring>::iterator tempMatchIt = tempMatch.begin(); tempMatchIt != tempMatch.end(); tempMatchIt++)
{
result.push_back(*tempMatchIt);
}
}
if (pTo < pSourceEnd)
{
pFrom = pTo;
}
else
{
break;
}
}
else
{
break;
}
}
delete[] pSource;
return true;
}
#endif // REGEXP_H
+569
View File
@@ -0,0 +1,569 @@
/**
* Copyright 2008-2009 Cheng Shi. All rights reserved.
* Email: [email protected]
*/
#ifndef STRINGPROCESS_H
#define STRINGPROCESS_H
#include "RegExp.h"
#include <Windows.h>
#include <iostream>
#include <string>
#include <comutil.h>
#pragma warning(push)
#pragma warning(disable: 4127)
#include <atlcomtime.h>
#pragma warning(pop)
using namespace std;
inline wstring Trim(const wstring &source, const wstring &targets)
{
wstring::size_type start = 0;
wstring::size_type end = 0;
for (start = 0; start < source.size(); start++)
{
bool bIsTarget = false;
for (wstring::size_type i = 0; i < targets.size(); i++)
{
if (source[start] == targets[i])
{
bIsTarget = true;
break;
}
}
if (!bIsTarget)
{
break;
}
}
for (end = source.size() - 1; (int)end >= 0; end--)
{
bool bIsTarget = false;
for (wstring::size_type i = 0; i < targets.size(); i++)
{
if (source[end] == targets[i])
{
bIsTarget = true;
break;
}
}
if (!bIsTarget)
{
break;
}
}
wstring result = L"";
if (end >= start && start < source.size() && end >= 0)
{
result = source.substr(start, end-start+1);
}
return result;
}
inline bool PrepareString(wchar_t *dest, size_t *size, const wstring &src)
{
if (dest == NULL)
{
if (size != NULL)
{
*size = src.size();
}
return false;
}
else
{
if (size != NULL)
{
wcsncpy_s(dest, *size, src.c_str(), _TRUNCATE);
if (*size <= src.size())
{
::SetLastError(ERROR_INSUFFICIENT_BUFFER);
return false;
}
}
}
return true;
}
inline wstring ReplaceString(const wstring &srcStr, const wstring &oldStr, const wstring &newStr)
{
if (srcStr.size() <= 0 || oldStr.size() <= 0)
{
return srcStr;
}
wstring strReturn = srcStr;
wstring::size_type offset = 0;
wstring::size_type start = strReturn.find(oldStr);
while (start != wstring::npos)
{
offset = start + newStr.size();
strReturn.replace(start, oldStr.size(), newStr);
start = strReturn.find(oldStr, offset);
}
return strReturn;
}
inline int StringToInteger(const wstring &number)
{
if (number.size() <= 0)
{
return 0;
}
wstring num = ReplaceString(number, L",", L"");
num = ReplaceString(num, L" ", L"");
return _wtoi(num.c_str());
}
inline wstring LowerString(const wstring &text)
{
if (text.size() <= 0)
{
return L"";
}
unsigned int iLength = text.size() + 1;
wchar_t *pTemp = new wchar_t[iLength];
if (pTemp == NULL)
{
return L"";
}
wcscpy_s(pTemp, iLength, text.c_str());
_wcslwr_s(pTemp, iLength);
wstring retStr = pTemp;
delete[] pTemp;
return retStr;
}
inline wstring UpperString(const wstring &text)
{
if (text.size() <= 0)
{
return L"";
}
unsigned int iLength = text.size() + 1;
wchar_t *pTemp = new wchar_t[iLength];
if (pTemp == NULL)
{
return L"";
}
wcscpy_s(pTemp, iLength, text.c_str());
_wcsupr_s(pTemp, iLength);
wstring retStr = pTemp;
delete[] pTemp;
return retStr;
}
inline wstring GetAnchorText(const wstring &anchor)
{
wstring regExp = L"<a.*?>[ \t\r\n]*{.*?}[ \t\r\n]*</a>";
vector<wstring> result;
if (ParseRegExp(regExp, false, 1, anchor, result) && result.size() == 1)
{
wstring text = result[0];
return text;
}
return L"";
}
inline wstring GetAnchorLink(const wstring &anchor)
{
wstring regExp = L"<a.*?href=\"|\'{.*?}\"|\'.*?>.*?</a>";
vector<wstring> result;
if (ParseRegExp(regExp, false, 1, anchor, result) && result.size() == 1)
{
wstring link = result[0];
return link;
}
return L"";
}
inline bool SeparateString(const wstring &content, const wstring &delimiter, vector<wstring> &result)
{
if (content.size() <= 0 || delimiter.size() <= 0)
{
return false;
}
result.clear();
wstring::size_type start = 0;
wstring::size_type index = 0;
index = content.find(delimiter, start);
while (index != wstring::npos)
{
wstring::size_type size = index - start;
if (size > 0)
{
wstring temp = content.substr(start, size);
if (temp.size() > 0)
{
result.push_back(temp);
}
}
start += size + delimiter.size();
index = content.find(delimiter, start);
}
if (content.find(delimiter) != wstring::npos)
{
wstring last = content.substr(start);
if (last.size() > 0)
{
result.push_back(last);
}
}
else
{
false;
}
return true;
}
inline wstring URLEncoding(const wstring &keyword, bool convertToUTF8 = true)
{
int iLength = 0;
char *szKeyword = NULL;
if (convertToUTF8)
{
iLength = ::WideCharToMultiByte(CP_UTF8,
0,
keyword.c_str(),
keyword.length(),
NULL,
0,
NULL,
NULL);
if (iLength <= 0)
{
return L"";
}
szKeyword = new char[iLength];
if (szKeyword == NULL)
{
return L"";
}
iLength = ::WideCharToMultiByte(CP_UTF8,
0,
keyword.c_str(),
keyword.length(),
szKeyword,
iLength,
NULL,
NULL);
}
else
{
string strKeyword = (char *)(_bstr_t)keyword.c_str();
iLength = (int)strKeyword.length();
szKeyword = new char[strKeyword.length() + 1];
strcpy_s(szKeyword, strKeyword.length() + 1, strKeyword.c_str());
}
wstring encodedKeyword = L"";
string strEncodedKeyword = "";
for (int i = 0; i < iLength; i++)
{
unsigned char c = (unsigned char)szKeyword[i];
char temp[MAX_PATH] = "";
sprintf_s(temp, MAX_PATH, "%%%2X", c);
if (temp[1] == ' ')
{
temp[1] = '0';
}
strEncodedKeyword += temp;
}
if (szKeyword != NULL)
{
delete[] szKeyword;
}
encodedKeyword = (wchar_t *)(_bstr_t)strEncodedKeyword.c_str();
encodedKeyword = ReplaceString(encodedKeyword, L" ", L"+");
return encodedKeyword;
}
inline unsigned int GetSeparateKeywordMatchGrade(const wstring &source, const wstring &keyword)
{
if (source.length() <= 0 || keyword.length() <= 0)
{
return 0;
}
wstring lowerSource = LowerString(source);
wstring lowerKeyword = LowerString(keyword);
unsigned int grade = 0;
if (lowerKeyword.length() <= 3)
{
if (lowerSource.find(lowerKeyword) != wstring::npos)
{
grade = 100;
}
else
{
grade = 0;
}
}
else
{
unsigned int matchLength = 0;
unsigned int index = 0;
while (index < lowerKeyword.length())
{
unsigned int compareLength = lowerKeyword.length() - index;
while (compareLength > 0 && index < lowerKeyword.length())
{
wstring subKeyword = lowerKeyword.substr(index, compareLength);
if (lowerSource.find(subKeyword) != wstring::npos)
{
matchLength += compareLength;
index += compareLength;
}
else
{
compareLength--;
}
}
index++;
}
grade = matchLength * 100 / lowerKeyword.length();
}
return grade;
}
inline unsigned int GetKeywordMatchGrade(const wstring &source, const wstring & keyword)
{
if (source.length() <= 0 || keyword.length() <= 0)
{
return 0;
}
unsigned int grade = 0;
wstring src = source;
while (src.find(L"\t") != wstring::npos)
{
src = ReplaceString(src, L"\t", L" ");
}
while (src.find(L" ") != wstring::npos)
{
src = ReplaceString(src, L" ", L" ");
}
vector<wstring> results;
if (SeparateString(keyword, L" ", results) && results.size() > 0)
{
unsigned int keywordTotalLength = 0;
for (vector<wstring>::size_type index = 0; index < results.size(); index++)
{
keywordTotalLength += results[index].length();
}
for (vector<wstring>::size_type index = 0; index < results.size(); index++)
{
grade += GetSeparateKeywordMatchGrade(src, results[index]) * results[index].length() / keywordTotalLength;
}
}
else
{
grade = GetSeparateKeywordMatchGrade(src, keyword);
}
return grade;
}
inline wstring GetDateString(const COleDateTime &time, const wstring &separator = L"-", bool align = true)
{
wstring date = L"";
wchar_t szTemp[MAX_PATH] = L"";
swprintf_s(szTemp, MAX_PATH, L"%d", time.GetYear());
date += szTemp;
date += separator;
memset(szTemp, 0, sizeof(wchar_t) * MAX_PATH);
swprintf_s(szTemp, MAX_PATH, L"%d", time.GetMonth());
if (time.GetMonth() < 10 && align)
{
date += L"0";
}
date += szTemp;
date += separator;
memset(szTemp, 0, sizeof(wchar_t) * MAX_PATH);
swprintf_s(szTemp, MAX_PATH, L"%d", time.GetDay());
if (time.GetDay() < 10 && align)
{
date += L"0";
}
date += szTemp;
return date;
}
inline wstring GetDateString(int dayOffset, const wstring &separator = L"-", bool align = true)
{
COleDateTime time = COleDateTime::GetCurrentTime();
time += COleDateTimeSpan(dayOffset, 0, 0, 0);
return GetDateString(time, separator, align);
}
inline wstring GetTimeString(const COleDateTime &time, const wstring &separator = L":", bool align = true)
{
wstring date = L"";
wchar_t szTemp[MAX_PATH] = L"";
swprintf_s(szTemp, MAX_PATH, L"%d", time.GetHour());
date += szTemp;
date += separator;
memset(szTemp, 0, sizeof(wchar_t) * MAX_PATH);
swprintf_s(szTemp, MAX_PATH, L"%d", time.GetMinute());
if (time.GetMinute() < 10 && align)
{
date += L"0";
}
date += szTemp;
date += separator;
memset(szTemp, 0, sizeof(wchar_t) * MAX_PATH);
swprintf_s(szTemp, MAX_PATH, L"%d", time.GetSecond());
if (time.GetSecond() < 10 && align)
{
date += L"0";
}
date += szTemp;
return date;
}
inline wstring MD5(const wstring &text)
{
if (text.size() <= 0)
{
return L"";
}
string asciiText = (char *)(_bstr_t)text.c_str();
wstring encrypted = L"";
HCRYPTPROV hCryptProv = NULL;
if (::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET))
{
HCRYPTHASH hHash = NULL;
if (::CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash))
{
if (::CryptHashData(hHash, (BYTE *)asciiText.c_str(), asciiText.size(), 0))
{
BYTE result[16];
DWORD dwSize = 16;
wchar_t temp[3] = L"";
if (::CryptGetHashParam(hHash, HP_HASHVAL, result, &dwSize, 0))
{
for (unsigned int i = 0; i < 16; i++)
{
memset(temp, 0, 6);
swprintf(temp, 3, L"%02x", result[i]);
encrypted += temp;
}
}
}
::CryptDestroyHash(hHash);
::CryptReleaseContext(hCryptProv, 0);
}
}
return encrypted;
}
inline wstring FilterFileName(const wstring &name)
{
if (name.size() <= 0)
{
return L"";
}
wstring filteredName = name;
filteredName = ReplaceString(filteredName, L"/", L"_");
filteredName = ReplaceString(filteredName, L"\\", L"_");
filteredName = ReplaceString(filteredName, L":", L"_");
filteredName = ReplaceString(filteredName, L"*", L"_");
filteredName = ReplaceString(filteredName, L"?", L"_");
filteredName = ReplaceString(filteredName, L"\"", L"_");
filteredName = ReplaceString(filteredName, L"<", L"_");
filteredName = ReplaceString(filteredName, L">", L"_");
filteredName = ReplaceString(filteredName, L"|", L"_");
return filteredName;
}
inline wstring GetMagic(unsigned int length)
{
srand(::GetTickCount());
if (length <= 0)
{
return L"";
}
wstring margic = L"";
for (unsigned int i = 0; i < length; i++)
{
wchar_t szMargic[50] = L"";
swprintf_s(szMargic, 50, L"%c", rand() % 26 + L'a');
margic += szMargic;
}
return margic;
}
inline wstring GetHost(const wstring &url)
{
if (url.size() <= 0)
{
return L"";
}
wstring urlWidthoutHttp = ReplaceString(LowerString(url), L"http://", L"");
unsigned int index = urlWidthoutHttp.find(L"/");
if (index == wstring::npos)
{
index = urlWidthoutHttp.find(L"\\");
}
if (index == wstring ::npos)
{
return urlWidthoutHttp;
}
return urlWidthoutHttp.substr(0, index);
}
inline wstring GetValidFileName(const wstring &fileName)
{
if (fileName.size() == 0)
{
return L"";
}
wstring tempFileName = fileName;
tempFileName = ReplaceString(tempFileName, L"\\", L"_");
tempFileName = ReplaceString(tempFileName, L"/", L"_");
tempFileName = ReplaceString(tempFileName, L":", L"_");
tempFileName = ReplaceString(tempFileName, L"*", L"_");
tempFileName = ReplaceString(tempFileName, L"?", L"_");
tempFileName = ReplaceString(tempFileName, L"\"", L"_");
tempFileName = ReplaceString(tempFileName, L"<", L"_");
tempFileName = ReplaceString(tempFileName, L">", L"_");
tempFileName = ReplaceString(tempFileName, L"|", L"_");
tempFileName = ReplaceString(tempFileName, L"\r", L"_");
tempFileName = ReplaceString(tempFileName, L"\n", L"_");
tempFileName = ReplaceString(tempFileName, L"%", L"_");
return tempFileName;
}
#endif // STRINGPROCESS_H
+858
View File
@@ -0,0 +1,858 @@
/**
* Copyright 2008-2010 Cheng Shi. All rights reserved.
* Email: [email protected]
*/
#ifndef WINHTTPCLIENT_H
#define WINHTTPCLIENT_H
#pragma comment(lib, "Winhttp.lib")
#include "RegExp.h"
#include "StringProcess.h"
#include <comutil.h>
#include <windows.h>
#include <Winhttp.h>
#include <string>
using namespace std;
typedef bool (*PROGRESSPROC)(double);
static const unsigned int INT_RETRYTIMES = 3;
static wchar_t *SZ_AGENT = L"WinHttpClient";
static const int INT_BUFFERSIZE = 10240; // Initial 10 KB temporary buffer, double if it is not enough.
class WinHttpClient
{
public:
inline WinHttpClient(PROGRESSPROC progressProc = NULL);
inline ~WinHttpClient(void);
void Init();
void Destroy();
public:
// It is a synchronized method and may take a long time to finish.
inline bool SendHttpRequest(const wstring &httpVerb = L"GET", bool disableAutoRedirect = false);
inline wstring GetResponseHeader(void);
inline wstring GetResponseContent(void);
inline wstring GetResponseCharset(void);
inline wstring GetResponseStatusCode(void);
inline wstring GetResponseLocation(void);
inline wstring GetRequestHost(void);
inline const BYTE *GetRawResponseContent(void);
inline unsigned int GetRawResponseContentLength(void);
inline unsigned int GetRawResponseReceivedContentLength(void);
inline bool SaveResponseToFile(const wstring &filePath);
inline wstring GetResponseCookies(void);
inline bool SetAdditionalRequestCookies(const wstring &cookies);
inline bool SetAdditionalDataToSend(BYTE *data, unsigned int dataSize);
inline bool UpdateUrl(const wstring &url);
inline bool ResetAdditionalDataToSend(void);
inline bool SetAdditionalRequestHeaders(const wstring &additionalRequestHeaders);
inline bool SetRequireValidSslCertificates(bool require);
inline bool SetProxy(const wstring &proxy);
inline DWORD GetLastError(void);
inline bool SetUserAgent(const wstring &userAgent);
inline bool SetForceCharset(const wstring &charset);
inline bool SetProxyUsername(const wstring &username);
inline bool SetProxyPassword(const wstring &password);
inline bool SetTimeouts(unsigned int resolveTimeout = 0,
unsigned int connectTimeout = 60000,
unsigned int sendTimeout = 30000,
unsigned int receiveTimeout = 30000);
private:
inline WinHttpClient(const WinHttpClient &other);
inline WinHttpClient &operator =(const WinHttpClient &other);
inline bool SetProgress(unsigned int byteCountReceived);
HINTERNET m_sessionHandle;
bool m_requireValidSsl;
wstring m_requestURL;
wstring m_requestHost;
wstring m_responseHeader;
wstring m_responseContent;
wstring m_responseCharset;
BYTE *m_pResponse;
unsigned int m_responseByteCountReceived; // Up to 4GB.
PROGRESSPROC m_pfProcessProc;
unsigned int m_responseByteCount;
wstring m_responseCookies;
wstring m_additionalRequestCookies;
BYTE *m_pDataToSend;
unsigned int m_dataToSendSize;
wstring m_additionalRequestHeaders;
wstring m_proxy;
DWORD m_dwLastError;
wstring m_statusCode;
wstring m_userAgent;
bool m_bForceCharset;
wstring m_proxyUsername;
wstring m_proxyPassword;
wstring m_location;
unsigned int m_resolveTimeout;
unsigned int m_connectTimeout;
unsigned int m_sendTimeout;
unsigned int m_receiveTimeout;
};
WinHttpClient::WinHttpClient(PROGRESSPROC progressProc)
: m_sessionHandle(NULL),
m_requireValidSsl(false),
m_responseHeader(L""),
m_responseContent(L""),
m_responseCharset(L""),
m_requestHost(L""),
m_pResponse(NULL),
m_responseByteCountReceived(0),
m_pfProcessProc(progressProc),
m_responseByteCount(0),
m_responseCookies(L""),
m_additionalRequestCookies(L""),
m_pDataToSend(NULL),
m_dataToSendSize(0),
m_proxy(L""),
m_dwLastError(0),
m_statusCode(L""),
m_userAgent(SZ_AGENT),
m_bForceCharset(false),
m_proxyUsername(L""),
m_proxyPassword(L""),
m_location(L""),
m_resolveTimeout(0),
m_connectTimeout(60000),
m_sendTimeout(30000),
m_receiveTimeout(30000)
{
Init();
}
WinHttpClient::~WinHttpClient(void)
{
Destroy();
}
void WinHttpClient::Init()
{
m_requestURL = L"";
}
void WinHttpClient::Destroy()
{
if (m_pResponse != NULL)
{
delete[] m_pResponse;
}
if (m_pDataToSend != NULL)
{
delete[] m_pDataToSend;
}
if (m_sessionHandle != NULL)
{
::WinHttpCloseHandle(m_sessionHandle);
}
}
bool WinHttpClient::SendHttpRequest(const wstring &httpVerb, bool disableAutoRedirect)
{
if (m_requestURL.size() <= 0)
{
m_dwLastError = ERROR_PATH_NOT_FOUND;
return false;
}
// Make verb uppercase.
wstring verb = httpVerb;
if (_wcsicmp(httpVerb.c_str(), L"GET") == 0)
{
verb = L"GET";
}
else if (_wcsicmp(verb.c_str(), L"POST") == 0)
{
verb = L"POST";
}
else
{
m_dwLastError = ERROR_INVALID_PARAMETER;
return false;
}
bool bRetVal = true;
if (m_sessionHandle == NULL)
{
m_sessionHandle = ::WinHttpOpen(m_userAgent.c_str(),
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
0);
if (m_sessionHandle == NULL)
{
m_dwLastError = ::GetLastError();
return false;
}
}
::WinHttpSetTimeouts(m_sessionHandle,
m_resolveTimeout,
m_connectTimeout,
m_sendTimeout,
m_receiveTimeout);
wchar_t szHostName[MAX_PATH] = L"";
wchar_t szURLPath[MAX_PATH * 5] = L"";
URL_COMPONENTS urlComp;
memset(&urlComp, 0, sizeof(urlComp));
urlComp.dwStructSize = sizeof(urlComp);
urlComp.lpszHostName = szHostName;
urlComp.dwHostNameLength = MAX_PATH;
urlComp.lpszUrlPath = szURLPath;
urlComp.dwUrlPathLength = MAX_PATH * 5;
urlComp.dwSchemeLength = 1; // None zero
if (::WinHttpCrackUrl(m_requestURL.c_str(), m_requestURL.size(), 0, &urlComp))
{
m_requestHost = szHostName;
HINTERNET hConnect = NULL;
hConnect = ::WinHttpConnect(m_sessionHandle, szHostName, urlComp.nPort, 0);
if (hConnect != NULL)
{
DWORD dwOpenRequestFlag = (urlComp.nScheme == INTERNET_SCHEME_HTTPS) ? WINHTTP_FLAG_SECURE : 0;
HINTERNET hRequest = NULL;
hRequest = ::WinHttpOpenRequest(hConnect,
verb.c_str(),
urlComp.lpszUrlPath,
NULL,
WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
dwOpenRequestFlag);
if (hRequest != NULL)
{
// If HTTPS, then client is very susceptable to invalid certificates
// Easiest to accept anything for now
if (!m_requireValidSsl && urlComp.nScheme == INTERNET_SCHEME_HTTPS)
{
DWORD options = SECURITY_FLAG_IGNORE_CERT_CN_INVALID
| SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
| SECURITY_FLAG_IGNORE_UNKNOWN_CA;
::WinHttpSetOption(hRequest,
WINHTTP_OPTION_SECURITY_FLAGS,
(LPVOID)&options,
sizeof(DWORD));
}
bool bGetReponseSucceed = false;
unsigned int iRetryTimes = 0;
// Retry for several times if fails.
while (!bGetReponseSucceed && iRetryTimes++ < INT_RETRYTIMES)
{
if (m_additionalRequestHeaders.size() > 0)
{
if (!::WinHttpAddRequestHeaders(hRequest, m_additionalRequestHeaders.c_str(), m_additionalRequestHeaders.size(), WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON))
{
m_dwLastError = ::GetLastError();
}
}
if (m_additionalRequestCookies.size() > 0)
{
wstring cookies = L"Cookie: ";
cookies += m_additionalRequestCookies;
if (!::WinHttpAddRequestHeaders(hRequest, cookies.c_str(), cookies.size(), WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON))
{
m_dwLastError = ::GetLastError();
}
}
if (m_proxy.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, m_proxy.c_str());
proxyInfo.lpszProxy = szProxy;
if (!::WinHttpSetOption(hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo)))
{
m_dwLastError = ::GetLastError();
}
if (m_proxyUsername.size() > 0)
{
if (!::WinHttpSetOption(hRequest, WINHTTP_OPTION_PROXY_USERNAME, (LPVOID)m_proxyUsername.c_str(), m_proxyUsername.size() * sizeof(wchar_t)))
{
m_dwLastError = ::GetLastError();
}
if (m_proxyPassword.size() > 0)
{
if (!::WinHttpSetOption(hRequest, WINHTTP_OPTION_PROXY_PASSWORD, (LPVOID)m_proxyPassword.c_str(), m_proxyPassword.size() * sizeof(wchar_t)))
{
m_dwLastError = ::GetLastError();
}
}
}
}
if (disableAutoRedirect)
{
DWORD dwDisableFeature = WINHTTP_DISABLE_REDIRECTS;
if (!::WinHttpSetOption(hRequest, WINHTTP_OPTION_DISABLE_FEATURE, &dwDisableFeature, sizeof(dwDisableFeature)))
{
m_dwLastError = ::GetLastError();
}
}
bool bSendRequestSucceed = false;
if (::WinHttpSendRequest(hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS,
0,
WINHTTP_NO_REQUEST_DATA,
0,
0,
NULL))
{
bSendRequestSucceed = true;
}
else
{
// Query the proxy information from IE setting and set the proxy if any.
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_sessionHandle, m_requestURL.c_str(), &autoProxyOptions, &proxyInfo))
{
if (::WinHttpSetOption(hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo)))
{
if (::WinHttpSendRequest(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
{
m_dwLastError = ::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(hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo)))
{
m_dwLastError = ::GetLastError();
}
}
if (proxyConfig.lpszAutoConfigUrl != NULL)
{
::GlobalFree(proxyConfig.lpszAutoConfigUrl);
}
if (proxyConfig.lpszProxy != NULL)
{
::GlobalFree(proxyConfig.lpszProxy);
}
if (proxyConfig.lpszProxyBypass != NULL)
{
::GlobalFree(proxyConfig.lpszProxyBypass);
}
}
else
{
m_dwLastError = ::GetLastError();
}
}
if (bSendRequestSucceed)
{
if (m_pDataToSend != NULL)
{
DWORD dwWritten = 0;
if (!::WinHttpWriteData(hRequest,
m_pDataToSend,
m_dataToSendSize,
&dwWritten))
{
m_dwLastError = ::GetLastError();
}
}
if (::WinHttpReceiveResponse(hRequest, NULL))
{
DWORD dwSize = 0;
BOOL bResult = FALSE;
bResult = ::WinHttpQueryHeaders(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(hRequest,
WINHTTP_QUERY_RAW_HEADERS_CRLF,
WINHTTP_HEADER_NAME_BY_INDEX,
szHeader,
&dwSize,
WINHTTP_NO_HEADER_INDEX))
{
m_responseHeader.assign(szHeader);
vector<wstring> result;
wstring regExp = L"";
if (!m_bForceCharset)
{
regExp = L"charset={[A-Za-z0-9\\-_]+}";
if (ParseRegExp(regExp, false, 1, m_responseHeader, result) && result.size() > 0)
{
m_responseCharset = result[0];
}
}
regExp = L"Content-Length: {[0-9]+}";
if (ParseRegExp(regExp, false, 1, m_responseHeader, result) && result.size() > 0)
{
m_responseByteCount = (unsigned int)_wtoi(result[0].c_str());
}
regExp = L"Location: {[0-9]+}";
if (ParseRegExp(regExp, false, 1, m_responseHeader, result) && result.size() > 0)
{
m_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++)
{
m_responseCookies += result[i];
if (i != result.size() - 1)
{
m_responseCookies += L"; ";
}
}
m_responseCookies = Trim(m_responseCookies, L" ");
if (m_responseCookies.size() > 0 && m_responseCookies[m_responseCookies.size() - 1] != L';')
{
m_responseCookies += L";";
}
}
}
delete[] szHeader;
}
}
dwSize = 0;
bResult = ::WinHttpQueryHeaders(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(hRequest,
WINHTTP_QUERY_STATUS_CODE,
WINHTTP_HEADER_NAME_BY_INDEX,
szStatusCode,
&dwSize,
WINHTTP_NO_HEADER_INDEX))
{
m_statusCode = szStatusCode;
}
delete[] szStatusCode;
}
}
unsigned int iMaxBufferSize = INT_BUFFERSIZE;
unsigned int iCurrentBufferSize = 0;
if (m_pResponse != NULL)
{
delete[] m_pResponse;
m_pResponse = NULL;
}
m_pResponse = new BYTE[iMaxBufferSize];
if (m_pResponse == NULL)
{
bRetVal = false;
break;
}
memset(m_pResponse, 0, iMaxBufferSize);
do
{
dwSize = 0;
if (::WinHttpQueryDataAvailable(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(hRequest,
pResponse,
dwSize,
&dwRead))
{
if (dwRead + iCurrentBufferSize > iMaxBufferSize)
{
BYTE *pOldBuffer = m_pResponse;
m_pResponse = new BYTE[iMaxBufferSize * 2];
if (m_pResponse == NULL)
{
m_pResponse = pOldBuffer;
bRetVal = false;
break;
}
iMaxBufferSize *= 2;
memset(m_pResponse, 0, iMaxBufferSize);
memcpy(m_pResponse, pOldBuffer, iCurrentBufferSize);
delete[] pOldBuffer;
}
memcpy(m_pResponse + iCurrentBufferSize, pResponse, dwRead);
iCurrentBufferSize += dwRead;
}
delete[] pResponse;
}
}
else
{
m_dwLastError = ::GetLastError();
}
}
while (dwSize > 0);
SetProgress(iCurrentBufferSize);
m_responseByteCountReceived = 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;
}
}
bGetReponseSucceed = 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
{
m_dwLastError = ::GetLastError();
}
}
} // while
if (!bGetReponseSucceed)
{
bRetVal = false;
}
::WinHttpCloseHandle(hRequest);
}
::WinHttpCloseHandle(hConnect);
}
}
return bRetVal;
}
wstring WinHttpClient::GetResponseHeader(void)
{
return m_responseHeader;
}
wstring WinHttpClient::GetResponseContent(void)
{
return m_responseContent;
}
wstring WinHttpClient::GetResponseCharset(void)
{
return m_responseCharset;
}
wstring WinHttpClient::GetRequestHost(void)
{
return m_requestHost;
}
bool WinHttpClient::SaveResponseToFile(const wstring &filePath)
{
if (m_pResponse == NULL || m_responseByteCountReceived <= 0)
{
return false;
}
FILE *f = NULL;
int iResult = _wfopen_s(&f, filePath.c_str(), L"wb");
if (iResult == 0 && f != NULL)
{
fwrite(m_pResponse, m_responseByteCountReceived, 1, f);
fclose(f);
return true;
}
return false;
}
bool WinHttpClient::SetProgress(unsigned int byteCountReceived)
{
bool bReturn = false;
if (m_pfProcessProc != NULL && m_responseByteCount > 0)
{
double dProgress = (double)byteCountReceived * 100 / m_responseByteCount;
m_pfProcessProc(dProgress);
bReturn = true;
}
return bReturn;
}
wstring WinHttpClient::GetResponseCookies(void)
{
return m_responseCookies;
}
bool WinHttpClient::SetAdditionalRequestCookies(const wstring &cookies)
{
m_additionalRequestCookies = cookies;
return true;
}
bool WinHttpClient::SetAdditionalDataToSend(BYTE *data, unsigned int dataSize)
{
if (data == NULL || dataSize < 0)
{
return false;
}
if (m_pDataToSend != NULL)
{
delete[] m_pDataToSend;
}
m_pDataToSend = NULL;
m_pDataToSend = new BYTE[dataSize];
if (m_pDataToSend != NULL)
{
memcpy(m_pDataToSend, data, dataSize);
m_dataToSendSize = dataSize;
return true;
}
return false;
}
// Reset additional data fields
bool WinHttpClient::ResetAdditionalDataToSend(void)
{
if (m_pDataToSend != NULL)
{
delete[] m_pDataToSend;
}
m_pDataToSend = NULL;
m_dataToSendSize = 0;
return true;
}
// Allow us to reset the url on subsequent requests
bool WinHttpClient::UpdateUrl(const wstring &url)
{
m_requestURL = url;
ResetAdditionalDataToSend();
return true;
}
bool WinHttpClient::SetAdditionalRequestHeaders(const wstring &additionalRequestHeaders)
{
m_additionalRequestHeaders = additionalRequestHeaders;
return true;
}
bool WinHttpClient::SetProxy(const wstring &proxy)
{
m_proxy = proxy;
return true;
}
// If we don't require valid SSL Certs then accept any
// certificate on an SSL connection
bool WinHttpClient::SetRequireValidSslCertificates(bool require)
{
m_requireValidSsl = require;
return true;
}
const BYTE *WinHttpClient::GetRawResponseContent(void)
{
return m_pResponse;
}
unsigned int WinHttpClient::GetRawResponseContentLength(void)
{
return m_responseByteCount;
}
unsigned int WinHttpClient::GetRawResponseReceivedContentLength(void)
{
return m_responseByteCountReceived;
}
DWORD WinHttpClient::GetLastError(void)
{
return m_dwLastError;
}
wstring WinHttpClient::GetResponseStatusCode(void)
{
return m_statusCode;
}
bool WinHttpClient::SetUserAgent(const wstring &userAgent)
{
m_userAgent = userAgent;
return true;
}
bool WinHttpClient::SetForceCharset(const wstring &charset)
{
m_responseCharset = charset;
return true;
}
bool WinHttpClient::SetProxyUsername(const wstring &username)
{
m_proxyUsername = username;
return true;
}
bool WinHttpClient::SetProxyPassword(const std::wstring &password)
{
m_proxyPassword = password;
return true;
}
wstring WinHttpClient::GetResponseLocation(void)
{
return m_location;
}
bool WinHttpClient::SetTimeouts(unsigned int resolveTimeout,
unsigned int connectTimeout,
unsigned int sendTimeout,
unsigned int receiveTimeout)
{
m_resolveTimeout = resolveTimeout;
m_connectTimeout = connectTimeout;
m_sendTimeout = sendTimeout;
m_receiveTimeout = receiveTimeout;
return true;
}
#endif // WINHTTPCLIENT_H
File diff suppressed because it is too large. Load diff