Project

General

Profile

Feature #13382

[PATCH] Options for FTP PORT command

Added by osa (Shunsuke OSA) about 2 months ago. Updated 29 days ago.

Status:
Assigned
Priority:
Normal
Target version:
-
[ruby-dev:50057]

Description

Abstract

Add options to Net::FTP to set data listening host and port.

Background

Net::FTP sends local address and default port to remote FTP server.
In FTP active mode, remote server will connect to client to establish data connection, but it will fail if there is NAT in network.
(NAT doesn't rewrite address and port in PORT command because they are not in packet header but payload)
So, it's necessary to set host and port for FTP PORT command explicitly.

Real use cases

Active FTP is not working in AWS EC2.

Pull request

History

#1 [ruby-dev:50058] Updated by shugo (Shugo Maeda) about 2 months ago

  • Assignee set to shugo (Shugo Maeda)

osa (Shunsuke OSA) wrote:

Real use cases

Active FTP is not working in AWS EC2.

The default mode of Net::FTP is now passive, but do you really need the active mode?

Do you know any FTP client implementation which provides similar options?
Python's ftplib doesn't seem to have such options.

Pull request

Your patch doesn't seem to change Net::FTP#makeport. Does it work?

#2 [ruby-dev:50060] Updated by osa (Shunsuke OSA) about 2 months ago

The default mode of Net::FTP is now passive, but do you really need the active mode?

In the real world, sometimes we have to connect FTP servers without passive mode support. But modern server environment such as clouds like AWS EC2, inbound port is strictly restricted. To connect to the server from such environment with active mode, we need a support of explicit incoming data port.

Do you know any FTP client implementation which provides similar options?

Net::FTP of Perl has port method. (And it resembles to FTP PORT command)
http://perldoc.perl.org/Net/FTP.html#port-(-[-PORT-]-)

I've considered an interface like port(host, port) but I think passing host to port method will confuse and port method is looks like getter method.

Your patch doesn't seem to change Net::FTP#makeport. Does it work?

I'm sorry. It is a bug. I'll fix and test it.

#3 [ruby-dev:50061] Updated by shugo (Shugo Maeda) about 2 months ago

osa (Shunsuke OSA) wrote:

The default mode of Net::FTP is now passive, but do you really need the active mode?

In the real world, sometimes we have to connect FTP servers without passive mode support. But modern server environment such as clouds like AWS EC2, inbound port is strictly restricted. To connect to the server from such environment with active mode, we need a support of explicit incoming data port.

Understood.

Do you know any FTP client implementation which provides similar options?

Net::FTP of Perl has port method. (And it resembles to FTP PORT command)
http://perldoc.perl.org/Net/FTP.html#port-(-[-PORT-]-)

I've considered an interface like port(host, port) but I think passing host to port method will confuse and port method is looks like getter method.

FTPClient of Apache Commons seems to have setActivePortRange() and setActiveExternalIPAddress().

https://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html#setActiveExternalIPAddress(java.lang.String)

However, setActiveExternalIPAddress() seems to be for specifying the address to bind.

#4 [ruby-dev:50062] Updated by shugo (Shugo Maeda) about 2 months ago

shugo (Shugo Maeda) wrote:

FTPClient of Apache Commons seems to have setActivePortRange() and setActiveExternalIPAddress().

https://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html#setActiveExternalIPAddress(java.lang.String)

However, setActiveExternalIPAddress() seems to be for specifying the address to bind.

I found setReportActiveExternalIPAddress().

https://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html#setReportActiveExternalIPAddress(java.lang.String)

#5 [ruby-dev:50079] Updated by osa (Shunsuke OSA) about 1 month ago

Thank you so much for your survey.

If we translate java's setReportActiveExternalIPAddress() into Ruby method literally, it seems to be report_active_external_ip_address=.
But this name is difficult to understand for me.
("report" looks like verb and "active external IP address" doesn't mean "external IP address for active mode".)

So, how about data_listening_address= and data_listening_port=.

These names involve below.

  • Address (or port) for data connection
  • Address (or port) for active mode
    • Only active mode listens data connection.

I don't cling to my suggestion.
Other expressive names are very welcome.

#6 [ruby-dev:50083] Updated by shugo (Shugo Maeda) about 1 month ago

osa (Shunsuke OSA) wrote:

Thank you so much for your survey.

If we translate java's setReportActiveExternalIPAddress() into Ruby method literally, it seems to be report_active_external_ip_address=.
But this name is difficult to understand for me.
("report" looks like verb and "active external IP address" doesn't mean "external IP address for active mode".)

So, how about data_listening_address= and data_listening_port=.

These names involve below.

  • Address (or port) for data connection
  • Address (or port) for active mode
    • Only active mode listens data connection.

I don't cling to my suggestion.
Other expressive names are very welcome.

The name data_listening_address= seems misleading because it doesn't
change the address to be bound.
And data_listening_port= is less flexible than setActivePortRange()
because it doesn't allow multiple port numbers.

So I prefer the following APIs:

  • data_port_address = addr
  • data_port_range = min .. max

#7 [ruby-dev:50086] Updated by osa (Shunsuke OSA) about 1 month ago

shugo (Shugo Maeda) wrote:

The name data_listening_address= seems misleading because it doesn't
change the address to be bound.

I see. It is reasonable.

And data_listening_port= is less flexible than setActivePortRange()
because it doesn't allow multiple port numbers.

This is reasonable too.
But as you know, PORT command can send only one port number.
I will implement that Net::FTP choose one of the port number in the range randomly.
(FTPClient of Apache Commons does so)

#8 Updated by shyouhei (Shyouhei Urabe) 29 days ago

  • Status changed from Open to Assigned

Also available in: Atom PDF