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 }