This might be a bit more complex than it appears - SFTP protocol is basically a POSIX-like file system API, and does not actually offer any "download file" or "upload file" operations. Instead, when an SFTP clients intends to download a file, it opens it for reading and receives a handle (using
SSH_FXP_OPEN request). Then it issues a series of read requests (
SSH_FXP_READ) using that handle until the end of file is reached. Finally, it closes the file handle (using
If the SFTP client just downloads a file this way,
GetLength will not be called at all. However, some SFTP clients have chosen to determine the file length prior to performing the download sequence by issuing an
SSH_FXP_STAT or equivalent request - this is not really needed (as explained above), but it makes it possible for the client to display transfer progress, for example.
But in your scenario, this presents a problem, because when the client issues
SSH_FXP_STAT, it does not imply that a file transfer is about to be started.
SSH_FXP_LSTAT requests are used for other purposes as well, for example to determine file attributes or to determine whether a file or directory exists. Unfortunately, this implies that it's not possible to determine whether
GetLenth has been called because the client is about to start a transfer, and this is due to SFTP protocol's design.
However, it's worth noting that many SFTP clients won't mind if
GetLength returns 0, and proceed with the download anyway. Our Rebex SFTP client does, and I just verified that OpenSSH's
sftp client does as well (it issues
SSH_FXP_STAT before opening the file for reading, which results in
GetLength getting called twice, but if it returns zero, OpenSSH's
sftp still downloads the whole file - it simply reads the file data until the end of file is reached).
Which SFTP client did you use for the download? Are your users only going to use a specific SFTP client, or can they choose to use whatever client they want? If there is some control over SFTP clients that are to be used, it might be possible to find a workaround that makes those clients work fine. Otherwise, perhaps some caching mechanism could be used?