Java Source Code: org.apache.commons.httpclient.server.TransparentProxyRequestHandler


   1: /*
   2:  * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/test/org/apache/commons/httpclient/server/TransparentProxyRequestHandler.java,v 1.7 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.io.InputStream;
  35: import java.io.InterruptedIOException;
  36: import java.io.OutputStream;
  37: import java.net.Socket;
  38: 
  39: import org.apache.commons.httpclient.Header;
  40: import org.apache.commons.httpclient.HttpStatus;
  41: import org.apache.commons.httpclient.HttpVersion;
  42: 
  43: /**
  44:  * This request handler can handle the CONNECT method. It does nothing for any
  45:  * other HTTP methods.
  46:  * 
  47:  * @author Ortwin Glueck
  48:  */
  49:	  public class TransparentProxyRequestHandler implements HttpRequestHandler {
  50:
  51:    /*
  52:     * (non-Javadoc)
  53:     * 
  54:     * @see org.apache.commons.httpclient.server.HttpRequestHandler#processRequest(org.apache.commons.httpclient.server.SimpleHttpServerConnection)
  55:     */
  56:    public boolean processRequest(
  57:        final SimpleHttpServerConnection conn,
  58:        final SimpleRequest request) throws IOException
  59:	      {
  60:
  61:        RequestLine line = request.getRequestLine();
  62:        HttpVersion ver = line.getHttpVersion();
  63:        String method = line.getMethod();
  64:	          if (!"CONNECT".equalsIgnoreCase(method)) {
  65:            return false;
  66:        }
  67:        Socket targetSocket = null;
  68:	          try {
  69:            targetSocket = connect(line.getUri());
  70:        } catch (IOException e) {
  71:            SimpleResponse response = new SimpleResponse();
  72:            response.setStatusLine(ver, HttpStatus.SC_NOT_FOUND);
  73:            response.setHeader(new Header("Server", "test proxy"));
  74:            response.setBodyString("Cannot connect to " + line.getUri());
  75:            conn.writeResponse(response);
  76:            return true;
  77:        }
  78:        SimpleResponse response = new SimpleResponse();
  79:        response.setHeader(new Header("Server", "test proxy"));
  80:        response.setStatusLine(ver, HttpStatus.SC_OK, "Connection established");
  81:        conn.writeResponse(response);
  82:        
  83:        SimpleHttpServerConnection target = new SimpleHttpServerConnection(targetSocket); 
  84:        pump(conn, target);
  85:        return true;
  86:    }
  87:
  88:    private void pump(final SimpleHttpServerConnection source, final SimpleHttpServerConnection target)
  89:	          throws IOException {
  90:
  91:        source.setSocketTimeout(100);
  92:        target.setSocketTimeout(100);
  93:
  94:        InputStream sourceIn = source.getInputStream();
  95:        OutputStream sourceOut = source.getOutputStream();
  96:        InputStream targetIn = target.getInputStream();
  97:        OutputStream targetOut = target.getOutputStream();
  98:        
  99:        byte[] tmp = new byte[1024];
 100:        int l;
 101:	          for (;;) {
 102:	              if (!source.isOpen() || !target.isOpen()) { 
 103:                break;
 104:            }
 105:	              try {
 106:                l = sourceIn.read(tmp);
 107:	                  if (l == -1) {
 108:                    break;
 109:                }
 110:                targetOut.write(tmp, 0, l);
 111:            } catch (InterruptedIOException ignore) {
 112:	                  if (Thread.interrupted()) {
 113:                    break;
 114:                }
 115:            }
 116:	              try {
 117:                l = targetIn.read(tmp);
 118:	                  if (l == -1) {
 119:                    break;
 120:                }
 121:                sourceOut.write(tmp, 0, l);
 122:            } catch (InterruptedIOException ignore) {
 123:	                  if (Thread.interrupted()) {
 124:                    break;
 125:                }
 126:            }
 127:        }
 128:    }
 129:    
 130:	      private static Socket connect(final String host) throws IOException {
 131:        String hostname = null; 
 132:        int port; 
 133:        int i = host.indexOf(':');
 134:	          if (i != -1) {
 135:            hostname = host.substring(0, i);
 136:	              try {
 137:                port = Integer.parseInt(host.substring(i + 1));
 138:            } catch (NumberFormatException ex) {
 139:                throw new IOException("Invalid host address: " + host);
 140:            }
 141:        } else {
 142:            hostname = host;
 143:            port = 80;
 144:        }
 145:        return new Socket(hostname, port);        
 146:    }
 147:    
 148:}