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

HttpURLConnection.getInputStream() throws IOException on http 500

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P5 P5
    • None
    • 1.3.1
    • core-libs
    • generic
    • generic



      Name: bsT130419 Date: 10/11/2001


      java version "1.3.1_01"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_01)
      Java HotSpot(TM) Client VM (build 1.3.1_01, mixed mode)

      java version "1.4.0-beta2"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta2-b77)
      Java HotSpot(TM) Client VM (build 1.4.0-beta2-b77, mixed mode)

      1)
      Both in JDK 1.3.1_01 and 1.4.0-beta2,
      calling getInputStream on a URLConnection for which the server returns a staus
      code of 500, result in a IOException like :

      java.io.IOException: Server returned HTTP response code: 500 for URL:
      http://easysoap.sourceforge.net/cgi-bin/interopserver

      This makes impossible using HttpURLConnection for reading SOAP responses, like
      example 9 of the SOAP 1.1. spec.


      import java.io.BufferedReader;
      import java.io.IOException;
      import java.io.InputStream;
      import java.io.InputStreamReader;
      import java.io.OutputStream;
      import java.io.OutputStreamWriter;
      import java.io.PrintWriter;
      import java.io.Reader;
      import java.net.ServerSocket;
      import java.net.Socket;
      import java.net.URL;
      import java.net.URLConnection;

      /**
       * test case to show that on jdk 1.3.1_01 and 1.4.0-beta2
       * it is not possible to read the body of an HTTP response with status code 500,
       * as for example a SOAP response with a fault.
       */
      public class TestCaseFaultHttp500
      {
          private static final int SERVER_PORT = 7008;

          private TestFakeHttpServer fakeHttpServer;
          private String baseServerURL;

          private static String SOAP_REQUEST =
          "<SOAP-ENV:Envelope" + "\n" +
          " xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/&#39;" + "\n" +
          " SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/&#39;>" + "\n" +
          " <SOAP-ENV:Body>" + "\n" +
          " <m:GetLastTradePrice xmlns:m='Some-URI'>" + "\n" +
          " <symbol>DIS</symbol>" + "\n" +
          " </m:GetLastTradePrice>" + "\n" +
          " </SOAP-ENV:Body>" +
          "</SOAP-ENV:Envelope>";

          public static void main(String[] args)
          {
              TestCaseFaultHttp500 _tc = null;
              try {
                  _tc = new TestCaseFaultHttp500();
                  _tc.testFault200();
                  _tc.testFault500();
              }
              catch (Exception e) {
                  e.printStackTrace();
              }
              finally{
                  if(_tc!=null)
                      _tc.fakeHttpServer.stop();
              }
          }

          public TestCaseFaultHttp500() throws Exception {
              fakeHttpServer = new TestFakeHttpServer(SERVER_PORT);
              baseServerURL = "http://localhost:" + SERVER_PORT;
          }

          /**
           * this works with no problems
           * with jdk 1.3.1 and 1.3.1_01
           */
          public void testFault200() throws Exception
          {
              doTest(TestFakeHttpServer.PATH_USE_200);
          }

          /**
           * with jdk1.3.1_01 fails with
           * java.io.IOException: Server returned HTTP response code: 500 for URL: http://localhost:8008/use500
           *
           * with 1.3.1 fails with
           * java.io.FileNotFoundException: http://localhost:8008/use500
           */
          public void testFault500() throws Exception
          {
              System.out.println("-------------------------------------");
              doTest(TestFakeHttpServer.PATH_USE_500);
              System.out.println("-------------------------------------");
          }

          private void doTest(String aPath) throws Exception {
              URL _url = new URL(baseServerURL + aPath);

              System.out.println("testing with " + _url.toExternalForm());

              URLConnection _urlConnection = _url.openConnection();
              _urlConnection.setDoInput(true);
              _urlConnection.setDoOutput(true);
              _urlConnection.setUseCaches(false);

              OutputStream _os = _urlConnection.getOutputStream();
              PrintWriter _pw = new PrintWriter(new OutputStreamWriter(_os));

               System.out.println("writing ...");
              _pw.write(SOAP_REQUEST);
              _pw.flush();

              InputStream _is = _urlConnection.getInputStream();
              BufferedReader _br = new BufferedReader(new InputStreamReader(_is));

              System.out.println("reading ...");
              String _line = null;
              while(((_line = _br.readLine()) !=null)) {
                  System.out.print(_line);
                  System.out.print("\n");
              }
          }


      }


      /**
       * sends back a hardcoded soap fault, using http response code that depends
       * on the path of the POST request (200 or 500)
       */
      class TestFakeHttpServer {

          public static String PATH_USE_200 = "/use200";
          public static String PATH_USE_500 = "/use500";

          private static String SOAP_FAULT_RESPONSE =
          "<SOAP-ENV:Envelope " + "\n" +
          " xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/&#39;>" + "\n" +
          " <SOAP-ENV:Body>" + "\n" +
          " <SOAP-ENV:Fault>" + "\n" +
          " <faultcode>SOAP-ENV:Server</faultcode>" + "\n" +
          " <faultstring>I am just a fake server!</faultstring>" + "\n" +
          " </SOAP-ENV:Fault>" + "\n" +
          " </SOAP-ENV:Body>" + "\n" +
          "</SOAP-ENV:Envelope>";


          private ServerSocket serverSocket;
          private boolean keepRunning = true;

          public TestFakeHttpServer(int aPort) throws Exception {
              serverSocket = new ServerSocket(aPort);

              new Thread(new Runnable() {

                  public void run() {
                      while (keepRunning) {
                          Socket _clientSocket = null;
                          try {
                              _clientSocket = serverSocket.accept();
                              fakeHttp(_clientSocket);
                          }
                          catch (Exception anExc) {
                              if(keepRunning)
                                anExc.printStackTrace();
                              //else a socket close is expected and normal
                          }

                          finally {
                              if (_clientSocket != null)
                                  try {
                                      _clientSocket.close();
                                  }
                                  catch (IOException e) {
                                      //ignore
                                  }
                          }
                      }
                  }
              }).start();
           }


          private void fakeHttp(Socket aSocket) throws Exception {
              InputStream _inputStream = aSocket.getInputStream();
              Reader _br = new InputStreamReader(_inputStream);

              int _responseCodeToUse = 0;
              int _contentLength = 0;
              boolean _firstLine = true;

              String _line=null;
              //read headers
              while(((_line = readLine(_br))!=null)) {

                  if(_firstLine) {
                      //not interested in anything but the path to see
                      // if we should respond with 200 or 500
                      if(_line.startsWith("POST")) {
                          if(_line.indexOf(PATH_USE_200)!=-1)
                              _responseCodeToUse = 200;
                          else if(_line.indexOf(PATH_USE_500)!=-1)
                              _responseCodeToUse = 500;
                          else
                              throw new Exception("TestFakeHttpServer - " +
                                                  PATH_USE_200 + " or " + PATH_USE_500 +
                                                  " POST PATH expected");
                      }
                      else {
                          throw new Exception("TestFakeHttpServer - POST expected");
                      }
                      _firstLine = false;
                  }


                  if(_line.toUpperCase().indexOf("CONTENT-LENGTH:")!=-1) {
                      _contentLength = Integer.parseInt(_line.substring("CONTENT-LENGTH: ".length()));
                  }

                  if(_line.equals(""))
                      break;
              }

              //read body (and discard, because we're a fake server ;-)
              for(int i=0; i<_contentLength; i++)
                 _br.read();

              OutputStream _outputStream = aSocket.getOutputStream();
              PrintWriter _pw = new PrintWriter(new OutputStreamWriter(_outputStream));

              if(_responseCodeToUse==200)
                  _pw.write("HTTP/1.0 200 OK\r\n");
              else if(_responseCodeToUse==500)
                 _pw.write("HTTP/1.0 500 Internal Server Error\r\n");
              else
                  throw new Exception("TestFakeHttpServer - _responseCode should be 200 or 500");

              _pw.write("Content-Type: text/xml\r\n");
              _pw.write("Content-Length: " + SOAP_FAULT_RESPONSE.length() +"\r\n");
              _pw.write("\r\n");
              _pw.write(SOAP_FAULT_RESPONSE);
              _pw.flush();
          }


          /**
           * @return line without ending \r\n
           */
          private String readLine(Reader aReader) throws Exception {
              StringBuffer _line = new StringBuffer();
              int _char = 0;

              while(((_char = aReader.read())!=-1)) {
                  _line.append((char)_char);

                  int _length = _line.length();
                  if(_length >=2) {
                      if(_line.charAt(_length-1) == '\n' &&
                         _line.charAt(_length-2) == '\r') {
                          break;
                      }
                  }
              }

              if(_line.length() == 0)
                  return null;
              else {
                  return _line.substring(0, _line.length()-2);
              }
          }


          public void stop() {
              if (serverSocket != null) {
                  keepRunning = false;
                  try {
                      ServerSocket _tmp = serverSocket;
                      serverSocket = null;
                      _tmp.close();
                  }
                  catch (IOException anIOExc) {
                      anIOExc.printStackTrace();
                  }
              }
          }

      }





      3) the output of the above program on jdk131_01 is :
      C:\Edo\java\jdk1.3.1_01\bin\javaw.exe -classpath C:\Edo\java\jdk1.3.1_01
      \jre\lib\rt.jar;C:\Edo\myDev\http500\classes TestCaseFaultHttp500
      testing with http://localhost:7008/use200
      writing ...
      reading ...
      <SOAP-ENV:Envelope
        xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/&#39;>
         <SOAP-ENV:Body>
             <SOAP-ENV:Fault>
                 <faultcode>SOAP-ENV:Server</faultcode>
                 <faultstring>I am just a fake server!</faultstring>
             </SOAP-ENV:Fault>
         </SOAP-ENV:Body>
      </SOAP-ENV:Envelope>
      -------------------------------------
      testing with http://localhost:7008/use500
      writing ...
      java.io.IOException: Server returned HTTP response code: 500 for URL:
      http://localhost:7008/use500
      at sun.net.www.protocol.http.HttpURLConnection.getInputStream
      (HttpURLConnection.java:564)
      at TestCaseFaultHttp500.doTest(TestCaseFaultHttp500.java:93)
      at TestCaseFaultHttp500.testFault500(TestCaseFaultHttp500.java:72)
      at TestCaseFaultHttp500.main(TestCaseFaultHttp500.java:37)
      Process terminated with exit code 0
      (Review ID: 133429)
      ======================================================================

            alanb Alan Bateman
            bstrathesunw Bill Strathearn (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: