惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

SecWiki News
SecWiki News
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
博客园 - 叶小钗
S
SegmentFault 最新的问题
IT之家
IT之家
大猫的无限游戏
大猫的无限游戏
博客园_首页
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
腾讯CDC
D
Darknet – Hacking Tools, Hacker News & Cyber Security
V
V2EX
阮一峰的网络日志
阮一峰的网络日志
L
Lohrmann on Cybersecurity
量子位
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Tor Project blog
J
Java Code Geeks
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
博客园 - 三生石上(FineUI控件)
Attack and Defense Labs
Attack and Defense Labs
AI
AI
The Cloudflare Blog
T
Tailwind CSS Blog
S
Schneier on Security
爱范儿
爱范儿
PCI Perspectives
PCI Perspectives
Stack Overflow Blog
Stack Overflow Blog
S
Secure Thoughts
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
The Exploit Database - CXSecurity.com
博客园 - 【当耐特】
V2EX - 技术
V2EX - 技术
S
Securelist
P
Proofpoint News Feed
T
Threat Research - Cisco Blogs
Help Net Security
Help Net Security
C
Cisco Blogs
N
News and Events Feed by Topic
人人都是产品经理
人人都是产品经理
B
Blog RSS Feed
K
Kaspersky official blog
T
The Blog of Author Tim Ferriss
G
Google Developers Blog
S
Security Affairs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Simon Willison's Weblog
Simon Willison's Weblog

博客园 - hcfalan

Mybatis分页功能 安聊服务端Netty的应用 安聊系统1.0发布 VC中发送电子邮件 自绘窗口边框和标题栏 Windows下生产者-消费者问题的解法 Javascript 时间日期转换 Java Threading - Consumer&Producer Boost socket 同步编程示例(服务端,客户端) MFC CSocket的跨线程问题 用于主题检测的临时日志(54b8134e-5e4a-46fc-95af-c75ccf06d66e - 3bfe001a-32de-4114-a6b4-4005b770f6d7) 网络电话 VC 剪贴板操作 The 1st Boost Serial Demo - hcfalan 《斯坦福大学开放课程: 编程方法学》 VC2005下编译log4cpp的修正方法 - hcfalan - 博客园 适合孩子的书籍 一个最经典的线程类(转) 应用MFC开发高级应用程序(转)
MS Proxy FTP Sample
hcfalan · 2010-12-28 · via 博客园 - hcfalan

This sample demonstrates how to use InternetOpenUrl to access FTP server
through HTTP-Based (i.e. CERN) proxy.

WinInet uses HTTP protocol to communicate with the proxy, but proxy
connects to FTP server via FTP protocol. This fact makes impossible to
use specific WinInet FTP APIs such as FtpOpenFile, FtpPutFile, etc.

However it is still possible to obtain a directory listing of the FTP server
and download files using InternetOpenUrl. This protocol independent API
is capable of taking URL such as ftp://server or http://server.

Under certain conditions, in addition to FTP server requiring a set of
credentials (user name and password), proxy server may require a separate set
of credentials. With InternetOpenUrl user name and password required by the
FTP server may be include on the URL, like this:

ftp://User:Pass@ftp.server.com/file.txt

Please note this syntax is invalid for HTTP and does not allow password
to include "@" sign. The technique below outlines steps that can be used to
handle proxy authentication. In other words it explaines how to
submit second set of credentials for the proxy itself.

1. Call InternetOpenUrl. If FTP server requires name and password,
include it in the URL.
2. Check if handle return by InternetOpenUrl is HTTP type of handle. If
handle type is HTTP, it indicates that WinInet is communicating with HTTP
type proxy.
3. Check for the HTTP status code. If status code indicates that proxy
authentication is required, acquire user credentials.
4. User name and password may be acquired with UI by calling InternetErrorDlg
API or without UI by calling InternetSetOption API.
5. Once credentials are acquired request must be resubmitted with
HttpSendRequest API.

