com.adito.server.jetty.TunnelAdapter.java Source code

Java tutorial

Introduction

Here is the source code for com.adito.server.jetty.TunnelAdapter.java

Source

/*
*  Adito
*
*  Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU General Public License
*  as published by the Free Software Foundation; either version 2 of
*  the License, or (at your option) any later version.
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public
*  License along with this program; if not, write to the Free Software
*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

package com.adito.server.jetty;

import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mortbay.http.HttpTunnel;

import com.adito.boot.RequestHandlerTunnel;

class TunnelAdapter extends HttpTunnel {

    static Log log = LogFactory.getLog(TunnelAdapter.class);

    private RequestHandlerTunnel tunnel;
    private int timeoutMs;
    private OutputStream originalOutputStream;

    public TunnelAdapter(RequestHandlerTunnel tunnel) {
        this(tunnel, 0);
    }

    public TunnelAdapter(RequestHandlerTunnel tunnel, int timeoutMs) {
        this.tunnel = tunnel;
        this.timeoutMs = timeoutMs;
    }

    /* (non-Javadoc)
     * @see org.mortbay.http.HttpTunnel#handle(java.io.InputStream, java.io.OutputStream)
     */
    public void handle(InputStream in, OutputStream out) {

        this.originalOutputStream = out;

        if (timeoutMs > 0) {
            setSocketTimeout(out, timeoutMs);
        }

        tunnel.tunnel(in, out);
    }

    private void setSocketTimeout(Object obj, int timeoutMs) {

        if (log.isDebugEnabled())
            log.debug("Looking for com.sun.net.ssl.internal.ssl.SSLSocketImpl to set timeout");

        Object ssl = getPrivateMember(obj, "com.sun.net.ssl.internal.ssl.SSLSocketImpl");

        if (ssl != null) {
            try {
                Method m = ssl.getClass().getMethod("setSoTimeout", new Class[] { int.class });
                if (m != null) {
                    m.setAccessible(true);
                    m.invoke(ssl, new Object[] { timeoutMs });

                    if (log.isDebugEnabled())
                        log.debug("Configured socket timeout on tunnel of " + timeoutMs + "ms");
                } else {
                    if (log.isInfoEnabled())
                        log.warn("Could not configure a timeout on socket! no setSoTimeout available");
                }
            } catch (Throwable t) {
                log.error("Could not access setSoTimeout method", t);
            }
        } else {
            if (log.isInfoEnabled())
                log.warn("Could not configure a timeout on socket! no SSLSocketImpl available");
        }
    }

    private Object getPrivateMember(Object obj, String type) {

        Class secretClass = obj.getClass();

        // Print all the field names & values
        Field fields[] = secretClass.getDeclaredFields();

        if (log.isDebugEnabled())
            log.debug("Access all the fields on " + obj.getClass().getName() + " looking for type " + type);

        for (int i = 0; i < fields.length; i++) {

            if (log.isDebugEnabled())
                log.debug("Field Name: " + fields[i].getName());

            fields[i].setAccessible(true);

            try {
                Object obj2 = fields[i].get(obj);
                if (obj2 != null && obj2.getClass().getName().equals(type)) {
                    return obj2;
                }
            } catch (Throwable e) {
                log.error("Failed to set timeout on SSLSocketImpl", e);
            }

        }

        log.error("Could not find " + type + " on object " + obj.getClass().getName());

        return null;
    }
}