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: 155418 $
4    * $Date: 2005-02-26 08:01:52 -0500 (Sat, 26 Feb 2005) $
5    *
6    * ====================================================================
7    *
8    *  Copyright 1999-2004 The Apache Software Foundation
9    *
10   *  Licensed under the Apache License, Version 2.0 (the "License");
11   *  you may not use this file except in compliance with the License.
12   *  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   */
29  
30  package org.apache.commons.httpclient.server;
31  
32  import java.io.IOException;
33  
34  import org.apache.commons.httpclient.Header;
35  import org.apache.commons.httpclient.HttpException;
36  import org.apache.commons.httpclient.HttpStatus;
37  import org.apache.commons.httpclient.HttpVersion;
38  import org.apache.commons.httpclient.URI;
39  import org.apache.commons.logging.Log;
40  import org.apache.commons.logging.LogFactory;
41  
42  /***
43   * @author Ortwin Glueck
44   * @author Oleg Kalnichevski
45   */
46  public class ProxyRequestHandler implements HttpRequestHandler {
47  
48      private static final Log LOG = LogFactory.getLog(ProxyRequestHandler.class);
49  
50      private SimpleConnManager connmanager = null;
51      
52      public ProxyRequestHandler(final SimpleConnManager connmanager) {
53          super();
54          if (connmanager == null) {
55              throw new IllegalArgumentException("Connection manager may not be null");
56          }
57          this.connmanager = connmanager;
58      }
59      
60  	/***
61  	 * @see org.apache.commons.httpclient.server.HttpRequestHandler#processRequest(org.apache.commons.httpclient.server.SimpleHttpServerConnection)
62  	 */
63  	public boolean processRequest(
64          final SimpleHttpServerConnection conn,
65          final SimpleRequest request) throws IOException
66      {
67          httpProxy(conn, request);
68          return true;
69  	}
70  
71  	private void httpProxy(
72          final SimpleHttpServerConnection conn,
73          final SimpleRequest request) throws IOException {
74  
75          RequestLine oldreqline = request.getRequestLine(); 
76          URI uri = new URI(oldreqline.getUri(), true);
77          SimpleHost host = new SimpleHost(uri.getHost(), uri.getPort());
78          SimpleHttpServerConnection proxyconn = this.connmanager.openConnection(host);
79          proxyconn.setSocketTimeout(0);
80          try {
81  
82              
83              // Rewrite target url
84              RequestLine newreqline = new RequestLine(
85                      oldreqline.getMethod(), 
86                      uri.getEscapedPath(), 
87                      oldreqline.getHttpVersion()); 
88              request.setRequestLine(newreqline);
89              // Remove proxy-auth headers if present
90              request.removeHeaders("Proxy-Authorization");
91              // Manage connection persistence
92              Header connheader = request.getFirstHeader("Proxy-Connection");
93              if (connheader != null) {
94                  if (connheader.getValue().equalsIgnoreCase("close")) {
95                      request.setHeader(new Header("Connection", "close"));
96                  }
97              }
98              request.removeHeaders("Proxy-Connection");
99              
100             proxyconn.writeRequest(request);
101             
102             SimpleResponse response = proxyconn.readResponse();
103             if (response == null) {
104                 return;
105             }
106             connheader = response.getFirstHeader("Connection");
107             if (connheader != null) {
108                 String s = connheader.getValue(); 
109                 if (s.equalsIgnoreCase("close")) {
110                     response.setHeader(new Header("Proxy-Connection", "close"));
111                     conn.setKeepAlive(false);
112                     proxyconn.setKeepAlive(false);
113                     response.removeHeaders("Connection");
114                 }
115                 if (s.equalsIgnoreCase("keep-alive")) {
116                     response.setHeader(new Header("Proxy-Connection", "keep-alive"));
117                     conn.setKeepAlive(true);
118                     proxyconn.setKeepAlive(true);
119                     response.removeHeaders("Connection");
120                 }
121             } else {
122                 // Use protocol default connection policy
123                 if (response.getHttpVersion().greaterEquals(HttpVersion.HTTP_1_1)) {
124                     conn.setKeepAlive(true);
125                     proxyconn.setKeepAlive(true);
126                 } else {
127                     conn.setKeepAlive(false);
128                     proxyconn.setKeepAlive(false);
129                 }
130             }
131             if ("HEAD".equalsIgnoreCase(request.getRequestLine().getMethod())) {
132                 // this is a head request, we don't want to send the actualy content
133                 response.setBody(null);
134             }
135             conn.writeResponse(response);
136 
137         } catch (HttpException e) {
138             SimpleResponse response = ErrorResponse.getResponse(HttpStatus.SC_BAD_REQUEST);
139             conn.writeResponse(response);
140             proxyconn.setKeepAlive(false);
141         } catch (IOException e) {
142             LOG.warn(e.getMessage());
143             proxyconn.setKeepAlive(false);
144         } finally {
145             this.connmanager.releaseConnection(host, proxyconn);
146         }
147 	}
148     
149 }