Notes:
1. Before request is resubmitted all outstanding data must be read with
InternetReadFile APIs
2. When InternetReadFile is used to obtain a directory listing
(ftp://server/MyDir), it may fail with error 122 "Insufficient buffer". In
this case forth parameter to the APIs (lpNumberOfBytesRead) will be set to
0 and will NOT indicate the size of the needed buffer. To determine the size
of the minimal buffer to allocate call InternetQueryDataAvailable API.

How to run the sample:
Sample uses INTERNET_OPEN_TYPE_PRECONFIG internet access type. Therefor if
Internet Explorer is configured to use HTTP proxy, the sample will use the
same proxy.

To get myfile.txt and dump to the console by using anonymous FTP connection:
c:> readurlftp ftp://myserver/myfile.txt con

The same as above, but save file localy:
c:> readurlftp ftp://myserver/myfile.txt d:\temp\myfile.txt

To get directory listing from MyDir and dump to the console by using
specific user name and password required by FTP server:
c:> readurlftp ftp://User:Pass@myserver/MyDir con

The same as above, accept use UI (i.e. bring up dialog box) to enter proxy
credentials in addition to FTP server credentials:
c:> readurlftp ftp://myserver/MyDir con -u

readurlftp.cpp

#include <windows.h>
#include <wininet.h>
#include <iostream.h>

BOOL bUI = FALSE;
BOOL ErrorOut ( DWORD dError, TCHAR * szCallFunc);
BOOL GetRemoteFile (HINTERNET IN hOpen, TCHAR * IN szUrl, TCHAR * IN szFileName );

int main  (int argc, char *argv[])
{

    HINTERNET hOpen;
    if (argc < 3)
    {
        cerr << "Usage: " << argv[0] << " URL LocalFile [-u]" << endl;
        cerr << "\t URL - ftp://ftp.domain.com/file.txt" << endl;
        cerr << "\t or ftp://user:password@ftp.domain.com/file.txt" << endl;
        cerr << "\t LocalFile - c:\\temp\\file.txt" << endl;
        cerr << "\t [-u] - use UI to authenticate with proxy" << endl;
        return 0;
    }
    if ( (argc == 4) && (!strcmp (argv [3], "-u")) )
        bUI = TRUE;

    if ( !(hOpen = InternetOpen ( "Simple Ftp",  INTERNET_OPEN_TYPE_PRECONFIG , NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION) ) )
    {
        ErrorOut ( GetLastError(), "InternetOpen");
        return 0;
    }

    if (!GetRemoteFile (hOpen, argv[1],  argv[2]))
    {
        cerr << "GetRemoteFile failed" << endl;
        return 0;
    }
    return 1;
}

BOOL  GetRemoteFile (HINTERNET IN hOpen, TCHAR * IN szUrl, TCHAR * IN szFileName )
{
    DWORD dwLength, dWritten, dwCode, dwSize;
    SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, FALSE};
    HANDLE hFile;
    HINTERNET  hConnect;
    BOOL bInitalRequest = TRUE;
    CHAR *szBuffer;

    if ( !(hConnect = InternetOpenUrl ( hOpen, szUrl , NULL, 0,
                                       INTERNET_FLAG_DONT_CACHE |
                                       INTERNET_FLAG_KEEP_CONNECTION |
                                       INTERNET_FLAG_RELOAD, 0) ) )
    {
        ErrorOut (GetLastError (), TEXT ("InternetOpenUrl"));
        return 0;
    }
    again:
    if (!bInitalRequest)
    {
        if ( !HttpSendRequest (hConnect, NULL,0,NULL, 0))
        {
            ErrorOut (GetLastError(), "HttpSendRequest");
            return FALSE;
        }     
    }
    dwSize = sizeof (dwCode);
    if ( !InternetQueryOption (hConnect, INTERNET_OPTION_HANDLE_TYPE ,
                         &dwCode, &dwSize))
    {
        ErrorOut (GetLastError(), "HttpQueryInfo");
        return FALSE;
    }
    if ( (dwCode == INTERNET_HANDLE_TYPE_HTTP_REQUEST )  ||
         (dwCode == INTERNET_HANDLE_TYPE_CONNECT_HTTP ) )
    {
        // if were are here, it means that we use HTTP to talk the proxy
        dwSize = sizeof (DWORD) ; 
        if ( !HttpQueryInfo (hConnect, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,
                             &dwCode, &dwSize, NULL))
        {
            ErrorOut (GetLastError(), "HttpQueryInfo");
            return FALSE;
        }

        if ( dwCode == HTTP_STATUS_PROXY_AUTH_REQ)
        {   
            if (!InternetQueryDataAvailable (hConnect, &dwLength, 0,0) )
            {
               ErrorOut (GetLastError (),  "InternetQueryDataAvailable");
               return FALSE;
            }

            szBuffer = new CHAR [dwLength];
            // read all the data and ignore it
            do
            {
                InternetReadFile (hConnect, szBuffer, dwLength, &dwSize);
            }
            while (dwSize != 0);
            delete [] szBuffer;

            if (!bUI)
            {
                // This is a secure page.
                cerr << "Proxy authentication is required." << endl;
                CHAR szUser[50]="";
                CHAR szPass[50]="";

                cerr << "User: ";
                cin  >> szUser;
                cerr << "Pass: ";
                cin  >> szPass;
                if ( !InternetSetOption (hConnect, INTERNET_OPTION_PROXY_USERNAME, (LPVOID) szUser, lstrlen (szUser) ))
                {
                    cerr << "InternetSetOptionFailed: " << GetLastError() << endl;
                    return FALSE;
                }
                if ( !InternetSetOption (hConnect, INTERNET_OPTION_PROXY_PASSWORD, (LPVOID) szPass, lstrlen (szPass) ))
                {
                    cerr << "InternetSetOptionFailed: " << GetLastError() << endl;
                    return FALSE;
                }
                bInitalRequest = FALSE;
                goto again;   
            }
            else
            {
                if ( InternetErrorDlg (GetDesktopWindow(),
                                       hConnect,
                                       ERROR_INTERNET_INCORRECT_PASSWORD,
                                       FLAGS_ERROR_UI_FILTER_FOR_ERRORS |
                                       FLAGS_ERROR_UI_FLAGS_GENERATE_DATA |
                                       FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS,
                                       NULL) == ERROR_INTERNET_FORCE_RETRY)
               {
                    bInitalRequest = FALSE;
                    goto again;
               }
            } // else
        }   // if ( dwCode == HTTP_STATUS_PROXY_AUTH_REQ
    }   // if ( (dwCode == INTERNET_HANDLE_TYPE_HTTP_REQUEST

    if  ( (hFile = CreateFile (szFileName,
                            GENERIC_WRITE,
                            FILE_SHARE_READ,
                            &sa,
                            CREATE_ALWAYS,
                            FILE_ATTRIBUTE_NORMAL, NULL) ) == INVALID_HANDLE_VALUE)
    {
        cerr << "Can't open file file: " << szFileName << endl;
        return FALSE;
    }
    if (!InternetQueryDataAvailable (hConnect, &dwLength, 0,0) )
    {
       ErrorOut (GetLastError (),  "InternetQueryDataAvailable");
       return FALSE;
    }
    szBuffer = new CHAR [dwLength];

    do
    {
       if (!InternetReadFile (hConnect, szBuffer, dwLength,  &dWritten) )
       {
           CloseHandle (hFile);
           ErrorOut (GetLastError (),  "InternetReadFile");
           delete [] szBuffer;
           return FALSE;
       }

       if (!dWritten)
           break;
       else
          if (!WriteFile(hFile,  szBuffer, dWritten ,  &dwSize,  NULL))
          {
                CloseHandle (hFile);
                cerr << "error " << GetLastError () << endl;
                delete [] szBuffer;
                return FALSE;
          }
    }
    while (TRUE);
    FlushFileBuffers (hFile);
    CloseHandle (hFile);
    delete [] szBuffer;
    return 1;
}

