9
votes

Proxies dans l'application FTP Python

Je développe un client FTP dans Python FTplib. Comment puis-je ajouter le support des proxies (la plupart des applications FTP que j'ai vues semblent l'avoir)? Je pense surtout aux proxy de chaussettes, mais aussi d'autres types ... FTP, HTTP (est-il même possible d'utiliser des proxies HTTP avec le programme FTP?)

Des idées Comment le faire?


0 commentaires

6 Réponses :


2
votes

module standard ftplib ne prend pas en charge les proxies. Il semble que la seule solution consiste à écrire votre propre version personnalisée du ftplib .


0 commentaires

8
votes

Selon Cette source.

Dépend de la proxy, mais une méthode commune est de FTP au proxy, puis utilisez Nom d'utilisateur et mot de passe pour le serveur de destination. P>

E.g. Pour ftp.example.com:

from ftplib import FTP
site = FTP('my_proxy')
site.set_debuglevel(1)
msg = site.login('anonymous@ftp.example.com', 'password')
site.cwd('/pub')


2 commentaires

Le lien de la réponse ci-dessus est de 404. On pourrait vouloir dire celui-ci: Mail.pytHon.org/pipermarth/python-list/2004-octobre/863602.ht ml


La partie "Anonymous de ftp.download.com" est pure fiction. Rien de tel que cela n'a jamais été mentionné dans une RFC ou mis en œuvre / soutenu par un serveur, autant que je sache. Nativement, le protocole FTP ne prend pas en charge la proxy. AFAIK, le seul moyen de procuration FTP consiste à utiliser une chaussettes dans laquelle le client est censé se connecter aux chaussettes et que ce dernier doit être informé de ce que le serveur FTP réel est.



4
votes

Vous pouvez utiliser proxyhandler dans urllib2 .

ph = urllib2.ProxyHandler( { 'ftp' : proxy_server_url } )
server= urllib2.build_opener( ph )


1 commentaires

La typographie de "URLLI2" dans l'exemple ne peut pas être éditée car "les modifications doivent avoir au moins 6 caractères".



3
votes

J'ai eu le même problème et j'ai besoin d'utiliser le module ftplib (ne pas réécrire tous mes scripts avec urllib2).

J'ai réussi à écrire un script qui installe le tunneling HTTP transparent sur la couche de socket (utilisé par FTPLIB).

Maintenant, je peux faire FTP sur http de manière transparente!

Vous pouvez l'obtenir là-bas: http: // code. Activeestate.com/RECIPES/577643-TRANSPARENT-HTTP-TUNnel-FOR-PLYTHON-Sockets-a-be-u/


0 commentaires

2
votes

Patching La bibliothèque de socket intégrée ne sera certainement pas une option pour tout le monde, mais ma solution était de corriger socket.create_connection () code> pour utiliser un proxy HTTP lorsque le nom d'hôte correspond à un whitelist:

from ftplib import FTP
import paramiko  # For SFTP
from proxied_socket import register_proxy

class FTPIgnoreHost (FTP):
    def makepasv (self):
        # Ignore the host returned by PASV or EPSV commands (only use the port).
        return self.host, FTP.makepasv(self)[1]

register_proxy('ftp.example.com', 'proxy.example.com', 3128, 'proxy_username', 'proxy_password')

ftp_connection = FTP('ftp.example.com', 'ftp_username', 'ftp_password')

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())  # If you don't care about security.
ssh.connect('ftp.example.com', username='sftp_username', password='sftp_password')
sftp_connection = ssh.open_sftp()


2 commentaires

Merci, c'est la seule solution que j'ai trouvée jusqu'à présent ce genre de travail, mais cela ne fonctionne toujours pas pour moi. Après avoir ajouté des quelques -encodes et .Decode pour rendre ce Python 3 compatible, je peux maintenant établir une connexion au serveur FTP sur le proxy, mais le moment où je gère une commande de liste par exemple, je reçois ftplib.error_temp: 425 Impossible d'ouvrir la connexion de données et n'obtenez aucune donnée. Des idées?


@Jordandimov pourriez-vous s'il vous plaît poster ce que vous avez fait? J'essaie de trouver une solution pour ce problème, mais aucun des extraits mentionnés ici ne fonctionne pour moi.



0
votes

voici la solution de contournement en utilisant Demandes code>, testé avec un proxy Squid qui ne prend pas en charge Connexion Tunneling:

def ftp_fetch_file_through_http_proxy(host, user, password, remote_filepath, http_proxy, output_filepath):
    """
    This function let us to make a FTP RETR query through a HTTP proxy that does NOT support CONNECT tunneling.
    It is equivalent to: curl -x $HTTP_PROXY --user $USER:$PASSWORD ftp://$FTP_HOST/path/to/file
    It returns the 'Last-Modified' HTTP header value from the response.

    More precisely, this function sends the following HTTP request to $HTTP_PROXY:
        GET ftp://$USER:$PASSWORD@$FTP_HOST/path/to/file HTTP/1.1
    Note that in doing so, the host in the request line does NOT match the host we send this packet to.

    Python `requests` lib does not let us easily "cheat" like this.
    In order to achieve what we want, we need:
    - to mock urllib3.poolmanager.parse_url so that it returns a (host,port) pair indicating to send the request to the proxy
    - to register a connection adapter to the 'ftp://' prefix. This is basically a HTTP adapter but it uses the FULL url of
    the resource to build the request line, instead of only its relative path.
    """
    url = 'ftp://{}:{}@{}/{}'.format(user, password, host, remote_filepath)
    proxy_host, proxy_port = http_proxy.split(':')

    def parse_url_mock(url):
        return requests.packages.urllib3.util.url.parse_url(url)._replace(host=proxy_host, port=proxy_port, scheme='http')

    with open(output_filepath, 'w+b') as output_file, patch('requests.packages.urllib3.poolmanager.parse_url', new=parse_url_mock):
        session = requests.session()
        session.mount('ftp://', FTPWrappedInFTPAdapter())
        response = session.get(url)
        response.raise_for_status()
        output_file.write(response.content)
        return response.headers['last-modified']


class FTPWrappedInFTPAdapter(requests.adapters.HTTPAdapter):
    def request_url(self, request, _):
        return request.url


0 commentaires