Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6427768

FtpURLConnection doesn't close FTP connection when login fails

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 7
    • 5.0
    • core-libs
    • b03
    • x86
    • windows_xp
    • Verified

      FULL PRODUCT VERSION :
      java version "1.5.0_06"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
      Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows XP [Version 5.1.2600]

      A DESCRIPTION OF THE PROBLEM :
      When a FTP URL is used with an incorrect user or password, the FTP connection
      is remains open; the client receives an IOException when calling URLConnection.getInputStream() or URLConnection.getOutputStream and so isn't able to close the FTP connection using the input or ouput stream. I think the connection should be closed when logging in fails.

      Please note you have to provide an incorrect password as command-line
      argument e.g.:
      java -cp FTPupload.jar FTPupload host user invalidpassword FTPupload.jar

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Create a FTP URL with an invalid password
      2. Get the URLConnection urlc = url.openConnection()
      3. Open an ouputstream: OutputStream os = urlc.getOutputStream();
          An IOException is thrown and the FTP connection remains open.
      4. Do a netstat on the FTP server

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      a closed FTP connection.
      ACTUAL -
      the FTP connection remains open

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      - Complete IOException stack trace
      sun.net.ftp.FtpLoginException: Not logged in
             at sun.net.ftp.FtpClient.readReply(FtpClient.java:231)
             at sun.net.ftp.FtpClient.issueCommand(FtpClient.java:193)
             at sun.net.ftp.FtpClient.login(FtpClient.java:516)
             at
      sun.net.www.protocol.ftp.FtpURLConnection.connect(FtpURLConnection.java:276)

             at
      sun.net.www.protocol.ftp.FtpURLConnection.getOutputStream(FtpURLConnection.java:460)

             at FTPclientConn.openUploadStream(FTPupload.java:41)
             at FTPupload.doit(FTPupload.java:80)
             at FTPupload.<init>(FTPupload.java:73)
             at FTPupload.main(FTPupload.java:110)


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      // FTPupload.java by Rowland http://www.home.comcast.net/~rowland3/
      // Upload a file via FTP, using the JDK.

      import java.io.*;
      import java.net.*;


      class FTPclientConn
      {
          public final String host;
          public final String user;
          protected final String password;
          protected URLConnection urlc;
          
          public FTPclientConn(String _host, String _user, String _password)
          {
              host = _host; user = _user; password = _password;
              urlc = null;
          }
          
          protected URL makeURL(String targetfile) throws MalformedURLException
          {
              if (user == null)
                  return new URL("ftp://"+ host+ "/"+ targetfile+ ";type=i");
              else
                  return new URL("ftp://"+ user+ ":"+ password+ "@"+ host+ "/"+ targetfile+ ";type=i");
          }
          
          protected InputStream openDownloadStream(String targetfile) throws Exception
          {
              URL url = makeURL(targetfile);
              urlc = url.openConnection();
              InputStream is = urlc.getInputStream();
              return is;
          }
          
          protected OutputStream openUploadStream(String targetfile) throws Exception
          {
              URL url = makeURL(targetfile);
              urlc = url.openConnection();
              OutputStream os = urlc.getOutputStream();
              return os;
          }
          
          protected void close()
          {
              urlc = null;
      // Workaround: see below
              System.gc();
          }
      }


      public class FTPupload
      {
          protected FTPclientConn cconn;
          public final String localfile;
          public final String targetfile;
          
          public FTPupload(String _host, String _user, String _password,
                  String _localfile, String _targetfile)
          {
              cconn = new FTPclientConn(_host, _user, _password);
              localfile = _localfile;
              targetfile = _targetfile;
              doit();
          }
          public FTPupload(String _host, String _user, String _password, String _file)
          {
              cconn = new FTPclientConn(_host, _user, _password);
              localfile = _file;
              targetfile = _file;
              doit();
          }
          
          protected void doit()
          {
              try
              {
                  OutputStream os = cconn.openUploadStream(targetfile);
                  FileInputStream is = new FileInputStream(localfile);
                  byte[] buf = new byte[16384];
                  int c;
                  while (true)
                  {
                      //System.out.print(".");
                      c = is.read(buf);
                      if (c <= 0) break;
                      //System.out.print("[");
                      os.write(buf, 0, c);
                      //System.out.print("]");
                  }
                  os.close();
                  is.close();
                  cconn.close(); // section 3.2.5 of RFC1738
              }
              catch (Exception E)
              {
      // place a breakpoint here and notice the FTP connection is still open
      // on the server
                  System.err.println(E.getMessage());
                  E.printStackTrace();
              }
          }
          
          public static void main(String args[])
          {
      // Usage: FTPupload host, user, password, file
      // Use an invalid password
              new FTPupload(args[0], args[1], args[2], args[3]);
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Force a garbage collection with System.gc(). Then the finalize() method is called on the FtpURLConnection object which then checks whether the FTP connection is still open and if so closes the FTP connection.

            jccollet Jean-Christophe Collet (Inactive)
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: