zoukankan      html  css  js  c++  java
  • 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 ", 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("设置代理失败! ");
    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 ", 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] ", dwContentLength);

    char szResource[256] = {0};
    DWORD dwResourceLength = 255;
    if(!InternetReadFile( hResourceHandle, szResource, dwResourceLength, &dwResourceLength))
    {
    printf("InternetReadFile失败! ");
    dwError = GetLastError();
    }
    else
    {
    printf("%s%s ", szResource, dwResourceLength<dwContentLength?"......":"");
    }
    }
    }
    else
    {
    printf("HttpOpenRequest失败! ");
    dwError = GetLastError();
    }
    }
    else
    {
    printf("InternetConnect失败! ");
    dwError = GetLastError();
    }
    }
    else
    {
    printf("解析%s地址失败! ", lpszUrl);
    dwError = GetLastError();
    }


    //重置代理
    //INTERNET_PROXY_INFO ResetProxyInfo = {0};
    //InternetSetOption(hOpenHandle, INTERNET_OPTION_PROXY, &ResetProxyInfo, sizeof(ResetProxyInfo));
    }
    else
    {
    printf("InternetOpen失败! ");
    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! ");


    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(" ====================代理格式==================== ");
    printf("[<protocol>=][<scheme>://]<proxyserver>[:<port>] ");
    printf("eg: ");
    printf("proxyserver:port(默认HTTP代理) ");
    printf("FTP=ftp://proxyserver:port ");
    printf("SOCKS=proxyserver:port ");
    printf(" ================================================ ");
    }
    SetConsoleTextAttribute( (void *)0x7, FOREGROUND_INTENSITY | FOREGROUND_GREEN );
    printf("请输入代理地址:(参考代理格式,输入任意字符换行表示不使用代理) ");
    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重新设置代理 ");
    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! ", ret, szBuffer);
    SetConsoleTextAttribute( (void *)0x7, FOREGROUND_INTENSITY | FOREGROUND_GREEN );
    }
    else
    {
    printf("测试代理完成! ");
    }
    } while (1);
    } while (flag);

    SetStdHandle( STD_OUTPUT_HANDLE, hStdin );
    //system("pause");
    return 0;
    }

  • 相关阅读:
    CSS3实现0.5px的边框
    解决nvm导致终端启动慢的问题
    解决zsh: command not found: gitk,将git路径/usr/bin/git修改为/usr/local/bin/git
    MAC之zsh终端使用nvm安装指定版本node
    解决npm包node-sass下载失败问题
    forEach中使用async await的问题
    使用module-alias别名简化CommonJS的require路径
    关系型数据库的ACID
    Node.js ORM 框架对比
    mysql字符集 utf8 和utf8mb4 的区别
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3159611.html
Copyright © 2011-2022 走看看