Author: sebb
Date: Sat Mar 5 21:05:41 2011
New Revision: 1078354
URL: http://svn.apache.org/viewvc?rev=1078354&view=rev
Log:
NET-363 Can't connect to a server behind firewall in passive mode.
Modified:
commons/proper/net/trunk/src/changes/changes.xml
commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPClient.java
Modified: commons/proper/net/trunk/src/changes/changes.xml
URL:
http://svn.apache.org/viewvc/commons/proper/net/trunk/src/changes/changes.xml?rev=1078354&r1=1078353&r2=1078354&view=diff
==============================================================================
--- commons/proper/net/trunk/src/changes/changes.xml (original)
+++ commons/proper/net/trunk/src/changes/changes.xml Sat Mar 5 21:05:41 2011
@@ -57,6 +57,9 @@ The <action> type attribute can be add,u
<body>
<release version="3.0" date="TBA" description="TBA">
+ <action issue="NET-363" dev="sebb" type="fix" due-to="daniel
damon">
+ Can't connect to a server behind firewall in passive mode.
+ </action>
<action issue="NET-348" dev="sebb" type="fix">
Queue is full TelnetInputStream.
</action>
Modified:
commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPClient.java
URL:
http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPClient.java?rev=1078354&r1=1078353&r2=1078354&view=diff
==============================================================================
---
commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPClient.java
(original)
+++
commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPClient.java
Sat Mar 5 21:05:41 2011
@@ -346,11 +346,11 @@ implements Configurable
// Most FTP servers don't seem to support concurrent control and data
connection usage
private int __controlKeepAliveReplyTimeout=1000;
- /** Pattern for PASV mode responses */
- private static final String __parms =
"\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3}";
- private static final java.util.regex.Pattern __parms_pat;
+ /** Pattern for PASV mode responses. Groups: (n,n,n,n),(n),(n) */
+ private static final java.util.regex.Pattern __PARMS_PAT;
static {
- __parms_pat = java.util.regex.Pattern.compile(__parms);
+ __PARMS_PAT = java.util.regex.Pattern.compile(
+ "(\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3}),(\\d{1,3}),(\\d{1,3})");
}
private static class PropertiesSingleton {
@@ -430,28 +430,41 @@ implements Configurable
private void __parsePassiveModeReply(String reply)
throws MalformedServerReplyException
{
- java.util.regex.Matcher m = __parms_pat.matcher(reply);
+ java.util.regex.Matcher m = __PARMS_PAT.matcher(reply);
if (!m.find()) {
throw new MalformedServerReplyException(
"Could not parse passive host information.\nServer Reply:
" + reply);
}
- reply = m.group();
- String parts[] = m.group().split(",");
- __passiveHost = parts[0] + '.' + parts[1] + '.' + parts[2] + '.' +
parts[3];
+ __passiveHost = m.group(1).replace(',', '.'); // Fix up to look like
IP address
try
{
- int oct1 = Integer.parseInt(parts[4]);
- int oct2 = Integer.parseInt(parts[5]);
+ int oct1 = Integer.parseInt(m.group(2));
+ int oct2 = Integer.parseInt(m.group(3));
__passivePort = (oct1 << 8) | oct2;
}
catch (NumberFormatException e)
{
throw new MalformedServerReplyException(
- "Could not parse passive host information.\nServer Reply:
" + reply);
+ "Could not parse passive port information.\nServer Reply:
" + reply);
}
+ try {
+ InetAddress host = InetAddress.getByName(__passiveHost);
+ // reply is a local address, but target is not - assume NAT box
changed the PASV reply
+ if (host.isSiteLocalAddress() &&
!getRemoteAddress().isSiteLocalAddress()){
+ String hostAddress = getRemoteAddress().getHostAddress();
+ if (_commandSupport_.getListenerCount() > 0) {
+ _commandSupport_.fireReplyReceived(0,
+ "[Replacing site local address "+__passiveHost+"
with "+hostAddress+"]\n");
+ }
+ __passiveHost = hostAddress;
+ }
+ } catch (UnknownHostException e) { // Should not happen as we are
passing in an IP address
+ throw new MalformedServerReplyException(
+ "Could not parse passive host information.\nServer Reply:
" + reply);
+ }
}
private void __parseExtendedPassiveModeReply(String reply)