| /******************************************************************************* |
| * Copyright (c) 2009 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Thomas Joiner - HttpClient 4 implementation |
| *******************************************************************************/ |
| package org.eclipse.ecf.internal.provider.filetransfer.httpclient4; |
| |
| import java.io.IOException; |
| import java.net.InetSocketAddress; |
| import java.net.Socket; |
| import java.net.UnknownHostException; |
| import javax.net.SocketFactory; |
| import javax.net.ssl.SSLSocket; |
| import org.apache.http.conn.ConnectTimeoutException; |
| import org.apache.http.conn.scheme.SchemeSocketFactory; |
| import org.apache.http.params.CoreConnectionPNames; |
| import org.apache.http.params.HttpParams; |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.ecf.core.util.Trace; |
| import org.eclipse.ecf.filetransfer.events.socket.ISocketEvent; |
| import org.eclipse.ecf.filetransfer.events.socket.ISocketEventSource; |
| import org.eclipse.ecf.filetransfer.events.socket.ISocketListener; |
| import org.eclipse.ecf.filetransfer.events.socketfactory.INonconnectedSocketFactory; |
| import org.eclipse.ecf.provider.filetransfer.events.socket.SocketClosedEvent; |
| import org.eclipse.ecf.provider.filetransfer.events.socket.SocketConnectedEvent; |
| import org.eclipse.ecf.provider.filetransfer.events.socket.SocketCreatedEvent; |
| |
| public class ECFHttpClientProtocolSocketFactory implements SchemeSocketFactory { |
| |
| protected ISocketEventSource source; |
| private INonconnectedSocketFactory unconnectedFactory; |
| private ISocketListener socketConnectListener; |
| |
| private static final ISocketListener NULL_SOCKET_EVENT_LISTENER = new ISocketListener() { |
| public void handleSocketEvent(ISocketEvent event) { |
| //empty |
| } |
| }; |
| |
| public ECFHttpClientProtocolSocketFactory(INonconnectedSocketFactory unconnectedFactory, ISocketEventSource source, ISocketListener socketConnectListener) { |
| super(); |
| Assert.isNotNull(unconnectedFactory); |
| Assert.isNotNull(source); |
| this.unconnectedFactory = unconnectedFactory; |
| this.source = source; |
| this.socketConnectListener = socketConnectListener != null ? socketConnectListener : NULL_SOCKET_EVENT_LISTENER; |
| } |
| |
| public ECFHttpClientProtocolSocketFactory(final SocketFactory socketFactory, ISocketEventSource source, ISocketListener socketConnectListener) { |
| this(new INonconnectedSocketFactory() { |
| public Socket createSocket() throws IOException { |
| return socketFactory.createSocket(); |
| } |
| }, source, socketConnectListener); |
| } |
| |
| public Socket createSocket(HttpParams params) throws IOException { |
| Trace.entering(Activator.PLUGIN_ID, DebugOptions.METHODS_ENTERING, ECFHttpClientProtocolSocketFactory.class, "createSocket"); //$NON-NLS-1$ |
| |
| final Socket factorySocket = unconnectedFactory.createSocket(); |
| fireEvent(socketConnectListener, new SocketCreatedEvent(source, factorySocket)); |
| |
| Trace.exiting(Activator.PLUGIN_ID, DebugOptions.METHODS_EXITING, ECFHttpClientProtocolSocketFactory.class, "socketCreated " + factorySocket); //$NON-NLS-1$ |
| |
| return factorySocket; |
| } |
| |
| public Socket connectSocket(final Socket sock, InetSocketAddress remoteAddress, InetSocketAddress localAddress, HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { |
| int timeout = params.getIntParameter(CoreConnectionPNames.SO_TIMEOUT, 0); |
| |
| Trace.entering(Activator.PLUGIN_ID, DebugOptions.METHODS_ENTERING, ECFHttpClientProtocolSocketFactory.class, "connectSocket " + remoteAddress.toString() + " timeout=" + timeout); //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| try { |
| // Use String.valueOf to protect against null |
| Trace.trace(Activator.PLUGIN_ID, "bind(" + String.valueOf(localAddress) + ")"); //$NON-NLS-1$//$NON-NLS-2$ |
| sock.bind(localAddress); |
| Trace.trace(Activator.PLUGIN_ID, "connect(" + remoteAddress.toString() + ", " + timeout + ")"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ |
| sock.connect(remoteAddress, timeout); |
| Trace.trace(Activator.PLUGIN_ID, "connected"); //$NON-NLS-1$ |
| } catch (IOException e) { |
| Trace.catching(Activator.PLUGIN_ID, DebugOptions.EXCEPTIONS_CATCHING, ECFHttpClientProtocolSocketFactory.class, "createSocket", e); //$NON-NLS-1$ |
| fireEvent(socketConnectListener, new SocketClosedEvent(source, sock, sock)); |
| Trace.throwing(Activator.PLUGIN_ID, DebugOptions.EXCEPTIONS_THROWING, ECFHttpClientProtocolSocketFactory.class, "createSocket", e); //$NON-NLS-1$ |
| throw e; |
| } |
| |
| Socket toReturn; |
| Socket wrapped = new CloseMonitoringSocket(sock, socketConnectListener, source); |
| |
| SocketConnectedEvent connectedEvent = new SocketConnectedEvent(source, sock, wrapped); |
| fireEvent(socketConnectListener, connectedEvent); |
| |
| // Change the wrapped socket if one of the receivers of the SocketConnectedEvent changed it |
| if (connectedEvent.getSocket() != wrapped) { |
| toReturn = connectedEvent.getSocket(); |
| ((CloseMonitoringSocket) wrapped).setWrappedSocket(toReturn); |
| } else { |
| toReturn = wrapped; |
| } |
| |
| return toReturn; |
| } |
| |
| private static void fireEvent(final ISocketListener spyListener, ISocketEvent event) { |
| if (spyListener != null) { |
| spyListener.handleSocketEvent(event); |
| } |
| event.getSource().fireEvent(event); |
| } |
| |
| public boolean isSecure(Socket sock) throws IllegalArgumentException { |
| if (sock instanceof SSLSocket) { |
| throw new IllegalArgumentException("Socket not created by this factory."); //$NON-NLS-1$ |
| } |
| |
| return false; |
| } |
| |
| public boolean equals(Object obj) { |
| return (obj instanceof ECFHttpClientProtocolSocketFactory); |
| } |
| |
| public int hashCode() { |
| return ECFHttpClientProtocolSocketFactory.class.hashCode(); |
| } |
| } |