summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShugo Maeda <shugo@ruby-lang.org>2019-09-02 05:43:35 (GMT)
committerShugo Maeda <shugo@ruby-lang.org>2019-09-02 05:43:51 (GMT)
commit633ae3278ecce7c2b98fa1aa6106f963894c538a (patch)
tree71e3095b81cc14c4e1cd5eb02eb9bbe239711162
parente9b271d1e2251a2e2f613431ae2d9eb2a14ba0a9 (diff)
Add Net::FTP#features and Net::FTP#option
Patch by darkphnx (Dan Wentworth) . Thanks! [Feature #15964]
-rw-r--r--NEWS4
-rw-r--r--lib/net/ftp.rb35
-rw-r--r--test/net/ftp/test_ftp.rb96
3 files changed, 135 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index baebe5c..2857cc9 100644
--- a/NEWS
+++ b/NEWS
@@ -254,6 +254,10 @@ IRB::
* Enable auto indent and save/load history by default.
+Net::FTP::
+
+ * Add features and options. [Feature #15964]
+
Net::IMAP::
* Add Server Name Indication (SNI) support. [Feature #15594]
diff --git a/lib/net/ftp.rb b/lib/net/ftp.rb
index 757daa9..d125c2c 100644
--- a/lib/net/ftp.rb
+++ b/lib/net/ftp.rb
@@ -1298,6 +1298,41 @@ module Net
end
#
+ # Issues a FEAT command
+ #
+ # Returns an array of supported optional features
+ #
+ def features
+ resp = sendcmd("FEAT")
+ if !resp.start_with?("211")
+ raise FTPReplyError, resp
+ end
+
+ feats = []
+ resp.split("\n").each do |line|
+ next if !line.start_with?(' ') # skip status lines
+
+ feats << line.strip
+ end
+
+ return feats
+ end
+
+ #
+ # Issues an OPTS command
+ # - name Should be the name of the option to set
+ # - params is any optional parameters to supply with the option
+ #
+ # example: option('UTF8', 'ON') => 'OPTS UTF8 ON'
+ #
+ def option(name, params = nil)
+ cmd = "OPTS #{name}"
+ cmd += " #{params}" if params
+
+ voidcmd(cmd)
+ end
+
+ #
# Closes the connection. Further operations are impossible until you open
# a new connection with #connect.
#
diff --git a/test/net/ftp/test_ftp.rb b/test/net/ftp/test_ftp.rb
index 39f1220..2504a48 100644
--- a/test/net/ftp/test_ftp.rb
+++ b/test/net/ftp/test_ftp.rb
@@ -1530,6 +1530,102 @@ EOF
end
end
+ def test_features
+ commands = []
+ server = create_ftp_server { |sock|
+ sock.print("220 (test_ftp).\r\n")
+ commands.push(sock.gets)
+ sock.print("211-Features\r\n")
+ sock.print(" LANG EN*\r\n")
+ sock.print(" UTF8\r\n")
+ sock.print("211 End\r\n")
+ }
+ begin
+ begin
+ ftp = Net::FTP.new
+ ftp.connect(SERVER_ADDR, server.port)
+ assert_equal(['LANG EN*', 'UTF8'], ftp.features)
+ assert_equal("FEAT\r\n", commands.shift)
+ assert_equal(nil, commands.shift)
+ ensure
+ ftp.close if ftp
+ end
+ ensure
+ server.close
+ end
+ end
+
+ def test_features_not_implemented
+ commands = []
+ server = create_ftp_server { |sock|
+ sock.print("220 (test_ftp).\r\n")
+ commands.push(sock.gets)
+ sock.print("502 Not Implemented\r\n")
+ }
+ begin
+ begin
+ ftp = Net::FTP.new
+ ftp.connect(SERVER_ADDR, server.port)
+ assert_raise(Net::FTPPermError) do
+ ftp.features
+ end
+ assert_equal("FEAT\r\n", commands.shift)
+ assert_equal(nil, commands.shift)
+ ensure
+ ftp.close if ftp
+ end
+ ensure
+ server.close
+ end
+
+ end
+
+ def test_option
+ commands = []
+ server = create_ftp_server { |sock|
+ sock.print("220 (test_ftp)\r\n")
+ commands.push(sock.gets)
+ sock.print("200 OPTS UTF8 command successful\r\n")
+ }
+ begin
+ begin
+ ftp = Net::FTP.new
+ ftp.connect(SERVER_ADDR, server.port)
+ ftp.option("UTF8", "ON")
+ assert_equal("OPTS UTF8 ON\r\n", commands.shift)
+ assert_equal(nil, commands.shift)
+ ensure
+ ftp.close if ftp
+ end
+ ensure
+ server.close
+ end
+ end
+
+ def test_option_not_implemented
+ commands = []
+ server = create_ftp_server { |sock|
+ sock.print("220 (test_ftp)\r\n")
+ commands.push(sock.gets)
+ sock.print("502 Not implemented\r\n")
+ }
+ begin
+ begin
+ ftp = Net::FTP.new
+ ftp.connect(SERVER_ADDR, server.port)
+ assert_raise(Net::FTPPermError) do
+ ftp.option("UTF8", "ON")
+ end
+ assert_equal("OPTS UTF8 ON\r\n", commands.shift)
+ assert_equal(nil, commands.shift)
+ ensure
+ ftp.close if ftp
+ end
+ ensure
+ server.close
+ end
+ end
+
def test_mlst
commands = []
server = create_ftp_server { |sock|