1   /*
2    * $Header$
3    * $Revision: 155418 $
4    * $Date: 2005-02-26 08:01:52 -0500 (Sat, 26 Feb 2005) $
5    * ====================================================================
6    *
7    *  Copyright 2002-2004 The Apache Software Foundation
8    *
9    *  Licensed under the Apache License, Version 2.0 (the "License");
10   *  you may not use this file except in compliance with the License.
11   *  You may obtain a copy of the License at
12   *
13   *      http://www.apache.org/licenses/LICENSE-2.0
14   *
15   *  Unless required by applicable law or agreed to in writing, software
16   *  distributed under the License is distributed on an "AS IS" BASIS,
17   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   *  See the License for the specific language governing permissions and
19   *  limitations under the License.
20   * ====================================================================
21   *
22   * This software consists of voluntary contributions made by many
23   * individuals on behalf of the Apache Software Foundation.  For more
24   * information on the Apache Software Foundation, please see
25   * <http://www.apache.org/>.
26   *
27   * [Additional notices, if required by prior licensing conditions]
28   *
29   */
30  
31  package org.apache.commons.httpclient;
32  
33  import java.io.IOException;
34  import java.io.InputStream;
35  import java.io.OutputStream;
36  import java.net.InetAddress;
37  import java.net.Socket;
38  import java.net.UnknownHostException;
39  
40  import junit.framework.Test;
41  import junit.framework.TestSuite;
42  
43  import org.apache.commons.httpclient.methods.GetMethod;
44  import org.apache.commons.httpclient.params.HttpConnectionParams;
45  import org.apache.commons.httpclient.protocol.Protocol;
46  import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
47  import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory;
48  
49  /***
50   *
51   * Unit tests for {@link HttpConnection}.
52   *
53   * @author Sean C. Sullivan
54   *
55   * @version $Id: TestHttpConnection.java 155418 2005-02-26 13:01:52Z dirkv $
56   *
57   */
58  public class TestHttpConnection extends TestLocalHostBase {
59      
60      // ------------------------------------------------------------ Constructor
61      public TestHttpConnection(String testName) {
62          super(testName);
63      }
64  
65      // ------------------------------------------------------------------- Main
66      public static void main(String args[]) {
67          String[] testCaseName = { TestHttpConnection.class.getName() };
68          junit.textui.TestRunner.main(testCaseName);
69      }
70  
71      // ------------------------------------------------------- TestCase Methods
72  
73      public static Test suite() {
74          return new TestSuite(TestHttpConnection.class);
75      }
76  
77  
78      // ----------------------------------------------------------- Test Methods
79  
80      public void testConstructThenClose() {
81          HttpConnection conn = new HttpConnection(getHost(), getPort());
82          conn.close();
83          assertTrue(!conn.isOpen());
84      }
85  
86      public void testConnTimeoutRelease() {
87  
88          // create a custom protocol that will delay for 500 milliseconds
89          Protocol testProtocol = new Protocol(
90              "timeout",
91              new DelayedProtocolSocketFactory(
92                  500, 
93                  Protocol.getProtocol("http").getSocketFactory()
94              ),
95              getPort()
96          );
97  
98          NoHostHttpConnectionManager connectionManager = new NoHostHttpConnectionManager();
99          connectionManager.setConnection(new HttpConnection(getHost(), getPort(), testProtocol));
100         HttpClient client = createHttpClient(connectionManager);
101         client.getHostConfiguration().setHost(getHost(), getPort(), testProtocol);
102         client.getHttpConnectionManager().getParams().setConnectionTimeout(1);
103         
104         try {
105             GetMethod get = new GetMethod();
106             client.executeMethod(get);
107             fail("Should have timed out");
108         } catch(IOException e) {
109             /* should fail */
110             assertTrue(e instanceof ConnectTimeoutException);
111             assertTrue(connectionManager.isConnectionReleased());
112         }
113     }
114 
115 
116     public void testConnTimeout() {
117 
118         // create a custom protocol that will delay for 500 milliseconds
119         Protocol testProtocol = new Protocol(
120             "timeout",
121             new DelayedProtocolSocketFactory(
122                 500, 
123                 Protocol.getProtocol("http").getSocketFactory()
124             ),
125             getPort()
126         );
127 
128         HttpConnection conn = new HttpConnection(getHost(), getPort(), testProtocol);
129         // 1 ms is short enough to make this fail
130         conn.getParams().setConnectionTimeout(1);
131         try {
132             conn.open();
133             fail("Should have timed out");
134         } catch(IOException e) {
135             assertTrue(e instanceof ConnectTimeoutException);
136             /* should fail */
137         }
138     }
139 
140     public void testForIllegalStateExceptions() {
141         HttpConnection conn = new HttpConnection(getHost(), getPort());
142 
143         try {
144             OutputStream out = conn.getRequestOutputStream();
145             fail("getRequestOutputStream did not throw the expected exception");
146         }
147         catch (IllegalStateException expected) {
148             // this exception is expected
149         }
150         catch (IOException ex) {
151             fail("getRequestOutputStream did not throw the expected exception");
152         }
153 
154         try {
155             OutputStream out = new ChunkedOutputStream(conn.getRequestOutputStream());
156             fail("getRequestOutputStream(true) did not throw the expected exception");
157         }
158         catch (IllegalStateException expected) {
159             // this exception is expected
160         }
161         catch (IOException ex) {
162             fail("getRequestOutputStream(true) did not throw the expected exception");
163         }
164 
165         try {
166             InputStream in = conn.getResponseInputStream();
167             fail("getResponseInputStream() did not throw the expected exception");
168         }
169         catch (IllegalStateException expected) {
170             // this exception is expected
171         }
172         catch (IOException ex) {
173             fail("getResponseInputStream() did not throw the expected exception");
174         }
175 
176     }
177     
178     /***
179      * A ProtocolSocketFactory that delays before creating a socket.
180      */
181     class DelayedProtocolSocketFactory implements ProtocolSocketFactory {
182         
183         private int delay;
184         private ProtocolSocketFactory realFactory;
185             
186         public DelayedProtocolSocketFactory(int delay, ProtocolSocketFactory realFactory) {
187             this.delay = delay;
188             this.realFactory = realFactory;            
189         }
190                 
191         public Socket createSocket(
192             String host,
193             int port,
194             InetAddress localAddress,
195             int localPort
196         ) throws IOException, UnknownHostException {
197             
198             synchronized (this) {
199                 try {
200                     this.wait(delay);
201                 } catch (InterruptedException e) {}
202             }
203             return realFactory.createSocket(host, port, localAddress, localPort);
204         }
205 
206         public Socket createSocket(
207             final String host,
208             final int port,
209             final InetAddress localAddress,
210             final int localPort,
211             final HttpConnectionParams params
212         ) throws IOException, UnknownHostException {
213             
214             if (params == null) {
215                 throw new IllegalArgumentException("Parameters may not be null");
216             }
217             int timeout = params.getConnectionTimeout();
218             ControllerThreadSocketFactory.SocketTask task = new ControllerThreadSocketFactory.SocketTask() {
219                 public void doit() throws IOException {
220                     synchronized (this) {
221                         try {
222                             this.wait(delay);
223                         } catch (InterruptedException e) {}
224                     }
225                     setSocket(realFactory.createSocket(host, port, localAddress, localPort));
226                 }
227             };
228             return ControllerThreadSocketFactory.createSocket(task, timeout);
229         }
230 
231         public Socket createSocket(String host, int port)
232             throws IOException, UnknownHostException {
233             synchronized (this) {
234                 try {
235                     this.wait(delay);
236                 } catch (InterruptedException e) {}
237             }
238             return realFactory.createSocket(host, port);
239         }
240 
241     }
242 
243 }
244