Winet API 支持HTTPP/SOCKS代理
4、下面是程序源码:
void GetLastErrorMessage(DWORD dwError, LPTSTR lpBuffer, DWORD nSize)
{
if (lpBuffer == NULL || nSize == 0)
return;
HLOCAL hLocal = NULL;
BOOL rlt = ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, dwError, LANG_NEUTRAL, (LPTSTR)&hLocal, 0, NULL);
if (!rlt)
{
HMODULE hDll = ::LoadLibraryEx(_T("netmsg.dll"), NULL, DONT_RESOLVE_DLL_REFERENCES);
if (hDll != NULL)
{
::FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM,
hDll, dwError, LANG_NEUTRAL, (LPTSTR)&hLocal, 0, NULL);
::FreeLibrary(hDll);
}
}
//FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_FROM_SYSTEM,
//NULL, dwError, LANG_NEUTRAL, (PTSTR)&hLocal, 0, NULL);
if (hLocal)
{
lpBuffer[nSize-1] = 0;
_tcsncpy(lpBuffer, (LPTSTR)::LocalLock(hLocal), nSize - 1);
::LocalFree(hLocal);
}
else
{
_tcscpy(lpBuffer, _T("没找到对应的错误码信息"));
}
}
BOOL ParseURL(const char* lpszURL, char* lpszServer, int& Port, char* lpszObject)
{
if (lpszURL == NULL || lpszServer == NULL || lpszObject == NULL)
{
return FALSE;
}
char szCanonicalizeUrl[INTERNET_MAX_URL_LENGTH] = {0};
DWORD dwCanonicalizeUrlLength = INTERNET_MAX_URL_LENGTH;
BOOL bRet = ::InternetCanonicalizeUrlA(lpszURL, szCanonicalizeUrl, &dwCanonicalizeUrlLength, ICU_BROWSER_MODE);
if (bRet)
{
URL_COMPONENTSA Components;
::memset(&Components, 0, sizeof(Components));
Components.dwStructSize = sizeof(Components);
Components.lpszHostName = lpszServer ;
Components.dwHostNameLength = INTERNET_MAX_URL_LENGTH;
Components.lpszUrlPath = lpszObject;
Components.dwUrlPathLength = INTERNET_MAX_URL_LENGTH;
::InternetCrackUrl(szCanonicalizeUrl, dwCanonicalizeUrlLength, 0, &Components);
Port = Components.nPort;
}
return bRet;
}
DWORD DoInternetProxy(LPCTSTR lpszUrl, LPCTSTR lpszProxy)
{
/*The following example code shows how authentication
could be handled using InternetSetOption. */
DWORDdwError = 0;
HINTERNET hOpenHandle, hConnectHandle, hResourceHandle;
hOpenHandle = InternetOpen("DoInternetProxy",
INTERNET_OPEN_TYPE_PRECONFIG,
NULL, NULL, 0);
if (hOpenHandle)
{
if (lpszProxy && lpszProxy[0])
{
printf("设置代理%s\n", lpszProxy);
/*INTERNET_PER_CONN_OPTION_LIST List;
INTERNET_PER_CONN_OPTION Option[1];
unsigned long nSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
Option[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
Option[0].Value.pszValue = (char*)lpszProxy;
List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
List.pszConnection = NULL;
List.dwOptionCount = 1;
List.dwOptionError = 0;
List.pOptions = Option;
if(InternetSetOption(hOpenHandle, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, nSize))*/
INTERNET_PROXY_INFO ProxyInfo = {0};
ProxyInfo.dwAccessType = INTERNET_OPEN_TYPE_PROXY;
ProxyInfo.lpszProxy = lpszProxy;
ProxyInfo.lpszProxyBypass = NULL;
if(InternetSetOption(hOpenHandle, INTERNET_OPTION_PROXY, &ProxyInfo, sizeof(ProxyInfo)))
{
/*char szYN[64];
printf("是否输入代理用户名/密码(输入Y/N)?");
scanf("%s", szYN);
if (stricmp(szYN, "Y") == 0)
{
char szUsername[64] = {0}, szPassword[64] = {0};
printf("请输入代理用户名:");
scanf("%s", szUsername);
printf("请输入代理用户密码:");
scanf("%s", szPassword);
InternetSetOption(hOpenHandle,
INTERNET_OPTION_PROXY_USERNAME,
szUsername,
strlen(szUsername)+1);
InternetSetOption(hOpenHandle,
INTERNET_OPTION_PROXY_PASSWORD,
szPassword,
strlen(szPassword)+1);
}*/
}
else
{
printf("设置代理失败!\n");
dwError = GetLastError();
}
}
char szServer[INTERNET_MAX_URL_LENGTH] = {0};
int nPort = 80;
char szObject[INTERNET_MAX_URL_LENGTH] = {0};
if(ParseURL(lpszUrl, szServer, nPort, szObject))
{
printf("测试URL:%s:%d %s\n", szServer, nPort, szObject);
hConnectHandle = InternetConnect(hOpenHandle,
szServer,
nPort,
NULL,
NULL,
INTERNET_SERVICE_HTTP,
0,0);
if (hConnectHandle)
{
hResourceHandle = HttpOpenRequest(hConnectHandle,
"GET",
szObject,
NULL,
NULL,
NULL,
INTERNET_FLAG_KEEP_CONNECTION,
0);
if (hResourceHandle)
{
do
{
if(HttpSendRequest(hResourceHandle,
NULL,
0,
NULL,
0))
{
DWORDdwStatus = 0;
DWORDdwStatusSize = sizeof(dwStatus);
charszUsername[64] = {0}, szPassword[64] = {0};
HttpQueryInfo(hResourceHandle,
HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE,
&dwStatus, &dwStatusSize,
NULL);
if(dwStatus == HTTP_STATUS_PROXY_AUTH_REQ)
{// Proxy Authentication Required
// Insert code to set strUsername and strPassword.
// cchUserLength is the length of strUsername and
// cchPasswordLength is the length of strPassword.
printf("请输入代理用户名:");
scanf("%s", szUsername);
printf("请输入代理用户密码:");
scanf("%s", szPassword);
// Insert code to safely determine cchUserLength and
// cchPasswordLength. Insert appropriate error handling code.
InternetSetOption(hResourceHandle,
INTERNET_OPTION_PROXY_USERNAME,
szUsername,
strlen(szUsername)+1);
InternetSetOption(hResourceHandle,
INTERNET_OPTION_PROXY_PASSWORD,
szPassword,
strlen(szPassword)+1);
continue;
}
if(dwStatus == HTTP_STATUS_DENIED)
{// Server Authentication Required.
// Insert code to set strUsername and strPassword.
// cchUserLength is the length of strUsername and
// cchPasswordLength is the length of strPassword.
printf("请输入%s用户名:", szServer);
scanf("%s", szUsername);
printf("请输入%s用户密码:", szServer);
scanf("%s", szPassword);
// Insert code to safely determine cchUserLength and
// cchPasswordLength. Insert error handling code as
// appropriate.
InternetSetOption(hResourceHandle,
INTERNET_OPTION_USERNAME,
szUsername,
strlen(szUsername)+1);
InternetSetOption(hResourceHandle,
INTERNET_OPTION_PASSWORD,
szPassword,
strlen(szPassword)+1);
continue;
}
}
else
{
dwError = GetLastError();
}
break;
} while (1);
// Insert code to read the data from the hResourceHandle
// at this point.
if (dwError == 0)
{
DWORD dwContentLength = 0;
DWORD dwContentLengthSize = sizeof(dwContentLengthSize);
if(!HttpQueryInfo( hResourceHandle, HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwContentLength, &dwContentLengthSize, NULL))
{
dwContentLength = 0;
}
printf("内容长度[%d]\n", dwContentLength);
char szResource[256] = {0};
DWORD dwResourceLength = 255;
if(!InternetReadFile( hResourceHandle, szResource, dwResourceLength, &dwResourceLength))
{
printf("InternetReadFile失败!\n");
dwError = GetLastError();
}
else
{
printf("%s%s\n", szResource, dwResourceLength<dwContentLength?"......":"");
}
}
}
else
{
printf("HttpOpenRequest失败!\n");
dwError = GetLastError();
}
}
else
{
printf("InternetConnect失败!\n");
dwError = GetLastError();
}
}
else
{
printf("解析%s地址失败!\n", lpszUrl);
dwError = GetLastError();
}
//重置代理
//INTERNET_PROXY_INFO ResetProxyInfo = {0};
//InternetSetOption(hOpenHandle, INTERNET_OPTION_PROXY, &ResetProxyInfo, sizeof(ResetProxyInfo));
}
else
{
printf("InternetOpen失败!\n");
dwError = GetLastError();
}
if(hResourceHandle)
{
InternetCloseHandle(hResourceHandle);
hResourceHandle = NULL;
}
if(hConnectHandle)
{
InternetCloseHandle(hConnectHandle);
hConnectHandle = NULL;
}
if (hOpenHandle)
{
InternetCloseHandle(hOpenHandle);
hOpenHandle = NULL;
}
return dwError;
}
int main(int argc, char* argv[])
{
//printf("Hello World!\n");
HANDLE hStdin = GetStdHandle( STD_OUTPUT_HANDLE );
SetStdHandle( STD_OUTPUT_HANDLE, (void *)0x7 );
char szBuffer[2048] = {0};
long flag = 1; //0 退出
do
{
SetConsoleTextAttribute( (void *)0x7, FOREGROUND_INTENSITY | FOREGROUND_INTENSITY );
/*if (argc < 2
|| strcmp(argv[1],"help") == 0
|| strcmp(argv[1],"?") == 0)*/
{
printf("\n====================代理格式====================\n");
printf("[<protocol>=][<scheme>://]<proxyserver>[:<port>]\n");
printf("eg:\n");
printf("proxyserver:port(默认HTTP代理)\n");
printf("FTP=ftp://proxyserver:port\n");
printf("SOCKS=proxyserver:port\n");
printf("\n================================================\n");
}
SetConsoleTextAttribute( (void *)0x7, FOREGROUND_INTENSITY | FOREGROUND_GREEN );
printf("请输入代理地址:(参考代理格式,输入任意字符换行表示不使用代理)\n");
char szProxy[INTERNET_MAX_URL_LENGTH] = {0};
memset(szBuffer, 0, sizeof(szBuffer));
scanf("%s", szBuffer);
if (strlen(szBuffer) >= 8)
{
strcpy(szProxy, szBuffer);
}
do
{
printf("请输入测试URL,例如:http://www.baidu.com:80/),输入exit退出,reset重新设置代理\n");
char szUrl[INTERNET_MAX_URL_LENGTH] = {0};
memset(szBuffer, 0, sizeof(szBuffer));
scanf("%s", szBuffer);
if (stricmp(szBuffer, "exit") == 0)
{
flag = 0;
break;
}
if (stricmp(szBuffer, "reset") == 0)
{
flag = 1;
break;
}
if (strnicmp(szBuffer, "http://", strlen("http://")) != 0)
{
strcpy(szUrl, "http://");
}
strcat(szUrl, szBuffer);
DWORD ret = DoInternetProxy(szUrl, szProxy);
if (ret)
{
SetConsoleTextAttribute( (void *)0x7, FOREGROUND_INTENSITY | FOREGROUND_RED );
GetLastErrorMessage(ret, szBuffer, 2048);
printf("测试代理完成[%d]%s!\n", ret, szBuffer);
SetConsoleTextAttribute( (void *)0x7, FOREGROUND_INTENSITY | FOREGROUND_GREEN );
}
else
{
printf("测试代理完成!\n");
}
} while (1);
} while (flag);
SetStdHandle( STD_OUTPUT_HANDLE, hStdin );
//system("pause");
return 0;
}