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