zoukankan      html  css  js  c++  java
  • MS Proxy FTP Sample

    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

  • 相关阅读:
    批量ping工具fping
    图形文件元数据管理工具exiv2
    JPG图片EXIF信息提取工具exif
    网络图片嗅探工具driftnet
    复杂密码生成工具apg
    前端面试题目准备
    JS中同步与异步的理解
    angular初体验
    媒体查询的两种方式
    CSS3多列布局
  • 原文地址:https://www.cnblogs.com/hcfalan/p/1918854.html
Copyright © 2011-2022 走看看