Package org.apache.mina.proxy

Source Code of org.apache.mina.proxy.ProxyConnector

/*
*  Licensed to the Apache Software Foundation (ASF) under one
*  or more contributor license agreements.  See the NOTICE file
*  distributed with this work for additional information
*  regarding copyright ownership.  The ASF licenses this file
*  to you 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.
*
*/
package org.apache.mina.proxy;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.concurrent.Executor;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.file.FileRegion;
import org.apache.mina.core.filterchain.IoFilter;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.future.DefaultConnectFuture;
import org.apache.mina.core.future.IoFuture;
import org.apache.mina.core.service.AbstractIoConnector;
import org.apache.mina.core.service.DefaultTransportMetadata;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.service.TransportMetadata;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.session.IoSessionConfig;
import org.apache.mina.core.session.IoSessionInitializer;
import org.apache.mina.proxy.filter.ProxyFilter;
import org.apache.mina.proxy.handlers.socks.SocksProxyRequest;
import org.apache.mina.proxy.session.ProxyIoSession;
import org.apache.mina.proxy.session.ProxyIoSessionInitializer;
import org.apache.mina.transport.socket.DefaultSocketSessionConfig;
import org.apache.mina.transport.socket.SocketConnector;
import org.apache.mina.transport.socket.SocketSessionConfig;

/**
* ProxyConnector.java - Decorator for {@link SocketConnector} to provide proxy support, as suggested by MINA list discussions.
* <p>
* Operates by intercepting connect requests and replacing the endpoint address with the proxy address,
* then adding a {@link ProxyFilter} as the first {@link IoFilter} which performs any necessary
* handshaking with the proxy before allowing data to flow normally. During the handshake, any outgoing
* write requests are buffered.
*
* @see    http://www.nabble.com/Meta-Transport%3A-an-idea-on-implementing-reconnection-and-proxy-td12969001.html
* @see    http://issues.apache.org/jira/browse/DIRMINA-415
*
* @author The Apache MINA Project (dev@mina.apache.org)
* @version $Rev: 685703 $, $Date: 2008-08-14 00:14:47 +0200 (Thu, 14 Aug 2008) $
* @since MINA 2.0.0-M3
*/
public class ProxyConnector extends AbstractIoConnector {
    static final TransportMetadata METADATA = new DefaultTransportMetadata(
            "proxy", "proxyconnector", false, true, InetSocketAddress.class,
            SocketSessionConfig.class, IoBuffer.class, FileRegion.class);

    /**
     * Wrapped connector to use for outgoing TCP connections.
     */
    private SocketConnector connector = null;

    /**
     * Proxy filter instance.
     */
    private final ProxyFilter proxyFilter = new ProxyFilter();

    /**
     * The {@link ProxyIoSession} in use.
     */
    private ProxyIoSession proxyIoSession;

    /**
     * This future will notify it's listeners when really connected to the target
     */
    private DefaultConnectFuture future;

    /**
     * Creates a new proxy connector.
     */
    public ProxyConnector() {
        super(new DefaultSocketSessionConfig(), null);
    }

    /**
     * Creates a new proxy connector.
     *
     * @param connector         Connector used to establish proxy connections.
     */
    public ProxyConnector(final SocketConnector connector) {       
        this(connector, new DefaultSocketSessionConfig(), null);
    }

    /**
     * Creates a new proxy connector.
     * @see AbstractIoConnector(IoSessionConfig, Executor).
     */
    public ProxyConnector(final SocketConnector connector, IoSessionConfig config, Executor executor) {
        super(config, executor);
        setConnector(connector);
    }   
       
    @Override
    public IoSessionConfig getSessionConfig() {
        return connector.getSessionConfig();
    }

    public ProxyIoSession getProxyIoSession() {
        return proxyIoSession;
    }

    public void setProxyIoSession(ProxyIoSession proxyIoSession) {
        if (proxyIoSession == null) {
            throw new NullPointerException("proxySession cannot be null");
        }

        if (proxyIoSession.getProxyAddress() == null) {
            throw new NullPointerException(
                    "proxySession.proxyAddress cannot be null");
        }

        proxyIoSession.setConnector(this);
        setDefaultRemoteAddress(proxyIoSession.getProxyAddress());
        this.proxyIoSession = proxyIoSession;
    }

    /**
     * Connects to the specified <code>address</code>.  If communication starts
     * successfully, events are fired to the specified
     * <code>handler</code>.
     *
     * @return {@link ConnectFuture} that will tell the result of the connection attempt
     */
    @SuppressWarnings("unchecked")
    @Override
    protected ConnectFuture connect0(
            final SocketAddress remoteAddress,
            final SocketAddress localAddress,
            final IoSessionInitializer<? extends ConnectFuture> sessionInitializer) {
        if (!proxyIoSession.isReconnectionNeeded()) {
            // First connection
            IoHandler handler = getHandler();
            if (!(handler instanceof AbstractProxyIoHandler)) {
                throw new IllegalArgumentException(
                        "IoHandler must be an instance of AbstractProxyIoHandler");
            }

            connector.setHandler(handler);
            future = new DefaultConnectFuture();
        }

        ConnectFuture conFuture = connector.connect(proxyIoSession
                .getProxyAddress(), new ProxyIoSessionInitializer(
                sessionInitializer, proxyIoSession));

        if (proxyIoSession.getRequest() instanceof SocksProxyRequest
                || proxyIoSession.isReconnectionNeeded()) {
            return conFuture;
        } else {
            return future;
        }
    }

    public void cancelConnectFuture() {
        future.cancel();
    }

    protected ConnectFuture fireConnected(final IoSession session) {
        future.setSession(session);
        return future;
    }

    /**
     * Get the {@link SocketConnector} to be used for connections
     * to the proxy server.
     */
    public final SocketConnector getConnector() {
        return connector;
    }

    /**
     * Set the {@link SocketConnector} to be used for connections
     * to the proxy server.
     */
    public final void setConnector(final SocketConnector newConnector) {
        if (newConnector == null) {
            throw new NullPointerException("connector cannot be null");
        }

        SocketConnector oldConnector = this.connector;

        // Remove the ProxyFilter from the old filter chain builder
        if (oldConnector != null) {
            oldConnector.getFilterChain().remove(ProxyFilter.class.getName());
        }

        this.connector = newConnector;

        // Insert the ProxyFilter as the first filter in the filter chain builder
        if (newConnector.getFilterChain().contains(ProxyFilter.class.getName())) {
            newConnector.getFilterChain().remove(ProxyFilter.class.getName());
        }

        newConnector.getFilterChain().addFirst(ProxyFilter.class.getName(),
                proxyFilter);
    }

    /* (non-Javadoc)
     * @see org.apache.mina.common.AbstractIoService#dispose0()
     */
    @Override
    protected IoFuture dispose0() throws Exception {
        if (connector != null) {
            connector.dispose();
        }
        return null;
    }

    /* (non-Javadoc)
     * @see org.apache.mina.common.IoService#getTransportMetadata()
     */
    public TransportMetadata getTransportMetadata() {
        return METADATA;
    }
}
TOP

Related Classes of org.apache.mina.proxy.ProxyConnector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.