    1   /*
    2    * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/test/org/apache/commons/httpclient/TestResponseHeaders.java,v 1.18 2004/11/07 12:31:42 olegk Exp $
    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
    36  import junit.framework.Test;
    37  import junit.framework.TestSuite;
    38
    39  import org.apache.commons.httpclient.methods.GetMethod;
    40  import org.apache.commons.httpclient.server.HttpRequestHandler;
    41  import org.apache.commons.httpclient.server.HttpService;
    42  import org.apache.commons.httpclient.server.ResponseWriter;
    43  import org.apache.commons.httpclient.server.SimpleHttpServerConnection;
    44  import org.apache.commons.httpclient.server.SimpleRequest;
    45  import org.apache.commons.httpclient.server.SimpleResponse;
    46
    47  /**
    48   * Tests for reading response headers.
    49   *
    50   * @author <a href="mailto:dims@apache.org">Davanum Srinivas</a>
    51   * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
    52   * @author <a href="mailto:adrian@intencha.com">Adrian Sutton</a>
    53   * @version $Id: TestResponseHeaders.java 480424 2006-11-29 05:56:49Z bayard $
    54   */
    55  public class TestResponseHeaders extends HttpClientTestBase {
    56
    57      private AccessibleHttpConnectionManager connectionManager;
    58
    59      // ------------------------------------------------------------ Constructor
    60      public TestResponseHeaders(final String testName) throws IOException {
    61          super(testName);
    62      }
    63
    64      public void setUp() throws IOException {
    65          super.setUp();
    66          this.connectionManager = new AccessibleHttpConnectionManager();
    67          this.client.setHttpConnectionManager(connectionManager);
    68      }
    69
    70      // ------------------------------------------------------------------- Main
    71      public static void main(String args[]) {
    72          String[] testCaseName = {TestResponseHeaders.class.getName()};
    73          junit.textui.TestRunner.main(testCaseName);
    74      }
    75
    76      // ------------------------------------------------------- TestCase Methods
    77      public static Test suite() {
    78          return new TestSuite(TestResponseHeaders.class);
    79      }
    80
    81      // ----------------------------------------------------------- Test Methods
    82      public void testHeaders() throws Exception {
    83          final String body = "XXX\r\nYYY\r\nZZZ";
    84          this.server.setHttpService(new HttpService() {
    85              public boolean process(SimpleRequest request,
    86                      SimpleResponse response) throws IOException {
    87                  response.setStatusLine(request.getRequestLine().getHttpVersion(), 200);
    88                  response.addHeader(new Header("Connection", "close"));
    89                  response.addHeader(new Header("Content-Length", Integer.toString(body.length())));
    90                  response.addHeader(new Header("Content-Type", "text/xml; charset=utf-8"));
    91                  response.addHeader(new Header("Date", "Wed, 28 Mar 2001 05:05:04 GMT"));
    92                  response.addHeader(new Header("Server", "UserLand Frontier/7.0-WinNT"));
    93                  response.setBodyString(body);
    94                  return true;
    95              }
    96          });
    97
    98          HttpMethod method = new GetMethod();
    99          client.executeMethod(method);
    100         assertEquals("close", method.getResponseHeader("Connection").getValue());
    101         assertEquals(body.length(), Integer.parseInt(method.getResponseHeader("Content-Length").getValue()));
    102         assertEquals("text/xml; charset=utf-8", method.getResponseHeader("Content-Type").getValue());
    103         assertEquals("Wed, 28 Mar 2001 05:05:04 GMT", method.getResponseHeader("Date").getValue());
    104         assertEquals("UserLand Frontier/7.0-WinNT", method.getResponseHeader("Server").getValue());
    105     }
    106
    107     /**
    108      * Tests that having a duplicate content length causes no problems.
    109      */
    110     public void testDuplicateContentLength() throws Exception {
    111
    112         final String body = "XXX\r\nYYY\r\nZZZ";
    113         this.server.setHttpService(new HttpService() {
    114             public boolean process(SimpleRequest request,
    115                     SimpleResponse response) throws IOException {
    116                 response.setStatusLine(request.getRequestLine().getHttpVersion(), 200);
    117                 response.addHeader(new Header("Content-Length", Integer.toString(body.length())));
    118                 response.addHeader(new Header("Content-Length", Integer.toString(body.length())));
    119                 response.setBodyString(body);
    120                 return true;
    121             }
    122         });
    123         HttpMethod method = new GetMethod();
    124         client.executeMethod(method);
    125         assertNotNull( "Response body is null.", method.getResponseBodyAsStream() );
    126     }
    127
    128     public void testDuplicateConnection() throws Exception {
    129
    130         this.server.setHttpService(new HttpService() {
    131             public boolean process(SimpleRequest request,
    132                     SimpleResponse response) throws IOException {
    133                 response.setStatusLine(request.getRequestLine().getHttpVersion(), 200);
    134                 response.addHeader(new Header("Connection", "close"));
    135                 response.addHeader(new Header("Connection", "close"));
    136                 return true;
    137             }
    138         });
    139
    140         GetMethod method = new GetMethod("/");
    141         client.executeMethod(method);
    142         method.getResponseBodyAsString();
    143
    144         assertFalse(connectionManager.getConection().isOpen());
    145
    146         this.server.setHttpService(new HttpService() {
    147             public boolean process(SimpleRequest request,
    148                     SimpleResponse response) throws IOException {
    149                 response.setStatusLine(HttpVersion.HTTP_1_0, 200);
    150                 response.addHeader(new Header("Connection", "keep-alive"));
    151                 response.addHeader(new Header("Connection", "keep-alive"));
    152                 response.setBodyString("aa");
    153                 return true;
    154             }
    155         });
    156
    157         method = new GetMethod("/");
    158         client.executeMethod(method);
    159         method.getResponseBodyAsString();
    160
    161         assertTrue(connectionManager.getConection().isOpen());
    162     }
    163
    164     public void testNoContentLength() throws Exception {
    165         // test with connection header
    166         this.server.setRequestHandler(new HttpRequestHandler() {
    167             public boolean processRequest(SimpleHttpServerConnection conn,
    168                     SimpleRequest request) throws IOException {
    169                 ResponseWriter out = conn.getWriter();
    170                 out.println("HTTP/1.1 200 OK");
    171                 out.println("Connection: keep-alive");
    172                 out.println();
    173                 out.println("12345");
    174                 out.flush();
    175                 return true;
    176             }
    177         });
    178
    179         GetMethod method = new GetMethod("/");
    180         client.executeMethod(method);
    181         method.getResponseBodyAsString();
    182
    183         assertFalse(connectionManager.getConection().isOpen());
    184
    185         // test without connection header
    186         this.server.setRequestHandler(new HttpRequestHandler() {
    187             public boolean processRequest(SimpleHttpServerConnection conn,
    188                     SimpleRequest request) throws IOException {
    189                 ResponseWriter out = conn.getWriter();
    190                 out.println("HTTP/1.1 200 OK");
    191                 out.println();
    192                 out.println("12345");
    193                 out.flush();
    194                 return true;
    195             }
    196         });
    197
    198         // test with connection header
    199         method = new GetMethod("/");
    200         client.executeMethod(method);
    201         method.getResponseBodyAsString();
    202
    203         assertFalse(connectionManager.getConection().isOpen());
    204     }
    205
    206     public void testInvalidContentLength1() throws Exception {
    207         this.server.setHttpService(new HttpService() {
    208             public boolean process(SimpleRequest request,
    209                     SimpleResponse response) throws IOException {
    210                 response.setStatusLine(request.getRequestLine().getHttpVersion(), 200);
    211                 response.addHeader(new Header("Content-Length", "5"));
    212                 response.addHeader(new Header("Content-Length", "stuff"));
    213                 response.setBodyString("12345");
    214                 return true;
    215             }
    216         });
    217         GetMethod method = new GetMethod("/");
    218         client.executeMethod(method);
    219         assertEquals(5, method.getResponseContentLength());
    220     }
    221
    222     public void testInvalidContentLength2() throws Exception {
    223         this.server.setHttpService(new HttpService() {
    224             public boolean process(SimpleRequest request,
    225                     SimpleResponse response) throws IOException {
    226                 response.setStatusLine(request.getRequestLine().getHttpVersion(), 200);
    227                 response.addHeader(new Header("Content-Length", "stuff"));
    228                 response.addHeader(new Header("Content-Length", "5"));
    229                 response.setBodyString("12345");
    230                 return true;
    231             }
    232         });
    233         GetMethod method = new GetMethod("/");
    234         client.executeMethod(method);
    235         assertEquals(5, method.getResponseContentLength());
    236     }
    237
    238     public void testProxyNoContentLength() throws Exception {
    239         // test with proxy-connection header
    240         this.server.setRequestHandler(new HttpRequestHandler() {
    241             public boolean processRequest(SimpleHttpServerConnection conn,
    242                     SimpleRequest request) throws IOException {
    243                 ResponseWriter out = conn.getWriter();
    244                 out.println("HTTP/1.1 200 OK");
    245                 out.println("proxy-connection: keep-alive");
    246                 out.println();
    247                 out.println("12345");
    248                 out.flush();
    249                 return true;
    250             }
    251         });
    252
    253         client.getHostConfiguration().setProxy(server.getLocalAddress(), server.getLocalPort());
    254         GetMethod method = new GetMethod("/");
    255         client.executeMethod(method);
    256         method.getResponseBodyAsString();
    257
    258         assertFalse(connectionManager.getConection().isOpen());
    259
    260         // test without proxy-connection header
    261         this.server.setRequestHandler(new HttpRequestHandler() {
    262             public boolean processRequest(SimpleHttpServerConnection conn,
    263                     SimpleRequest request) throws IOException {
    264                 ResponseWriter out = conn.getWriter();
    265                 out.println("HTTP/1.1 200 OK");
    266                 out.println();
    267                 out.println("12345");
    268                 out.flush();
    269                 return true;
    270             }
    271         });
    272
    273         method = new GetMethod("/");
    274         client.executeMethod(method);
    275         method.getResponseBodyAsString();
    276
    277         assertFalse(connectionManager.getConection().isOpen());
    278     }
    279
    280     public void testNullHeaders() throws Exception {
    281         this.server.setHttpService(new HttpService() {
    282             public boolean process(SimpleRequest request,
    283                     SimpleResponse response) throws IOException {
    284                 response.setStatusLine(request.getRequestLine().getHttpVersion(), 200);
    285                 response.addHeader(new Header("Connection", "close"));
    286                 response.setBodyString("XXX\r\nYYY\r\nZZZ");
    287                 return true;
    288             }
    289         });
    290         HttpMethod method = new GetMethod("/");
    291         client.executeMethod(method);
    292         assertEquals(null, method.getResponseHeader(null));
    293         assertEquals(null, method.getResponseHeader("bogus"));
    294     }
    295
    296     public void testFoldedHeaders() throws Exception {
    297         final String body = "XXX\r\nYYY\r\nZZZ";
    298         this.server.setRequestHandler(new HttpRequestHandler() {
    299             public boolean processRequest(SimpleHttpServerConnection conn,
    300                     SimpleRequest request) throws IOException {
    301                 ResponseWriter out = conn.getWriter();
    302                 out.println("HTTP/1.1 200 OK");
    303                 out.println("Connection: close");
    304                 out.println("Content-Length: " + body.length());
    305                 out.println("Content-Type: text/xml; charset=utf-8");
    306                 out.println("\tboundary=XXXX");
    307                 out.println("Date: Wed, 28 Mar 2001");
    308                 out.println(" 05:05:04 GMT");
    309                 out.println("Server: UserLand Frontier/7.0-WinNT");
    310                 out.println();
    311                 out.println(body);
    312                 out.flush();
    313                 return true;
    314             }
    315         });
    316         HttpMethod method = new GetMethod("/");
    317         client.executeMethod(method);
    318         assertEquals("close", method.getResponseHeader("Connection").getValue());
    319         assertEquals(body.length(), Integer.parseInt(method.getResponseHeader("Content-Length").getValue()));
    320         assertEquals("text/xml; charset=utf-8 boundary=XXXX", method.getResponseHeader("Content-Type").getValue());
    321         assertEquals("Wed, 28 Mar 2001 05:05:04 GMT", method.getResponseHeader("Date").getValue());
    322         assertEquals("UserLand Frontier/7.0-WinNT", method.getResponseHeader("Server").getValue());
    323         assertTrue(method.getResponseHeader("Content-Type").toString().indexOf("boundary") != -1);
    324     }
    325
    326
    327 	public void testForceCloseConnection() throws Exception {
    328         this.server.setRequestHandler(new HttpRequestHandler() {
    329             public boolean processRequest(SimpleHttpServerConnection conn,
    330                     SimpleRequest request) throws IOException {
    331                 ResponseWriter out = conn.getWriter();
    332                 out.println("HTTP/1.1 200 OK");
    333                 out.println("Content-Type: garbage");
    334                 out.println();
    335                 out.println("stuff");
    336                 out.flush();
    337                 return true;
    338             }
    339         });
    340         FakeHttpMethod method = new FakeHttpMethod();
    341         client.executeMethod(method);
    342 		assertTrue("Connection should be closed",
    343                 method.shouldCloseConnection(connectionManager.getConection()));
    344 		assertTrue("Connection should be force-closed", method.isConnectionCloseForced());
    345 	}
    346
    347 	public void testForceCloseConnection2() throws Exception {
    348         this.server.setRequestHandler(new HttpRequestHandler() {
    349             public boolean processRequest(SimpleHttpServerConnection conn,
    350                     SimpleRequest request) throws IOException {
    351                 ResponseWriter out = conn.getWriter();
    352                 out.println("HTTP/1.1 200 OK");
    353                 out.println("Content-Type: garbage");
    354                 out.println("Connection: close");
    355                 out.println();
    356                 out.println("stuff");
    357                 out.flush();
    358                 return true;
    359             }
    360         });
    361         FakeHttpMethod method = new FakeHttpMethod();
    362         client.executeMethod(method);
    363 		assertTrue("Connection should be closed",
    364                 method.shouldCloseConnection(connectionManager.getConection()));
    365 		assertFalse("Connection should NOT be closed", method.isConnectionCloseForced());
    366 	}
    367
    368     public void testNoContent() throws Exception {
    369         // test with connection header
    370         this.server.setRequestHandler(new HttpRequestHandler() {
    371             public boolean processRequest(SimpleHttpServerConnection conn,
    372                     SimpleRequest request) throws IOException {
    373                 ResponseWriter out = conn.getWriter();
    374                 out.println("HTTP/1.1 204 NO CONTENT");
    375                 out.println();
    376                 out.flush();
    377                 return true;
    378             }
    379         });
    380
    381         GetMethod method = new GetMethod("/");
    382         client.executeMethod(method);
    383         method.getResponseBodyAsString();
    384
    385         assertTrue(connectionManager.getConection().isOpen());
    386
    387         // test without connection header
    388         this.server.setRequestHandler(new HttpRequestHandler() {
    389             public boolean processRequest(SimpleHttpServerConnection conn,
    390                     SimpleRequest request) throws IOException {
    391                 ResponseWriter out = conn.getWriter();
    392                 out.println("HTTP/1.1 204 NO CONTENT");
    393                 out.println("Connection: keep-alive");
    394                 out.println();
    395                 out.flush();
    396                 return true;
    397             }
    398         });
    399
    400         // test with connection header
    401         method = new GetMethod("/");
    402         client.executeMethod(method);
    403         method.getResponseBodyAsString();
    404
    405         assertTrue(connectionManager.getConection().isOpen());
    406     }
    407
    408 }