View Javadoc

1   /***
2    * Simple Web Spider - <http://simplewebspider.sourceforge.net/>
3    * Copyright (C) 2009  <berendona@users.sourceforge.net>
4    *
5    * This program is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  package simplespider.simplespider.bot.http.apache.ssl;
19  
20  import java.io.IOException;
21  import java.net.InetAddress;
22  import java.net.InetSocketAddress;
23  import java.net.Socket;
24  import java.net.SocketAddress;
25  import java.net.UnknownHostException;
26  
27  import javax.net.SocketFactory;
28  import javax.net.ssl.SSLContext;
29  import javax.net.ssl.TrustManager;
30  
31  import org.apache.commons.httpclient.ConnectTimeoutException;
32  import org.apache.commons.httpclient.HttpClientError;
33  import org.apache.commons.httpclient.params.HttpConnectionParams;
34  import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
35  import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
36  import org.apache.commons.logging.Log;
37  import org.apache.commons.logging.LogFactory;
38  
39  public class EasySSLProtocolSocketFactory implements ProtocolSocketFactory {
40  
41  	/*** Log object for this class. */
42  	private static final Log	LOG			= LogFactory.getLog(EasySSLProtocolSocketFactory.class);
43  
44  	private SSLContext			sslcontext	= null;
45  
46  	/***
47  	 * Constructor for EasySSLProtocolSocketFactory.
48  	 */
49  	public EasySSLProtocolSocketFactory() {
50  		super();
51  	}
52  
53  	private static SSLContext createEasySSLContext() {
54  		try {
55  			final SSLContext context = SSLContext.getInstance("SSL");
56  			context.init(null, new TrustManager[] { new EasyX509TrustManager(null) }, null);
57  			return context;
58  		} catch (final Exception e) {
59  			LOG.error(e.getMessage(), e);
60  			throw new HttpClientError(e.toString());
61  		}
62  	}
63  
64  	private SSLContext getSSLContext() {
65  		if (this.sslcontext == null) {
66  			this.sslcontext = createEasySSLContext();
67  		}
68  		return this.sslcontext;
69  	}
70  
71  	/***
72  	 * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
73  	 */
74  	public Socket createSocket(final String host, final int port, final InetAddress clientHost, final int clientPort) throws IOException,
75  			UnknownHostException {
76  
77  		return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);
78  	}
79  
80  	/***
81  	 * Attempts to get a new socket connection to the given host within the given time limit.
82  	 * <p>
83  	 * To circumvent the limitations of older JREs that do not support connect timeout a controller thread is executed. The controller thread attempts
84  	 * to create a new socket within the given limit of time. If socket constructor does not return until the timeout expires, the controller
85  	 * terminates and throws an {@link ConnectTimeoutException}
86  	 * </p>
87  	 * 
88  	 * @param host
89  	 *            the host name/IP
90  	 * @param port
91  	 *            the port on the host
92  	 * @param clientHost
93  	 *            the local host name/IP to bind the socket to
94  	 * @param clientPort
95  	 *            the port on the local machine
96  	 * @param params
97  	 *            {@link HttpConnectionParams Http connection parameters}
98  	 * @return Socket a new socket
99  	 * @throws IOException
100 	 *             if an I/O error occurs while creating the socket
101 	 * @throws UnknownHostException
102 	 *             if the IP address of the host cannot be determined
103 	 */
104 	public Socket createSocket(final String host, final int port, final InetAddress localAddress, final int localPort,
105 			final HttpConnectionParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
106 		if (params == null) {
107 			throw new IllegalArgumentException("Parameters may not be null");
108 		}
109 		final int timeout = params.getConnectionTimeout();
110 		final SocketFactory socketfactory = getSSLContext().getSocketFactory();
111 		if (timeout == 0) {
112 			return socketfactory.createSocket(host, port, localAddress, localPort);
113 		} else {
114 			final Socket socket = socketfactory.createSocket();
115 			final SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
116 			final SocketAddress remoteaddr = new InetSocketAddress(host, port);
117 			socket.bind(localaddr);
118 			socket.connect(remoteaddr, timeout);
119 			return socket;
120 		}
121 	}
122 
123 	/***
124 	 * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
125 	 */
126 	public Socket createSocket(final String host, final int port) throws IOException, UnknownHostException {
127 		return getSSLContext().getSocketFactory().createSocket(host, port);
128 	}
129 
130 	/***
131 	 * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
132 	 */
133 	public Socket createSocket(final Socket socket, final String host, final int port, final boolean autoClose) throws IOException,
134 			UnknownHostException {
135 		return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
136 	}
137 
138 	@Override
139 	public boolean equals(final Object obj) {
140 		return ((obj != null) && obj.getClass().equals(EasySSLProtocolSocketFactory.class));
141 	}
142 
143 	@Override
144 	public int hashCode() {
145 		return EasySSLProtocolSocketFactory.class.hashCode();
146 	}
147 
148 }