Форум сайта python.su
Привет всем!
Обнаружилась проблема в следующей задаче: загрузка файлов размером более 1Гб на ftp находясь за squid прокси. Файлы меньшего размера загружаются без проблем. Сразу скажу, что явно заданных ограничений ни на размер файла, ни на время сессии ни на стороне ftp, ни на стороне прокси нет. Это подтверждается тем, что при использовании ftp-клиента (например, того, который есть в TotalCommander), загрузка проходит успешно. Загружались файлы размером от 1 до 5 Гб.
Вот python-скрипт (за основу взят скрипт из примеров работы pycurl):
# -*- coding: utf-8 -*- import os, sys import pycurl ftp_user_name = "*****" ftp_user_password = "*****" proxy = "*****" proxy_port = ***** proxy_user_name = "*****" proxy_user_password = "*****" ftp_destination = "ftp://*****/test.zip" source_file = "test.zip" class FileReader: def __init__(self, fp): self.fp = fp def read_callback(self, size): return self.fp.read(size) if not os.path.exists(source_file): print("Error: the file '%s' does not exist" % source_file) raise SystemExit c = pycurl.Curl() c.setopt(pycurl.URL, ftp_destination) c.setopt(pycurl.UPLOAD, 1) c.setopt(pycurl.USERPWD, "%s:%s" % (ftp_user_name, ftp_user_password)) c.setopt(pycurl.PROXY, proxy) c.setopt(pycurl.PROXYPORT, proxy_port) c.setopt(pycurl.PROXYUSERPWD, "%s:%s" % (proxy_user_name, proxy_user_password)) c.setopt(pycurl.VERBOSE, 1) c.setopt(pycurl.HTTPPROXYTUNNEL, 1) c.setopt(pycurl.READFUNCTION, FileReader(open(source_file, 'rb')).read_callback) filesize = os.path.getsize(source_file) c.setopt(pycurl.INFILESIZE, filesize) print('Uploading file %s to url %s' % (source_file, ftp_destination)) c.perform() c.close()
* Send failure: Connection was aborted * Closing connection 0 Traceback (most recent call last): File ".\file_upload.py", line 39, in <module> c.perform() pycurl.error: (55, 'Send failure: Connection was aborted')
Офлайн
shuhartУменьши до 800Mb, посмотри.
Файлы меньшего размера загружаются без проблем.
Отредактировано py.user.next (Сен. 9, 2015 05:00:29)
Офлайн
shuhartВы можете контролировать что TotalCommander не посылает каждые 10 сек keep alive пакеты?
Это подтверждается тем, что при использовании ftp-клиента (например, того, который есть в TotalCommander)
Офлайн
doza_andДумал об этом. Как проверить\проконтролировать, не знаю. Скорее всего что-то в этом роде и происходит. Можно ли организовать подобное поведение для PyCurl?
Вы можете контролировать что TotalCommander не посылает каждые 10 сек keep alive пакеты?
Офлайн
Удалось найти решение обходным путём!
Оказалось, что соединение закрывалось по истечени времени, определенном в параметре read_timeout squid'а. По умолчанию значение параметра: 15 минут. После увеличения временного интервала, появилась возможность при помощи pycurl “успевать” копировать на ftp файлы бОльшего размера.
Всем спасибо! Тему можно закрывать.
Отредактировано shuhart (Сен. 10, 2015 12:50:29)
Офлайн
Как оказалось, тему закрывать рано. Вылез ещё один “косяк”.
Обнаружилось, что файл загружается не полностью. Сравнивались размеры и CRC. При сравнении файлов по содержимому выяснилось, что какое-то кол-во байт “конца” файла не загружается на ftp-сервер. При чем от размера файла это не зависит.
Код скрипта такой же как и в тексте темы.
Не связано ли это с тем что, что машина под x64, а python (ну, и, соответственно, pycurl) 32-х разрядный?
Офлайн
shuhartОчень сомневаюсь. А сколько байт не догружается?
Не связано ли это с тем что, что машина под x64, а python (ну, и, соответственно, pycurl) 32-х разрядный?
Офлайн
shuhartВозьми 800-метровый файл, посчитай у него md5, выгрузи и сравни.
Обнаружилось, что файл загружается не полностью. Сравнивались размеры и CRC.
Офлайн
py.user.nextА что это даст? Если воспользоваться утилитами сравнения то больше информации получится. Под windows fc /b file1 file2,winmerge под unix diff, cmp -l, vbindiff, dhex, Jdiff,meld
посчитай у него md5, выгрузи и сравни.
Отредактировано doza_and (Сен. 15, 2015 08:02:11)
Офлайн
Прикрепил скрин из winmerge. Слева оригинал, справа файл с ftp.
Что-то пока не понимаю, в какую сторону копать. То ли прокся где-то мешает, то ли что-то с параметрами режима работы pycurl. А может стоит искать другой инструмент для этой задачи.
Отредактировано shuhart (Сен. 15, 2015 11:09:21)
Прикреплённый файлы:
diff.PNG (59,4 KБ)
Офлайн