pythonpython-3.xproxyftpftplib

Connecting with ftplib via FTP proxy in Python?


I am trying to download files from FTP. It works fine at home but it doesn't work when I run through company's network. I know there is something to do with proxy. I have looked at a few posts regarding the proxy issue in Python. I have tried to set up a connection to the proxy. It works ok for url but it failed when connecting to FTP. Does anyone know a way to do that? Thanks in advance.

Below is my code:

import os
import urllib
import ftplib
from ftplib import FTP
from getpass import getpass
from urllib.request import urlopen, ProxyHandler, HTTPHandler,     HTTPBasicAuthHandler, \
                                build_opener, install_opener

user_proxy = "XXX"
pass_proxy = "YYY"
url_proxy = "ZZZ"
port_proxy = "89"
url_proxy = "ftp://%s:%s@%s:%s" % (user_proxy, pass_proxy, url_proxy,     port_proxy)
authinfo = urllib.request.HTTPBasicAuthHandler()
proxy_support = urllib.request.ProxyHandler({"ftp" : url_proxy})

# build a new opener that adds authentication and caching FTP handlers
opener = urllib.request.build_opener(proxy_support, authinfo,
                                 urllib.request.CacheFTPHandler)

# install it
urllib.request.install_opener(opener)

#url works ok
f = urllib.request.urlopen('http://www.google.com/')
print(f.read(500))
urllib.request.install_opener(opener)

#ftp is not working
ftp = ftplib.FTP('ftp:/ba1.geog.umd.edu', 'user', 'burnt_data')

The error message I got:

730     # and socket type values to enum constants.
731     addrlist = []
--> 732     for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
733         af, socktype, proto, canonname, sa = res
734         addrlist.append((_intenum_converter(af, AddressFamily),

gaierror: [Errno 11004] getaddrinfo failed

I can connect via the proxy using FileZilla by selecting custom FTP proxy with specification:

USER %u@%h %s
PASS %p
ACCT %w

FTP Proxy using FileZilla


Solution

  • You are connecting using an FTP proxy.

    FTP proxy cannot work with HTTP, so your test against http:// URL to www.google.com is completely irrelevant and does not prove anything.

    FTP proxy works as an FTP server. You connect to the proxy, instead of to the actual server. And then use some special syntax of a username (or other credentials) to specify your actual target FTP server and its credentials. In your case the special syntax of username is user@host user_proxy. Your proxy expects the proxy password in FTP ACCT command.

    This should work for your specific case:

    host_proxy = '192.168.149.50'
    user_proxy = 'XXX'
    pass_proxy = 'YYY'
    
    user = 'user'
    user_pass = 'burnt_data'
    host = 'ba1.geog.umd.edu'
    
    u = "%s@%s %s" % (user, host, user_proxy)
    
    ftp = ftplib.FTP(host_proxy, u, user_pass, pass_proxy)
    

    No other code should be needed (urllib or any other).

    If the proxy uses a custom port (not 21), use this:

    ftp = ftplib.FTP()
    ftp.connect(host_proxy, port_proxy)
    ftp.login(u, user_pass, pass_proxy)