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

Multiple bug fixes/enhancements to support file output via ftp URL

XMLWordPrintable

    • beta
    • generic, x86, sparc
    • generic, solaris_2.5.1, windows_nt



      Name: tb29552 Date: 09/07/99


      1) Run the test program to reproduce the problem.
      2) Error msg:
      java.net.UnknownServiceException: protocol doesn't support output
      at java.net.URLConnection.getOutputStream(URLConnection.java:618)
      at FtpTest.main(Compiled Code)
      3) none
      4) java version "1.2.1"
      Classic VM (build JDK-1.2.1-A, native threads)
      5) This has bearing on part of the problem. A computer (Win98)
      with multiple ethernet interfaces (one netword card and one PPP
      via modem).

      In the process of providing an output stream via an ftp URL I
      have fixed three bugs and written eight distinct enhancements.
      All of the code overlaps in the same files so separating them
      into multiple reports is impractical (I'd have to assume that
      you processed each in precise order for the context diffs to
      make any sense). I have, therefore, included all of the changes
      in one context diff. However, each change is discussed
      individually below.

      The changes are as follows:
      1) BUG: The input stream processed the
      URL: ftp://ftp.sun.com/pub/showrev.dat as a request for the
      file '/pub/showrev.dat' on the host 'ftp.sun.com'. Please note
      that this does not conform with the description of a URL in
      RFC1738:
          url-path
              The rest of the locator consists of data specific to the
              scheme, and is known as the "url-path". It supplies the
              details of how the specified resource can be accessed.
              Note that the "/" between the host (or port) and the
              url-path is NOT part of the url-path.

      The first character returned by getURL() [the '/' at the
      beginning of '/pub/showrev.dat'] is now discarded.

      2) BUG: Hosts with multiple IP addresses were not properly
      supported. The problem was that FtpClient relied on
      InetAddress.getLocalHost().getAddress() to get the IP address
      sent via the PORT command to the ftp server. However, this
      IP address has only a 1 in N (where N is the number of
      network/modem/other IP interfaces present on the computer) of
      succeeding. The modified code now tries to use the local IP
      address of the existing command channel (the inherited telnet
      socket). If that fails, which it may since getLocalAddress
      is permitted to return '0.0.0.0', the code attempts to open a
      data channel using every IP address returned by
      InetAddress.getAllByName (The successful address is cached so
      subsequent PORT commands require no iteration).

      3) BUG: The reply processing did not allow for the (obscure)
      case of two pending replies being sent consequtively by the
      server. The old code cleared replyPending AFTER reading the
      second reply rather than BEFORE reading it.

      4) ENHANCEMENT: Added an inner class, DataSocket, to perform the
      functionality of FtpInputStream. The new class eliminated the
      need to create FtpOutputStream and actually eliminated all use
      of FtpInputStream.
      The new DataSocket offers two new capabilities:
      a) It's instance counted so that code with access to the
      FtpClient instance can't close the command channel BEFORE
      closing the data channels. This usually forces the data channels
      to terminate.
      b) It can support multiple, simultaneous data channels (provided
      the ftp server supports them). This capability is indicated by
      the ftp server issuing a completed reply prior to the data
      channel closing.

      5)ENHANCEMENT: Thrown exceptions, if at all possible, now
      include the ftp server's reply in their message [This is why I
      started working on this code. The original exception message
      printed "POST" when I really needed to see "POST 10.0.0.2"!].

      6) ENHANCEMENT: FtpClient now supports the pwd() method. This
      method was added as FtpURLConnection objects may now "share" a
      single FtpClient. The second FtpURLConnection needs to reset
      the FtpClient to its original directory (hence pwd()) so that
      a relative url-path will work.

      7) ENHANCEMENT: FtpClient's cd method now accepts either null
      or "" as a request to return the ftp server to the same working
      directory as it had when the FtpClient first opened the command
      connection. This would not be necessary if I knew that all
      servers supported "~" as the "home directory".

      8) ENHANCEMENT: FtpClient now supports the noop() method. This
      can be used to test whether the ftp server has closed
      (timed-out) the command channel.

      9) ENHANCEMENT: FtpClient now supports the isBusy() method.
      Many, if not all, ftp servers are highly serialized. As a
      result, any command sent after FtpClient recieves a pending
      reply and before FtpClient recieves the completed reply will
      block this thread (It's an I/O wait, not something that I did).
      The isBusy() method simply indicates that FtpClient is still
      expecting a completed reply from the ftp server.

      10) ENHANCEMENT: FtpURLConnection now supports opening either
      (but not both) an input stream or an output stream.

      11) ENHANCEMENT: FtpURLConnection is no longer tightly coupled
      to a single FtpClient. Multiple, sequential file transfers can
      now be performed using a single FtpClient. Parallel transfers,
      or transfers to distinct hosts, are still handled using
      individual FtpClient objects. This particular change was not
      required to make ftp output streams work. The original author
      of FtpURLConnection left a comment in the code indicating
      that this change would be desireable.
      TEST CASE:
      class FtpTest {
          public static void main(String[] args) {
      int i;

      try {
      java.net.URL inURL = new java.net.URL
      ("ftp://ftp.sun.com/pub/showrev.dat");
      java.net.URL outURL = new java.net.URL
      ("ftp://localhost/tmp/showrev.out");

      java.net.URLConnection inConnection = inURL.openConnection ();
      java.net.URLConnection outConnection = outURL.openConnection ();

      java.io.InputStream is = inConnection.getInputStream ();
      java.io.OutputStream os = outConnection.getOutputStream ();

      byte[] buffer = new byte [1024];
      boolean once = true;
      while ((i = is.read (buffer)) >= 0) {
      os.write (buffer, 0, i);
      }
      is.close ();
      os.close ();
      } catch (Throwable e) {
      e.printStackTrace ();
      }
          }
      }
      (Review ID: 94414)
      ======================================================================



      krystyna.polomski@Eng 2001-03-22
      updated FtpTest class to work within
      Sun. Attached as xxFtpTest.java

            jccollet Jean-Christophe Collet (Inactive)
            tbell Tim Bell
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: