/*
* $Header: /home/data/cvs/rt/org.eclipse.ecf/tests/bundles/org.eclipse.ecf.tests.apache.httpclient.server/src/org/apache/commons/httpclient/server/TransparentProxyRequestHandler.java,v 1.1 2009/02/13 18:07:50 slewis Exp $
* $Revision: 1.1 $
* $Date: 2009/02/13 18:07:50 $
*
* ====================================================================
*
* Copyright 1999-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.httpclient.server;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.net.Socket;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.HttpVersion;
/**
* This request handler can handle the CONNECT method. It does nothing for any
* other HTTP methods.
*
* @author Ortwin Glueck
*/
public class TransparentProxyRequestHandler implements HttpRequestHandler {
/*
* (non-Javadoc)
*
* @see org.apache.commons.httpclient.server.HttpRequestHandler#processRequest(org.apache.commons.httpclient.server.SimpleHttpServerConnection)
*/
public boolean processRequest(
final SimpleHttpServerConnection conn,
final SimpleRequest request) throws IOException
{
RequestLine line = request.getRequestLine();
HttpVersion ver = line.getHttpVersion();
String method = line.getMethod();
if (!"CONNECT".equalsIgnoreCase(method)) {
return false;
}
Socket targetSocket = null;
try {
targetSocket = connect(line.getUri());
} catch (IOException e) {
SimpleResponse response = new SimpleResponse();
response.setStatusLine(ver, HttpStatus.SC_NOT_FOUND);
response.setHeader(new Header("Server", "test proxy"));
response.setBodyString("Cannot connect to " + line.getUri());
conn.writeResponse(response);
return true;
}
SimpleResponse response = new SimpleResponse();
response.setHeader(new Header("Server", "test proxy"));
response.setStatusLine(ver, HttpStatus.SC_OK, "Connection established");
conn.writeResponse(response);
SimpleHttpServerConnection target = new SimpleHttpServerConnection(targetSocket);
pump(conn, target);
return true;
}
private void pump(final SimpleHttpServerConnection source, final SimpleHttpServerConnection target)
throws IOException {
source.setSocketTimeout(100);
target.setSocketTimeout(100);
InputStream sourceIn = source.getInputStream();
OutputStream sourceOut = source.getOutputStream();
InputStream targetIn = target.getInputStream();
OutputStream targetOut = target.getOutputStream();
byte[] tmp = new byte[1024];
int l;
for (;;) {
if (!source.isOpen() || !target.isOpen()) {
break;
}
try {
l = sourceIn.read(tmp);
if (l == -1) {
break;
}
targetOut.write(tmp, 0, l);
} catch (InterruptedIOException ignore) {
if (Thread.interrupted()) {
break;
}
}
try {
l = targetIn.read(tmp);
if (l == -1) {
break;
}
sourceOut.write(tmp, 0, l);
} catch (InterruptedIOException ignore) {
if (Thread.interrupted()) {
break;
}
}
}
}
private static Socket connect(final String host) throws IOException {
String hostname = null;
int port;
int i = host.indexOf(':');
if (i != -1) {
hostname = host.substring(0, i);
try {
port = Integer.parseInt(host.substring(i + 1));
} catch (NumberFormatException ex) {
throw new IOException("Invalid host address: " + host);
}
} else {
hostname = host;
port = 80;
}
return new Socket(hostname, port);
}
}