    1   /*
    2    * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/test/org/apache/commons/httpclient/server/ProxyRequestHandler.java,v 1.11 2004/12/11 22:35:26 olegk Exp $
    3    * $Revision: 480424 $
    4    * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
    5    *
    6    * ====================================================================
    7    *
    8    *  Licensed to the Apache Software Foundation (ASF) under one or more
    9    *  contributor license agreements.  See the NOTICE file distributed with
    10   *  this work for additional information regarding copyright ownership.
    11   *  The ASF licenses this file to You under the Apache License, Version 2.0
    12   *  (the "License"); you may not use this file except in compliance with
    13   *  the License.  You may obtain a copy of the License at
    14   *
    15   *      http://www.apache.org/licenses/LICENSE-2.0
    16   *
    17   *  Unless required by applicable law or agreed to in writing, software
    18   *  distributed under the License is distributed on an "AS IS" BASIS,
    19   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    20   *  See the License for the specific language governing permissions and
    21   *  limitations under the License.
    22   * ====================================================================
    23   *
    24   * This software consists of voluntary contributions made by many
    25   * individuals on behalf of the Apache Software Foundation.  For more
    26   * information on the Apache Software Foundation, please see
    27   * <http://www.apache.org/>.
    28   *
    29   */
    30
    31  package org.apache.commons.httpclient.server;
    32
    33  import java.io.IOException;
    34  import java.net.UnknownHostException;
    35
    36  import org.apache.commons.httpclient.Header;
    37  import org.apache.commons.httpclient.HttpException;
    38  import org.apache.commons.httpclient.HttpStatus;
    39  import org.apache.commons.httpclient.HttpVersion;
    40  import org.apache.commons.httpclient.URI;
    41  import org.apache.commons.httpclient.URIException;
    42  import org.apache.commons.logging.Log;
    43  import org.apache.commons.logging.LogFactory;
    44
    45  /**
    46   * @author Ortwin Glueck
    47   * @author Oleg Kalnichevski
    48   */
    49  public class ProxyRequestHandler implements HttpRequestHandler {
    50
    51      private static final Log LOG = LogFactory.getLog(ProxyRequestHandler.class);
    52
    53      private SimpleConnManager connmanager = null;
    54
    55      public ProxyRequestHandler(final SimpleConnManager connmanager) {
    56          super();
    57          if (connmanager == null) {
    58              throw new IllegalArgumentException("Connection manager may not be null");
    59          }
    60          this.connmanager = connmanager;
    61      }
    62
    63  	/**
    64  	 * @see org.apache.commons.httpclient.server.HttpRequestHandler#processRequest(org.apache.commons.httpclient.server.SimpleHttpServerConnection)
    65  	 */
    66  	public boolean processRequest(
    67          final SimpleHttpServerConnection conn,
    68          final SimpleRequest request) throws IOException
    69      {
    70          httpProxy(conn, request);
    71          return true;
    72  	}
    73
    74  	private void httpProxy(
    75          final SimpleHttpServerConnection conn,
    76          final SimpleRequest request) throws IOException {
    77
    78          RequestLine oldreqline = request.getRequestLine();
    79          URI uri = null;
    80          SimpleHost host = null;
    81          try {
    82              uri = new URI(oldreqline.getUri(), true);
    83              host = new SimpleHost(uri.getHost(), uri.getPort());
    84          } catch (URIException ex) {
    85              SimpleResponse response = ErrorResponse.getResponse(HttpStatus.SC_BAD_REQUEST);
    86              conn.writeResponse(response);
    87              return;
    88          }
    89          SimpleHttpServerConnection proxyconn = null;
    90          try {
    91              proxyconn = this.connmanager.openConnection(host);
    92          } catch (UnknownHostException e) {
    93              SimpleResponse response = ErrorResponse.getResponse(HttpStatus.SC_NOT_FOUND);
    94              conn.writeResponse(response);
    95              return;
    96          }
    97          try {
    98              proxyconn.setSocketTimeout(0);
    99              // Rewrite target url
    100             RequestLine newreqline = new RequestLine(
    101                     oldreqline.getMethod(),
    102                     uri.getEscapedPath(),
    103                     oldreqline.getHttpVersion());
    104             request.setRequestLine(newreqline);
    105             // Remove proxy-auth headers if present
    106             request.removeHeaders("Proxy-Authorization");
    107             // Manage connection persistence
    108             Header connheader = request.getFirstHeader("Proxy-Connection");
    109             if (connheader != null) {
    110                 if (connheader.getValue().equalsIgnoreCase("close")) {
    111                     request.setHeader(new Header("Connection", "close"));
    112                 }
    113             }
    114             request.removeHeaders("Proxy-Connection");
    115
    116             proxyconn.writeRequest(request);
    117
    118             SimpleResponse response = proxyconn.readResponse();
    119             if (response == null) {
    120                 return;
    121             }
    122             response.setHeader(new Header("Via", "1.1 test (Test-Proxy)"));
    123             connheader = response.getFirstHeader("Connection");
    124             if (connheader != null) {
    125                 String s = connheader.getValue();
    126                 if (s.equalsIgnoreCase("close")) {
    127                     response.setHeader(new Header("Proxy-Connection", "close"));
    128                     conn.setKeepAlive(false);
    129                     proxyconn.setKeepAlive(false);
    130                     response.removeHeaders("Connection");
    131                 }
    132                 if (s.equalsIgnoreCase("keep-alive")) {
    133                     response.setHeader(new Header("Proxy-Connection", "keep-alive"));
    134                     conn.setKeepAlive(true);
    135                     proxyconn.setKeepAlive(true);
    136                     response.removeHeaders("Connection");
    137                 }
    138             } else {
    139                 // Use protocol default connection policy
    140                 if (response.getHttpVersion().greaterEquals(HttpVersion.HTTP_1_1)) {
    141                     conn.setKeepAlive(true);
    142                     proxyconn.setKeepAlive(true);
    143                 } else {
    144                     conn.setKeepAlive(false);
    145                     proxyconn.setKeepAlive(false);
    146                 }
    147             }
    148             if ("HEAD".equalsIgnoreCase(request.getRequestLine().getMethod())) {
    149                 // this is a head request, we don't want to send the actualy content
    150                 response.setBody(null);
    151             }
    152             conn.writeResponse(response);
    153
    154         } catch (HttpException e) {
    155             SimpleResponse response = ErrorResponse.getResponse(HttpStatus.SC_BAD_REQUEST);
    156             conn.writeResponse(response);
    157             proxyconn.setKeepAlive(false);
    158         } catch (IOException e) {
    159             LOG.warn(e.getMessage());
    160             proxyconn.setKeepAlive(false);
    161         } finally {
    162             this.connmanager.releaseConnection(host, proxyconn);
    163         }
    164 	}
    165
    166 }