/* * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /** * @test * @bug 5026745 6631048 * @modules jdk.httpserver * @run main/othervm/timeout=500 Test * @summary Cannot flush output stream when writing to an HttpUrlConnection */ import java.io.*; import java.net.*; import com.sun.net.httpserver.*; public class Test implements HttpHandler { static volatile int count = 0; static final String str1 = "Helloworld1234567890abcdefghijklmnopqrstuvwxyz"+ "1234567890abcdefkjsdlkjflkjsldkfjlsdkjflkj"+ "1434567890abcdefkjsdlkjflkjsldkfjlsdkjflkj"; static final String str2 = "Helloworld1234567890abcdefghijklmnopqrstuvwxyz"+ "1234567890"; public void handle(HttpExchange exchange) { String reqbody; try { switch (exchange.getRequestURI().toString()) { case "/test/test1": /* test1 -- keeps conn alive */ case "/test/test2": /* test2 -- closes conn */ printRequestURI(exchange); reqbody = read(exchange.getRequestBody()); if (!reqbody.equals(str1)) { exchange.sendResponseHeaders(500, 0); break; } Headers headers = exchange.getRequestHeaders(); String chunk = headers.getFirst("Transfer-encoding"); if (!"chunked".equals (chunk)) { exchange.sendResponseHeaders(501, 0); break; } exchange.sendResponseHeaders(200, reqbody.length()); write(exchange.getResponseBody(), reqbody); if (count == 1) { Headers resHeaders = exchange.getResponseHeaders() ; resHeaders.set("Connection", "close"); } break; case "/test/test3": /* test 3 */ printRequestURI(exchange); reqbody = read(exchange.getRequestBody()); if (!reqbody.equals(str2)) { exchange.sendResponseHeaders(500, 0); break; } headers = exchange.getRequestHeaders(); int clen = Integer.parseInt( headers.getFirst("Content-length")); if (clen != str2.length()) { exchange.sendResponseHeaders(501, 0); break; } Headers resHeaders = exchange.getResponseHeaders() ; resHeaders.set("Connection", "close"); exchange.sendResponseHeaders(200, reqbody.length()); write(exchange.getResponseBody(), reqbody); break; case "/test/test4": /* test 4 */ case "/test/test5": /* test 5 */ printRequestURI(exchange); break; case "/test/test6": /* test 6 */ printRequestURI(exchange); resHeaders = exchange.getResponseHeaders() ; resHeaders.set("Location", "http://foo.bar/"); resHeaders.set("Connection", "close"); exchange.sendResponseHeaders(307, 0); break; case "/test/test7": /* test 7 */ case "/test/test8": /* test 8 */ printRequestURI(exchange); reqbody = read(exchange.getRequestBody()); if (reqbody != null && !"".equals(reqbody)) { exchange.sendResponseHeaders(501, 0); break; } resHeaders = exchange.getResponseHeaders() ; resHeaders.set("Connection", "close"); exchange.sendResponseHeaders(200, 0); break; case "/test/test9": /* test 9 */ printRequestURI(exchange); reqbody = read(exchange.getRequestBody()); if (!reqbody.equals(str1)) { exchange.sendResponseHeaders(500, 0); break; } headers = exchange.getRequestHeaders(); chunk = headers.getFirst("Transfer-encoding"); if (!"chunked".equals(chunk)) { exchange.sendResponseHeaders(501, 0); break; } exchange.sendResponseHeaders(200, reqbody.length()); write(exchange.getResponseBody(), reqbody); break; case "/test/test10": /* test10 */ printRequestURI(exchange); InputStream is = exchange.getRequestBody(); String s = read (is, str1.length()); boolean error = false; for (int i=10; i< 200 * 1024; i++) { byte c = (byte)is.read(); if (c != (byte)i) { error = true; System.out.println ("error at position " + i); } } if (!s.equals(str1) ) { System.out.println ("received string : " + s); exchange.sendResponseHeaders(500, 0); } else if (error) { System.out.println ("error"); exchange.sendResponseHeaders(500, 0); } else { exchange.sendResponseHeaders(200, 0); } break; case "/test/test11": /* test11 */ printRequestURI(exchange); is = exchange.getRequestBody(); s = read (is, str1.length()); error = false; for (int i=10; i< 30 * 1024; i++) { byte c = (byte)is.read(); if (c != (byte)i) { error = true; System.out.println ("error at position " + i); } } if (!s.equals(str1) ) { System.out.println ("received string : " + s); exchange.sendResponseHeaders(500, 0); } else if (error) { System.out.println ("error"); exchange.sendResponseHeaders(500, 0); } else { exchange.sendResponseHeaders(200, 0); } break; case "/test/test12": /* test12 */ printRequestURI(exchange); is = exchange.getRequestBody(); error = false; for (int i=10; i< 30 * 1024; i++) { byte c = (byte)is.read(); if (c != (byte)i) { error = true; System.out.println ("error at position " + i); } } if (error) { System.out.println ("error"); exchange.sendResponseHeaders(500, 0); } else { exchange.sendResponseHeaders(200, 0); } break; } count ++; exchange.close(); } catch (IOException e) { e.printStackTrace(); } } static void printRequestURI(HttpExchange exchange) { URI uri = exchange.getRequestURI(); System.out.println("HttpServer: handle " + uri); } static String read (InputStream is, int len) { try { byte[] ba = new byte [len]; int c; int l = 0; while ((c= is.read(ba, l, ba.length-l)) != -1 && l<len) { l += c; } return new String (ba, 0, l, "ISO8859-1"); } catch (Exception e) { e.printStackTrace(); } return null; } static String read(InputStream is) { try { byte[] ba = new byte [8096]; int off = 0, c; while ((c= is.read(ba, off, ba.length)) != -1) { off += c; } return new String(ba, 0, off, "ISO8859-1"); } catch (Exception e) { e.printStackTrace(); } return null; } static void write(OutputStream os, String str) { try { byte[] ba = str.getBytes("ISO8859-1"); os.write(ba); } catch (Exception e) { e.printStackTrace(); } } static void readAndCompare(InputStream is, String cmp) throws IOException { int c; byte buf[] = new byte [1024]; int off = 0; int len = 1024; while ((c=is.read(buf, off, len)) != -1) { off += c; len -= c; } String s1 = new String(buf, 0, off, "ISO8859_1"); if (!cmp.equals(s1)) { throw new IOException("strings not same"); } } /* basic chunked test (runs twice) */ static void test1 (String u) throws Exception { URL url = new URL (u); System.out.println ("client opening connection to: " + u); HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); urlc.setChunkedStreamingMode (20); urlc.setDoOutput(true); urlc.setRequestMethod ("POST"); OutputStream os = urlc.getOutputStream (); os.write (str1.getBytes()); os.close(); InputStream is = urlc.getInputStream(); readAndCompare (is, str1); is.close(); } /* basic fixed length test */ static void test3 (String u) throws Exception { URL url = new URL (u); System.out.println ("client opening connection to: " + u); HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); urlc.setFixedLengthStreamingMode (str2.length()); urlc.setDoOutput(true); urlc.setRequestMethod ("POST"); OutputStream os = urlc.getOutputStream (); os.write (str2.getBytes()); os.close(); InputStream is = urlc.getInputStream(); readAndCompare (is, str2); is.close(); } /* write too few bytes */ static void test4 (String u) throws Exception { URL url = new URL (u); System.out.println ("client opening connection to: " + u); HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); urlc.setFixedLengthStreamingMode (str2.length()+1); urlc.setDoOutput(true); urlc.setRequestMethod ("POST"); OutputStream os = urlc.getOutputStream (); os.write (str2.getBytes()); try { os.close(); throw new Exception ("should have thrown IOException"); } catch (IOException e) {} } /* write too many bytes */ static void test5 (String u) throws Exception { URL url = new URL (u); System.out.println ("client opening connection to: " + u); HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); urlc.setFixedLengthStreamingMode (str2.length()-1); urlc.setDoOutput(true); urlc.setRequestMethod ("POST"); OutputStream os = urlc.getOutputStream (); try { os.write (str2.getBytes()); throw new Exception ("should have thrown IOException"); } catch (IOException e) {} } /* check for HttpRetryException on redirection */ static void test6 (String u) throws Exception { URL url = new URL (u); System.out.println ("client opening connection to: " + u); HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); urlc.setChunkedStreamingMode (20); urlc.setDoOutput(true); urlc.setRequestMethod ("POST"); OutputStream os = urlc.getOutputStream (); os.write (str1.getBytes()); os.close(); try { InputStream is = urlc.getInputStream(); throw new Exception ("should have gotten HttpRetryException"); } catch (HttpRetryException e) { if (e.responseCode() != 307) { throw new Exception ("Wrong response code " + e.responseCode()); } if (!e.getLocation().equals ("http://foo.bar/")) { throw new Exception ("Wrong location " + e.getLocation()); } } } /* next two tests send zero length posts */ static void test7 (String u) throws Exception { URL url = new URL (u); System.out.println ("client opening connection to: " + u); HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); urlc.setChunkedStreamingMode (20); urlc.setDoOutput(true); urlc.setRequestMethod ("POST"); OutputStream os = urlc.getOutputStream (); os.close(); int ret = urlc.getResponseCode(); if (ret != 200) { throw new Exception ("Expected 200: got " + ret); } } static void test8 (String u) throws Exception { URL url = new URL (u); System.out.println ("client opening connection to: " + u); HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); urlc.setFixedLengthStreamingMode (0); urlc.setDoOutput(true); urlc.setRequestMethod ("POST"); OutputStream os = urlc.getOutputStream (); os.close(); int ret = urlc.getResponseCode(); if (ret != 200) { throw new Exception ("Expected 200: got " + ret); } } /* calling setChunkedStreamingMode with -1 should entail using the default chunk size */ static void test9 (String u) throws Exception { URL url = new URL (u); System.out.println ("client opening connection to: " + u); HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); urlc.setChunkedStreamingMode (-1); urlc.setDoOutput(true); urlc.setRequestMethod ("POST"); OutputStream os = urlc.getOutputStream (); os.write (str1.getBytes()); os.close(); InputStream is = urlc.getInputStream(); readAndCompare (is, str1); is.close(); } static void test10 (String u) throws Exception { URL url = new URL (u); System.out.println ("client opening connection to: " + u); HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); urlc.setChunkedStreamingMode (4 * 1024); urlc.setDoOutput(true); urlc.setRequestMethod ("POST"); OutputStream os = urlc.getOutputStream (); byte[] buf = new byte [200 * 1024]; for (int i=0; i< 200 * 1024; i++) { buf[i] = (byte) i; } /* write a small bit first, and then the large buffer */ os.write (str1.getBytes()); os.write (buf, 10, buf.length - 10); /* skip 10 bytes to test offset */ os.close(); InputStream is = urlc.getInputStream(); is.close(); int ret = urlc.getResponseCode(); if (ret != 200) { throw new Exception ("Expected 200: got " + ret); } } static void test11 (String u) throws Exception { URL url = new URL (u); System.out.println ("client opening connection to: " + u); HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); urlc.setChunkedStreamingMode (36 * 1024); urlc.setDoOutput(true); urlc.setRequestMethod ("POST"); OutputStream os = urlc.getOutputStream (); byte[] buf = new byte [30 * 1024]; for (int i=0; i< 30 * 1024; i++) { buf[i] = (byte) i; } /* write a small bit first, and then the large buffer */ os.write (str1.getBytes()); //os.write (buf, 10, buf.length - 10); /* skip 10 bytes to test offset */ os.write (buf, 10, (10 * 1024) - 10); os.write (buf, (10 * 1024), (10 * 1024)); os.write (buf, (20 * 1024), (10 * 1024)); os.close(); InputStream is = urlc.getInputStream(); is.close(); int ret = urlc.getResponseCode(); if (ret != 200) { throw new Exception ("Expected 200: got " + ret); } } static void test12 (String u) throws Exception { URL url = new URL (u); System.out.println ("client opening connection to: " + u); HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); urlc.setChunkedStreamingMode (36 * 1024); urlc.setDoOutput(true); urlc.setRequestMethod ("POST"); OutputStream os = urlc.getOutputStream (); byte[] buf = new byte [30 * 1024]; for (int i=0; i< 30 * 1024; i++) { buf[i] = (byte) i; } os.write (buf, 10, buf.length - 10); /* skip 10 bytes to test offset */ os.close(); InputStream is = urlc.getInputStream(); is.close(); int ret = urlc.getResponseCode(); if (ret != 200) { throw new Exception ("Expected 200: got " + ret); } } static com.sun.net.httpserver.HttpServer httpserver; public static void main (String[] args) throws Exception { try { httpserver = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0); HttpContext ctx = httpserver.createContext("/test/", new Test() ); httpserver.start(); int port = httpserver.getAddress().getPort(); System.out.println ("Server started: listening on port: " + port); test1("http://localhost:"+ port + "/test/test1"); test1("http://localhost:"+ port + "/test/test2"); test3("http://localhost:"+ port + "/test/test3"); test4("http://localhost:"+ port + "/test/test4"); test5("http://localhost:"+ port + "/test/test5"); test6("http://localhost:"+ port + "/test/test6"); test7("http://localhost:"+ port + "/test/test7"); test8("http://localhost:"+ port + "/test/test8"); test9("http://localhost:"+ port + "/test/test9"); test10("http://localhost:"+ port + "/test/test10"); test11("http://localhost:"+ port + "/test/test11"); test12("http://localhost:"+ port + "/test/test12"); } finally { if (httpserver != null) httpserver.stop(0); } } }