HttpStreams.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 * @bug 8011719
27 * @modules jdk.httpserver
28 * @summary Basic checks to verify behavior of returned input streams
29 */
30
31import com.sun.net.httpserver.HttpExchange;
32import com.sun.net.httpserver.HttpHandler;
33import com.sun.net.httpserver.HttpServer;
34import java.io.*;
35import java.net.*;
36import java.nio.charset.StandardCharsets;
37import java.util.*;
38
39public class HttpStreams {
40
41    void client(String u) throws Exception {
42        byte[] ba = new byte[5];
43        HttpURLConnection urlc = (HttpURLConnection)(new URL(u)).openConnection();
44        int resp = urlc.getResponseCode();
45        InputStream is;
46        if (resp == 200)
47            is = urlc.getInputStream();
48        else
49            is = urlc.getErrorStream();
50
51        expectNoThrow(() -> { is.read(); }, "read on open stream should not throw :" + u);
52        expectNoThrow(() -> { is.close(); }, "close should never throw: " + u);
53        expectNoThrow(() -> { is.close(); }, "close should never throw: " + u);
54        expectThrow(() -> { is.read(); }, "read on closed stream should throw: " + u);
55        expectThrow(() -> { is.read(ba); }, "read on closed stream should throw: " + u);
56        expectThrow(() -> { is.read(ba, 0, 2); }, "read on closed stream should throw: " + u);
57    }
58
59    void test() throws Exception {
60        HttpServer server = null;
61        try {
62            server = startHttpServer();
63            String baseUrl = "http://localhost:" + server.getAddress().getPort() + "/";
64            client(baseUrl +  "chunked/");
65            client(baseUrl +  "fixed/");
66            client(baseUrl +  "error/");
67            client(baseUrl +  "chunkedError/");
68
69            // Test with a response cache
70            ResponseCache ch = ResponseCache.getDefault();
71            ResponseCache.setDefault(new TrivialCacheHandler());
72            try {
73                client(baseUrl +  "chunked/");
74                client(baseUrl +  "fixed/");
75                client(baseUrl +  "error/");
76                client(baseUrl +  "chunkedError/");
77            } finally {
78                ResponseCache.setDefault(ch);
79            }
80        } finally {
81            if (server != null)
82                server.stop(0);
83        }
84
85        System.out.println("passed: " + pass + ", failed: " + fail);
86        if (fail > 0)
87            throw new RuntimeException("some tests failed check output");
88    }
89
90    public static void main(String[] args) throws Exception {
91        (new HttpStreams()).test();
92    }
93
94    // HTTP Server
95    HttpServer startHttpServer() throws IOException {
96        HttpServer httpServer = HttpServer.create(new InetSocketAddress(0), 0);
97        httpServer.createContext("/chunked/", new ChunkedHandler());
98        httpServer.createContext("/fixed/", new FixedHandler());
99        httpServer.createContext("/error/", new ErrorHandler());
100        httpServer.createContext("/chunkedError/", new ChunkedErrorHandler());
101        httpServer.start();
102        return httpServer;
103    }
104
105    static abstract class AbstractHandler implements HttpHandler {
106        @Override
107        public void handle(HttpExchange t) throws IOException {
108            try (InputStream is = t.getRequestBody()) {
109                while (is.read() != -1);
110            }
111            t.sendResponseHeaders(respCode(), length());
112            try (OutputStream os = t.getResponseBody()) {
113                os.write(message());
114            }
115            t.close();
116        }
117
118        abstract int respCode();
119        abstract int length();
120        abstract byte[] message();
121    }
122
123    static class ChunkedHandler extends AbstractHandler {
124        static final byte[] ba =
125                "Hello there from chunked handler!".getBytes(StandardCharsets.US_ASCII);
126        int respCode() { return 200; }
127        int length() { return 0; }
128        byte[] message() { return ba; }
129    }
130
131    static class FixedHandler extends AbstractHandler {
132        static final byte[] ba =
133                "Hello there from fixed handler!".getBytes(StandardCharsets.US_ASCII);
134        int respCode() { return 200; }
135        int length() { return ba.length; }
136        byte[] message() { return ba; }
137    }
138
139    static class ErrorHandler extends AbstractHandler {
140        static final byte[] ba =
141                "This is an error mesg from the server!".getBytes(StandardCharsets.US_ASCII);
142        int respCode() { return 400; }
143        int length() { return ba.length; }
144        byte[] message() { return ba; }
145    }
146
147    static class ChunkedErrorHandler extends ErrorHandler {
148        int length() { return 0; }
149    }
150
151    static class TrivialCacheHandler extends ResponseCache
152    {
153       public CacheResponse get(URI uri, String rqstMethod, Map rqstHeaders) {
154          return null;
155       }
156
157       public CacheRequest put(URI uri, URLConnection conn) {
158          return new TrivialCacheRequest();
159       }
160    }
161
162    static class TrivialCacheRequest extends CacheRequest
163    {
164       ByteArrayOutputStream baos = new ByteArrayOutputStream();
165       public void abort() {}
166       public OutputStream getBody() throws IOException { return baos; }
167    }
168
169    static interface ThrowableRunnable {
170        void run() throws IOException;
171    }
172
173    void expectThrow(ThrowableRunnable r, String msg) {
174        try { r.run(); fail(msg); } catch (IOException x) { pass(); }
175    }
176
177    void expectNoThrow(ThrowableRunnable r, String msg) {
178        try { r.run(); pass(); } catch (IOException x) { fail(msg, x); }
179    }
180
181    private int pass;
182    private int fail;
183    void pass() { pass++; }
184    void fail(String msg, Exception x) { System.out.println(msg); x.printStackTrace(); fail++; }
185    void fail(String msg) { System.out.println(msg); Thread.dumpStack(); fail++; }
186}
187