1/*
2 * Copyright (c) 2004, 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 5026745 6631048
27 * @modules jdk.httpserver
28 * @run main/othervm/timeout=500 Test
29 * @summary Cannot flush output stream when writing to an HttpUrlConnection
30 */
31
32import java.io.*;
33import java.net.*;
34import com.sun.net.httpserver.*;
35
36public class Test implements HttpHandler {
37
38    static volatile int count = 0;
39
40    static final String str1 = "Helloworld1234567890abcdefghijklmnopqrstuvwxyz"+
41                                "1234567890abcdefkjsdlkjflkjsldkfjlsdkjflkj"+
42                                "1434567890abcdefkjsdlkjflkjsldkfjlsdkjflkj";
43
44    static final String str2 = "Helloworld1234567890abcdefghijklmnopqrstuvwxyz"+
45                                "1234567890";
46
47    public void handle(HttpExchange exchange) {
48        String reqbody;
49        try {
50            switch (exchange.getRequestURI().toString()) {
51            case "/test/test1": /* test1 -- keeps conn alive */
52            case "/test/test2": /* test2 -- closes conn */
53                printRequestURI(exchange);
54                reqbody = read(exchange.getRequestBody());
55                if (!reqbody.equals(str1)) {
56                    exchange.sendResponseHeaders(500, 0);
57                    break;
58                }
59
60                Headers headers = exchange.getRequestHeaders();
61                String chunk =  headers.getFirst("Transfer-encoding");
62
63                if (!"chunked".equals (chunk)) {
64                    exchange.sendResponseHeaders(501, 0);
65                    break;
66                }
67
68                exchange.sendResponseHeaders(200, reqbody.length());
69                write(exchange.getResponseBody(), reqbody);
70
71                if (count == 1) {
72                    Headers resHeaders = exchange.getResponseHeaders() ;
73                    resHeaders.set("Connection", "close");
74                }
75                break;
76            case "/test/test3": /* test 3 */
77                printRequestURI(exchange);
78                reqbody = read(exchange.getRequestBody());
79
80                if (!reqbody.equals(str2)) {
81                    exchange.sendResponseHeaders(500, 0);
82                    break;
83                }
84                headers = exchange.getRequestHeaders();
85                int clen = Integer.parseInt( headers.getFirst("Content-length"));
86
87                if (clen != str2.length()) {
88                    exchange.sendResponseHeaders(501, 0);
89                    break;
90                }
91                Headers resHeaders = exchange.getResponseHeaders() ;
92                resHeaders.set("Connection", "close");
93
94                exchange.sendResponseHeaders(200, reqbody.length());
95                write(exchange.getResponseBody(), reqbody);
96                break;
97            case "/test/test4": /* test 4 */
98            case "/test/test5": /* test 5 */
99                printRequestURI(exchange);
100                break;
101            case "/test/test6": /* test 6 */
102                printRequestURI(exchange);
103                resHeaders = exchange.getResponseHeaders() ;
104                resHeaders.set("Location", "http://foo.bar/");
105                resHeaders.set("Connection", "close");
106                exchange.sendResponseHeaders(307, 0);
107                break;
108            case "/test/test7": /* test 7 */
109            case "/test/test8": /* test 8 */
110                printRequestURI(exchange);
111                reqbody = read(exchange.getRequestBody());
112                if (reqbody != null && !"".equals(reqbody)) {
113                    exchange.sendResponseHeaders(501, 0);
114                    break;
115                }
116                resHeaders = exchange.getResponseHeaders() ;
117                resHeaders.set("Connection", "close");
118                exchange.sendResponseHeaders(200, 0);
119                break;
120            case "/test/test9": /* test 9 */
121                printRequestURI(exchange);
122                reqbody = read(exchange.getRequestBody());
123                if (!reqbody.equals(str1)) {
124                    exchange.sendResponseHeaders(500, 0);
125                    break;
126                }
127
128                headers = exchange.getRequestHeaders();
129                chunk =  headers.getFirst("Transfer-encoding");
130                if (!"chunked".equals(chunk)) {
131                    exchange.sendResponseHeaders(501, 0);
132                    break;
133                }
134
135                exchange.sendResponseHeaders(200, reqbody.length());
136                write(exchange.getResponseBody(), reqbody);
137                break;
138            case "/test/test10": /* test10 */
139                printRequestURI(exchange);
140                InputStream is = exchange.getRequestBody();
141                String s = read (is, str1.length());
142
143                boolean error = false;
144                for (int i=10; i< 200 * 1024; i++) {
145                    byte c = (byte)is.read();
146
147                    if (c != (byte)i) {
148                        error = true;
149                        System.out.println ("error at position " + i);
150                    }
151                }
152                if (!s.equals(str1) ) {
153                    System.out.println ("received string : " + s);
154                    exchange.sendResponseHeaders(500, 0);
155                } else if (error) {
156                    System.out.println ("error");
157                    exchange.sendResponseHeaders(500, 0);
158                } else {
159                    exchange.sendResponseHeaders(200, 0);
160                }
161                break;
162            case "/test/test11": /* test11 */
163                printRequestURI(exchange);
164                is = exchange.getRequestBody();
165                s = read (is, str1.length());
166
167                error = false;
168                for (int i=10; i< 30 * 1024; i++) {
169                    byte c = (byte)is.read();
170
171                    if (c != (byte)i) {
172                        error = true;
173                        System.out.println ("error at position " + i);
174                    }
175                }
176                if (!s.equals(str1) ) {
177                    System.out.println ("received string : " + s);
178                    exchange.sendResponseHeaders(500, 0);
179                } else if (error) {
180                    System.out.println ("error");
181                    exchange.sendResponseHeaders(500, 0);
182                } else {
183                    exchange.sendResponseHeaders(200, 0);
184                }
185                break;
186            case "/test/test12": /* test12 */
187                printRequestURI(exchange);
188                is = exchange.getRequestBody();
189
190                error = false;
191                for (int i=10; i< 30 * 1024; i++) {
192                    byte c = (byte)is.read();
193
194                    if (c != (byte)i) {
195                        error = true;
196                        System.out.println ("error at position " + i);
197                    }
198                }
199                if (error) {
200                    System.out.println ("error");
201                    exchange.sendResponseHeaders(500, 0);
202                } else {
203                    exchange.sendResponseHeaders(200, 0);
204                }
205                break;
206            }
207            count ++;
208            exchange.close();
209        } catch (IOException e) {
210            e.printStackTrace();
211        }
212    }
213
214    static void printRequestURI(HttpExchange exchange) {
215        URI uri = exchange.getRequestURI();
216        System.out.println("HttpServer: handle " + uri);
217    }
218
219
220    static String read (InputStream is, int len) {
221        try {
222            byte[] ba = new byte [len];
223            int c;
224            int l = 0;
225            while ((c= is.read(ba, l, ba.length-l)) != -1 && l<len)  {
226                l += c;
227            }
228            return new String (ba, 0, l, "ISO8859-1");
229        } catch (Exception e) {
230            e.printStackTrace();
231        }
232        return null;
233    }
234
235    static String read(InputStream is) {
236        try {
237            byte[] ba = new byte [8096];
238            int off = 0, c;
239            while ((c= is.read(ba, off, ba.length)) != -1)  {
240                off += c;
241            }
242            return new String(ba, 0, off, "ISO8859-1");
243        } catch (Exception e) {
244            e.printStackTrace();
245        }
246        return null;
247    }
248
249    static void write(OutputStream os, String str) {
250        try {
251            byte[] ba = str.getBytes("ISO8859-1");
252            os.write(ba);
253        } catch (Exception e) {
254            e.printStackTrace();
255        }
256    }
257
258    static void readAndCompare(InputStream is, String cmp) throws IOException {
259        int c;
260        byte buf[] = new byte [1024];
261        int off = 0;
262        int len = 1024;
263        while ((c=is.read(buf, off, len)) != -1) {
264            off += c;
265            len -= c;
266        }
267        String s1 = new String(buf, 0, off, "ISO8859_1");
268        if (!cmp.equals(s1)) {
269            throw new IOException("strings not same");
270        }
271    }
272
273    /* basic chunked test (runs twice) */
274
275    static void test1 (String u) throws Exception {
276        URL url = new URL (u);
277        System.out.println ("client opening connection to: " + u);
278        HttpURLConnection urlc = (HttpURLConnection)url.openConnection ();
279        urlc.setChunkedStreamingMode (20);
280        urlc.setDoOutput(true);
281        urlc.setRequestMethod ("POST");
282        OutputStream os = urlc.getOutputStream ();
283        os.write (str1.getBytes());
284        os.close();
285        InputStream is = urlc.getInputStream();
286        readAndCompare (is, str1);
287        is.close();
288    }
289
290    /* basic fixed length test */
291
292    static void test3 (String u) throws Exception {
293        URL url = new URL (u);
294        System.out.println ("client opening connection to: " + u);
295        HttpURLConnection urlc = (HttpURLConnection)url.openConnection ();
296        urlc.setFixedLengthStreamingMode (str2.length());
297        urlc.setDoOutput(true);
298        urlc.setRequestMethod ("POST");
299        OutputStream os = urlc.getOutputStream ();
300        os.write (str2.getBytes());
301        os.close();
302        InputStream is = urlc.getInputStream();
303        readAndCompare (is, str2);
304        is.close();
305    }
306
307    /* write too few bytes */
308
309    static void test4 (String u) throws Exception {
310        URL url = new URL (u);
311        System.out.println ("client opening connection to: " + u);
312        HttpURLConnection urlc = (HttpURLConnection)url.openConnection ();
313        urlc.setFixedLengthStreamingMode (str2.length()+1);
314        urlc.setDoOutput(true);
315        urlc.setRequestMethod ("POST");
316        OutputStream os = urlc.getOutputStream ();
317        os.write (str2.getBytes());
318        try {
319            os.close();
320            throw new Exception ("should have thrown IOException");
321        } catch (IOException e) {}
322    }
323
324    /* write too many bytes */
325
326    static void test5 (String u) throws Exception {
327        URL url = new URL (u);
328        System.out.println ("client opening connection to: " + u);
329        HttpURLConnection urlc = (HttpURLConnection)url.openConnection ();
330        urlc.setFixedLengthStreamingMode (str2.length()-1);
331        urlc.setDoOutput(true);
332        urlc.setRequestMethod ("POST");
333        OutputStream os = urlc.getOutputStream ();
334        try {
335            os.write (str2.getBytes());
336            throw new Exception ("should have thrown IOException");
337        } catch (IOException e) {}
338    }
339
340    /* check for HttpRetryException on redirection */
341
342    static void test6 (String u) throws Exception {
343        URL url = new URL (u);
344        System.out.println ("client opening connection to: " + u);
345        HttpURLConnection urlc = (HttpURLConnection)url.openConnection ();
346        urlc.setChunkedStreamingMode (20);
347        urlc.setDoOutput(true);
348        urlc.setRequestMethod ("POST");
349        OutputStream os = urlc.getOutputStream ();
350        os.write (str1.getBytes());
351        os.close();
352        try {
353            InputStream is = urlc.getInputStream();
354            throw new Exception ("should have gotten HttpRetryException");
355        } catch (HttpRetryException e) {
356            if (e.responseCode() != 307) {
357                throw new Exception ("Wrong response code " + e.responseCode());
358            }
359            if (!e.getLocation().equals ("http://foo.bar/")) {
360                throw new Exception ("Wrong location " + e.getLocation());
361            }
362        }
363    }
364
365    /* next two tests send zero length posts */
366
367    static void test7 (String u) throws Exception {
368        URL url = new URL (u);
369        System.out.println ("client opening connection to: " + u);
370        HttpURLConnection urlc = (HttpURLConnection)url.openConnection ();
371        urlc.setChunkedStreamingMode (20);
372        urlc.setDoOutput(true);
373        urlc.setRequestMethod ("POST");
374        OutputStream os = urlc.getOutputStream ();
375        os.close();
376        int ret = urlc.getResponseCode();
377        if (ret != 200) {
378            throw new Exception ("Expected 200: got " + ret);
379        }
380    }
381
382    static void test8 (String u) throws Exception {
383        URL url = new URL (u);
384        System.out.println ("client opening connection to: " + u);
385        HttpURLConnection urlc = (HttpURLConnection)url.openConnection ();
386        urlc.setFixedLengthStreamingMode (0);
387        urlc.setDoOutput(true);
388        urlc.setRequestMethod ("POST");
389        OutputStream os = urlc.getOutputStream ();
390        os.close();
391        int ret = urlc.getResponseCode();
392        if (ret != 200) {
393            throw new Exception ("Expected 200: got " + ret);
394        }
395    }
396
397    /* calling setChunkedStreamingMode with -1 should entail using
398       the default chunk size */
399   static void test9 (String u) throws Exception {
400        URL url = new URL (u);
401        System.out.println ("client opening connection to: " + u);
402        HttpURLConnection urlc = (HttpURLConnection)url.openConnection ();
403        urlc.setChunkedStreamingMode (-1);
404        urlc.setDoOutput(true);
405        urlc.setRequestMethod ("POST");
406        OutputStream os = urlc.getOutputStream ();
407        os.write (str1.getBytes());
408        os.close();
409        InputStream is = urlc.getInputStream();
410        readAndCompare (is, str1);
411        is.close();
412    }
413
414   static void test10 (String u) throws Exception {
415        URL url = new URL (u);
416        System.out.println ("client opening connection to: " + u);
417        HttpURLConnection urlc = (HttpURLConnection)url.openConnection ();
418        urlc.setChunkedStreamingMode (4 * 1024);
419        urlc.setDoOutput(true);
420        urlc.setRequestMethod ("POST");
421        OutputStream os = urlc.getOutputStream ();
422        byte[] buf = new byte [200 * 1024];
423        for (int i=0; i< 200 * 1024; i++) {
424            buf[i] = (byte) i;
425        }
426        /* write a small bit first, and then the large buffer */
427        os.write (str1.getBytes());
428        os.write (buf, 10, buf.length - 10); /* skip 10 bytes to test offset */
429        os.close();
430        InputStream is = urlc.getInputStream();
431        is.close();
432        int ret = urlc.getResponseCode();
433        if (ret != 200) {
434            throw new Exception ("Expected 200: got " + ret);
435        }
436    }
437
438    static void test11 (String u) throws Exception {
439        URL url = new URL (u);
440        System.out.println ("client opening connection to: " + u);
441        HttpURLConnection urlc = (HttpURLConnection)url.openConnection ();
442        urlc.setChunkedStreamingMode (36 * 1024);
443        urlc.setDoOutput(true);
444        urlc.setRequestMethod ("POST");
445        OutputStream os = urlc.getOutputStream ();
446        byte[] buf = new byte [30 * 1024];
447        for (int i=0; i< 30 * 1024; i++) {
448            buf[i] = (byte) i;
449        }
450        /* write a small bit first, and then the large buffer */
451        os.write (str1.getBytes());
452        //os.write (buf, 10, buf.length - 10); /* skip 10 bytes to test offset */
453        os.write (buf, 10, (10 * 1024) - 10);
454        os.write (buf, (10 * 1024), (10 * 1024));
455        os.write (buf, (20 * 1024), (10 * 1024));
456        os.close();
457        InputStream is = urlc.getInputStream();
458        is.close();
459        int ret = urlc.getResponseCode();
460        if (ret != 200) {
461            throw new Exception ("Expected 200: got " + ret);
462        }
463    }
464
465    static void test12 (String u) throws Exception {
466        URL url = new URL (u);
467        System.out.println ("client opening connection to: " + u);
468        HttpURLConnection urlc = (HttpURLConnection)url.openConnection ();
469        urlc.setChunkedStreamingMode (36 * 1024);
470        urlc.setDoOutput(true);
471        urlc.setRequestMethod ("POST");
472        OutputStream os = urlc.getOutputStream ();
473        byte[] buf = new byte [30 * 1024];
474        for (int i=0; i< 30 * 1024; i++) {
475            buf[i] = (byte) i;
476        }
477        os.write (buf, 10, buf.length - 10); /* skip 10 bytes to test offset */
478        os.close();
479        InputStream is = urlc.getInputStream();
480        is.close();
481        int ret = urlc.getResponseCode();
482        if (ret != 200) {
483            throw new Exception ("Expected 200: got " + ret);
484        }
485    }
486
487
488    static com.sun.net.httpserver.HttpServer httpserver;
489
490    public static void main (String[] args) throws Exception {
491        try {
492            httpserver = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0);
493            HttpContext ctx = httpserver.createContext("/test/", new Test() );
494            httpserver.start();
495
496            int port = httpserver.getAddress().getPort();
497
498            System.out.println ("Server started: listening on port: " + port);
499            test1("http://localhost:"+ port + "/test/test1");
500            test1("http://localhost:"+ port + "/test/test2");
501            test3("http://localhost:"+ port + "/test/test3");
502            test4("http://localhost:"+ port + "/test/test4");
503            test5("http://localhost:"+ port + "/test/test5");
504            test6("http://localhost:"+ port + "/test/test6");
505            test7("http://localhost:"+ port + "/test/test7");
506            test8("http://localhost:"+ port + "/test/test8");
507            test9("http://localhost:"+ port + "/test/test9");
508            test10("http://localhost:"+ port + "/test/test10");
509            test11("http://localhost:"+ port + "/test/test11");
510            test12("http://localhost:"+ port + "/test/test12");
511        } finally {
512            if (httpserver != null)
513                httpserver.stop(0);
514        }
515    }
516
517}
518