B6299712.java revision 6073:cea72c2bf071
1/*
2 * Copyright (c) 2005, 2012, 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 * @bug 6299712
27 * @library ../../httptest/
28 * @build HttpCallback TestHttpServer ClosedChannelList HttpTransaction
29 * @run main/othervm B6299712
30 * @summary  NullPointerException in sun.net.www.protocol.http.HttpURLConnection.followRedirect
31 */
32
33import java.net.*;
34import java.io.*;
35import java.util.*;
36
37/*
38 * Test Description:
39 *      - main thread run as a http client
40 *      - another thread runs a http server, which redirect the first call to "/redirect"
41 *        and return '200 OK' for the successive call
42 *      - a global ResponseCache instance is installed, which return DeployCacheResponse
43 *        for url ends with "/redirect", i.e. the url redirected to by our simple http server,
44 *        and null for other url.
45 *      - the whole result is that the first call will be served by our simple
46 *        http server and is redirected to "/redirect". The successive call will be done
47 *        automatically by HttpURLConnection, which will be served by DeployCacheResponse.
48 *        The NPE will be thrown on the second round if the bug is there.
49 */
50public class B6299712 {
51    static SimpleHttpTransaction httpTrans;
52    static TestHttpServer server;
53
54    public static void main(String[] args) throws Exception {
55        ResponseCache.setDefault(new DeployCacheHandler());
56        startHttpServer();
57
58        makeHttpCall();
59    }
60
61    public static void startHttpServer() {
62        try {
63            httpTrans = new SimpleHttpTransaction();
64            server = new TestHttpServer(httpTrans, 1, 10, 0);
65        } catch (IOException e) {
66            e.printStackTrace();
67        }
68    }
69
70    public static void makeHttpCall() {
71        try {
72            System.out.println("http server listen on: " + server.getLocalPort());
73            URL url = new URL("http" , InetAddress.getLocalHost().getHostAddress(),
74                                server.getLocalPort(), "/");
75            HttpURLConnection uc = (HttpURLConnection)url.openConnection();
76            System.out.println(uc.getResponseCode());
77        } catch (IOException e) {
78            e.printStackTrace();
79        } finally {
80            server.terminate();
81        }
82    }
83}
84
85class SimpleHttpTransaction implements HttpCallback {
86    /*
87     * Our http server which simply redirect first call
88     */
89    public void request(HttpTransaction trans) {
90        try {
91            String path = trans.getRequestURI().getPath();
92            if (path.equals("/")) {
93                // the first call, redirect it
94                String location = "/redirect";
95                trans.addResponseHeader("Location", location);
96                trans.sendResponse(302, "Moved Temporarily");
97            } else {
98                // the second call
99                trans.sendResponse(200, "OK");
100            }
101        } catch (Exception e) {
102            e.printStackTrace();
103        }
104    }
105}
106
107class DeployCacheHandler extends java.net.ResponseCache {
108    private boolean inCacheHandler = false;
109    private boolean _downloading = false;
110
111    public synchronized CacheResponse get(final URI uri, String rqstMethod,
112            Map requestHeaders) throws IOException {
113        System.out.println("get!!!: " + uri);
114        try {
115            if (!uri.toString().endsWith("redirect")) {
116                return null;
117            }
118        } catch (Exception e) {
119            e.printStackTrace();
120        }
121
122        return new DeployCacheResponse(new EmptyInputStream(), new HashMap());
123    }
124
125    public synchronized CacheRequest put(URI uri, URLConnection conn)
126    throws IOException {
127        URL url = uri.toURL();
128        return new DeployCacheRequest(url, conn);
129
130    }
131}
132
133class DeployCacheRequest extends java.net.CacheRequest {
134
135    private URL _url;
136    private URLConnection _conn;
137    private boolean _downloading = false;
138
139    DeployCacheRequest(URL url, URLConnection conn) {
140        _url = url;
141        _conn = conn;
142    }
143
144    public void abort() {
145
146    }
147
148    public OutputStream getBody() throws IOException {
149
150        return null;
151    }
152}
153
154class DeployCacheResponse extends java.net.CacheResponse {
155    protected InputStream is;
156    protected Map headers;
157
158    DeployCacheResponse(InputStream is, Map headers) {
159        this.is = is;
160        this.headers = headers;
161    }
162
163    public InputStream getBody() throws IOException {
164        return is;
165    }
166
167    public Map getHeaders() throws IOException {
168        return headers;
169    }
170}
171
172class EmptyInputStream extends InputStream {
173    public EmptyInputStream() {
174    }
175
176    public int read()
177    throws IOException {
178        return -1;
179    }
180}
181