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

using defaultReadTimeout appear to retry request upon timeout

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 5.0
    • 1.4.1
    • core-libs
    • b28
    • x86
    • windows_2000



        Name: nt126004 Date: 10/31/2002


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

        FULL OPERATING SYSTEM VERSION : Microsoft Windows 2000
        [Version 5.00.2195]


        A DESCRIPTION OF THE PROBLEM :
        I'm using System.setProperty
        ("sun.net.client.defaultReadTimeout", "10000"); to set the
        read timeout on my http request.

        I have a simple demo program where it sends out an http
        request. The server receives the request and then sleeps
        for 20000 msec. Just before the client receives the
        SocketTimeoutException, I see that the server reads in the
        exact same request. Where is this duplicate request coming
        from? Is the jre resending it for me? Is this
        configurable?


        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :

        Below is a my sample test driver that can be used as both
        the client and the server:

        1. start a server: java -cp . HttpCommTest -p 5555
        2. start a client: java -cp . HttpCommTest -p 7777 -
        u "http://127.0.0.1:5555"
        3. at the client's enter prompt, press the enter key
        4. watch the timestamps for
           a. the original message received
           b. the exception received by the client
           c. the duplicate message received by the server

        It looks like the server receives the duplicate before the
        client receives the exception




        EXPECTED VERSUS ACTUAL BEHAVIOR :
        ACTUAL
        -------
        Watch the timestamps for
           a. the original message received
           b. the exception received by the client
           c. the duplicate message received by the server

        It looks like the server receives the duplicate before the
        client receives the exception

        EXPECTED
        --------
        I did not expect for the server to receive a duplicate
        message after the socket read timeout exception was
        received by the client.

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------

        /**
         * This class can take a variable number of parameters on the command
         * line. Program execution begins with the main() method. The class
         * constructor is not invoked unless an object of type 'Class1'
         * created in the main() method.
         */

        // for server --> -cp . HttpCommTest -p 5555
        // for client --> -cp . HttpCommTest -p 7777 -u "http://127.0.0.1:5555"



        import java.net.*;
        import java.util.*;
        import java.io.*;
        import java.text.SimpleDateFormat;

        public class HttpCommTest implements Runnable
        {
        private static int m_port = 80;
            private static String m_sendToUrl = "http://127.0.0.1:5555";

        /**
        * The main entry point for the application.
        *
        * @param args Array of parameters passed to the application
        * via the command line.
        */
        public static void main (String[] args)
        {
        System.setProperty
        ("sun.net.client.defaultReadTimeout", "10000");

               //must have an even number of args
        if( (args.length % 2) != 0 )
        {
        outputUsage();
        return;
        }

        //get command line args
        for( int i = 0; i < args.length; i++ )
        {
        if( args[i].equalsIgnoreCase( "-p" ) )
        m_port = Integer.valueOf(args[++i]).intValue();
        else
        if( args[i].equalsIgnoreCase( "-u" ) )
        m_sendToUrl = args[++i];
        else
        {
        outputUsage();
        //return;
        }
        }

        HttpCommTest httpCommTest = new HttpCommTest();

        //start a thread to for incoming http requests
        Thread t = new Thread( httpCommTest );
        t.setDaemon( true );
        t.start();

        httpCommTest.doInput();

        }

        private void doInput()
        {
        //listen for command line input to do a send on main thread
        try
        {
        String dataToSend = "";
        System.out.print( "<Enter>" );
        while( true )
        {
        byte[] buf = new byte[1];
        int len = System.in.read( buf );
        if( len == -1 )
        break;

        if( buf[0] == '\r' )
        continue;

        if( buf[0] == '\n' )
        {


        try
        {
        URL url = new URL(m_sendToUrl);



        HttpURLConnection urlConn =
        (HttpURLConnection)url.openConnection();
        urlConn.setRequestMethod("GET");
        urlConn.setDoOutput(false);
        urlConn.setDoInput(true);
        urlConn.setAllowUserInteraction
        (false);
        urlConn.setRequestProperty("Content-
        type", "application/x-www-form-urlencoded");

        urlConn.setRequestProperty("Content-
        length", "0" );

        logTimestampedMsg("Sending
        Request---" );

        urlConn.connect();


        logTimestampedMsg("Waiting for
        response ---" );


        // Check the response code
        int responseCode =
        urlConn.getResponseCode();
        String responseMessage =
        urlConn.getResponseMessage();
        if (responseCode != 200) {
        System.out.println( "got bad http
        response code " + responseCode + ":" + responseMessage );
        throw new IOException("HTTP " +
        responseCode + " " + responseMessage);
        }
        logTimestampedMsg("Got response code
        = " + responseCode );

        }
        catch( Throwable t )
        {
        logTimestampedMsg("Unexpected
        Exception:" );
        t.printStackTrace();
        System.out.println
        ( "==================================================" );
        System.out.println( "" );
        }

        dataToSend = "";
        System.out.print( "<Enter>" );
        }
        else
        {
        String bufVal = new String( buf );
        dataToSend += bufVal;
        }
        }
        }
        catch( Exception e )
        {
        System.out.println( "INPUT FAILURE:" );
        e.printStackTrace();
        }
        }

        public static void outputUsage()
        {
        System.out.println( "java
        com.sentillion.test.httpCommunications -p <port> -u <url>" );
        System.out.println( "-p = port to listen for incoming requests,
        defaults to " + m_port );
        System.out.println( "-u = url to send a request to, defaults
        to " + m_sendToUrl );
        System.out.println( "Enter 'post' to send the request as a
        post" );
        }

        public void run()
        {
        ServerSocket connectSocket = null;
        try
        {
        connectSocket = new ServerSocket( m_port );
        connectSocket.setSoTimeout(5000);

        while( true )
        {
        Socket requestSocket = null;
        // Wait for a connection, then open a socket to
        receive the request
        try
        {
        requestSocket = connectSocket.accept();
        dispatchRequest( requestSocket );
        }
        catch (InterruptedIOException ex)
        {
        // System.out.println("CP Thread:
        timeout on connection - retrying");
        continue; // timeout on accept
        }
        catch (IOException e)
        {
        System.out.println("CP Thread: " +
        e.toString());
        break;
        }
        }

        connectSocket.close();
        connectSocket = null;
        System.out.println("CP Thread: exiting.");
        }
        catch( Exception e )
        {
        System.out.println( "LISTENING SOCKET FAILURE:" );
        e.printStackTrace();
        return;
        }

        }

        private void dispatchRequest( Socket socket )
        {
        String argContent = null;
        try
        {
        System.out.println("Reading request InputStream---");
        java.io.DataInputStream dataIn = new
        java.io.DataInputStream(socket.getInputStream());

        // Get first line of request, verify it's a POST
        //String line = dataIn.readLine();
        //System.out.println("Receiving Request---");
        //System.out.println(line);

        logTimestampedMsg("Receiving Request---");
        String firstLine = dataIn.readLine();
                    String line = firstLine;
                    while (line.length() != 0)
                    {
                        System.out.println(line);
                        line = dataIn.readLine();
                    }
        System.out.println( "" );

                   try
                   {
                    long sleepTime = 20000;
                    logTimestampedMsg("Sleeping for " + sleepTime + "
        Msec.");
                    Thread.currentThread().sleep(sleepTime);
                   }
                   catch(InterruptedException ex) {}
                    
                    
        System.out.println( "" );
        }
        catch (IOException e)
        {
        logTimestampedMsg("Request Handler: " + e.toString());
        e.printStackTrace();
        }
        finally
        {
        System.out.println("");
        System.out.println
        ( "==================================================" );
        System.out.println("");
        System.out.print("<Enter>");
        }

        }

        /**
        *
        */

        private void logTimestampedMsg(String msg)
        {
        String timeStamp = (new SimpleDateFormat("yyyy.MM.dd
        HH:mm:ss:SSS")).format(new Date());
        System.out.println(timeStamp + " " + msg);
        }
        }
        ---------- END SOURCE ----------
        (Review ID: 165851)
        ======================================================================

        Name: nt126004 Date: 10/31/2002


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

        FULL OPERATING SYSTEM VERSION :
        Microsoft Windows 2000 [Version 5.00.2195]
        ServicePack 3

        A DESCRIPTION OF THE PROBLEM :
        When HttpURLConnection makes a POST request to a web
        server, a separate timeout thread is used to call
        HttpURLConnection.disconnect() to break the connection to
        the web server. However, when HtppURLConnection.disconnect
        () is called, the connection is broken AND
        HttpURLConnection establishes a new connection, resending
        the request a second time. There is no way to timeout this
        second request, because at the higher application level
        (i.e. my program) I have already successfully called
        HttpUrlConnection.disconnect().

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        1. start a thread to timeout in 30 sec. to call disconnect()
        2. make a request to a server that will NOT send anything
        back (i.e. no HTTP Response Header).
        3. check logging on both sides and you will see that
        HttpURLConnection made 2 requests to the webserver.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        Only one POST should have been made and the
        HttpURLConnection.disconnect() should have broken its
        connection to the server.

        REPRODUCIBILITY :
        This bug can be reproduced always.
        (Review ID: 166180)
        ======================================================================

              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: