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

cannot disconnect an http url connection after close of input stream

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • 7
    • 1.4.2
    • core-libs
    • sparc
    • solaris_9

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

      ADDITIONAL OS VERSION INFORMATION :
      5.9 Generic_112233-12 sun4u sparc SUNW,Ultra-Enterprise

      A DESCRIPTION OF THE PROBLEM :
      The order of close/disconnect when an inputstream is used for
      I/O on an underlying http url connection is significant. If the inputstream
      is closed first, the disconnect does not seem to work. This has been observed when creating an HttpURLConnection to a cgi program hosted by an apache web server. A BufferedReader is used to encapsulate the
      inputstream of the url connection. After "readLine()" of BufferedReader indicates no more data, a close is done, then a disconnect. However,
      the socket remains connected, as if apache never sees the disconnect.
      If the order of disconnect/close is reversed everything behaves normally.

      BufferedReader bfr =
                          new BufferedReader(new InputStreamReader(// on some url connection));
                  String input;
                  int i = 0;
                  while((input = bfr.readLine()) != null)
                  {
                      System.out.println("input = " + input);
                  }
                  bfr.close();// The order of these is significant!!
                  h_uc.disconnect();

      Attached you will find a program exercise the test case and a sample cgi program that should be named "tester". Modify the line beginning with "String url" to construct a valid url to the "tester" cgi program on a Solaris machine running an Apache web server of any vintage.
      To compile: javac TestCase.java
      To run: java -classpath . TestCase

      You should see "hello" displayed. The program will then sleep allowing you to run "pfiles" on the process, if it's a Solaris box anyway. When you do this you will see that one of it's file descriptors is a socket connection back to the apache web server.

      Kill the program and modify the order of the close and disconnect statements. Recompile and run again. This time "pfiles" will show that the program does not have a socket connection back to Apache.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      It should be possible to disconnect the connection after the close.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.lang.*;
      import java.io.*;
      import java.net.*;

      public class TestCase {

          public TestCase()
          {
             try {
              String url = "http://<somedomain>/tester";
                      // some url to a cgi program that produces
                      // lines of string output
                  URL whereto = new URL(url);
              HttpURLConnection h_uc =
                  (HttpURLConnection)(whereto.openConnection());

              h_uc.setDoInput(true);
              h_uc.setUseCaches(false);
              h_uc.setDoOutput(false);
              h_uc.connect();
              InputStream ip = h_uc.getInputStream();
              BufferedReader bfr =
                      new BufferedReader(new InputStreamReader(ip));
      String input;
              while((input = bfr.readLine()) != null)
              {
                  System.out.println("input = " + input);
              }
              // Here is the problem code, If I close the
              // the BufferedStream reader first, the underlying
              // persistent http connection does not get dropped.
              // However, if I do the disconnect(), then the close()
              // it does get dropped immediately. This is a different
              // (and unexpected) behaviour from previous releases.
              bfr.close();
              h_uc.disconnect();
          }
          catch(Exception ex) {
                  System.out.println("ex = " + ex.toString());
          }
          }
          public static void main(String args[])
          {
              TestCase tc = new TestCase();
              try {
                  Thread.sleep(300000);
              }
              catch(Exception ex){};
          }
      }
      -----------------------tester cgi program -------------------------------
      #!/bin/ksh
      echo "Content-type: text/plain"
      echo "Status: 200 HTTP_OK\n"
      echo "hello"
      ----------------------------------------------------
                                                              
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      reversing the order of close/disconnect
      ###@###.### 2005-06-16 09:42:14 GMT

            yuwangsunw Yujiang Wang (Inactive)
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: