001: /*
002: * $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 $
003: * $Revision: 480424 $
004: * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
005: *
006: * ====================================================================
007: *
008: * Licensed to the Apache Software Foundation (ASF) under one or more
009: * contributor license agreements. See the NOTICE file distributed with
010: * this work for additional information regarding copyright ownership.
011: * The ASF licenses this file to You under the Apache License, Version 2.0
012: * (the "License"); you may not use this file except in compliance with
013: * the License. You may obtain a copy of the License at
014: *
015: * http://www.apache.org/licenses/LICENSE-2.0
016: *
017: * Unless required by applicable law or agreed to in writing, software
018: * distributed under the License is distributed on an "AS IS" BASIS,
019: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
020: * See the License for the specific language governing permissions and
021: * limitations under the License.
022: * ====================================================================
023: *
024: * This software consists of voluntary contributions made by many
025: * individuals on behalf of the Apache Software Foundation. For more
026: * information on the Apache Software Foundation, please see
027: * <http://www.apache.org/>.
028: *
029: */
030:
031: package org.apache.commons.httpclient.server;
032:
033: import java.io.IOException;
034: import java.net.UnknownHostException;
035:
036: import org.apache.commons.httpclient.Header;
037: import org.apache.commons.httpclient.HttpException;
038: import org.apache.commons.httpclient.HttpStatus;
039: import org.apache.commons.httpclient.HttpVersion;
040: import org.apache.commons.httpclient.URI;
041: import org.apache.commons.httpclient.URIException;
042: import org.apache.commons.logging.Log;
043: import org.apache.commons.logging.LogFactory;
044:
045: /**
046: * @author Ortwin Glueck
047: * @author Oleg Kalnichevski
048: */
049: public class ProxyRequestHandler implements HttpRequestHandler {
050:
051: private static final Log LOG = LogFactory
052: .getLog(ProxyRequestHandler.class);
053:
054: private SimpleConnManager connmanager = null;
055:
056: public ProxyRequestHandler(final SimpleConnManager connmanager) {
057: super ();
058: if (connmanager == null) {
059: throw new IllegalArgumentException(
060: "Connection manager may not be null");
061: }
062: this .connmanager = connmanager;
063: }
064:
065: /**
066: * @see org.apache.commons.httpclient.server.HttpRequestHandler#processRequest(org.apache.commons.httpclient.server.SimpleHttpServerConnection)
067: */
068: public boolean processRequest(
069: final SimpleHttpServerConnection conn,
070: final SimpleRequest request) throws IOException {
071: httpProxy(conn, request);
072: return true;
073: }
074:
075: private void httpProxy(final SimpleHttpServerConnection conn,
076: final SimpleRequest request) throws IOException {
077:
078: RequestLine oldreqline = request.getRequestLine();
079: URI uri = null;
080: SimpleHost host = null;
081: try {
082: uri = new URI(oldreqline.getUri(), true);
083: host = new SimpleHost(uri.getHost(), uri.getPort());
084: } catch (URIException ex) {
085: SimpleResponse response = ErrorResponse
086: .getResponse(HttpStatus.SC_BAD_REQUEST);
087: conn.writeResponse(response);
088: return;
089: }
090: SimpleHttpServerConnection proxyconn = null;
091: try {
092: proxyconn = this .connmanager.openConnection(host);
093: } catch (UnknownHostException e) {
094: SimpleResponse response = ErrorResponse
095: .getResponse(HttpStatus.SC_NOT_FOUND);
096: conn.writeResponse(response);
097: return;
098: }
099: try {
100: proxyconn.setSocketTimeout(0);
101: // Rewrite target url
102: RequestLine newreqline = new RequestLine(oldreqline
103: .getMethod(), uri.getEscapedPath(), oldreqline
104: .getHttpVersion());
105: request.setRequestLine(newreqline);
106: // Remove proxy-auth headers if present
107: request.removeHeaders("Proxy-Authorization");
108: // Manage connection persistence
109: Header connheader = request
110: .getFirstHeader("Proxy-Connection");
111: if (connheader != null) {
112: if (connheader.getValue().equalsIgnoreCase("close")) {
113: request
114: .setHeader(new Header("Connection", "close"));
115: }
116: }
117: request.removeHeaders("Proxy-Connection");
118:
119: proxyconn.writeRequest(request);
120:
121: SimpleResponse response = proxyconn.readResponse();
122: if (response == null) {
123: return;
124: }
125: response.setHeader(new Header("Via",
126: "1.1 test (Test-Proxy)"));
127: connheader = response.getFirstHeader("Connection");
128: if (connheader != null) {
129: String s = connheader.getValue();
130: if (s.equalsIgnoreCase("close")) {
131: response.setHeader(new Header("Proxy-Connection",
132: "close"));
133: conn.setKeepAlive(false);
134: proxyconn.setKeepAlive(false);
135: response.removeHeaders("Connection");
136: }
137: if (s.equalsIgnoreCase("keep-alive")) {
138: response.setHeader(new Header("Proxy-Connection",
139: "keep-alive"));
140: conn.setKeepAlive(true);
141: proxyconn.setKeepAlive(true);
142: response.removeHeaders("Connection");
143: }
144: } else {
145: // Use protocol default connection policy
146: if (response.getHttpVersion().greaterEquals(
147: HttpVersion.HTTP_1_1)) {
148: conn.setKeepAlive(true);
149: proxyconn.setKeepAlive(true);
150: } else {
151: conn.setKeepAlive(false);
152: proxyconn.setKeepAlive(false);
153: }
154: }
155: if ("HEAD".equalsIgnoreCase(request.getRequestLine()
156: .getMethod())) {
157: // this is a head request, we don't want to send the actualy content
158: response.setBody(null);
159: }
160: conn.writeResponse(response);
161:
162: } catch (HttpException e) {
163: SimpleResponse response = ErrorResponse
164: .getResponse(HttpStatus.SC_BAD_REQUEST);
165: conn.writeResponse(response);
166: proxyconn.setKeepAlive(false);
167: } catch (IOException e) {
168: LOG.warn(e.getMessage());
169: proxyconn.setKeepAlive(false);
170: } finally {
171: this.connmanager.releaseConnection(host, proxyconn);
172: }
173: }
174:
175: }
|