RedirectOnPost.java revision 14606:bc3775e25b52
1/*
2 * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
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 * @library /lib/testlibrary/
27 * @modules jdk.httpserver
28 * @build jdk.testlibrary.SimpleSSLContext
29 * @compile RedirectOnPost.java
30 * @run main/othervm RedirectOnPost
31 * @bug 8029127
32 * @summary A redirect POST request does not work and illegalStateException on HttpURLConnection.getInputStream
33 */
34
35import java.net.*;
36import java.io.*;
37import java.util.*;
38import com.sun.net.httpserver.*;
39import java.util.concurrent.*;
40import javax.net.ssl.*;
41import jdk.testlibrary.SimpleSSLContext;
42
43public class RedirectOnPost {
44
45
46    public static void main(String[] args) throws Exception {
47        ExecutorService e= Executors.newFixedThreadPool(5);
48        SSLContext ctx = new SimpleSSLContext().get();
49        HttpServer httpServer = getHttpServer(e);
50        HttpsServer httpsServer = getHttpsServer(e, ctx);
51
52        try {
53            // take the keystore from elsewhere in test hierarchy
54            int port = httpServer.getAddress().getPort();
55            int sslPort = httpsServer.getAddress().getPort();
56            httpServer.start();
57            httpsServer.start();
58            runTest("http://127.0.0.1:"+port+"/test/", null);
59            runTest("https://127.0.0.1:"+sslPort+"/test/", ctx);
60            System.out.println("Main thread waiting");
61        } finally {
62            httpServer.stop(0);
63            httpsServer.stop(0);
64            e.shutdownNow();
65        }
66    }
67
68    public static void runTest(String baseURL, SSLContext ctx) throws Exception
69    {
70        byte[] buf = "Hello world".getBytes();
71        URL url = new URL(baseURL + "a");
72        HttpURLConnection con = (HttpURLConnection)url.openConnection();
73        if (con instanceof HttpsURLConnection) {
74            HttpsURLConnection ssl = (HttpsURLConnection)con;
75            ssl.setHostnameVerifier(new HostnameVerifier() {
76                public boolean verify(String host, SSLSession sess) {
77                    return true;
78                }
79            });
80            ssl.setSSLSocketFactory (ctx.getSocketFactory());
81        }
82        con.setDoOutput(true);
83        con.setDoInput(true);
84        con.setRequestMethod("POST");
85        try (OutputStream out = con.getOutputStream()) {
86            out.write(buf);
87        }
88        try (InputStream in = con.getInputStream()) {
89            byte[] newBuf = readFully(in);
90        }
91    }
92
93    private static byte[] readFully(InputStream istream) throws IOException {
94        ByteArrayOutputStream bout = new ByteArrayOutputStream();
95        byte[] buf = new byte[1024];
96        int num = 0;
97
98        if (istream != null) {
99            while ((num = istream.read(buf)) != -1) {
100                bout.write(buf, 0, num);
101            }
102        }
103        byte[] ret = bout.toByteArray();
104        return ret;
105    }
106
107
108    static class Handler implements HttpHandler {
109
110        String baseURL;
111
112        Handler(String baseURL) {
113            this.baseURL = baseURL;
114        }
115
116        int calls = 0;
117
118        public void handle(HttpExchange msg) {
119            try {
120                String method = msg.getRequestMethod();
121                System.out.println ("Server: " + baseURL);
122                if (calls++ == 0) {
123                    System.out.println ("Server: redirecting");
124                    InputStream is = msg.getRequestBody();
125                    byte[] buf = readFully(is);
126                    is.close();
127                    Headers h = msg.getResponseHeaders();
128                    h.add("Location", baseURL + "b");
129                    msg.sendResponseHeaders(302, -1);
130                    msg.close();
131                } else {
132                    System.out.println ("Server: second call");
133                    InputStream is = msg.getRequestBody();
134                    byte[] buf = readFully(is);
135                    is.close();
136                    msg.sendResponseHeaders(200, -1);
137                    msg.close();
138                }
139            }
140            catch(Exception e) {
141                e.printStackTrace();
142            }
143            finally {
144                msg.close();
145            }
146        }
147    }
148
149    private static HttpServer getHttpServer(ExecutorService execs)
150        throws Exception
151    {
152        InetSocketAddress inetAddress = new InetSocketAddress(0);
153        HttpServer testServer = HttpServer.create(inetAddress, 15);
154        int port = testServer.getAddress().getPort();
155        testServer.setExecutor(execs);
156        String base = "http://127.0.0.1:"+port+"/test";
157        HttpContext context = testServer.createContext("/test");
158        context.setHandler(new Handler(base));
159        return testServer;
160    }
161
162    private static HttpsServer getHttpsServer(
163        ExecutorService execs, SSLContext ctx
164    )
165        throws Exception
166    {
167        InetSocketAddress inetAddress = new InetSocketAddress(0);
168        HttpsServer testServer = HttpsServer.create(inetAddress, 15);
169        int port = testServer.getAddress().getPort();
170        testServer.setExecutor(execs);
171        testServer.setHttpsConfigurator(new HttpsConfigurator (ctx));
172        String base = "https://127.0.0.1:"+port+"/test";
173        HttpContext context = testServer.createContext("/test");
174        context.setHandler(new Handler(base));
175        return testServer;
176    }
177}
178