Winet API 支持HTTPP/SOCKS代理

 


1、Winet API 支持使用IE代理、或者不使用代理、或者使用自定义代理三种方式。
2、使用自定义代理的话,支持HTTP代理,SOCKS代理,但是SOCKS代理不知支持用户名密码,HTTP代理支持
3、这里写了一个使用Winet API写的测试程序,测试Winet API对各种代理的支持,截图如下:

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;
}

 

posted @ 2013-06-27 19:25  爱生活,爱编程  阅读(1609)  评论(0编辑  收藏  举报