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

Closing a keep alive stream gives NullPointerException

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 1.4.1
    • 1.4.0
    • core-libs
    • hopper
    • generic, x86
    • generic, windows_95
    • Verified



      Name: nt126004 Date: 11/29/2001


      E:\work\bug>java -version
      java version "1.4.0-beta3"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta3-b84)
      Java HotSpot(TM) Client VM (build 1.4.0-beta3-b84, mixed mode)



      When opening a HTTP-connection to a Web Server that supports keep-alive, the
      Java client may throw a NullPointerException. This occurs, if the received content
      length header does not meet the actual content length that was sent by the
      server.

      Scenario:
      - client creates a HttpURLConnection object and gets the input stream
      - the server answers the request
      - for some reason, the server does not send as many bytes as it indicated in
      the content-length header and closes the connection
      - the client recognizes the end of the stream and tries to close the
      KeepAliveStream
      - this class performs skip operations, until as many bytes are received as
      expected
      - unfortunately, the underlying SocketInputStream cannot return more content,
      instead it returns -1 (EOF)
      - Exception

      here is the stacktrace:

      D:\development\mp\code\keepalive>java Client
      sun.net.www.protocol.http.HttpURLConnection$HttpInputStream
      123456789java.lang.NullPointerException
              at sun.net.www.http.KeepAliveStream.close(Unknown Source)
              at java.io.FilterInputStream.close(Unknown Source)
              at
      sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.close(Unk
      nown Source)
              at java.io.BufferedInputStream.close(Unknown Source)
              at sun.nio.cs.StreamDecoder$CharsetSD.implClose(Unknown Source)
              at sun.nio.cs.StreamDecoder.close(Unknown Source)
              at java.io.InputStreamReader.close(Unknown Source)
              at Client.main(Client.java:32)

      The following test code shows the problem.

      Server.java:

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

      public class Server
      {
          public static void main(String[] args)
          {
              try
              {
                  ServerSocket socket = new ServerSocket(8080);
                  System.out.println("ServerSocket ready");

                  Socket s = socket.accept();
                  System.out.println("accepted");

                  // read HTTP request from client
                  DataInputStream din = new DataInputStream(s.getInputStream());
                  while (true)
                  {
                      String line = din.readLine();
                      System.out.println(line);
                      if ((line == null) || line.trim().length() == 0)
                      {
                          break;
                      }
                  }

                  OutputStream out = s.getOutputStream();
                  OutputStreamWriter ow = new OutputStreamWriter(out);

                  ow.write("HTTP/1.0 200 OK\n");

                  // Note: The client expects 10 bytes.
                  ow.write("Content-Length: 10\n");
                  ow.write("Content-Type: text/html\n");

                  // Note: If this line is missing, everything works fine.
                  ow.write("Connection: Keep-Alive\n");
                  ow.write("\n");

                  // Note: The (buggy) server only sends 9 bytes.
                  ow.write("123456789");
                  ow.flush();
                  ow.close();

                  System.out.println("Response sent");
              }
              catch (Exception ex)
              {
                  ex.printStackTrace();
              }
          }
      }

      Client.java:

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

      public class Client
      {
          public static void main(String[] args)
          {
              HttpURLConnection con = null;
              InputStreamReader isr = null;

              try
              {
                  // open connection
                  con = (HttpURLConnection) new URL
      ("http://localhost:8080").openConnection();

                  // get content
                  InputStream in = con.getInputStream();
                  System.out.println(in.getClass().getName());

                  isr = new InputStreamReader(new BufferedInputStream(in));
                  int i = 0;
                  char cbuf[] = new char[1024];
                  while (true)
                  {
                      i = isr.read(cbuf, 0, 1024);
                      if (i <= 0) break;

                      System.out.print(new String(cbuf, 0, i));
                      System.out.flush();
                  }
                  
                  isr.close();
                  con.disconnect();
              }
              catch (Exception e)
              {
                  e.printStackTrace();
              }
          }
      }

      Of course, the behavior of the web server is not correct, but this may not hang
      up the client!
      (Review ID: 135870)
      ======================================================================

            ywangsunw Yingxian Wang (Inactive)
            nthompsosunw Nathanael Thompson (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: