commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s...@apache.org
Subject svn commit: r1228513 - in /commons/proper/net/trunk/src: changes/changes.xml main/java/examples/ftp/FTPClientExample.java main/java/org/apache/commons/net/ftp/FTPClient.java main/java/org/apache/commons/net/ftp/FTPHTTPClient.java
Date Sat, 07 Jan 2012 00:30:40 GMT
Author: sebb
Date: Sat Jan  7 00:30:39 2012
New Revision: 1228513

URL: http://svn.apache.org/viewvc?rev=1228513&view=rev
Log:
NET-422 FTP using HTTP proxy not working

Modified:
    commons/proper/net/trunk/src/changes/changes.xml
    commons/proper/net/trunk/src/main/java/examples/ftp/FTPClientExample.java
    commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPClient.java
    commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPHTTPClient.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=1228513&r1=1228512&r2=1228513&view=diff
==============================================================================
--- commons/proper/net/trunk/src/changes/changes.xml (original)
+++ commons/proper/net/trunk/src/changes/changes.xml Sat Jan  7 00:30:39 2012
@@ -59,6 +59,9 @@ The <action> type attribute can be add,u
         <release version="3.1-SNAPSHOT" date="TBA" description="
 TBA
         ">
+            <action issue="NET-422" dev="sebb" type="fix" due-to="Tomas Mysik / Magnus
Johansson">
+            FTP using HTTP proxy not working
+            </action>
             <action issue="NET-423" dev="sebb" type="fix" due-to="Jens Koch">
             FTPClient.storeFIle might fail when ControlKeepAliveTimeout is set (ditto for
FTPCLient.retrieveFile)
             </action>

Modified: commons/proper/net/trunk/src/main/java/examples/ftp/FTPClientExample.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/examples/ftp/FTPClientExample.java?rev=1228513&r1=1228512&r2=1228513&view=diff
==============================================================================
--- commons/proper/net/trunk/src/main/java/examples/ftp/FTPClientExample.java (original)
+++ commons/proper/net/trunk/src/main/java/examples/ftp/FTPClientExample.java Sat Jan  7 00:30:39
2012
@@ -27,6 +27,7 @@ import java.io.PrintWriter;
 import org.apache.commons.net.PrintCommandListener;
 import org.apache.commons.net.ftp.FTP;
 import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPHTTPClient;
 import org.apache.commons.net.ftp.FTPClientConfig;
 import org.apache.commons.net.ftp.FTPConnectionClosedException;
 import org.apache.commons.net.ftp.FTPFile;
@@ -66,6 +67,9 @@ public final class FTPClientExample
         "\t-t - list file details using MLST (remote is used as the pathname if provided)\n"
+
         "\t-w msec - wait time for keep-alive reply (setControlKeepAliveReplyTimeout)\n"
+
         "\t-T  all|valid|none - use one of the built-in TrustManager implementations (none
= JVM default)\n" +
+        "\t-PrH server[:port] - HTTP Proxy host and optional port[80] \n" +
+        "\t-PrU user - HTTP Proxy server username\n" +
+        "\t-PrP password - HTTP Proxy server password\n" +
         "\t-# - add hash display during transfers\n";
 
     public static final void main(String[] args)
@@ -80,6 +84,10 @@ public final class FTPClientExample
         String protocol = null; // SSL protocol
         String doCommand = null;
         String trustmgr = null;
+        String proxyHost = null;
+        int proxyPort = 80;
+        String proxyUser = null;
+        String proxyPassword = null;
 
         int base = 0;
         for (base = 0; base < args.length; base++)
@@ -138,6 +146,20 @@ public final class FTPClientExample
             else if (args[base].equals("-T")) {
                 trustmgr = args[++base];
             }
+            else if (args[base].equals("-PrH")) {
+                proxyHost = args[++base]; 
+                String parts[] = proxyHost.split(":");
+                if (parts.length == 2){
+                    proxyHost=parts[0];
+                    proxyPort=Integer.parseInt(parts[1]);
+                }
+            }
+            else if (args[base].equals("-PrU")) {
+                proxyUser = args[++base];
+            }
+            else if (args[base].equals("-PrP")) {
+                proxyPassword = args[++base];
+            }
             else if (args[base].equals("-#")) {
                 printHash = true;
             }
@@ -175,7 +197,13 @@ public final class FTPClientExample
 
         final FTPClient ftp;
         if (protocol == null ) {
-            ftp = new FTPClient();
+            if(proxyHost !=null) {
+                System.out.println("Using HTTP proxy server: " + proxyHost);
+                ftp = new FTPHTTPClient(proxyHost, proxyPort, proxyUser, proxyPassword);
+            }
+            else {
+                ftp = new FTPClient();
+            }
         } else {
             FTPSClient ftps;
             if (protocol.equals("true")) {
@@ -222,7 +250,7 @@ public final class FTPClientExample
             } else {
                 ftp.connect(server);
             }
-            System.out.println("Connected to " + server + " on "+ftp.getRemotePort());
+            System.out.println("Connected to " + server + " on " + (port>0 ? port : ftp.getDefaultPort()));
 
             // After connection attempt, you should check the reply code to verify
             // success.

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=1228513&r1=1228512&r2=1228513&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 Jan
 7 00:30:39 2012
@@ -470,7 +470,7 @@ implements Configurable
     }
 
 
-    private void __parsePassiveModeReply(String reply)
+    protected void _parsePassiveModeReply(String reply)
     throws MalformedServerReplyException
     {
         java.util.regex.Matcher m = __PARMS_PAT.matcher(reply);
@@ -508,7 +508,7 @@ implements Configurable
         }
     }
 
-    private void __parseExtendedPassiveModeReply(String reply)
+    protected void _parseExtendedPassiveModeReply(String reply)
     throws MalformedServerReplyException
     {
         int port;
@@ -739,7 +739,7 @@ implements Configurable
             boolean attemptEPSV = isUseEPSVwithIPv4() || isInet6Address;
             if (attemptEPSV && epsv() == FTPReply.ENTERING_EPSV_MODE)
             {
-                __parseExtendedPassiveModeReply(_replyLines.get(0));
+                _parseExtendedPassiveModeReply(_replyLines.get(0));
             }
             else
             {
@@ -750,7 +750,7 @@ implements Configurable
                 if (pasv() != FTPReply.ENTERING_PASSIVE_MODE) {
                     return null;
                 }
-                __parsePassiveModeReply(_replyLines.get(0));
+                _parsePassiveModeReply(_replyLines.get(0));
             }
 
             socket = _socketFactory_.createSocket();
@@ -1174,7 +1174,7 @@ implements Configurable
         }
 
         __dataConnectionMode = PASSIVE_REMOTE_DATA_CONNECTION_MODE;
-        __parsePassiveModeReply(_replyLines.get(0));
+        _parsePassiveModeReply(_replyLines.get(0));
 
         return true;
     }
@@ -2282,7 +2282,7 @@ implements Configurable
      * @exception IOException  If an I/O error occurs while either sending a
      *      command to the server or receiving a reply from the server.
      ***/
