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