ftp
ftp copied to clipboard
Using server IP as IP for passive mode in case of PASV connection error
Hi!
Faced this error while working with bad-configured third-party FTP server...
> PASV
< 227 Entering Passive Mode (172,19,192,40,204,178).
dial tcp 172.19.192.40:53441: connect: no route to host
Logs from connection to the same server in FileZilla:
...
Server sent passive reply with unroutable address. Using server address instead.
...
It would be better to have the similar behavior.
May be implemented as a new DialOption.
The workaround I'm currently using for this is as follows (it stores the address used for the initial connection and then just reuses that for any further connections). This is quite a common problem where FTP servers are behind NAT.
var d net.Dialer
var firstHost string
dialFunc = func(network, address string) (net.Conn, error) {
host, port, err := net.SplitHostPort(address)
if err != nil {
return nil, fmt.Errorf("ftp.Open: Failed to split address %s: %w", address, err)
}
if len(firstHost) == 0 {
firstHost = host
}
return d.DialContext(ctx, "tcp", net.JoinHostPort(firstHost, port))
}
c, err := ftp.Dial(ftpUrl.Host, ftp.DialWithContext(ctx), ftp.DialWithDialFunc(dialFunc))
@MattBrittan thanks! Did the same and it works fine. But seems that it have to be implemented as builtin feature.
AFAIS #349 solved this.
@tgulacsi that should fix some uses; in my case all of the addresses are private so the isBogusDataIP() would return false (and the fix would not be applied).
@MattBrittan sorry, I've missed that the server has private IP address. Then your solution is the most straightforward. Maybe documenting it would be enough.