1. /*
  2. * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/protocol/SSLProtocolSocketFactory.java,v 1.10 2004/05/13 04:01:22 mbecke Exp $
  3. * $Revision: 1.10 $
  4. * $Date: 2004/05/13 04:01:22 $
  5. *
  6. * ====================================================================
  7. *
  8. * Copyright 2002-2004 The Apache Software Foundation
  9. *
  10. * Licensed under the Apache License, Version 2.0 (the "License");
  11. * you may not use this file except in compliance with the License.
  12. * You may obtain a copy of the License at
  13. *
  14. * http://www.apache.org/licenses/LICENSE-2.0
  15. *
  16. * Unless required by applicable law or agreed to in writing, software
  17. * distributed under the License is distributed on an "AS IS" BASIS,
  18. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19. * See the License for the specific language governing permissions and
  20. * limitations under the License.
  21. * ====================================================================
  22. *
  23. * This software consists of voluntary contributions made by many
  24. * individuals on behalf of the Apache Software Foundation. For more
  25. * information on the Apache Software Foundation, please see
  26. * <http://www.apache.org/>.
  27. *
  28. */
  29. package org.apache.commons.httpclient.protocol;
  30. import java.io.IOException;
  31. import java.net.InetAddress;
  32. import java.net.Socket;
  33. import java.net.UnknownHostException;
  34. import javax.net.ssl.SSLSocketFactory;
  35. import org.apache.commons.httpclient.ConnectTimeoutException;
  36. import org.apache.commons.httpclient.params.HttpConnectionParams;
  37. /**
  38. * A SecureProtocolSocketFactory that uses JSSE to create sockets.
  39. *
  40. * @author Michael Becke
  41. * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
  42. *
  43. * @since 2.0
  44. */
  45. public class SSLProtocolSocketFactory implements SecureProtocolSocketFactory {
  46. /**
  47. * The factory singleton.
  48. */
  49. private static final SSLProtocolSocketFactory factory = new SSLProtocolSocketFactory();
  50. /**
  51. * Gets an singleton instance of the SSLProtocolSocketFactory.
  52. * @return a SSLProtocolSocketFactory
  53. */
  54. static SSLProtocolSocketFactory getSocketFactory() {
  55. return factory;
  56. }
  57. /**
  58. * Constructor for SSLProtocolSocketFactory.
  59. */
  60. public SSLProtocolSocketFactory() {
  61. super();
  62. }
  63. /**
  64. * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
  65. */
  66. public Socket createSocket(
  67. String host,
  68. int port,
  69. InetAddress clientHost,
  70. int clientPort)
  71. throws IOException, UnknownHostException {
  72. return SSLSocketFactory.getDefault().createSocket(
  73. host,
  74. port,
  75. clientHost,
  76. clientPort
  77. );
  78. }
  79. /**
  80. * Attempts to get a new socket connection to the given host within the given time limit.
  81. * <p>
  82. * This method employs several techniques to circumvent the limitations of older JREs that
  83. * do not support connect timeout. When running in JRE 1.4 or above reflection is used to
  84. * call Socket#connect(SocketAddress endpoint, int timeout) method. When executing in older
  85. * JREs a controller thread is executed. The controller thread attempts to create a new socket
  86. * within the given limit of time. If socket constructor does not return until the timeout
  87. * expires, the controller terminates and throws an {@link ConnectTimeoutException}
  88. * </p>
  89. *
  90. * @param host the host name/IP
  91. * @param port the port on the host
  92. * @param localAddress the local host name/IP to bind the socket to
  93. * @param localPort the port on the local machine
  94. * @param params {@link HttpConnectionParams Http connection parameters}
  95. *
  96. * @return Socket a new socket
  97. *
  98. * @throws IOException if an I/O error occurs while creating the socket
  99. * @throws UnknownHostException if the IP address of the host cannot be
  100. * determined
  101. *
  102. * @since 3.0
  103. */
  104. public Socket createSocket(
  105. final String host,
  106. final int port,
  107. final InetAddress localAddress,
  108. final int localPort,
  109. final HttpConnectionParams params
  110. ) throws IOException, UnknownHostException, ConnectTimeoutException {
  111. if (params == null) {
  112. throw new IllegalArgumentException("Parameters may not be null");
  113. }
  114. int timeout = params.getConnectionTimeout();
  115. if (timeout == 0) {
  116. return createSocket(host, port, localAddress, localPort);
  117. } else {
  118. // To be eventually deprecated when migrated to Java 1.4 or above
  119. Socket socket = ReflectionSocketFactory.createSocket(
  120. "javax.net.ssl.SSLSocketFactory", host, port, localAddress, localPort, timeout);
  121. if (socket == null) {
  122. socket = ControllerThreadSocketFactory.createSocket(
  123. this, host, port, localAddress, localPort, timeout);
  124. }
  125. return socket;
  126. }
  127. }
  128. /**
  129. * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
  130. */
  131. public Socket createSocket(String host, int port)
  132. throws IOException, UnknownHostException {
  133. return SSLSocketFactory.getDefault().createSocket(
  134. host,
  135. port
  136. );
  137. }
  138. /**
  139. * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
  140. */
  141. public Socket createSocket(
  142. Socket socket,
  143. String host,
  144. int port,
  145. boolean autoClose)
  146. throws IOException, UnknownHostException {
  147. return ((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(
  148. socket,
  149. host,
  150. port,
  151. autoClose
  152. );
  153. }
  154. /**
  155. * All instances of SSLProtocolSocketFactory are the same.
  156. */
  157. public boolean equals(Object obj) {
  158. return ((obj != null) && obj.getClass().equals(SSLProtocolSocketFactory.class));
  159. }
  160. /**
  161. * All instances of SSLProtocolSocketFactory have the same hash code.
  162. */
  163. public int hashCode() {
  164. return SSLProtocolSocketFactory.class.hashCode();
  165. }
  166. }