test/sun/net/www/protocol/http/ChunkedErrorStream.java

Print this page




   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 6488669 6595324
  27  * @run main/othervm ChunkedErrorStream
  28  * @summary Chunked ErrorStream tests
  29  */
  30 
  31 import java.net.*;
  32 import java.io.*;
  33 import com.sun.net.httpserver.*;
  34 
  35 /**
  36  * Part 1: 6488669
  37  * 1) Http server that responds with an error code (>=400)
  38  *    and a chunked response body. It also indicates that
  39  *    the connection will be closed.
  40  * 2) Client sends request to server and tries to
  41  *    getErrorStream(). Some data must be able to be read
  42  *    from the errorStream.
  43  *
  44  * Part 2: 6595324
  45  * 1) Http server that responds with an error code (>=400)
  46  *    and a chunked response body greater than
  47  *    sun.net.http.errorstream.bufferSize, 4K + 10 bytes.
  48  * 2) Client sends request to server and tries to
  49  *    getErrorStream(). 4K + 10 bytes must be read from
  50  *    the errorStream.












  51  */
  52 
  53 public class ChunkedErrorStream
  54 {
  55     com.sun.net.httpserver.HttpServer httpServer;
  56 
  57     static {
  58         // Enable ErrorStream buffering
  59         System.getProperties().setProperty("sun.net.http.errorstream.enableBuffering", "true");
  60 
  61         // No need to set this as 4K is the default
  62         // System.getProperties().setProperty("sun.net.http.errorstream.bufferSize", "4096");
  63     }
  64 
  65     public static void main(String[] args) {
  66         new ChunkedErrorStream();
  67     }
  68 
  69     public ChunkedErrorStream() {
  70         try {
  71             startHttpServer();
  72             doClient();
  73         } catch (IOException ioe) {
  74             ioe.printStackTrace();
  75         }  finally {
  76             httpServer.stop(1);
  77         }
  78 
  79     }
  80 
  81     void doClient() {
  82         for (int times=0; times<2; times++) {
  83             HttpURLConnection uc = null;
  84             try {
  85                 InetSocketAddress address = httpServer.getAddress();
  86                 String URLStr = "http://localhost:" + address.getPort() + "/test/";
  87                 if (times == 0) {
  88                     URLStr += 6488669;
  89                 } else {
  90                     URLStr += 6595324;
  91                 }
  92 
  93                 System.out.println("Trying " + URLStr);
  94                 URL url = new URL(URLStr);
  95                 uc = (HttpURLConnection)url.openConnection();
  96                 uc.getInputStream();
  97 
  98                 throw new RuntimeException("Failed: getInputStream should throw and IOException");
  99             }  catch (IOException e) {





 100                 // This is what we expect to happen.
 101                 InputStream es = uc.getErrorStream();
 102                 byte[] ba = new byte[1024];
 103                 int count = 0, ret;
 104                 try {
 105                     while ((ret = es.read(ba)) != -1)
 106                         count += ret;
 107                     es.close();
 108                 } catch  (IOException ioe) {
 109                     ioe.printStackTrace();
 110                 }
 111 
 112                 if (count == 0)
 113                     throw new RuntimeException("Failed: ErrorStream returning 0 bytes");
 114 
 115                 if (times == 1 && count != (4096+10))
 116                     throw new RuntimeException("Failed: ErrorStream returning " + count +
 117                                                  " bytes. Expecting " + (4096+10));
 118 
 119                 System.out.println("Read " + count + " bytes from the errorStream");
 120             }
 121         }
 122     }
 123 
 124     /**
 125      * Http Server
 126      */
 127     void startHttpServer() throws IOException {
 128         httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0);
 129 
 130         // create HttpServer context
 131         HttpContext ctx1 = httpServer.createContext("/test/6488669", new Handler6488669());
 132         HttpContext ctx2 = httpServer.createContext("/test/6595324", new Handler6595324());
 133 
 134         httpServer.start();
 135     }
 136 
 137     class Handler6488669 implements HttpHandler {
 138         public void handle(HttpExchange t) throws IOException {
 139             InputStream is = t.getRequestBody();
 140             byte[] ba = new byte[1024];
 141             while (is.read(ba) != -1);
 142             is.close();
 143 
 144             Headers resHeaders = t.getResponseHeaders();
 145             resHeaders.add("Connection", "close");
 146             t.sendResponseHeaders(404, 0);
 147             OutputStream os = t.getResponseBody();
 148 
 149             // actual data doesn't matter. Just send 2K worth.
 150             byte b = 'a';
 151             for (int i=0; i<2048; i++)
 152                 os.write(b);
 153 
 154             os.close();
 155             t.close();
 156         }
 157     }
 158 
 159     class Handler6595324 implements HttpHandler {



 160         public void handle(HttpExchange t) throws IOException {
 161             InputStream is = t.getRequestBody();
 162             byte[] ba = new byte[1024];
 163             while (is.read(ba) != -1);
 164             is.close();
 165 






 166             t.sendResponseHeaders(404, 0);
 167             OutputStream os = t.getResponseBody();
 168 
 169             // actual data doesn't matter. Just send more than 4K worth
 170             byte b = 'a';
 171             for (int i=0; i<(4096+10); i++)
 172                 os.write(b);
 173 
 174             os.close();
 175             t.close();
 176         }
 177     }
 178 }


   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 6488669 6595324 6993490
  27  * @run main/othervm ChunkedErrorStream
  28  * @summary Chunked ErrorStream tests
  29  */
  30 
  31 import java.net.*;
  32 import java.io.*;
  33 import com.sun.net.httpserver.*;
  34 
  35 /**
  36  * Part 1: 6488669
  37  * 1) Http server that responds with an error code (>=400)
  38  *    and a chunked response body. It also indicates that
  39  *    the connection will be closed.
  40  * 2) Client sends request to server and tries to
  41  *    getErrorStream(). Some data must be able to be read
  42  *    from the errorStream.
  43  *
  44  * Part 2: 6595324
  45  * 1) Http server that responds with an error code (>=400)
  46  *    and a chunked response body greater than
  47  *    sun.net.http.errorstream.bufferSize, 4K + 10 bytes.
  48  * 2) Client sends request to server and tries to
  49  *    getErrorStream(). 4K + 10 bytes must be read from
  50  *    the errorStream.
  51  *
  52  * Part 3: 6993490
  53  *    Reuse persistent connection from part 2, the error stream
  54  *    buffering will have set a reduced timeout on the socket and
  55  *    tried to reset it to the default, infinity. Client must not
  56  *    throw a timeout exception. If it does, it indicates that the
  57  *    default timeout was not reset correctly.
  58  *    If no timeout exception is thrown, it does not guarantee that
  59  *    the timeout was reset correctly, as there is a potential race
  60  *    between the sleeping server and the client thread. Typically,
  61  *    1000 millis has been enought to reliable reproduce this problem
  62  *    since the error stream buffering sets the timeout to 60 millis.
  63  */
  64 
  65 public class ChunkedErrorStream
  66 {
  67     com.sun.net.httpserver.HttpServer httpServer;
  68 
  69     static {
  70         // Enable ErrorStream buffering
  71         System.getProperties().setProperty("sun.net.http.errorstream.enableBuffering", "true");
  72 
  73         // No need to set this as 4K is the default
  74         // System.getProperties().setProperty("sun.net.http.errorstream.bufferSize", "4096");
  75     }
  76 
  77     public static void main(String[] args) {
  78         new ChunkedErrorStream();
  79     }
  80 
  81     public ChunkedErrorStream() {
  82         try {
  83             startHttpServer();
  84             doClient();
  85         } catch (IOException ioe) {
  86             ioe.printStackTrace();
  87         }  finally {
  88             httpServer.stop(1);
  89         }

  90     }
  91 
  92     void doClient() {
  93         for (int times=0; times<3; times++) {
  94             HttpURLConnection uc = null;
  95             try {
  96                 InetSocketAddress address = httpServer.getAddress();
  97                 String URLStr = "http://localhost:" + address.getPort() + "/test/";
  98                 if (times == 0) {
  99                     URLStr += "first";
 100                 } else {
 101                     URLStr += "second";
 102                 }
 103 
 104                 System.out.println("Trying " + URLStr);
 105                 URL url = new URL(URLStr);
 106                 uc = (HttpURLConnection)url.openConnection();
 107                 uc.getInputStream();
 108 
 109                 throw new RuntimeException("Failed: getInputStream should throw and IOException");
 110             }  catch (IOException e) {
 111                 if (e instanceof SocketTimeoutException) {
 112                     e.printStackTrace();
 113                     throw new RuntimeException("Failed: SocketTimeoutException should not happen");
 114                 }
 115 
 116                 // This is what we expect to happen.
 117                 InputStream es = uc.getErrorStream();
 118                 byte[] ba = new byte[1024];
 119                 int count = 0, ret;
 120                 try {
 121                     while ((ret = es.read(ba)) != -1)
 122                         count += ret;
 123                     es.close();
 124                 } catch  (IOException ioe) {
 125                     ioe.printStackTrace();
 126                 }
 127 
 128                 if (count == 0)
 129                     throw new RuntimeException("Failed: ErrorStream returning 0 bytes");
 130 
 131                 if (times >= 1 && count != (4096+10))
 132                     throw new RuntimeException("Failed: ErrorStream returning " + count +
 133                                                  " bytes. Expecting " + (4096+10));
 134 
 135                 System.out.println("Read " + count + " bytes from the errorStream");
 136             }
 137         }
 138     }
 139 
 140     /**
 141      * Http Server
 142      */
 143     void startHttpServer() throws IOException {
 144         httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0);
 145 
 146         // create HttpServer context
 147         httpServer.createContext("/test/first", new FirstHandler());
 148         httpServer.createContext("/test/second", new SecondHandler());
 149 
 150         httpServer.start();
 151     }
 152 
 153     class FirstHandler implements HttpHandler {
 154         public void handle(HttpExchange t) throws IOException {
 155             InputStream is = t.getRequestBody();
 156             byte[] ba = new byte[1024];
 157             while (is.read(ba) != -1);
 158             is.close();
 159 
 160             Headers resHeaders = t.getResponseHeaders();
 161             resHeaders.add("Connection", "close");
 162             t.sendResponseHeaders(404, 0);
 163             OutputStream os = t.getResponseBody();
 164 
 165             // actual data doesn't matter. Just send 2K worth.
 166             byte b = 'a';
 167             for (int i=0; i<2048; i++)
 168                 os.write(b);
 169 
 170             os.close();
 171             t.close();
 172         }
 173     }
 174 
 175     static class SecondHandler implements HttpHandler {
 176         /* count greater than 0, slow response */
 177         static int count = 0;
 178 
 179         public void handle(HttpExchange t) throws IOException {
 180             InputStream is = t.getRequestBody();
 181             byte[] ba = new byte[1024];
 182             while (is.read(ba) != -1);
 183             is.close();
 184 
 185             if (count > 0) {
 186                 System.out.println("server sleeping...");
 187                 try { Thread.sleep(1000); } catch(InterruptedException e) {}
 188             }
 189             count++;
 190  
 191             t.sendResponseHeaders(404, 0);
 192             OutputStream os = t.getResponseBody();
 193 
 194             // actual data doesn't matter. Just send more than 4K worth
 195             byte b = 'a';
 196             for (int i=0; i<(4096+10); i++)
 197                 os.write(b);
 198 
 199             os.close();
 200             t.close();
 201         }
 202     }
 203 }