1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 package org.apache.commons.httpclient.protocol;
32
33 import java.io.IOException;
34 import java.net.InetAddress;
35 import java.net.Socket;
36 import java.net.UnknownHostException;
37
38 import javax.net.ssl.SSLSocketFactory;
39
40 import org.apache.commons.httpclient.ConnectTimeoutException;
41 import org.apache.commons.httpclient.params.HttpConnectionParams;
42
43 /***
44 * A SecureProtocolSocketFactory that uses JSSE to create sockets.
45 *
46 * @author Michael Becke
47 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
48 *
49 * @since 2.0
50 */
51 public class SSLProtocolSocketFactory implements SecureProtocolSocketFactory {
52
53 /***
54 * The factory singleton.
55 */
56 private static final SSLProtocolSocketFactory factory = new SSLProtocolSocketFactory();
57
58 /***
59 * Gets an singleton instance of the SSLProtocolSocketFactory.
60 * @return a SSLProtocolSocketFactory
61 */
62 static SSLProtocolSocketFactory getSocketFactory() {
63 return factory;
64 }
65
66 /***
67 * Constructor for SSLProtocolSocketFactory.
68 */
69 public SSLProtocolSocketFactory() {
70 super();
71 }
72
73 /***
74 * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
75 */
76 public Socket createSocket(
77 String host,
78 int port,
79 InetAddress clientHost,
80 int clientPort)
81 throws IOException, UnknownHostException {
82 return SSLSocketFactory.getDefault().createSocket(
83 host,
84 port,
85 clientHost,
86 clientPort
87 );
88 }
89
90 /***
91 * Attempts to get a new socket connection to the given host within the given time limit.
92 * <p>
93 * This method employs several techniques to circumvent the limitations of older JREs that
94 * do not support connect timeout. When running in JRE 1.4 or above reflection is used to
95 * call Socket#connect(SocketAddress endpoint, int timeout) method. When executing in older
96 * JREs a controller thread is executed. The controller thread attempts to create a new socket
97 * within the given limit of time. If socket constructor does not return until the timeout
98 * expires, the controller terminates and throws an {@link ConnectTimeoutException}
99 * </p>
100 *
101 * @param host the host name/IP
102 * @param port the port on the host
103 * @param localAddress the local host name/IP to bind the socket to
104 * @param localPort the port on the local machine
105 * @param params {@link HttpConnectionParams Http connection parameters}
106 *
107 * @return Socket a new socket
108 *
109 * @throws IOException if an I/O error occurs while creating the socket
110 * @throws UnknownHostException if the IP address of the host cannot be
111 * determined
112 *
113 * @since 3.0
114 */
115 public Socket createSocket(
116 final String host,
117 final int port,
118 final InetAddress localAddress,
119 final int localPort,
120 final HttpConnectionParams params
121 ) throws IOException, UnknownHostException, ConnectTimeoutException {
122 if (params == null) {
123 throw new IllegalArgumentException("Parameters may not be null");
124 }
125 int timeout = params.getConnectionTimeout();
126 if (timeout == 0) {
127 return createSocket(host, port, localAddress, localPort);
128 } else {
129
130 Socket socket = ReflectionSocketFactory.createSocket(
131 "javax.net.ssl.SSLSocketFactory", host, port, localAddress, localPort, timeout);
132 if (socket == null) {
133 socket = ControllerThreadSocketFactory.createSocket(
134 this, host, port, localAddress, localPort, timeout);
135 }
136 return socket;
137 }
138 }
139
140 /***
141 * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
142 */
143 public Socket createSocket(String host, int port)
144 throws IOException, UnknownHostException {
145 return SSLSocketFactory.getDefault().createSocket(
146 host,
147 port
148 );
149 }
150
151 /***
152 * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
153 */
154 public Socket createSocket(
155 Socket socket,
156 String host,
157 int port,
158 boolean autoClose)
159 throws IOException, UnknownHostException {
160 return ((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(
161 socket,
162 host,
163 port,
164 autoClose
165 );
166 }
167
168 /***
169 * All instances of SSLProtocolSocketFactory are the same.
170 */
171 public boolean equals(Object obj) {
172 return ((obj != null) && obj.getClass().equals(getClass()));
173 }
174
175 /***
176 * All instances of SSLProtocolSocketFactory have the same hash code.
177 */
178 public int hashCode() {
179 return getClass().hashCode();
180 }
181
182 }