[ https://issues.apache.org/jira/browse/SSHD-1181?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Guillaume Nodet reassigned SSHD-1181: ------------------------------------- Assignee: Guillaume Nodet > SFTP Get downloads empty file from servers which supports EOF indication > after data > ----------------------------------------------------------------------------------- > > Key: SSHD-1181 > URL: https://issues.apache.org/jira/browse/SSHD-1181 > Project: MINA SSHD > Issue Type: Bug > Affects Versions: 2.6.0 > Reporter: Pavel Pohner > Assignee: Guillaume Nodet > Priority: Major > Labels: SFTP, mina, sshd > > So, apparently there's a bug in Mina implementation when downloading the > file, which is smaller than Mina's buffer (meaning it gets read in one > iteration), from servers, which send EOF indicator at the end of data > (https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#[section-9.3|https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-9.3]). > The bug seems to be in setting up EOF indicator in > {noformat} > org.apache.sshd.sftp.client.impl.SftpInputStreamAsync#pollBuffer{noformat} > prematurely (one iteration sooner), trace with me this example situation - > download of the small file (14 B): > At some point we arrive to mentioned function _pollBuffer()_, note that > _this.pendingReads_ is set to 2. In first call of _pollBuffer()_ we go > through this code on receiving SSH_FXP_DATA > {code:java} > if (type == SftpConstants.SSH_FXP_DATA) { > int dlen = buf.getInt(); > int rpos = buf.rpos(); > buf.rpos(rpos + dlen); > Boolean b = SftpHelper.getEndOfFileIndicatorValue(buf, > client.getVersion()); > if ((b != null) && b.booleanValue()) { > eofIndicator = true; > }{code} > Here, consider this situation, we're downloading file with 14B, remote server > adds EOF indicator to the end of the data, so it makes 15B, let's add some > necessary overhead (size etc.) which is, according to my experience, 13B, so > we receive 15 + 13 = 28B into initial buffer. > Now, if we populate these variables, _dlen_ = 14B (file size), _rpos_ = 13 > (overhead), and we set _buf.rpos_ to 27 (14 + 13), but _wpos_ is at the > moment equal to 28B, as that's what we received. (We're not taking EOF into > account here) > Then the _SftpHelper.getEndOfFileIndicatorValue_ is called, which in it's > implementation looks like this: > {code:java} > public static Boolean getEndOfFileIndicatorValue(Buffer buffer, int version) { > return (version < SftpConstants.SFTP_V6) || (buffer.available() < 1) ? > null : buffer.getBoolean(); > } > {code} > Pay attention to the _buffer.available()_ function as it's implemented like > this: > {code:java} > public int available() { > return wpos - rpos; > } > {code} > therefore returning 1 (28 - 27), condition is then resolved in > _SftpHelper.getEndOfFileIndicatorValue_ as a true and true is also returned > to the _pollBuffer_ and _eofIndicator_ is set to true. > If you'd keep tracing further, you'd find out that the buffer is then never > read and returned from _SftpInputStreamAsync_ class, just because > _eofIndicator_ was set sooner than it should have been. > > -- This message was sent by Atlassian Jira (v8.3.4#803005) --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@mina.apache.org For additional commands, e-mail: dev-h...@mina.apache.org