Proftpd проверить завершение загрузки - PullRequest
4 голосов
/ 04 октября 2011

Мне было интересно, есть ли лучший способ проверить, была ли загрузка на ваш ftp-сервер успешной.

Система, с которой я работаю, имеет каталог загрузки, который содержит подкаталоги для каждого пользователя, куда загружаются файлы.

Файлы в этих каталогах являются только временными, они удаляются после обработки.

Система перебирает все эти подкаталоги и новые файлы в них, и для каждого файла проверяется, был ли он изменен в течение 10 секунд. Если он не был изменен в течение 10 секунд, система предположила, что файл был успешно загружен.

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

Мне также не нравятся циклы каталогов и файлов, система работает вхолостую при высокой загрузке процессора, поэтому я реализовал pyinotify для запуска действия при записи файла. Я на самом деле не смотрел на исходный код, я могу только предположить, что он более оптимизирован, чем текущая реализация (которая делает больше, чем я описал).

Однако мне все еще нужно проверить, был ли файл успешно загружен.

Я знаю, что могу проанализировать xferlog, чтобы получить все полные загрузки. Нравится:

awk '($12 ~ /^i$/ && $NF ~ /^c$/){print $9}' /var/log/proftpd/xferlog

Это сделает pyinotify ненужным, поскольку я могу получить путь для полных и неполных загрузок, если я только добавлю журнал.

Таким образом, мое решение было бы проверить xferlog в моем цикле выполнения и обрабатывать только полные файлы.

Если нет лучшей практики или просто лучшего способа сделать это?

Каковы недостатки этого метода?

Я запускаю свое приложение на сервере Debian, и proftpd устанавливается на тот же сервер. Кроме того, я не контролирую клиентов, отправляющих файл.

Ответы [ 2 ]

7 голосов
/ 09 сентября 2012

Глядя на документы proftpd, я вижу http://www.proftpd.org/docs/directives/linked/config_ref_HiddenStores.html

Директива HiddenStores разрешает двухэтапную загрузку файлов: файлы загружено как ".in.filename." и после завершения загрузки переименовывается просто "имя файла". Это обеспечивает степень атомарности и помогает предотвратить 1) неполные загрузки и 2) файлы, используемые в то время как они все еще в процессе загрузки.

Это должен быть «лучший способ» решить проблему, когда вы управляете proftpd, поскольку он обрабатывает всю работу за вас - вы можете предположить, что любой файл, который не запускается .in., является завершенной загрузкой. Вы также можете безопасно удалить любые потерянные файлы .in.* после некоторого произвольного периода бездействия где-нибудь в сценарии очистки.

0 голосов
/ 10 марта 2015

Вы можете использовать pure-uploadscript, если ваша установка pure-ftpd была скомпилирована с опцией --with-uploadscript.

Используется для запуска указанного сценария после каждой загрузки полностью.

  1. Установите для CallUploadScript значение "да"
  2. Создайте скрипт с командой, подобной touch /tmp/script.sh
  3. Напишите код в нем.В моем примере скрипт переименовывает файл и добавляет «.completed» перед именем файла:

    #!/bin/bash fullpath=$1 filename=$(basename "$1") dirname=${fullpath%/*} mv "$fullpath" "$dirname/completed.$filename"

  4. Запустите chmod 755 /tmp/script.sh, чтобы сделать скрипт исполняемымpure-uploadscript

  5. Затем выполните команду pure-uploadscript -B -r /etc/pure-ftpd/uploadscript.sh

Теперь /tmp/script.sh будет запускаться после каждой завершенной загрузки.

...