Protheus e FTP Client

Introdução

No post Protheus como Servidor de FTP, vimos como configurar um Servidor Protheus como FTP Server. Agora, vamos ver uma classe AdvPL que permite estabelecer uma conexão com um servidor FTP, e fazer operações como Download e Upload de arquivos — a classe tFtpClient.

Protocolos FTP, FTPS e SFTP

FTP, acrônimo de File Transfer Protocol, é um protocolo criado com a finalidade de transferência de arquivos entre estações. Para isso, uma estação atua como Cliente, estabelecendo uma conexão TCP/IP com a estação servidora. A porta padrão para os servidores de FTP é a porta 21.

O FTPS nada mais é do que uma extensão do protocolo FTP, que acrescenta o suporte a conexão criptografada usando TLS e/ou SSL.

O SFTP normalmente é confundido com o FTPS.  Na verdade seu nome vêm apenas da finalidade de transferência de arquivos, porém sua origem e natureza de implementação é bem diferente do FTP. Acrônimo de SSH File Transfer Protocol, na verdade é uma extensão do protocolo SSH (Secure Shell Protocol)  versão 2.0, concebido para transferência segura de arquivos.

Classe TFTPClient

Através da classe TFTPClient() do AdvPL, podemos criar uma conexão com um servidor FTP, bastando ter em mãos no mínimo o IP — ou nome do host — e a porta do servidor. Caso o servidor exija autenticação, precisamos ter um nome de usuário e uma senha para ser autenticada pelo servidor e realizar as operações.

Vale mencionar que, por hora, a classe TFTPClient() suporta apenas o protocolo FTP. Não há (ainda) suporte nativo em AdvPL para conexão cliente com FTPS e/ou SFTP. Quando existe a necessidade de uma integração automatizada com um servidor de arquivos implementado sobre um destes protocolos, a alternativa atual é executar uma aplicação externa mediante script ou similar, que faça a conexão e as tarefas necessárias.

Funcionalidades

Basicamente, as operações de um Cliente de FTP são as equivalentes a uma navegação em uma estrutura de pastas ou diretórios. Ao estabelecer a conexão com um servidor de FTP, normalmente o nosso diretório de trabalho remoto é a pasta “raiz” de publicação do FTP Server. A partir desse ponto, podemos executar operações como “listar arquivos da pasta atual”, “entrar em uma pasta”, “voltar para a pasta anterior”, “copiar um arquivo da pasta do FTP para a estação atual”, “copiar um arquivo da estação atual para a pasta atual do FTP”, “apagar um arquivo” e assim por diante.

Através das propriedades e métodos da classe TFTPClient(), podemos consultar ou parametrizar — de acordo com as capacidades do Servidor de FTP — o modo de transferência de arquivos, o tipo de transferência, o modo de conexão (Ativo ou Passivo), entre outras particularidades. Será mais fácil entender o funcionamento da classe partindo de um exemplo.

Exemplo AdvPL

O primeiro exemplo de uso será bem simples. Sua função é identificar a existência de um determinado arquivo na pasta Raiz de um servidor de FTP, e caso o arquivo exista, a aplicação AdvPL fará o download deste arquivo para uma pasta local do ambiente (environment) a partir do rootpath, chamada “downloads”. O Servidor de FTP utilizado foi um IIS em um Windows 10, com um site de FTP configurado para permitir acesso anônimo.

#include 'protheus.ch'

User Function TSTFTP()
Local oFtp, nStat
Local aFtpFile 
Local cFtpSrv := 'note-juliow-ssd'
Local nFTPPort := 21

SET DATE BRITISH
SET CENTURY ON

// Cria o objeto Client
oFtp := tFtpClient():New()

// Estabelece a conexão com o FTP Server 
nStat := oFtp:FtpConnect(cFtpSrv,nFTPPort)
If nStat != 0
  conout("FTPClient - Erro de Conexao "+cValToChar(nStat))
  QUIT
Endif

// Procura pelo arquivo leiame.txt
aFtpFile := oFtp:Directory( "leiame.txt", .T. )

