Как обнаружить или зарегистрировать прерванные загрузки с SFTP-сервером OpenSSH?

9

У меня есть эта проблема, когда у нашего клиента были усеченные SFTP-данные. Я не уверен, проблема у нас или у него. Я включил ведение журнала SFTP, но он не позволяет мне определить, была ли загрузка прервана.

Например, если я запускаю sftp-клиент и нажимаю ^Cв середине загрузки, сервер просто говорит что-то вроде этого close "/data/README.md" bytes read 0 written 5366, что неотличимо от непрерывной загрузки.

Я думаю, что-то вроде .partпрефикса будет работать, но, глядя на другие сообщения о сбое сервера, я не думаю, что это возможно с sftp-сервером OpenSSH.

Итак, есть ли способ определить, была ли прервана загрузка файла?

surjikal
источник

Ответы:

8

Я предполагаю, что под «клиентом sftp» вы ссылаетесь на SFTP-клиента OpenSSH. «Проблема» в том, что при нажатии Ctrl+Cона останавливает загрузку и полностью закрывает удаленный файл, как если бы загрузка была полностью завершена (обратите внимание, что это правильное поведение, и многие другие клиенты SFTP ведут себя так же). Таким образом, сервер не может сказать, что загрузка была прервана.


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

Смотрите process_openв sftp-server.c:

a = get_attrib();
flags = flags_from_portable(pflags);
mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666;
logit("open \"%s\" flags %s mode 0%o",
    name, string_from_portable(pflags), mode);

Измените logitутверждение на:

logit("open \"%s\" flags %s mode 0%o size %llu",
    name, string_from_portable(pflags), mode, (unsigned long long)a->size);

Обратите внимание, что отправка подсказки о размере не является обязательной. Хотя некоторые SFTP-клиенты отправляют его (например, OpenSSH или WinSCP), некоторые не отправляют (например, PSFTP, FileZilla или LFTP). В таком случае вы получите 0 в a->size.


Если бы клиент действительно прервал загрузку (без чистого закрытия удаленного файла, например, когда sftpон был убит), вы могли бы отличить префикс «принудительный» от «закрыть» запись:

принудительное закрытие "/data/README.md" прочитанных байт 0 написано 5366

Мартин Прикрыл
источник
1
Ух ты, ты сделал winSCP ?? Большие взлеты чувак. Спасибо за ответ, я сделаю это.
Суржикал