BOOL ErrorOut ( DWORD dError, TCHAR * szCallFunc)
{
    TCHAR szTemp[512] = "", *szBuffer=NULL, *szBufferFinal = NULL;
    char strName[256]="";
    DWORD  dwIntError , dwLength = 0;

    FormatMessage(FORMAT_MESSAGE_FROM_HMODULE,
                   GetModuleHandle("wininet.dll"),dError,0,
                  (LPSTR)strName,256,NULL);
    wsprintf (szTemp,  "%s error code: %d\nMessage: %s\n",
    szCallFunc, dError, strName);
    if (dError == ERROR_INTERNET_EXTENDED_ERROR)
    {
        InternetGetLastResponseInfo (&dwIntError, NULL, &dwLength);
        if (dwLength)
        {
            if ( !(szBuffer = (TCHAR *) LocalAlloc ( LPTR,  dwLength) ) )
            {
                lstrcat (szTemp, TEXT ( "Unable to allocate memory to display Internet error code. Error code: ") );
                lstrcat (szTemp, TEXT (_itoa (GetLastError(), szBuffer, 10)  ) );
                lstrcat (szTemp, TEXT ("\n") );
                cerr << szTemp << endl;
                return FALSE;
            }
            if (!InternetGetLastResponseInfo (&dwIntError, (LPTSTR) szBuffer, &dwLength))
            {
                lstrcat (szTemp, TEXT ( "Unable to get Internet error. Error code: ") );
                lstrcat (szTemp, TEXT (_itoa (GetLastError(), szBuffer, 10)  ) );
                lstrcat (szTemp, TEXT ("\n") );
                cerr << szTemp << endl;
                return FALSE;
            }
            if ( !(szBufferFinal = (TCHAR *) LocalAlloc ( LPTR,  (strlen (szBuffer) +strlen (szTemp) + 1)  ) )  )
            {
                lstrcat (szTemp, TEXT ( "Unable to allocate memory. Error code: ") );
                lstrcat (szTemp, TEXT (_itoa (GetLastError(), szBuffer, 10)  ) );
                lstrcat (szTemp, TEXT ("\n") );
                cerr << szTemp << endl;
                return FALSE;
            }
            lstrcpy (szBufferFinal, szTemp);
            lstrcat (szBufferFinal, szBuffer);
            LocalFree (szBuffer);
            cerr <<  szBufferFinal  << endl;
            LocalFree (szBufferFinal);
        }
    }
    else
        cerr << szTemp << endl;
    return TRUE;
}

makefile

# Nmake macros for building Windows 32-Bit apps

TARGETOS=BOTH
APPVER=4.0

all:readurlftp.exe

!include <win32.mak>

lflags= /INCREMENTAL:NO /PDB:NONE /RELEASE /NOLOGO -subsystem:console,$(APPVER) -entry:mainCRTStartup
readurlftp.obj: readurlftp.cpp
    $(cc) $(cflags) $(cvars) $(cdebug) readurlftp.cpp

readurlftp.exe: readurlftp.obj
    $(link) $(lflags)  -out:readurlftp.exe readurlftp.obj wininet.lib  user32.lib kernel32.lib