8029127: Redirected POST request throws IllegalStateException on HttpURLConnection.getInputStream
authormichaelm
Tue, 03 Dec 2013 17:29:19 +0000
changeset 21952 6fdca3d54613
parent 21951 eb62ae4c1896
child 21953 3facfc87b92e
8029127: Redirected POST request throws IllegalStateException on HttpURLConnection.getInputStream Reviewed-by: alanb, chegar
jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
jdk/test/sun/net/www/protocol/http/RedirectOnPost.java
--- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Tue Dec 03 08:53:23 2013 +0100
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Tue Dec 03 17:29:19 2013 +0000
@@ -2594,7 +2594,7 @@
 
                 requests = new MessageHeader();
                 setRequests = false;
-                setRequestMethod("GET");
+                super.setRequestMethod("GET"); // avoid the connecting check
                 poster = null;
                 if (!checkReuseConnection())
                     connect();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/www/protocol/http/RedirectOnPost.java	Tue Dec 03 17:29:19 2013 +0000
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2013, 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
+ * @compile ../../../../../com/sun/net/httpserver/SimpleSSLContext.java RedirectOnPost.java
+ * @run main/othervm RedirectOnPost
+ * @bug 8029127
+ * @summary A redirect POST request does not work and illegalStateException on HttpURLConnection.getInputStream
+ */
+
+import java.net.*;
+import java.io.*;
+import java.util.*;
+import com.sun.net.httpserver.*;
+import java.util.concurrent.*;
+import javax.net.ssl.*;
+
+public class RedirectOnPost {
+
+
+    public static void main(String[] args) throws Exception {
+            ExecutorService e= Executors.newFixedThreadPool(5);
+        String keysdir = System.getProperty("test.src")
+                  + "/../../../../../com/sun/net/httpserver/";
+        SSLContext ctx = new SimpleSSLContext(keysdir).get();
+            HttpServer httpServer = getHttpServer(e);
+            HttpsServer httpsServer = getHttpsServer(e, ctx);
+
+        try {
+            // take the keystore from elsewhere in test hierarchy
+            int port = httpServer.getAddress().getPort();
+            int sslPort = httpsServer.getAddress().getPort();
+            httpServer.start();
+            httpsServer.start();
+            runTest("http://127.0.0.1:"+port+"/test/", null);
+            runTest("https://127.0.0.1:"+sslPort+"/test/", ctx);
+            System.out.println("Main thread waiting");
+        } finally {
+            httpServer.stop(0);
+            httpsServer.stop(0);
+            e.shutdownNow();
+        }
+    }
+
+    public static void runTest(String baseURL, SSLContext ctx) throws Exception
+    {
+        byte[] buf = "Hello world".getBytes();
+        URL url = new URL(baseURL + "a");
+        HttpURLConnection con = (HttpURLConnection)url.openConnection();
+        if (con instanceof HttpsURLConnection) {
+            HttpsURLConnection ssl = (HttpsURLConnection)con;
+            ssl.setHostnameVerifier(new HostnameVerifier() {
+                public boolean verify(String host, SSLSession sess) {
+                    return true;
+                }
+            });
+            ssl.setSSLSocketFactory (ctx.getSocketFactory());
+        }
+        con.setDoOutput(true);
+        con.setDoInput(true);
+        con.setRequestMethod("POST");
+        try (OutputStream out = con.getOutputStream()) {
+            out.write(buf);
+        }
+        try (InputStream in = con.getInputStream()) {
+            byte[] newBuf = readFully(in);
+        }
+    }
+
+    private static byte[] readFully(InputStream istream) throws IOException {
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        byte[] buf = new byte[1024];
+        int num = 0;
+
+        if (istream != null) {
+            while ((num = istream.read(buf)) != -1) {
+                bout.write(buf, 0, num);
+            }
+        }
+        byte[] ret = bout.toByteArray();
+        return ret;
+    }
+
+
+    static class Handler implements HttpHandler {
+
+        String baseURL;
+
+        Handler(String baseURL) {
+            this.baseURL = baseURL;
+        }
+
+        int calls = 0;
+
+        public void handle(HttpExchange msg) {
+            try {
+                String method = msg.getRequestMethod();
+                System.out.println ("Server: " + baseURL);
+                if (calls++ == 0) {
+                    System.out.println ("Server: redirecting");
+                    InputStream is = msg.getRequestBody();
+                    byte[] buf = readFully(is);
+                    is.close();
+                    Headers h = msg.getResponseHeaders();
+                    h.add("Location", baseURL + "b");
+                    msg.sendResponseHeaders(302, -1);
+                    msg.close();
+                } else {
+                    System.out.println ("Server: second call");
+                    InputStream is = msg.getRequestBody();
+                    byte[] buf = readFully(is);
+                    is.close();
+                    msg.sendResponseHeaders(200, -1);
+                    msg.close();
+                }
+            }
+            catch(Exception e) {
+                e.printStackTrace();
+            }
+            finally {
+                msg.close();
+            }
+        }
+    }
+
+    private static HttpServer getHttpServer(ExecutorService execs)
+        throws Exception
+    {
+        InetSocketAddress inetAddress = new InetSocketAddress(0);
+        HttpServer testServer = HttpServer.create(inetAddress, 15);
+        int port = testServer.getAddress().getPort();
+        testServer.setExecutor(execs);
+        String base = "http://127.0.0.1:"+port+"/test";
+        HttpContext context = testServer.createContext("/test");
+        context.setHandler(new Handler(base));
+        return testServer;
+    }
+
+    private static HttpsServer getHttpsServer(
+        ExecutorService execs, SSLContext ctx
+    )
+        throws Exception
+    {
+        InetSocketAddress inetAddress = new InetSocketAddress(0);
+        HttpsServer testServer = HttpsServer.create(inetAddress, 15);
+        int port = testServer.getAddress().getPort();
+        testServer.setExecutor(execs);
+        testServer.setHttpsConfigurator(new HttpsConfigurator (ctx));
+        String base = "https://127.0.0.1:"+port+"/test";
+        HttpContext context = testServer.createContext("/test");
+        context.setHandler(new Handler(base));
+        return testServer;
+    }
+}