PycURL предоставляет поддержку FTP и SOCKS из libcurl через один дескриптор передачи. При пассивной FTP-загрузке приложение может оставить и управляющее соединение, и отдельное соединение данных этой реализации.

import pycurl

transfer = pycurl.Curl()
try:
    transfer.setopt(pycurl.URL, ftp_url)
    transfer.setopt(pycurl.PROXY, "socks5h://proxy.example.net:1080")
    transfer.setopt(pycurl.NOPROXY, "")
    transfer.setopt(pycurl.WRITEDATA, output)
    transfer.setopt(pycurl.CONNECTTIMEOUT, 10)
    transfer.setopt(pycurl.TIMEOUT, 60)
    transfer.perform()
finally:
    transfer.close()

ftp_url — это URL FTP-ресурса приложения, а output — уже открытый двоичный поток вывода. Тайм-ауты — это примерные ограничения, которые выбирают по ожидаемому размеру файла и соединению. Для публичного FTP-ресурса, где разрешены публичные посредники, список прокси SOCKS5 предлагает кандидатов для URL прокси; проверьте, что выбранный узел разрешает и управляющий, и пассивный адрес данных.

socks5h передаёт разрешение имени хоста назначения прокси SOCKS. NOPROXY намеренно пуст, чтобы унаследованная переменная окружения no_proxy не обходила маршрут этой передачи.

Оставьте активный FTP отключённым: он ожидает входящего соединения от сервера и недоступен в этом режиме прокси. Политика исходящих соединений прокси должна разрешать управляющий порт FTP и пассивный порт данных, выбранный для передачи. Поэтому один только успешный вход не доказывает, что файл можно загрузить.

Если нужна аутентификация, используйте PROXYUSERNAME и PROXYPASSWORD из PycURL для посредника; учётные данные FTP-сервера относятся к FTP-соединению.

Похожие статьи