1   /*
2    * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java,v 1.23 2004/07/17 18:58:33 mbecke Exp $
3    * $Revision: 179178 $
4    * $Date: 2005-05-30 21:09:19 -0400 (Mon, 30 May 2005) $
5    * ====================================================================
6    *
7    *  Copyright 1999-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.lang.ref.WeakReference;
35  import java.net.InetAddress;
36  import java.net.Socket;
37  import java.net.UnknownHostException;
38  
39  import junit.framework.Test;
40  import junit.framework.TestSuite;
41  
42  import org.apache.commons.httpclient.methods.GetMethod;
43  import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
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.SecureProtocolSocketFactory;
48  import org.apache.commons.httpclient.server.SimpleRequest;
49  import org.apache.commons.httpclient.server.SimpleResponse;
50  
51  /***
52   * Unit tests for {@link HttpConnectionManager}.
53   *
54   * @author Marc A. Saegesser
55   * @version $Id: TestHttpConnectionManager.java 179178 2005-05-31 01:09:19Z mbecke $
56   */
57  public class TestHttpConnectionManager extends HttpClientTestBase {
58  
59      // ------------------------------------------------------------ Constructor
60      public TestHttpConnectionManager(String testName) throws IOException {
61          super(testName);
62      }
63  
64      // ------------------------------------------------------------------- Main
65      public static void main(String args[]) {
66          String[] testCaseName = { TestHttpConnectionManager.class.getName() };
67          junit.textui.TestRunner.main(testCaseName);
68      }
69  
70      // ------------------------------------------------------- TestCase Methods
71  
72      public static Test suite() {
73          return new TestSuite(TestHttpConnectionManager.class);
74      }
75  
76  
77      // ----------------------------------------------------------- Test Methods
78  
79      /***
80       * Test that the ConnectMethod correctly releases connections when
81       * CONNECT fails.
82       */
83      public void testConnectMethodFailureRelease() throws Exception {
84          
85          MultiThreadedHttpConnectionManager mgr = new MultiThreadedHttpConnectionManager();
86          mgr.getParams().setIntParameter(
87              HttpConnectionManagerParams.MAX_TOTAL_CONNECTIONS, 1);
88          client.setHttpConnectionManager(mgr);
89          this.server.setHttpService(new RejectConnectService());
90          
91          // we're going to execute a connect method against the localhost, assuming
92          // that CONNECT is not supported.  This should test the fakeResponse()
93          // code on HttpMethodBase.
94          client.getHostConfiguration().setProxy(server.getLocalAddress(), server.getLocalPort());
95          // we must set the host to a secure destination or the CONNECT method
96          // will not be used
97          client.getHostConfiguration().setHost(
98              "notARealHost", 
99              1234, 
100             new Protocol(
101                 "https", 
102                 (ProtocolSocketFactory)new FakeSecureProtocolSocketFactory(), 
103                 443)
104         );
105         
106         GetMethod get = new GetMethod("/");
107         try {
108             assertTrue(client.executeMethod(get) != 200);
109         } catch (IOException e) {
110             e.printStackTrace();
111             fail("Error executing connect: " + e);
112         }
113 
114         // this should calling releaseConnection() releases the connection
115         try {
116             get.releaseConnection();
117             mgr.getConnectionWithTimeout(client.getHostConfiguration(), 1).releaseConnection();
118         } catch (ConnectTimeoutException e1) {
119             fail("Connection should have been available.");
120         }
121         
122         get = new GetMethod("/");
123         
124         try {
125             assertTrue(client.executeMethod(get) != 200);
126         } catch (IOException e) {
127             e.printStackTrace();
128             fail("Error executing connect: " + e);
129         }
130 
131         // make sure reading the response fully releases the connection        
132         try {
133             get.getResponseBodyAsString();
134             mgr.getConnectionWithTimeout(client.getHostConfiguration(), 1).releaseConnection();
135         } catch (ConnectTimeoutException e1) {
136             fail("Connection should have been available.");
137         }     
138         
139         get = new GetMethod("/");
140         
141         try {
142             assertTrue(client.executeMethod(get) != 200);
143         } catch (IOException e) {
144             e.printStackTrace();
145             fail("Error executing connect: " + e);
146         }
147 
148         // make sure closing the output stream releases the connection        
149         try {
150             get.getResponseBodyAsStream().close();
151             mgr.getConnectionWithTimeout(client.getHostConfiguration(), 1).releaseConnection();
152         } catch (ConnectTimeoutException e) {
153             fail("Connection should have been available.");
154         } catch (IOException e) {
155             e.printStackTrace();
156             fail("Close connection failed: " + e);   
157         }
158     }
159 
160     public void testGetConnection() {
161         MultiThreadedHttpConnectionManager mgr = new MultiThreadedHttpConnectionManager();
162 
163         HostConfiguration hostConfiguration = new HostConfiguration();
164         hostConfiguration.setHost("www.nosuchserver.com", 80, "http");
165 
166         // Create a new connection
167         HttpConnection conn = mgr.getConnection(hostConfiguration);
168         // Validate the connection properties
169         assertEquals("Host", "www.nosuchserver.com", conn.getHost());
170         assertEquals("Port", 80, conn.getPort());
171         // Release the connection
172         mgr.releaseConnection(conn);
173 
174         // Create a new connection
175         hostConfiguration.setHost("www.nosuchserver.com", -1, "https");
176         conn = mgr.getConnection(hostConfiguration);
177         // Validate the connection properties
178         assertEquals("Host", "www.nosuchserver.com", conn.getHost());
179         assertEquals("Port", 443, conn.getPort());
180         // Release the connection
181         mgr.releaseConnection(conn);
182 
183         // Create a new connection
184         hostConfiguration.setHost("www.nowhere.org", 8080, "http");
185         conn = mgr.getConnection(hostConfiguration);
186         // Validate the connection properties
187         assertEquals("Host", "www.nowhere.org", conn.getHost());
188         assertEquals("Port", 8080, conn.getPort());
189         // Release the connection
190         mgr.releaseConnection(conn);
191 
192     }
193 
194     public void testDroppedThread() throws Exception {
195 
196         this.server.setHttpService(new EchoService());
197 
198         MultiThreadedHttpConnectionManager mthcm = new MultiThreadedHttpConnectionManager();
199         client.setHttpConnectionManager(mthcm);
200         WeakReference wr = new WeakReference(mthcm);
201 
202         GetMethod method = new GetMethod("/");
203         client.executeMethod(method);
204         method.releaseConnection();
205 
206         mthcm = null;
207         client = null;
208         method = null;
209         
210         System.gc();
211 
212         // this sleep appears to be necessary in order to give the JVM
213         // time to clean up the miscellaneous pointers to the connection manager
214         try {
215             Thread.sleep(1000);
216         } catch (InterruptedException e) {
217             fail("shouldn't be interrupted.");
218         }
219 
220         Object connectionManager = wr.get();
221         assertNull("connectionManager should be null", connectionManager);
222     }    
223     
224     public void testWriteRequestReleaseConnection() {
225 
226         MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
227         connectionManager.getParams().setDefaultMaxConnectionsPerHost(1);
228 
229         client.setHttpConnectionManager(connectionManager);
230         
231         GetMethod get = new GetMethod("/") {
232             protected boolean writeRequestBody(HttpState state, HttpConnection conn)
233                 throws IOException, HttpException {
234                 throw new IOException("Oh no!!");
235             }
236         };
237         
238         try {
239             client.executeMethod(get);
240             fail("An exception should have occurred.");
241         } catch (HttpException e) {
242             e.printStackTrace();
243             fail("HttpException should not have occurred: " + e);
244         } catch (IOException e) {
245             // expected
246         }
247         
248         try {
249             connectionManager.getConnectionWithTimeout(client.getHostConfiguration(), 1);
250         } catch (ConnectTimeoutException e) {
251             e.printStackTrace();
252             fail("Connection was not released: " + e);
253         }
254         
255     }
256     
257     public void testReleaseConnection() {
258 
259         this.server.setHttpService(new EchoService());
260 
261         MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
262         connectionManager.getParams().setDefaultMaxConnectionsPerHost(1);
263 
264         client.setHttpConnectionManager(connectionManager);
265         // we shouldn't have to wait if a connection is available
266         client.getParams().setConnectionManagerTimeout(1);
267 
268         GetMethod getMethod = new GetMethod("/");
269 
270         try {
271             client.executeMethod(getMethod);
272         } catch (Exception e) {
273             fail("error reading from server: " + e);
274         }
275 
276         try {
277             // this should fail quickly since the connection has not been released
278             client.executeMethod(getMethod);
279             fail("a httpConnection should not be available");
280         } catch (ConnectTimeoutException e) {            
281         } catch (HttpException e) {
282             fail("error reading from server; " + e);
283         } catch (IOException e) {
284             e.printStackTrace();
285             fail("error reading from server; " + e);
286         }
287 
288         // this should release the connection
289         getMethod.releaseConnection();
290 
291         getMethod = new GetMethod("/");
292 
293         try {
294             // this should fail quickly if the connection has not been released
295             client.executeMethod(getMethod);
296         } catch (HttpException e) {
297             fail("httpConnection does not appear to have been released: " + e);
298         } catch (IOException e) {
299             fail("error reading from server; " + e);
300         }
301 
302     }
303 
304     /***
305      * Makes sure that a connection gets released after the content of the body
306      * is read.
307      */
308     public void testResponseAutoRelease() throws Exception  {
309 
310         this.server.setHttpService(new EchoService());
311 
312         MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
313         connectionManager.getParams().setDefaultMaxConnectionsPerHost(1);
314 
315         client.setHttpConnectionManager(connectionManager);
316         // we shouldn't have to wait if a connection is available
317         client.getParams().setConnectionManagerTimeout( 1 );
318 
319         GetMethod getMethod = new GetMethod("/");
320 
321         try {
322             client.executeMethod(getMethod);
323         } catch (Exception e) {
324             fail("error reading from server: " + e);
325         }
326         
327         // this should release the connection
328         getMethod.getResponseBody();
329 
330         getMethod = new GetMethod("/");
331 
332         try {
333             // this should fail quickly if the connection has not been released
334             client.executeMethod(getMethod);
335         } catch (HttpException e) {
336             fail("httpConnection does not appear to have been released: " + e);
337         } catch (IOException e) {
338             fail("error reading from server; " + e);
339         }
340 
341     }
342     
343     /***
344      * Tests the MultiThreadedHttpConnectionManager's ability to reclaim unused 
345      * connections.
346      */
347     public void testConnectionReclaiming() {
348         
349         MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
350         connectionManager.getParams().setDefaultMaxConnectionsPerHost(1);
351         connectionManager.getParams().setMaxTotalConnections(1);
352 
353         HostConfiguration host1 = new HostConfiguration();
354         host1.setHost("host1", -1, "http");
355 
356         HostConfiguration host2 = new HostConfiguration();
357         host2.setHost("host2", -1, "http");
358 
359         HttpConnection connection = connectionManager.getConnection(host1);
360         // now release this connection
361         connection.releaseConnection();
362         connection = null;
363         
364         try {
365             // the connection from host1 should be reclaimed
366             connection = connectionManager.getConnectionWithTimeout(host2, 100);
367         } catch (ConnectTimeoutException e) {
368             e.printStackTrace();
369             fail("a httpConnection should have been available: " + e);
370         }        
371     }
372     
373     /***
374      * Tests that {@link MultiThreadedHttpConnectionManager#shutdownAll()} closes all resources
375      * and makes all connection mangers unusable.
376      */
377     public void testShutdownAll() {
378 
379         MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
380         connectionManager.getParams().setDefaultMaxConnectionsPerHost(1);
381         connectionManager.getParams().setMaxTotalConnections(1);
382 
383         HostConfiguration host1 = new HostConfiguration();
384         host1.setHost("host1", -1, "http");
385 
386         // hold on to the only connection
387         HttpConnection connection = connectionManager.getConnection(host1);
388 
389         // wait for a connection on another thread
390         GetConnectionThread getConn = new GetConnectionThread(host1, connectionManager, 0);
391         getConn.start();
392         
393         MultiThreadedHttpConnectionManager.shutdownAll();
394         
395         // now release this connection, this should close the connection, but have no other effect
396         connection.releaseConnection();
397         connection = null;
398         
399         try {
400             getConn.join();
401         } catch (InterruptedException e) {
402             e.printStackTrace();
403         }
404         
405         // this thread should have caught an exception without getting a connection
406         assertNull("Not connection should have been checked out", getConn.getConnection());
407         assertNotNull("There should have been an exception", getConn.getException());
408         
409         try {
410             connectionManager.getConnection(host1);
411             fail("An exception should have occurred");
412         } catch (Exception e) {
413             // this is expected
414         }
415     }
416         
417     /***
418      * Tests that {@link MultiThreadedHttpConnectionManager#shutdown()} closes all resources
419      * and makes the connection manger unusable.
420      */
421     public void testShutdown() {
422 
423         MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
424         connectionManager.getParams().setDefaultMaxConnectionsPerHost(1);
425         connectionManager.getParams().setMaxTotalConnections(1);
426 
427         HostConfiguration host1 = new HostConfiguration();
428         host1.setHost("host1", -1, "http");
429 
430         // hold on to the only connection
431         HttpConnection connection = connectionManager.getConnection(host1);
432 
433         // wait for a connection on another thread
434         GetConnectionThread getConn = new GetConnectionThread(host1, connectionManager, 0);
435         getConn.start();
436         
437         connectionManager.shutdown();
438         
439         // now release this connection, this should close the connection, but have no other effect
440         connection.releaseConnection();
441         connection = null;
442         
443         try {
444             getConn.join();
445         } catch (InterruptedException e) {
446             e.printStackTrace();
447         }
448         
449         // this thread should have caught an exception without getting a connection
450         assertNull("Not connection should have been checked out", getConn.getConnection());
451         assertNotNull("There should have been an exception", getConn.getException());
452         
453         try {
454             connectionManager.getConnection(host1);
455             fail("An exception should have occurred");
456         } catch (Exception e) {
457             // this is expected
458         }
459     }
460     
461     /***
462      * Tests the MultiThreadedHttpConnectionManager's ability to restrict the maximum number 
463      * of connections.
464      */    
465     public void testMaxConnections() {
466         
467         MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
468         connectionManager.getParams().setDefaultMaxConnectionsPerHost(1);
469         connectionManager.getParams().setMaxTotalConnections(2);
470 
471         HostConfiguration host1 = new HostConfiguration();
472         host1.setHost("host1", -1, "http");
473 
474         HostConfiguration host2 = new HostConfiguration();
475         host2.setHost("host2", -1, "http");
476 
477         HttpConnection connection1 = connectionManager.getConnection(host1);
478         HttpConnection connection2 = connectionManager.getConnection(host2);
479     
480         try {
481             // this should fail quickly since the connection has not been released
482             connectionManager.getConnectionWithTimeout(host2, 100);
483             fail("a httpConnection should not be available");
484         } catch (ConnectTimeoutException e) {
485             // this should throw an exception
486         }
487         
488         // release one of the connections
489         connection2.releaseConnection();
490         connection2 = null;
491         
492         try {
493             // there should be a connection available now
494             connection2 = connectionManager.getConnectionWithTimeout(host2, 100);
495         } catch (ConnectTimeoutException e) {
496             e.printStackTrace();
497             fail("a httpConnection should have been available: " + e);
498         }
499     }    
500 
501     public void testHostReusePreference() {
502         
503         final MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
504         connectionManager.getParams().setDefaultMaxConnectionsPerHost(1);
505         connectionManager.getParams().setMaxTotalConnections(1);
506 
507         final HostConfiguration host1 = new HostConfiguration();
508         host1.setHost("host1", -1, "http");
509 
510         final HostConfiguration host2 = new HostConfiguration();
511         host2.setHost("host2", -1, "http");
512 
513         HttpConnection connection = connectionManager.getConnection(host1);
514 
515         GetConnectionThread getHost1 = new GetConnectionThread(host1, connectionManager, 200);
516         GetConnectionThread getHost2 = new GetConnectionThread(host2, connectionManager, 200);
517         
518         getHost2.start();
519         getHost1.start();
520         
521         // give the threads some time to startup
522         try {
523             Thread.sleep(100);
524         } catch (InterruptedException e1) {
525             e1.printStackTrace();
526         }
527             
528         // after the connection to host1 is released it should be given to getHost1
529         connection.releaseConnection();
530         connection = null;
531 
532         try {
533             getHost1.join();
534             getHost2.join();
535         } catch (InterruptedException e) {
536             e.printStackTrace();
537         }
538 
539         assertNotSame(
540             "Connection should have been given to someone", 
541             getHost1.getConnection(),
542             getHost2.getConnection()
543         );        
544         assertNotNull("Connection should have been given to host1", getHost1.getConnection());
545         assertNull("Connection should NOT have been given to host2", getHost2.getConnection());
546         
547     } 
548     
549     public void testMaxConnectionsPerServer() {
550      
551         this.server.setHttpService(new EchoService());
552 
553         MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
554         connectionManager.getParams().setDefaultMaxConnectionsPerHost(1);
555 
556         client.setHttpConnectionManager(connectionManager);
557         // we shouldn't have to wait if a connection is available
558         client.getParams().setConnectionManagerTimeout( 1 );
559 
560         GetMethod getMethod = new GetMethod("/");
561 
562         try {
563             client.executeMethod(getMethod);
564         } catch (Exception e) {
565             fail("error reading from server: " + e);
566         }
567 
568         GetMethod getMethod2 = new GetMethod("/");
569 
570         try {
571             // this should fail quickly since the connection has not been released
572             client.executeMethod(getMethod2);
573             fail("a httpConnection should not be available");
574         } catch (ConnectTimeoutException e) {
575         } catch (HttpException e) {
576             fail("error reading from server; " + e);
577         } catch (IOException e) {
578             fail("error reading from server; " + e);
579         }
580                 
581     }
582     
583     public void testDeleteClosedConnections() {
584         
585         MultiThreadedHttpConnectionManager manager = new MultiThreadedHttpConnectionManager();
586         
587         HttpConnection conn = manager.getConnection(client.getHostConfiguration());
588         
589         assertEquals("connectionsInPool", manager.getConnectionsInPool(), 1);
590         assertEquals("connectionsInPool(host)", manager.getConnectionsInPool(client.getHostConfiguration()), 1);
591         
592         conn.close();
593         conn.releaseConnection();
594 
595         assertEquals("connectionsInPool", manager.getConnectionsInPool(), 1);
596         assertEquals("connectionsInPool(host)", manager.getConnectionsInPool(client.getHostConfiguration()), 1);
597 
598         manager.deleteClosedConnections();
599         
600         assertEquals("connectionsInPool", manager.getConnectionsInPool(), 0);
601         assertEquals("connectionsInPool(host)", manager.getConnectionsInPool(client.getHostConfiguration()), 0);
602     }
603     
604     public void testReclaimUnusedConnection() {
605 
606         this.server.setHttpService(new EchoService());
607 
608         MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
609         connectionManager.getParams().setIntParameter(
610             HttpConnectionManagerParams.MAX_TOTAL_CONNECTIONS, 1);
611 
612         client.setHttpConnectionManager(connectionManager);
613         // we shouldn't have to wait if a connection is available
614         client.getParams().setConnectionManagerTimeout( 30000 );
615 
616         GetMethod getMethod = new GetMethod("/");
617 
618         try {
619             client.executeMethod(getMethod);
620         } catch (Exception e) {
621             fail("error reading from server: " + e);
622         }
623 
624         getMethod = new GetMethod("/");
625         
626         Runtime.getRuntime().gc();
627 
628         try {
629             // we didn't explicitly release the connection, but it should be 
630             // reclaimed by the garbage collector, we hope:)
631             client.executeMethod(getMethod);
632         } catch (HttpException e) {
633             fail("httpConnection does not appear to have been reclaimed by the GC: " + e);
634         } catch (IOException e) {
635             fail("error reading from server; " + e);
636         }
637 
638     }
639     
640     public void testGetFromMultipleThreads() {
641         
642         this.server.setHttpService(new EchoService());
643 
644         client.setHttpConnectionManager(new MultiThreadedHttpConnectionManager());
645         ExecuteMethodThread[] threads = new ExecuteMethodThread[10];
646         
647         for (int i = 0; i < threads.length; i++) {
648             GetMethod method = new GetMethod("/");
649             method.setFollowRedirects(true);
650             
651             threads[i] = new ExecuteMethodThread(method, client);
652             threads[i].start();
653         }
654         
655         for (int i = 0; i < threads.length; i++) {
656             try {
657                 // wait until this thread finishes. we'll give it 10 seconds,
658                 // but it shouldn't take that long
659                 threads[i].join(10000);
660             } catch (InterruptedException e) {
661             }
662             // make sure an exception did not occur
663             Exception e = threads[i].getException();
664             if (e != null) {
665                 fail("An error occured in the get: " + e);
666             }
667             // we should have a 200 status
668             assertEquals(threads[i].getMethod().getStatusCode(), HttpStatus.SC_OK);
669         }
670     }
671 
672     public void testTimeout() {
673         MultiThreadedHttpConnectionManager mgr = new MultiThreadedHttpConnectionManager();
674         mgr.getParams().setDefaultMaxConnectionsPerHost(2);
675         
676         try{
677             HostConfiguration hostConfig = new HostConfiguration();
678             hostConfig.setHost("www.nosuchserver.com", 80, "http");
679             
680             HttpConnection conn1 = mgr.getConnection(hostConfig);
681             HttpConnection conn2 = mgr.getConnection(hostConfig);
682             
683             HttpConnection conn3 = mgr.getConnectionWithTimeout(hostConfig, 1000);
684             fail("Expected an HttpException.");
685             
686         }catch(ConnectTimeoutException e){
687             //Expected result
688         }
689     }
690     
691     static class FakeSecureProtocolSocketFactory implements SecureProtocolSocketFactory {
692         
693         public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
694             throws IOException, UnknownHostException {
695             throw new IllegalStateException("createSocket() should never have been called.");
696         }
697         
698         public Socket createSocket(String host, int port)
699             throws IOException, UnknownHostException {
700             throw new IllegalStateException("createSocket() should never have been called.");
701         }
702         
703         public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort)
704             throws IOException, UnknownHostException {
705             throw new IllegalStateException("createSocket() should never have been called.");
706         }
707         
708         public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort, 
709             HttpConnectionParams params)
710             throws IOException, UnknownHostException {
711             throw new IllegalStateException("createSocket() should never have been called.");
712         }
713     }
714     
715     static class RejectConnectService extends EchoService {
716 		public boolean process(SimpleRequest request, SimpleResponse response)
717 				throws IOException {
718             if (request.getRequestLine().getMethod().equalsIgnoreCase("CONNECT")) {
719                 response.setStatusLine(request.getRequestLine().getHttpVersion(), HttpStatus.SC_METHOD_NOT_ALLOWED);
720                 response.setHeader(new Header("Connection", "close"));
721                 return true;
722             } else {
723                 return super.process(request, response);
724             }
725 		}
726     }
727     
728     static class GetConnectionThread extends Thread {
729         
730         private HostConfiguration hostConfiguration;
731         private MultiThreadedHttpConnectionManager connectionManager;
732         private HttpConnection connection;
733         private long timeout;
734         private Exception exception;
735         
736         public GetConnectionThread(
737             HostConfiguration hostConfiguration, 
738             MultiThreadedHttpConnectionManager connectionManager,
739             long timeout
740         ) {
741             this.hostConfiguration = hostConfiguration;
742             this.connectionManager = connectionManager; 
743             this.timeout = timeout;
744         }
745         
746         public void run() {
747             try {
748                 connection = connectionManager.getConnectionWithTimeout(hostConfiguration, timeout);
749             } catch (Exception e) {
750                 this.exception = e;
751             }            
752         }
753         
754         public Exception getException() {
755             return exception;
756         }
757         
758         public HttpConnection getConnection() {
759             return connection;
760         }
761 
762     }
763     
764 }
765