diff options
author | Jeremy Evans <code@jeremyevans.net> | 2021-02-25 11:15:48 -0800 |
---|---|---|
committer | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2021-04-27 21:21:00 +0900 |
commit | 990baec41174a0b4cf7e285cf3185b4ab444437e (patch) | |
tree | 95536e7c83dc080502ee1347dbb6c9acfd320b1c /lib/net/ftp.rb | |
parent | a86c6cb34df0c44973efe6578ba1cd9150af22cf (diff) |
[ruby/net-ftp] Close the passive connection data socket if there is an error setting up the transfer
Previously, the connection leaked in this case. This uses
begin/ensure and checking for an error in the ensure block.
An alternative approach would be to not even perform the
connection until after the RETR (or other) command has been
sent. However, I'm not sure all FTP servers support that.
The current behavior is:
* Send (PASV/EPSV)
* Connect to the host/port returned in 227/229 reply
* Send (RETR/other command)
Changing it to connect after the RETR could break things.
FTP servers might expect that the client has already
connected before sending the RETR. The alternative
approach is more likely to introduce backwards compatibility
issues, compared to the begin/ensure approach taken here.
Fixes Ruby Bug 17027
https://github.com/ruby/net-ftp/commit/6e8535f076
Diffstat (limited to 'lib/net/ftp.rb')
-rw-r--r-- | lib/net/ftp.rb | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/lib/net/ftp.rb b/lib/net/ftp.rb index a2607a96a0..da502129a5 100644 --- a/lib/net/ftp.rb +++ b/lib/net/ftp.rb @@ -547,18 +547,22 @@ module Net def transfercmd(cmd, rest_offset = nil) # :nodoc: if @passive host, port = makepasv - conn = open_socket(host, port) - if @resume and rest_offset - resp = sendcmd("REST " + rest_offset.to_s) - if !resp.start_with?("3") + begin + conn = open_socket(host, port) + if @resume and rest_offset + resp = sendcmd("REST " + rest_offset.to_s) + if !resp.start_with?("3") + raise FTPReplyError, resp + end + end + resp = sendcmd(cmd) + # skip 2XX for some ftp servers + resp = getresp if resp.start_with?("2") + if !resp.start_with?("1") raise FTPReplyError, resp end - end - resp = sendcmd(cmd) - # skip 2XX for some ftp servers - resp = getresp if resp.start_with?("2") - if !resp.start_with?("1") - raise FTPReplyError, resp + ensure + conn.close if conn && $! end else sock = makeport |