-    private boolean restart(long offset) throws IOException
+    protected boolean restart(long offset) throws IOException
     {
         __restartOffset = 0;
         return FTPReply.isPositiveIntermediate(rest(Long.toString(offset)));

Modified: commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPHTTPClient.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPHTTPClient.java?rev=1228513&r1=1228512&r2=1228513&view=diff
==============================================================================
--- commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPHTTPClient.java (original)
+++ commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPHTTPClient.java Sat
Jan  7 00:30:39 2012
@@ -23,6 +23,7 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
+import java.net.Inet6Address;
 import java.net.Socket;
 import java.net.SocketException;
 import java.util.ArrayList;
@@ -33,7 +34,6 @@ import org.apache.commons.net.util.Base6
 /**
  * Experimental attempt at FTP client that tunnels over an HTTP proxy connection.
  *
- * @author rory
  * @since 2.2
  */
 public class FTPHTTPClient extends FTPClient {
@@ -41,8 +41,6 @@ public class FTPHTTPClient extends FTPCl
     private final int proxyPort;
     private final String proxyUsername;
     private final String proxyPassword;
-    private String host;
-    private int port;
 
     private final byte[] CRLF;
     private final Base64 base64 = new Base64();
@@ -66,22 +64,50 @@ public class FTPHTTPClient extends FTPCl
 
 
     @Override
-    protected Socket _openDataConnection_(int command, String arg)
+    protected Socket _openDataConnection_(int command, String arg) 
     throws IOException {
-        Socket socket = new Socket(host, port);
+        Socket socket;
+
+        //Force local passive mode, active mode not supported by through proxy
+        if (getDataConnectionMode() != PASSIVE_LOCAL_DATA_CONNECTION_MODE) {
+            enterLocalPassiveMode();
+        }
+
+        final boolean isInet6Address = getRemoteAddress() instanceof Inet6Address;
+        
+        boolean attemptEPSV = isUseEPSVwithIPv4() || isInet6Address;
+        if (attemptEPSV && epsv() == FTPReply.ENTERING_EPSV_MODE) {
+            _parseExtendedPassiveModeReply(_replyLines.get(0));
+        } else {
+            if (isInet6Address) {
+                return null; // Must use EPSV for IPV6
+            }
+            // If EPSV failed on IPV4, revert to PASV
+            if (pasv() != FTPReply.ENTERING_PASSIVE_MODE) {
+                return null;
+            }
+            _parsePassiveModeReply(_replyLines.get(0));
+        }
+
+        socket = new Socket(proxyHost, proxyPort);
         InputStream is = socket.getInputStream();
         OutputStream os = socket.getOutputStream();
+        tunnelHandshake(this.getPassiveHost(), this.getPassivePort(), is, os);
+        if ((getRestartOffset() > 0) && !restart(getRestartOffset())) {
+            socket.close();
+            return null;
+        }
 
-        tunnelHandshake(host, port, is, os);
+        if (!FTPReply.isPositivePreliminary(sendCommand(command, arg))) {
+            socket.close();
+            return null;
+        }
 
         return socket;
     }
 
     @Override
-    public void connect(String host, int port) throws SocketException,
-    IOException {
-        this.host = host;
-        this.port = port;
+    public void connect(String host, int port) throws SocketException, IOException {
 
         _socket_ = new Socket(proxyHost, proxyPort);
         _input_ = _socket_.getInputStream();
@@ -90,57 +116,62 @@ public class FTPHTTPClient extends FTPCl
             tunnelHandshake(host, port, _input_, _output_);
         }
         catch (Exception e) {
-            IOException ioe = new IOException("Could not connect to " + host);
+            IOException ioe = new IOException("Could not connect to " + host+ " using port
" + port);
             ioe.initCause(e);
             throw ioe;
         }
+        super._connectAction_();
     }
 
     private void tunnelHandshake(String host, int port, InputStream input, OutputStream output)
throws IOException,
     UnsupportedEncodingException {
         final String connectString = "CONNECT "  + host + ":" + port  + " HTTP/1.1";
+        final String hostString = "Host: " + host + ":" + port;
 
-        _output_.write(connectString.getBytes(getControlEncoding()));
-        _output_.write(CRLF);
+        output.write(connectString.getBytes("UTF-8"));
+        output.write(CRLF);
+        output.write(hostString.getBytes("UTF-8"));
+ 	    output.write(CRLF);
 
         if (proxyUsername != null && proxyPassword != null) {
+            final String auth = proxyUsername + ":" + proxyPassword;
             final String header = "Proxy-Authorization: Basic "
-                + base64.encode(proxyUsername + ":" + proxyPassword) + "\r\n";
-            _output_.write(header.getBytes("UTF-8"));
-            _output_.write(CRLF);
-
-            List<String> response = new ArrayList<String>();
-            BufferedReader reader = new BufferedReader(
-                    new InputStreamReader(_input_));
-
-            for (String line = reader.readLine(); line != null
-            && line.length() > 0; line = reader.readLine()) {
-                response.add(line);
-            }
+                + base64.encodeToString(auth.getBytes("UTF-8"));
+            output.write(header.getBytes("UTF-8"));
+        }
+        output.write(CRLF);
 
-            int size = response.size();
-            if (size == 0) {
-                throw new IOException("No response from proxy");
-            }
+        List<String> response = new ArrayList<String>();
+        BufferedReader reader = new BufferedReader(
+                new InputStreamReader(input));
+
+        for (String line = reader.readLine(); line != null
+        && line.length() > 0; line = reader.readLine()) {
+            response.add(line);
+        }
 
-            String code = null;
-            String resp = response.get(0);
-            if (resp.startsWith("HTTP/") && resp.length() >= 12) {
-                code = resp.substring(9, 12);
-            } else {
-                throw new IOException("Invalid response from proxy: " + resp);
-            }
+        int size = response.size();
+        if (size == 0) {
+            throw new IOException("No response from proxy");
+        }
+
+        String code = null;
+        String resp = response.get(0);
+        if (resp.startsWith("HTTP/") && resp.length() >= 12) {
+            code = resp.substring(9, 12);
+        } else {
+            throw new IOException("Invalid response from proxy: " + resp);
+        }
 
-            if (!"200".equals(code)) {
-                StringBuilder msg = new StringBuilder();
-                msg.append("HTTPTunnelConnector: connection failed\r\n");
-                msg.append("Response received from the proxy:\r\n");
-                for (String line : response) {
-                    msg.append(line);
-                    msg.append("\r\n");
-                }
-                throw new IOException(msg.toString());
+        if (!"200".equals(code)) {
+            StringBuilder msg = new StringBuilder();
+            msg.append("HTTPTunnelConnector: connection failed\r\n");
+            msg.append("Response received from the proxy:\r\n");
+            for (String line : response) {
+                msg.append(line);
+                msg.append("\r\n");
             }
+            throw new IOException(msg.toString());
         }
     }
 }



Mime
View raw message