if len(aFtpFile) > 0
  // Arquivo encontrado - Mostra os detalhes do arquivo 
  conout( cValToChar(aFtpFile[1][1])+" | "+; // nome
    cValToChar(aFtpFile[1][2])+" | "+; // tamanho
    cValToChar(aFtpFile[1][3])+" | "+; // data
    cValToChar(aFtpFile[1][4])+" | "+; // horario
    cValToChar(aFtpFile[1][5]) ) // Atributo . D = Diretorio
  // Faz o download do arquivo para a pasta local de downloads
  nStat := oFtp:ReceiveFile('leiame.txt','\downloads\leiame.txt' ) 
  If nStat != 0 
    conout("*** Falha no recebimento do arquivo - Erro "+cValToChar(nStat))
  Else
    conout("Arquivo recebido com sucesso.")
  Endif
Else
  conout("*** Arquivo nao encontrado.")
Endif
oFtp:Close()
Return

Caso ocorra falha de conexão, o programa não continua. Ao determinar a existência do arquivo no Servidor de FTP — através do método ::Directory() — fazemos o download do arquivo usando o método ::ReceiveFile(). Caso o arquivo na pasta local já exista, ele será sobrescrito.

Nas referências deste post, verifiquem todas as propriedades e métodos disponíveis na classe TFTPClient() na documentação dela na TDN. Para uma primeira versão, nosso exemplo será bem “arroz com feijão” mesmo, acredito que somente com um programa mais extenso, ou com mais programas de tamanho reduzido, será possível exemplificar as demais funcionalidades da classe TFTPClient()

Observações

Os primeiros testes das funcionalidades básicas foram feitos configurando o programa Cliente de exemplo usando o Protheus como FTP Server. E, para meu espanto, o método ::Directory()  não encontrava o arquivo, na verdade mesmo que a máscara de busca informada fosse  “*”  — para identificar todos os arquivos e sub-pastas a partir da pasta atual, não localizavam nada. Em um dos testes, eu resolvi acessar — para consulta — a propriedade chamada nDirInfo da engine Client de FTP, e para minha surpresa, após acessar esta propriedade, o método ::Directory(“leiame.txt”) localizou o arquivo, e o download / recebimento foi feito com sucesso. Como houveram falhas também em outras funcionalidades da API client, porém somente quando usado o Protheus como FTP Server, por hora os exemplos usados para demonstração das funcionalidades da classe TFTPClient serão testados com o FTP do Microsoft IIS, e posteriormente com um FTP Server no Linux,

Conclusão

Ainda vamos explorar mais esta classe, inclusive acessando um FTP Server na Internet. Porém, esta abordagem fica para o próximo post.

Agradeço novamente a audiência, curtidas, compartilhamentos, comentários e sugestões, e desejo a todos TERABYTES DE SUCESSO 😀

Referências

 

 

8 comentários sobre “Protheus e FTP Client

  1. Caro amigo! boa tarde
    Ouvi dizer que não temos funcionalidade para SFTP, se isso for positivo qual o posicionamento da TOTVS para a criação da classe? Pois grandes organizações utilizam com frenquência troca de arquivos em modo de segurança.

    Curtido por 1 pessoa

    • Atualmente não há funcionalidade nativa ainda implementada, para cliente SFTP e/ou FTPS. Porém, devido a crescente demanda de integrações desta natureza, acredito que isto esteja “no radar” do time de tecnologia responsável pelo Application Server. Hoje, quem precisa usar algo desta natureza contorna este déficit usando uma aplicação externa com script — WINSCP e/ou Putty PSFTP.

      Abraços

      Curtir

  2. Camarada Júlio!
    Estou desenvolvendo uma rotina para comunicação via FTP, o objetivo é fazer o download de apenas um arquivo especifico. Utilizei o seu modelo e obtive sucesso no download, a função oFtp:ReceiveFile baixa o arquivo porem o retorno da mesma é “-1”, testei deixando a pasta de destino vazia pois pensei que pudesse ser algo referente a tentativa de sobrescrever o arquivo, mais mesmo assim o retorno da função ainda foi “-1”, você saberia disser o que pode ser?

    Curtido por 1 pessoa

    • Olá Jefferson, beleza ? Então, muit estranho ele “baixar” o arquivo, mas o arquivo não ser criado. Voce colocou uma pasta que existe na maquina onde está o Protheus server ? o nome do arquivo de destino é a partir do RootPath do ambiente ? Me passa os detalhes por emaill ( siga0984@gmail.com )

      Abraços

      Curtir

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s