1   /*
2    * $Header: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/server/ProxyRequestHandler.java,v 1.10 2004/11/13 22:38:27 mbecke Exp $
3    * $Revision: 1.10 $
4    * $Date: 2004/11/13 22:38:27 $
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          try {
80  
81              
82              // Rewrite target url
83              RequestLine newreqline = new RequestLine(
84                      oldreqline.getMethod(), 
85                      uri.getEscapedPath(), 
86                      oldreqline.getHttpVersion()); 
87              request.setRequestLine(newreqline);
88              // Remove proxy-auth headers if present
89              request.removeHeaders("Proxy-Authorization");
90              // Manage connection persistence
91              Header connheader = request.getFirstHeader("Proxy-Connection");
92              if (connheader != null) {
93                  if (connheader.getValue().equalsIgnoreCase("close")) {
94                      request.setHeader(new Header("Connection", "close"));
95                  }
96              }
97              request.removeHeaders("Proxy-Connection");
98              
99              proxyconn.writeRequest(request);
100             
101             SimpleResponse response = proxyconn.readResponse();
102             if (response == null) {
103                 return;
104             }
105             connheader = response.getFirstHeader("Connection");
106             if (connheader != null) {
107                 String s = connheader.getValue(); 
108                 if (s.equalsIgnoreCase("close")) {
109                     response.setHeader(new Header("Proxy-Connection", "close"));
110                     conn.setKeepAlive(false);
111                     proxyconn.setKeepAlive(false);
112                     response.removeHeaders("Connection");
113                 }
114                 if (s.equalsIgnoreCase("keep-alive")) {
115                     response.setHeader(new Header("Proxy-Connection", "keep-alive"));
116                     conn.setKeepAlive(true);
117                     proxyconn.setKeepAlive(true);
118                     response.removeHeaders("Connection");
119                 }
120             } else {
121                 // Use protocol default connection policy
122                 if (response.getHttpVersion().greaterEquals(HttpVersion.HTTP_1_1)) {
123                     conn.setKeepAlive(true);
124                     proxyconn.setKeepAlive(true);
125                 } else {
126                     conn.setKeepAlive(false);
127                     proxyconn.setKeepAlive(false);
128                 }
129             }
130             if ("HEAD".equalsIgnoreCase(request.getRequestLine().getMethod())) {
131                 // this is a head request, we don't want to send the actualy content
132                 response.setBody(null);
133             }
134             conn.writeResponse(response);
135 
136         } catch (HttpException e) {
137             SimpleResponse response = ErrorResponse.getResponse(HttpStatus.SC_BAD_REQUEST);
138             conn.writeResponse(response);
139             proxyconn.setKeepAlive(false);
140         } catch (IOException e) {
141             LOG.warn(e.getMessage());
142             proxyconn.setKeepAlive(false);
143         } finally {
144             this.connmanager.releaseConnection(host, proxyconn);
145         }
146 	}
147     
148 }