1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17package org.apache.harmony.luni.tests.internal.net.www.protocol.http;
18
19import java.io.IOException;
20import java.io.InputStream;
21import java.net.Authenticator;
22import java.net.ConnectException;
23import java.net.HttpURLConnection;
24import java.net.InetSocketAddress;
25import java.net.MalformedURLException;
26import java.net.PasswordAuthentication;
27import java.net.Proxy;
28import java.net.ProxySelector;
29import java.net.ServerSocket;
30import java.net.Socket;
31import java.net.SocketAddress;
32import java.net.SocketTimeoutException;
33import java.net.URI;
34import java.net.URL;
35import java.security.Permission;
36import java.util.ArrayList;
37import java.util.List;
38import java.util.Map;
39
40// TODO: rewrite these tests to use MockWebServer, assuming we don't already have better equivalent tests.
41/*
42import javax.servlet.ServletException;
43import javax.servlet.http.HttpServletRequest;
44import javax.servlet.http.HttpServletResponse;
45
46import org.mortbay.jetty.HttpConnection;
47import org.mortbay.jetty.Request;
48import org.mortbay.jetty.Server;
49import org.mortbay.jetty.handler.DefaultHandler;
50
51import tests.support.Support_Jetty;
52*/
53
54import junit.framework.TestCase;
55
56/**
57 * Tests for <code>HttpURLConnection</code> class constructors and methods.
58 */
59public class HttpURLConnectionTest extends TestCase {
60
61/*
62    private static final boolean DEBUG = false;
63
64    private final static Object bound = new Object();
65
66    static class MockServer extends Thread {
67        ServerSocket serverSocket;
68        boolean accepted = false;
69        boolean started = false;
70
71        public MockServer(String name) throws IOException {
72            super(name);
73            serverSocket = new ServerSocket(0);
74            serverSocket.setSoTimeout(5000);
75        }
76
77        public int port() {
78            return serverSocket.getLocalPort();
79        }
80
81        @Override
82        public void run() {
83            try {
84                synchronized (bound) {
85                    started = true;
86                    bound.notify();
87                }
88                try {
89                    serverSocket.accept().close();
90                    accepted = true;
91                } catch (SocketTimeoutException ignore) {
92                }
93                serverSocket.close();
94            } catch (IOException e) {
95                throw new RuntimeException(e);
96            }
97        }
98    }
99
100    static class MockHTTPServer extends MockServer {
101        // HTTP response codes
102        static final int OK_CODE = 200;
103        static final int NOT_FOUND_CODE = 404;
104        // how many times persistent connection will be used
105        // by server
106        int persUses;
107        // result code to be sent to client
108        int responseCode;
109        // response content to be sent to client
110        String response = "<html></html>";
111        // client's POST message
112        String clientPost = "Hello from client!";
113
114        public MockHTTPServer(String name, int persUses) throws IOException {
115            this(name, persUses, OK_CODE);
116        }
117
118        public MockHTTPServer(String name, int persUses, int responseCode)
119                throws IOException {
120            super(name);
121            this.persUses = persUses;
122            this.responseCode = responseCode;
123        }
124
125        public int port() {
126            return serverSocket.getLocalPort();
127        }
128
129        @Override
130        public void run() {
131            try {
132                synchronized (bound) {
133                    started = true;
134                    bound.notify();
135                }
136                InputStream is = null;
137                Socket client = null;
138                try {
139                    client = serverSocket.accept();
140                    accepted = true;
141                    for (int i = 0; i < persUses; i++) {
142                        if (DEBUG) {
143                            System.out.println("*** Using connection for "
144                                    + (i + 1) + " time ***");
145                        }
146                        byte[] buff = new byte[1024];
147                        is = client.getInputStream();
148                        int num = 0; // number of read bytes
149                        int bytik; // read byte value
150                        boolean wasEOL = false;
151                        // read header (until empty string)
152                        while (((bytik = is.read()) > 0)) {
153                            if (bytik == '\r') {
154                                bytik = is.read();
155                            }
156                            if (wasEOL && (bytik == '\n')) {
157                                break;
158                            }
159                            wasEOL = (bytik == '\n');
160                            buff[num++] = (byte) bytik;
161                        }
162                        // int num = is.read(buff);
163                        String message = new String(buff, 0, num, "UTF-8");
164                        if (DEBUG) {
165                            System.out
166                                    .println("---- Server got request: ----\n"
167                                            + message
168                                            + "-----------------------------");
169                        }
170
171                        // Act as Server (not Proxy) side
172                        if (message.startsWith("POST")) {
173                            // client connection sent some data
174                            // if the data was not read with header
175                            if (DEBUG) {
176                                System.out
177                                        .println("---- Server read client's data: ----");
178                            }
179                            num = is.read(buff);
180                            message = new String(buff, 0, num, "UTF-8");
181                            if (DEBUG) {
182                                System.out.println("'" + message + "'");
183                                System.out
184                                        .println("------------------------------------");
185                            }
186                            // check the received data
187                            assertEquals(clientPost, message);
188                        }
189
190                        client
191                                .getOutputStream()
192                                .write(
193                                        ("HTTP/1.1 " + responseCode + " OK\n"
194                                                + "Content-type: text/html\n"
195                                                + "Content-length: "
196                                                + response.length() + "\n\n" + response)
197                                                .getBytes("UTF-8"));
198
199                        if (responseCode != OK_CODE) {
200                            // wait while test case check closed connection
201                            // and interrupt this thread
202                            try {
203                                while (!isInterrupted()) {
204                                    Thread.sleep(1000);
205                                }
206                            } catch (Exception ignore) {
207                            }
208                        }
209                    }
210                } catch (SocketTimeoutException ignore) {
211                    ignore.printStackTrace();
212                } finally {
213                    if (is != null) {
214                        is.close();
215                    }
216                    if (client != null) {
217                        client.close();
218                    }
219                    serverSocket.close();
220                }
221            } catch (IOException e) {
222                throw new RuntimeException(e);
223            }
224        }
225    }
226
227    static class MockProxyServer extends MockServer {
228
229        boolean acceptedAuthorizedRequest;
230
231        public MockProxyServer(String name) throws Exception {
232            super(name);
233        }
234
235        @Override
236        public void run() {
237            try {
238                Socket socket = serverSocket.accept();
239                socket.setSoTimeout(5000);
240                byte[] buff = new byte[1024];
241                int num = socket.getInputStream().read(buff);
242                socket
243                        .getOutputStream()
244                        .write(
245                                ("HTTP/1.0 407 Proxy authentication required\n"
246                                        + "Proxy-authenticate: Basic realm=\"remotehost\"\n\n")
247                                        .getBytes("UTF-8"));
248                num = socket.getInputStream().read(buff);
249                if (num == -1) {
250                    // this connection was closed, create new one:
251                    socket = serverSocket.accept();
252                    socket.setSoTimeout(5000);
253                    num = socket.getInputStream().read(buff);
254                }
255                String request = new String(buff, 0, num, "UTF-8");
256                acceptedAuthorizedRequest = request.toLowerCase().indexOf(
257                        "proxy-authorization:") > 0;
258                if (acceptedAuthorizedRequest) {
259                    socket.getOutputStream().write(
260                            ("HTTP/1.1 200 OK\n\n").getBytes("UTF-8"));
261                }
262            } catch (IOException e) {
263            }
264        }
265    }
266
267    private int jettyPort = 0;
268
269    private String jettyURL;
270
271    public void setUp() throws Exception {
272        jettyPort = Support_Jetty.startDefaultHttpServer();
273        jettyURL = "http://localhost:" + jettyPort + "/servlet";
274        if (DEBUG) {
275            System.out.println("\n==============================");
276            System.out.println("===== Execution: " + getName());
277            System.out.println("==============================");
278        }
279    }
280
281    public static class ResponseServer {
282        private Server server = null;
283
284        private int port = -1;
285
286        public class MyRealmHandler extends DefaultHandler {
287            public void handle(String target, HttpServletRequest request,
288                    HttpServletResponse response, int dispatch)
289                    throws IOException, ServletException {
290                boolean auth = request.getHeader("Authorization") != null;
291                String resLoc = request.getPathInfo();
292                boolean noRealm = "/norealm".equals(resLoc);
293
294                Request base_request = (request instanceof Request) ? (Request) request
295                        : HttpConnection.getCurrentConnection().getRequest();
296                base_request.setHandled(true);
297                response.setContentType("text/html");
298                response.addDateHeader("Date", System.currentTimeMillis());
299                if (noRealm) {
300                    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
301                    response.getWriter().print("<h1>No WWW-Authenticate</h1>");
302                } else {
303                    if (auth) {
304                        response.setStatus(HttpServletResponse.SC_OK);
305                    } else {
306                        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
307                        response.addHeader("WWW-Authenticate",
308                                "Basic realm=\"HelloWorld\"");
309                    }
310                }
311            }
312        }
313
314        public void startServer(DefaultHandler handler) throws Exception {
315            server = new Server(0);
316            server.setHandler(handler);
317            server.start();
318            port = server.getConnectors()[0].getLocalPort();
319        }
320
321        public void stopServer() throws Exception {
322            if (server != null) {
323                server.stop();
324                server = null;
325            }
326        }
327
328        public int getPort() {
329            return port;
330        }
331    }
332
333    // Test response code which need authenticate
334    public void testGetResponseCode() throws Exception {
335        ResponseServer server = new ResponseServer();
336        HttpURLConnection conn = null;
337        try {
338            server.startServer(server.new MyRealmHandler());
339            int port = server.getPort();
340            try {
341                conn = (HttpURLConnection) new URL("http://localhost:" + port
342                        + "/norealm").openConnection();
343                assertEquals(401, conn.getResponseCode());
344            } finally {
345                if (conn != null) {
346                    try {
347                        conn.disconnect();
348                    } catch (Exception e) {
349                    }
350                }
351            }
352
353            try {
354                conn = (HttpURLConnection) new URL("http://localhost:" + port
355                        + "/realm").openConnection();
356                assertEquals(401, conn.getResponseCode());
357                assertEquals("Basic realm=\"HelloWorld\"", conn
358                        .getHeaderField("WWW-Authenticate"));
359            } finally {
360                if (conn != null) {
361                    try {
362                        conn.disconnect();
363                    } catch (Exception e) {
364                    }
365                }
366            }
367
368            try {
369                Authenticator.setDefault(new Authenticator() {
370                    public PasswordAuthentication getPasswordAuthentication() {
371                        return new PasswordAuthentication("test", "password"
372                                .toCharArray());
373                    }
374                });
375                server.startServer(server.new MyRealmHandler());
376                conn = (HttpURLConnection) new URL("http://localhost:" + port
377                        + "/realm").openConnection();
378                assertEquals(200, conn.getResponseCode());
379                assertNull(conn.getHeaderField("WWW-Authenticate"));
380            } finally {
381                if (conn != null) {
382                    try {
383                        conn.disconnect();
384                    } catch (Exception e) {
385                    }
386                }
387            }
388        } finally {
389            server.stopServer();
390        }
391    }
392
393    // ProxySelector implementation used in the test.
394    static class TestProxySelector extends ProxySelector {
395        // proxy port
396        private int proxy_port;
397        // server port
398        private int server_port;
399
400        // Creates proxy selector instance. Selector will return the proxy, only
401        // if the connection is made to localhost:server_port. Otherwise it will
402        // return NO_PROXY. Address of the returned proxy will be
403        // localhost:proxy_port.
404        public TestProxySelector(int server_port, int proxy_port) {
405            this.server_port = server_port;
406            this.proxy_port = proxy_port;
407        }
408
409        @Override
410        public java.util.List<Proxy> select(URI uri) {
411            Proxy proxy = Proxy.NO_PROXY;
412            if (("localhost".equals(uri.getHost()))
413                    && (server_port == uri.getPort())) {
414                proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(
415                        "localhost", proxy_port));
416            }
417            ArrayList<Proxy> result = new ArrayList<Proxy>();
418            result.add(proxy);
419            return result;
420        }
421
422        @Override
423        public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
424            // do nothing
425        }
426    }
427
428    public void test_getHeaderFields() throws Exception {
429        URL url = new URL(jettyURL);
430        HttpURLConnection httpURLConnect = (HttpURLConnection) url
431                .openConnection();
432        assertEquals(200, httpURLConnect.getResponseCode());
433        assertEquals("OK", httpURLConnect.getResponseMessage());
434        Map headers = httpURLConnect.getHeaderFields();
435        // there should be at least 2 headers
436        assertTrue(headers.size() > 1);
437        List list = (List) headers.get("Content-Length");
438        if (list == null) {
439            list = (List) headers.get("content-length");
440        }
441        assertNotNull(list);
442        try {
443            headers.put("key", "value");
444            fail("should throw UnsupportedOperationException");
445        } catch (UnsupportedOperationException e) {
446            // Expected
447        }
448        try {
449            list.set(0, "value");
450            fail("should throw UnsupportedOperationException");
451        } catch (UnsupportedOperationException e) {
452            // Expected
453        }
454
455        try {
456            httpURLConnect.setRequestProperty("key", "value");
457            fail("should throw IlegalStateException");
458        } catch (IllegalStateException e) {
459            // Expected
460        }
461    }
462
463    // @tests the url with space
464    public void testConnectWithSpaceinURL() throws Exception {
465        String jettyURLwithSpace = "http://localhost:" + jettyPort
466                + "/servlet with space";
467        HttpURLConnection httpURLConnect = (HttpURLConnection) new URL(
468                jettyURLwithSpace).openConnection();
469        httpURLConnect.setDoOutput(true);
470        httpURLConnect.connect();
471        assertEquals(200, httpURLConnect.getResponseCode());
472        assertEquals("OK", httpURLConnect.getResponseMessage());
473    }
474
475    // @tests the url with space
476    public void testConnectWithSpaceinURL1() throws Exception {
477        String jettyURLwithSpace = "http://localhost:" + jettyPort
478                + "/servlet with space?arg1=value>1&arg2=%aval%1Aue&arg3=#";
479        HttpURLConnection httpURLConnect = (HttpURLConnection) new URL(
480                jettyURLwithSpace).openConnection();
481        httpURLConnect.setDoOutput(true);
482        httpURLConnect.connect();
483        assertEquals(200, httpURLConnect.getResponseCode());
484        assertEquals("OK", httpURLConnect.getResponseMessage());
485    }
486
487    public void testGetOutputStream() throws Exception {
488        // Regression for HARMONY-482
489        MockServer httpServer = new MockServer(
490                "ServerSocket for HttpURLConnectionTest");
491        httpServer.start();
492        synchronized (bound) {
493            if (!httpServer.started) {
494                bound.wait(5000);
495            }
496        }
497        HttpURLConnection c = (HttpURLConnection) new URL("http://127.0.0.1:"
498                + httpServer.port()).openConnection();
499        c.setDoOutput(true);
500        // use new String("POST") instead of simple "POST" to obtain other
501        // object instances then those that are in HttpURLConnection classes
502        c.setRequestMethod(new String("POST"));
503        c.getOutputStream();
504        httpServer.join();
505    }
506
507    // Test whether getOutputStream can work after connection
508    public void test_getOutputStream_AfterConnect() throws Exception {
509        URL url = new URL(jettyURL);
510        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
511        connection.setDoOutput(true);
512        connection.connect();
513        String str_get = connection.getRequestMethod();
514        assertTrue(str_get.equalsIgnoreCase("GET"));
515
516        // call to getOutputStream should implicitly set req. method to POST
517        connection.getOutputStream();
518        String str_post = connection.getRequestMethod();
519        assertTrue(str_post.equalsIgnoreCase("POST"));
520    }
521
522    // Test checks if the proxy specified in openConnection method will be used
523    // for connection to the server
524    public void testUsingProxy() throws Exception {
525        // Regression for HARMONY-570
526        MockServer server = new MockServer("server");
527        MockServer proxy = new MockServer("proxy");
528
529        URL url = new URL("http://localhost:" + server.port());
530
531        HttpURLConnection connection = (HttpURLConnection) url
532                .openConnection(new Proxy(Proxy.Type.HTTP,
533                        new InetSocketAddress("localhost", proxy.port())));
534        connection.setConnectTimeout(2000);
535        connection.setReadTimeout(2000);
536
537        server.start();
538        synchronized (bound) {
539            if (!server.started)
540                bound.wait(5000);
541        }
542        proxy.start();
543        synchronized (bound) {
544            if (!proxy.started)
545                bound.wait(5000);
546        }
547
548        connection.connect();
549
550        // wait while server and proxy run
551        server.join();
552        proxy.join();
553
554        assertTrue("Connection does not use proxy", connection.usingProxy());
555        assertTrue("Proxy server was not used", proxy.accepted);
556
557        HttpURLConnection huc = (HttpURLConnection) url
558                .openConnection(Proxy.NO_PROXY);
559        assertFalse(huc.usingProxy());
560    }
561
562    public void testUsingProxy2() throws Exception {
563        try {
564            System.setProperty("http.proxyHost", "localhost");
565            System.setProperty("http.proxyPort", jettyPort + "");
566            URL url = new URL(jettyURL);
567            HttpURLConnection urlConnect = (HttpURLConnection) url
568                    .openConnection();
569            urlConnect.getInputStream();
570            assertTrue(urlConnect.usingProxy());
571
572            // find a free port
573            ServerSocket serverSocket = new ServerSocket(0);
574            int port = serverSocket.getLocalPort();
575            serverSocket.close();
576
577            System.setProperty("http.proxyPort", port + "");
578            url = new URL(jettyURL);
579            urlConnect = (HttpURLConnection) url.openConnection();
580            urlConnect.getInputStream();
581            assertFalse(urlConnect.usingProxy());
582
583            url = new URL("http://localhost:" + port);
584            urlConnect = (HttpURLConnection) url.openConnection();
585            try {
586                urlConnect.getInputStream();
587                fail("should throw ConnectException");
588            } catch (ConnectException e) {
589                // Expected
590            }
591            assertFalse(urlConnect.usingProxy());
592        } finally {
593            System.setProperties(null);
594        }
595    }
596
597    // Test checks if the proxy provided by proxy selector will be used for
598    // connection to the server
599    public void testUsingProxySelector() throws Exception {
600        // Regression for HARMONY-570
601        MockServer server = new MockServer("server");
602        MockServer proxy = new MockServer("proxy");
603
604        URL url = new URL("http://localhost:" + server.port());
605
606        // keep default proxy selector
607        ProxySelector defPS = ProxySelector.getDefault();
608        // replace selector
609        ProxySelector.setDefault(new TestProxySelector(server.port(), proxy
610                .port()));
611
612        try {
613            HttpURLConnection connection = (HttpURLConnection) url
614                    .openConnection();
615            connection.setConnectTimeout(2000);
616            connection.setReadTimeout(2000);
617
618            server.start();
619            synchronized (bound) {
620                if (!server.started)
621                    bound.wait(5000);
622            }
623            proxy.start();
624            synchronized (bound) {
625                if (!proxy.started)
626                    bound.wait(5000);
627            }
628            connection.connect();
629
630            // wait while server and proxy run
631            server.join();
632            proxy.join();
633
634            assertTrue("Connection does not use proxy", connection.usingProxy());
635            assertTrue("Proxy server was not used", proxy.accepted);
636        } finally {
637            // restore default proxy selector
638            ProxySelector.setDefault(defPS);
639        }
640    }
641
642    public void testProxyAuthorization() throws Exception {
643        // Set up test Authenticator
644        Authenticator.setDefault(new Authenticator() {
645            @Override
646            protected PasswordAuthentication getPasswordAuthentication() {
647                return new PasswordAuthentication("user", "password"
648                        .toCharArray());
649            }
650        });
651
652        try {
653            MockProxyServer proxy = new MockProxyServer("ProxyServer");
654
655            URL url = new URL("http://remotehost:55555/requested.data");
656            HttpURLConnection connection = (HttpURLConnection) url
657                    .openConnection(new Proxy(Proxy.Type.HTTP,
658                            new InetSocketAddress("localhost", proxy.port())));
659            connection.setConnectTimeout(5000);
660            connection.setReadTimeout(5000);
661
662            proxy.start();
663
664            connection.connect();
665            assertEquals("unexpected response code", 200, connection
666                    .getResponseCode());
667            proxy.join();
668            assertTrue("Connection did not send proxy authorization request",
669                    proxy.acceptedAuthorizedRequest);
670        } finally {
671            // remove previously set authenticator
672            Authenticator.setDefault(null);
673        }
674    }
675
676    // Test that a connection is not closed if the client reads all the data but
677    // not closes input stream. read until -1.
678    public void testConnectionPersistence() throws Exception {
679        MockHTTPServer httpServer = new MockHTTPServer(
680                "HTTP Server for persistence checking", 2);
681        httpServer.start();
682        synchronized (bound) {
683            if (!httpServer.started) {
684                bound.wait(5000);
685            }
686        }
687
688        HttpURLConnection c = (HttpURLConnection) new URL("http://localhost:"
689                + httpServer.port()).openConnection();
690        if (DEBUG) {
691            System.out.println("Actual connection class: " + c.getClass());
692        }
693
694        c.setDoInput(true);
695        c.setConnectTimeout(5000);
696        c.setReadTimeout(5000);
697        InputStream is = c.getInputStream();
698        byte[] buffer = new byte[128];
699        int totalBytes = 0;
700        int bytesRead = 0;
701        while ((bytesRead = is.read(buffer)) > 0) {
702            if (DEBUG) {
703                System.out.println("Client got response: '"
704                        + new String(buffer, 0, bytesRead, "UTF-8") + "'");
705            }
706            totalBytes += bytesRead;
707        }
708
709        HttpURLConnection c2 = (HttpURLConnection) new URL("http://localhost:"
710                + httpServer.port()).openConnection();
711        c2.setDoInput(true);
712        c2.setConnectTimeout(5000);
713        c2.setReadTimeout(5000);
714        is = c2.getInputStream();
715        buffer = new byte[128];
716        totalBytes = 0;
717        bytesRead = 0;
718        while ((bytesRead = is.read(buffer)) > 0) {
719            if (DEBUG) {
720                System.out.println("Client got response: '"
721                        + new String(buffer, 0, bytesRead, "UTF-8") + "'");
722                totalBytes += bytesRead;
723            }
724        }
725    }
726
727    // Test that a connection is not closed if the client reads all the data but
728    // not closes input stream. read() not receives -1.
729    public void testConnectionPersistence2() throws Exception {
730        MockHTTPServer httpServer = new MockHTTPServer(
731                "HTTP Server for persistence checking", 2);
732        httpServer.start();
733        synchronized (bound) {
734            if (!httpServer.started) {
735                bound.wait(5000);
736            }
737        }
738
739        HttpURLConnection c = (HttpURLConnection) new URL("http://localhost:"
740                + httpServer.port()).openConnection();
741        if (DEBUG) {
742            System.out.println("Actual connection class: " + c.getClass());
743        }
744
745        c.setDoInput(true);
746        c.setConnectTimeout(5000);
747        c.setReadTimeout(5000);
748        InputStream is = c.getInputStream();
749        int bytes2Read = httpServer.response.length();
750        byte[] buffer = new byte[httpServer.response.length()];
751        while ((bytes2Read -= is.read(buffer)) > 0) {
752        }
753        if (DEBUG) {
754            System.out.println("Client got response: '" + new String(buffer)
755                    + "'");
756        }
757
758        HttpURLConnection c2 = (HttpURLConnection) new URL("http://localhost:"
759                + httpServer.port()).openConnection();
760        c2.setDoInput(true);
761        c2.setConnectTimeout(5000);
762        c2.setReadTimeout(5000);
763        is = c2.getInputStream();
764        buffer = new byte[httpServer.response.length()];
765        bytes2Read = httpServer.response.length();
766        while ((bytes2Read -= is.read(buffer)) > 0) {
767        }
768        if (DEBUG) {
769            System.out.println("Client got response: '" + new String(buffer)
770                    + "'");
771        }
772    }
773
774    // Test that a connection is not closed if it firstly does POST, and then
775    // does GET requests.
776    public void testConnectionPersistence3() throws Exception {
777        MockHTTPServer httpServer = new MockHTTPServer(
778                "HTTP Server for persistence checking", 2);
779        httpServer.start();
780        synchronized (bound) {
781            if (!httpServer.started) {
782                bound.wait(5000);
783            }
784        }
785
786        HttpURLConnection c = (HttpURLConnection) new URL("http://localhost:"
787                + httpServer.port()).openConnection();
788        if (DEBUG) {
789            System.out.println("Actual connection class: " + c.getClass());
790        }
791
792        c.setDoInput(true);
793        c.setDoOutput(true);
794        c.setConnectTimeout(5000);
795        c.setReadTimeout(5000);
796        c.getOutputStream().write(httpServer.clientPost.getBytes("UTF-8"));
797
798        InputStream is = c.getInputStream();
799        int bytes2Read = httpServer.response.length();
800        byte[] buffer = new byte[httpServer.response.length()];
801        while ((bytes2Read -= is.read(buffer)) > 0) {
802        }
803        if (DEBUG) {
804            System.out.println("Client got response: '" + new String(buffer)
805                    + "'");
806        }
807
808        HttpURLConnection c2 = (HttpURLConnection) new URL("http://localhost:"
809                + httpServer.port()).openConnection();
810        c2.setDoInput(true);
811        c2.setConnectTimeout(5000);
812        c2.setReadTimeout(5000);
813        is = c2.getInputStream();
814        buffer = new byte[httpServer.response.length()];
815        bytes2Read = httpServer.response.length();
816        while ((bytes2Read -= is.read(buffer)) > 0) {
817        }
818        if (DEBUG) {
819            System.out.println("Client got response: '" + new String(buffer)
820                    + "'");
821        }
822    }
823
824    // Test that a connection is not closed if it firstly does GET, and then
825    // does POST requests.
826    public void testConnectionPersistence4() throws Exception {
827        MockHTTPServer httpServer = new MockHTTPServer(
828                "HTTP Server for persistence checking", 2);
829        httpServer.start();
830        synchronized (bound) {
831            if (!httpServer.started) {
832                bound.wait(5000);
833            }
834        }
835
836        HttpURLConnection c = (HttpURLConnection) new URL("http://localhost:"
837                + httpServer.port()).openConnection();
838        if (DEBUG) {
839            System.out.println("Actual connection class: " + c.getClass());
840        }
841
842        c.setDoInput(true);
843        c.setConnectTimeout(5000);
844        c.setReadTimeout(5000);
845
846        InputStream is = c.getInputStream();
847        int bytes2Read = httpServer.response.length();
848        byte[] buffer = new byte[httpServer.response.length()];
849        while ((bytes2Read = is.read(buffer)) > 0) {
850        }
851        if (DEBUG) {
852            System.out.println("Client got response: '" + new String(buffer)
853                    + "'");
854        }
855
856        HttpURLConnection c2 = (HttpURLConnection) new URL("http://localhost:"
857                + httpServer.port()).openConnection();
858        c2.setDoOutput(true);
859        c2.setDoInput(true);
860        c2.setConnectTimeout(5000);
861        c2.setReadTimeout(5000);
862        c2.getOutputStream().write(httpServer.clientPost.getBytes("UTF-8"));
863        is = c2.getInputStream();
864        buffer = new byte[httpServer.response.length()];
865        bytes2Read = httpServer.response.length();
866        while ((bytes2Read = is.read(buffer)) > 0) {
867        }
868        if (DEBUG) {
869            System.out.println("Client got response: '" + new String(buffer)
870                    + "'");
871        }
872    }
873
874    // Test that a connection is not closed if it does POST for 2 times.
875    public void testConnectionPersistence5() throws Exception {
876        MockHTTPServer httpServer = new MockHTTPServer(
877                "HTTP Server for persistence checking", 2);
878        httpServer.start();
879        synchronized (bound) {
880            if (!httpServer.started) {
881                bound.wait(5000);
882            }
883        }
884
885        HttpURLConnection c = (HttpURLConnection) new URL("http://localhost:"
886                + httpServer.port()).openConnection();
887        if (DEBUG) {
888            System.out.println("Actual connection class: " + c.getClass());
889        }
890        c.setDoOutput(true);
891        c.setDoInput(true);
892        c.setConnectTimeout(5000);
893        c.setReadTimeout(5000);
894        c.getOutputStream().write(httpServer.clientPost.getBytes("UTF-8"));
895        InputStream is = c.getInputStream();
896        int bytes2Read = httpServer.response.length();
897        byte[] buffer = new byte[httpServer.response.length()];
898        while ((bytes2Read = is.read(buffer)) > 0) {
899        }
900        if (DEBUG) {
901            System.out.println("Client got response: '" + new String(buffer)
902                    + "'");
903        }
904
905        HttpURLConnection c2 = (HttpURLConnection) new URL("http://localhost:"
906                + httpServer.port()).openConnection();
907        c2.setDoOutput(true);
908        c2.setDoInput(true);
909        c2.setConnectTimeout(5000);
910        c2.setReadTimeout(5000);
911        c2.getOutputStream().write(httpServer.clientPost.getBytes("UTF-8"));
912        is = c2.getInputStream();
913        buffer = new byte[httpServer.response.length()];
914        bytes2Read = httpServer.response.length();
915        while ((bytes2Read = is.read(buffer)) > 0) {
916        }
917        if (DEBUG) {
918            System.out.println("Client got response: '" + new String(buffer)
919                    + "'");
920        }
921    }
922
923    // Test that a connection made through proxy will be reused for connection
924    // establishing without proxy.
925    public void testProxiedConnectionPersistence() throws Exception {
926        MockHTTPServer httpServer = new MockHTTPServer(
927                "HTTP Server for persistence checking", 2);
928        httpServer.start();
929        synchronized (bound) {
930            if (!httpServer.started) {
931                bound.wait(5000);
932            }
933        }
934
935        HttpURLConnection c = (HttpURLConnection) new URL(
936                "http://some.host:1234").openConnection(new Proxy(
937                Proxy.Type.HTTP, new InetSocketAddress("localhost", httpServer
938                        .port())));
939        if (DEBUG) {
940            System.out.println("Actual connection class: " + c.getClass());
941        }
942        c.setDoOutput(true);
943        c.setDoInput(true);
944        c.setConnectTimeout(5000);
945        c.setReadTimeout(5000);
946        c.getOutputStream().write(httpServer.clientPost.getBytes("UTF-8"));
947        InputStream is = c.getInputStream();
948        int bytes2Read = httpServer.response.length();
949        byte[] buffer = new byte[httpServer.response.length()];
950        while ((bytes2Read = is.read(buffer)) > 0) {
951        }
952        if (DEBUG) {
953            System.out.println("Client got response: '" + new String(buffer)
954                    + "'");
955        }
956
957        HttpURLConnection c2 = (HttpURLConnection) new URL(
958                "http://some.host:1234").openConnection();
959        c2.setDoOutput(true);
960        c2.setDoInput(true);
961        c2.setConnectTimeout(5000);
962        c2.setReadTimeout(5000);
963        c2.getOutputStream().write(httpServer.clientPost.getBytes("UTF-8"));
964        is = c2.getInputStream();
965        buffer = new byte[httpServer.response.length()];
966        bytes2Read = httpServer.response.length();
967        while ((bytes2Read = is.read(buffer)) > 0) {
968        }
969        if (DEBUG) {
970            System.out.println("Client got response: '" + new String(buffer)
971                    + "'");
972        }
973    }
974
975    public void testSetRequestProperty() throws Exception {
976        MockHTTPServer httpServer = new MockHTTPServer(
977                "HTTP Server for User-Specified Request Property", 2);
978        httpServer.start();
979        synchronized (bound) {
980            if (!httpServer.started) {
981                bound.wait(5000);
982            }
983        }
984
985        HttpURLConnection urlConnection = (HttpURLConnection) new URL(
986                "http://localhost:" + httpServer.port()).openConnection();
987        assertEquals(0, urlConnection.getRequestProperties().size());
988
989        final String PROPERTY1 = "Accept";
990        final String PROPERTY2 = "Connection";
991        urlConnection.setRequestProperty(PROPERTY1, null);
992        urlConnection.setRequestProperty(PROPERTY1, null);
993        urlConnection.setRequestProperty(PROPERTY2, "keep-alive");
994        assertEquals(2, urlConnection.getRequestProperties().size());
995        assertNull(urlConnection.getRequestProperty(PROPERTY1));
996        assertEquals("keep-alive", urlConnection.getRequestProperty(PROPERTY2));
997
998        urlConnection.setRequestProperty(PROPERTY1, "/");
999        urlConnection.setRequestProperty(PROPERTY2, null);
1000        assertEquals("/", urlConnection.getRequestProperty(PROPERTY1));
1001        assertNull(urlConnection.getRequestProperty(PROPERTY2));
1002    }
1003*/
1004}
1005