Como usar FTP com um proxy baseado em CERN usando APIs WinInet

Aviso

O aplicativo da área de trabalho desativado e sem suporte do Internet Explorer 11 está programado para ser desativado permanentemente por meio de uma atualização do Microsoft Edge em certas versões do Windows 10. Para obter mais informações, consulte Perguntas frequentes sobre a desativação do aplicativo de área de trabalho do Internet Explorer 11.

Um servidor de proxy Web baseado em CERN usa HTTP para todas as comunicações com seus clientes. Portanto, o conjunto FTP de funções Wininet não pode ser usado para baixar recursos em um servidor FTP se o servidor FTP for acessado por meio de um proxy baseado em CERN em nome do cliente. Em vez disso, o cliente precisa usar funções gerais do Wininet, como InternetOpenUrl e InternetReadFile para recuperar corretamente os dados do fluxo HTTP enviados do servidor proxy baseado em CERN.

Versão original do produto: Internet Explorer
Número de KB original: 166961

Informações adicionais

Os serviços proxy compatíveis com CERN dão suporte a solicitações HTTP (WWW), FTP e Gopher. Mas a comunicação entre o servidor proxy baseado em CERN e seus clientes usa somente HTTP. O diagrama a seguir mostra como uma solicitação FTP é encaminhada usando um serviço proxy compatível com CERN:

Get ftp://host.com/root/test.doc HTTP 1.0        FTP Request
   |=========|                 |=============|          |=============|
   |         |---------------->| Cern-based  |--------->|             |
   | Client  |    HTTP         | Proxy Server|   FTP    |  Ftp Server |
   |         |<----------------|             |<---------|             |
   |=========|                 |=============|          |=============|
         HTTP/1.0 200 <document>                  FTP Response

Como um servidor proxy baseado em CERN se comunica com seus clientes em HTTP, você não pode usar o conjunto FTP de funções Wininet se o cliente acessar o servidor FTP por meio do servidor proxy. Em vez disso, você deve usar InternetOpenUrl e InternetReadFile recuperar os dados solicitados do fluxo HTTP enviado pelo servidor proxy.

Se a URL FTP passada for InternetOpenUrl uma URL para um arquivo no servidor FTP, você poderá usar InternetReadFile para ler todo o conteúdo do arquivo. Se a URL FTP passada for InternetOpenUrl uma URL para um diretório no servidor FTP, InternetReadFile recuperará uma listagem de diretório da URL FTP como um documento HTML. Em ambos os casos, talvez você precise fazer loop chamando InternetReadFile até que todos os dados no fluxo HTTP sejam lidos.

Se o cliente pretende recuperar algo mais abaixo da URL do diretório FTP, ele precisará analisar o documento HTML para obter URLs para subdiretórios ou arquivos e emitir mais InternetOpenUrl e InternetReadFile chamadas. Também quando um proxy baseado em CERN é usado, o INTERNET_FLAG_RAW_DATA sinalizador não deve ser especificado na InternetOpenUrl chamada.

O pseudo código a seguir demonstra como chamar InternetOpenUrl e InternetReadFile quando um servidor proxy baseado em CERN é usado para acessar um servidor FTP:

CHAR strURL[] = "ftp://host.com/root/test.doc";
HANDLE f; //local file handle
HINTERNET hInternetFile;
DWORD dwRead, dwWritten;
CHAR szTemp[1024];
hInternetFile = InternetOpenUrl(hInternetSession, (LPCTSTR)strURL, NULL,
                                0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, 0);
if (hInternetFile == NULL)
{
    do
        some error processing;
    quit;
}
//download the file to c:\deleteme
f = CreateFile("c:\\deleteme", GENERIC_WRITE, 0, NULL,
               CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (f == INVALID_HANDLE_VALUE)
{
    do
        some error processing;
    quit;
}

while (InternetReadFile(hInternetFile, (LPVOID)szTemp, 1024, &dwRead))
{
    if (!dwRead)
        break;
    WriteFile(f, (LPVOID)szTemp, dwRead, &dwWritten, NULL);
}
CloseHandle(f);
//if the strURL is a URL to a file on the ftp server, we get the file
//and store it in c:\deleteme.
//if the strURL is a URL to a directory on the ftp server, c:\deleteme
//will be a HTML page of the directory listing. You will have to parse
//the html page, and construct new URLs, and call the above code again.

Quando o cliente tem conexão direta com um servidor FTP ou está conectado ao servidor FTP por meio de um servidor proxy TIS FTP, a comunicação de e para o cliente está no FTP. O cliente pode especificar o INTERNET_FLAG_RAW_DATA sinalizador InternetOpenUrl e usar InternetFindNextFile para obter uma estrutura WIN32_FIND_DATA e enumerar todos os subdiretórios e arquivos da URL. O cliente também pode usar o conjunto FTP de funções Wininet nessas situações.

O código pseudo a seguir demonstra como chamar InternetOpenUrl e quando o INTERNET_FLAG_RAW_DATA sinalizador é especificado na InternetOpenUrlInternetReadFile chamada:

CHAR strURL[] = "ftp://host.com/root/test.doc";
HANDLE f; //local file handle
HINTERNET hInternetFile;
DWORD dwRead, dwWritten;
CHAR szTemp[1024];
hInternetFile = InternetOpenUrl(hInternetSession, (LPCTSTR)strURL, NULL,
                                0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, 0);
if (hInternetFile == NULL)
{
    do
        some error processing;
    quit;
}
//download the file to c:\deleteme
f = CreateFile("c:\\deleteme", GENERIC_WRITE, 0, NULL,
               CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (f == INVALID_HANDLE_VALUE)
{
    do
        some error processing;
    quit;
}

while (InternetReadFile(hInternetFile, (LPVOID)szTemp, 1024, &dwRead))
{
    if (!dwRead)
        break;
    WriteFile(f, (LPVOID)szTemp, dwRead, &dwWritten, NULL);
}
CloseHandle(f);
//if the strURL is a URL to a file on the ftp server, we get the file
//and store it in c:\deleteme.
//if the strURL is a URL to a directory on the ftp server, c:\deleteme
//will be a HTML page of the directory listing. You will have to parse
//the html page, and construct new URLs, and call the above code again.

Quando a conexão entre o cliente e o servidor FTP é direta ou por meio de um proxy FTP do TIS, InternetOpenUrl e InternetReadFile na verdade estão gerando tráfego FTP em vez de tráfego HTTP.

A discussão acima sobre o uso de APIs Wininet com proxy baseado em CERN também se aplica ao GOPHER. Além disso, é importante observar que as APIs Wininet dão suporte apenas a URLs HTTP, HTTPS, FTP e GOPHER. Para URLs DE ARQUIVO, como file://server/share/file ou file://\server\share\file, você precisa usar APIs Win32, como FileCopy, para baixar o arquivo no computador cliente ou FindFirstFile, FindNextFile e FindClose para enumerar um diretório.