You are viewing a plain text version of this content. The canonical link for it is here.
Posted to soap-dev@xml.apache.org by sn...@apache.org on 2002/12/20 22:40:32 UTC

cvs commit: xml-soap/java/src/org/apache/soap/util/net SocketUtils.java HTTPUtils.java SSLUtils.java

snichol     2002/12/20 13:40:32

  Modified:    java/src/org/apache/soap/util/net HTTPUtils.java
                        SSLUtils.java
  Added:       java/src/org/apache/soap/util/net SocketUtils.java
  Log:
  For J2SE 1.4 and later, use the timeout value as the maximum time to block
  on connect, as well as read.  Thanks to Mike Ladwig for helping to test
  this.
  
  Revision  Changes    Path
  1.42      +23 -10    xml-soap/java/src/org/apache/soap/util/net/HTTPUtils.java
  
  Index: HTTPUtils.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/util/net/HTTPUtils.java,v
  retrieving revision 1.41
  retrieving revision 1.42
  diff -u -r1.41 -r1.42
  --- HTTPUtils.java	3 Dec 2002 21:16:08 -0000	1.41
  +++ HTTPUtils.java	20 Dec 2002 21:40:32 -0000	1.42
  @@ -82,6 +82,7 @@
   import org.apache.soap.transport.TransportMessage;
   import org.apache.soap.util.MutableBoolean;
   import org.apache.soap.util.StringUtils;
  +import org.apache.soap.util.net.SocketUtils;
   
   /**
    * A bunch of utility stuff for doing HTTP things.
  @@ -123,7 +124,7 @@
      *
      * @author Chris Nelson
      */
  -  private static Socket getSecureSocket(String host, int port,
  +  private static Socket getSecureSocket(String host, int port, int timeout,
                                           String httpProxyHost, int httpProxyPort,
                                           Hashtable headers, Boolean tcpNoDelay)
           throws Exception {
  @@ -151,11 +152,11 @@
       // Using reflection to avoid compile time dependencies
       Class SSLUtilsClass =
           Class.forName("org.apache.soap.util.net.SSLUtils");
  -    Class[] paramTypes = new Class[] {String.class, int.class,
  +    Class[] paramTypes = new Class[] {String.class, int.class, int.class,
                                         String.class, int.class,
                                         String.class, Boolean.class};
       Method buildSSLSocket = SSLUtilsClass.getMethod("buildSSLSocket", paramTypes);
  -    Object[] params = new Object[] {host, new Integer(port),
  +    Object[] params = new Object[] {host, new Integer(port), new Integer(timeout),
                                       httpProxyHost, new Integer(httpProxyPort),
                                       proxyAuth, tcpNoDelay};
   
  @@ -176,7 +177,7 @@
      *
      * @author Chris Nelson
      */
  -  private static Socket getSocket(String host, int port,
  +  private static Socket getSocket(String host, int port, int timeout,
                                     String httpProxyHost, int httpProxyPort,
                                     Hashtable headers, Boolean tcpNoDelay,
                                     MutableBoolean proxyUsed)
  @@ -208,11 +209,18 @@
         }
       }
   
  +    String theHost;
  +    int thePort;
  +    if (proxyUsed.getValue()) {
  +      theHost = httpProxyHost;
  +      thePort = httpProxyPort;
  +    } else {
  +      theHost = host;
  +      thePort = port;
  +    }
  +
       try {
  -      if (proxyUsed.getValue())
  -        s = new Socket(httpProxyHost, httpProxyPort);
  -      else
  -        s = new Socket(host, port);
  +      s = SocketUtils.createSocket(theHost, thePort, timeout);
       } catch (Exception e) {
         StringBuffer msg = new StringBuffer(512);
         msg.append("Error connecting to ").append(host).append(':').append(port);
  @@ -271,6 +279,7 @@
      * @param url the url to post to
      * @param request the message
      * @param timeout the amount of time, in ms, to block on reading data
  +   *        for J2SE 1.4 and later, also the time to block on connect
      * @param httpProxyHost the HTTP proxy host or null if no proxy
      * @param httpProxyPort the HTTP proxy port, if the proxy host is not null
      * @return the response message
  @@ -296,6 +305,7 @@
      * @param url the url to post to
      * @param request the message
      * @param timeout the amount of time, in ms, to block on reading data
  +   *        for J2SE 1.4 and later, also the time to block on connect
      * @param httpProxyHost the HTTP proxy host or null if no proxy
      * @param httpProxyPort the HTTP proxy port, if the proxy host is not null
      * @param outputBufferSize the size of the output buffer on the HTTP stream
  @@ -323,6 +333,7 @@
      * @param url the url to post to
      * @param request the message
      * @param timeout the amount of time, in ms, to block on reading data
  +   *        for J2SE 1.4 and later, also the time to block on connect
      * @param httpProxyHost the HTTP proxy host or null if no proxy
      * @param httpProxyPort the HTTP proxy port, if the proxy host is not null
      * @param outputBufferSize the size of the output buffer on the HTTP stream
  @@ -355,6 +366,7 @@
      * @param url the url to post to
      * @param request the message
      * @param timeout the amount of time, in ms, to block on reading data
  +   *        for J2SE 1.4 and later, also the time to block on connect
      * @param httpProxyHost the HTTP proxy host or null if no proxy
      * @param httpProxyPort the HTTP proxy port, if the proxy host is not null
      * @param outputBufferSize the size of the output buffer on the HTTP stream
  @@ -392,6 +404,7 @@
      * @param url the url to post to
      * @param request the message
      * @param timeout the amount of time, in ms, to block on reading data
  +   *        for J2SE 1.4 and later, also the time to block on connect
      * @param httpProxyHost the HTTP proxy host or null if no proxy
      * @param httpProxyPort the HTTP proxy port, if the proxy host is not null
      * @param outputBufferSize the size of the output buffer on the HTTP stream
  @@ -425,11 +438,11 @@
         /* Open the connection */
         try {
             if (protocol.equalsIgnoreCase("HTTPS")) {
  -              s = getSecureSocket(host, port, httpProxyHost, httpProxyPort,
  +              s = getSecureSocket(host, port, timeout, httpProxyHost, httpProxyPort,
                                     request.getHeaders(), tcpNoDelay);
             } else {
                 MutableBoolean isProxyUsed = new MutableBoolean(proxyUsed);
  -              s = getSocket(host, port, httpProxyHost, httpProxyPort,
  +              s = getSocket(host, port, timeout, httpProxyHost, httpProxyPort,
                                     request.getHeaders(), tcpNoDelay,
                                     isProxyUsed);
                 proxyUsed = isProxyUsed.getValue();
  
  
  
  1.10      +78 -13    xml-soap/java/src/org/apache/soap/util/net/SSLUtils.java
  
  Index: SSLUtils.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/util/net/SSLUtils.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- SSLUtils.java	8 Nov 2002 04:32:37 -0000	1.9
  +++ SSLUtils.java	20 Dec 2002 21:40:32 -0000	1.10
  @@ -57,11 +57,20 @@
   
   package org.apache.soap.util.net;
   
  -import java.net.*;
  -import java.io.*;
  -import java.util.*;
  -import javax.net.ssl.*;
  -import java.security.*;
  +import java.io.InputStream;
  +import java.io.IOException;
  +import java.io.OutputStream;
  +import java.io.UnsupportedEncodingException;
  +import java.lang.reflect.Constructor;
  +import java.lang.reflect.InvocationTargetException;
  +import java.lang.reflect.Method;
  +import java.net.Socket;
  +import java.net.UnknownHostException;
  +import java.util.StringTokenizer;
  +import javax.net.ssl.SSLSocket;
  +import javax.net.ssl.SSLSocketFactory;
  +
  +import org.apache.soap.util.net.SocketUtils;
   
   /**
    * A bunch of utility stuff for doing SSL things.  It is separate from
  @@ -88,7 +97,7 @@
                                           String tunnelHost, int tunnelPort)
           throws IOException, UnknownHostException {
   
  -        return buildSSLSocket(host, port,
  +        return buildSSLSocket(host, port, 0,
                                 tunnelHost, tunnelPort,
                                 null, null);
       }
  @@ -109,9 +118,9 @@
                                           Boolean tcpNoDelay)
           throws IOException, UnknownHostException {
   
  -        return buildSSLSocket(host, port,
  +        return buildSSLSocket(host, port, 0,
                                 tunnelHost, tunnelPort,
  -                              null, null);
  +                              null, tcpNoDelay);
       }
   
       /**
  @@ -131,12 +140,68 @@
                                           String tunnelAuth, Boolean tcpNoDelay)
           throws IOException, UnknownHostException {
   
  +        return buildSSLSocket(host, port, 0,
  +                              tunnelHost, tunnelPort,
  +                              tunnelAuth, tcpNoDelay);
  +    }
  +
  +    /**
  +     * Builds an SSL socket, after auto-starting SSL.
  +     *
  +     * @param host The host to which to connect.
  +     * @param port The port to which to connect.
  +     * @param timeout The maximum amount of time to wait to connect (0 for no timeout).
  +     * @param tunnelHost The host to which to tunnel through.
  +     * @param tunnelPort The port to which to tunnel through.
  +     * @param tunnelAuth The authentication string for the tunnel.
  +     * @param tcpNoDelay Whether or not to disable Nagling.
  +     *
  +     * @return The socket.
  +     */
  +    public static Socket buildSSLSocket(String host, int port, int timeout,
  +                                        String tunnelHost, int tunnelPort,
  +                                        String tunnelAuth, Boolean tcpNoDelay)
  +        throws IOException, UnknownHostException {
  +
           SSLSocket sslSocket =  null;
           SSLSocketFactory factory =
               (SSLSocketFactory)SSLSocketFactory.getDefault();
   
           if (tunnelHost == null) {
  -            sslSocket = (SSLSocket) factory.createSocket(host, port);
  +            if (timeout == 0) {
  +                sslSocket = (SSLSocket) factory.createSocket(host, port);
  +            } else {
  +                // for J2SE 1.4 and later, use Socket#connect to implement
  +                // timeout on the connect
  +                try {
  +                    Method createSocket = SSLSocketFactory.class.getMethod(
  +                                            "createSocket", new Class[]{});
  +                    Class socketAddress = Class.forName("java.net.SocketAddress");
  +                    Method connect = SSLSocket.class.getMethod("connect",
  +                                            new Class[]{socketAddress, int.class});
  +                    Class inetSocketAddress = Class.forName("java.net.InetSocketAddress");
  +                    Constructor ctor = inetSocketAddress.getConstructor(
  +                                            new Class[]{String.class, int.class});
  +
  +                    sslSocket = (SSLSocket) createSocket.invoke(null, 
  +                                                        new Object[]{});
  +                    Object address = ctor.newInstance(new Object[]{
  +                                                        host, new Integer(port)});
  +                    connect.invoke(sslSocket, new Object[]{address,
  +                                                        new Integer(timeout)});
  +                } catch (ClassNotFoundException e) {
  +                    sslSocket = (SSLSocket) factory.createSocket(host, port);
  +                } catch (InstantiationException e) {
  +                    sslSocket = (SSLSocket) factory.createSocket(host, port);
  +                } catch (NoSuchMethodException e) {
  +                    sslSocket = (SSLSocket) factory.createSocket(host, port);
  +                } catch (InvocationTargetException e) {
  +                    sslSocket = (SSLSocket) factory.createSocket(host, port);
  +                } catch (IllegalAccessException e) {
  +                    sslSocket = (SSLSocket) factory.createSocket(host, port);
  +                }
  +            }
  +
               if (sslSocket != null && tcpNoDelay != null)
                   sslSocket.setTcpNoDelay(tcpNoDelay.booleanValue());
           } else {
  @@ -147,7 +212,7 @@
                * over the top of it.
                */
               Socket tunnel = doTunnelHandshake(tunnelHost, tunnelPort, tunnelAuth,
  -                                              host, port, tcpNoDelay);
  +                                              host, port, timeout, tcpNoDelay);
   
               // Overlay tunnel socket with SSL
               sslSocket = (SSLSocket) factory.createSocket(tunnel, host, port, true);
  @@ -168,16 +233,16 @@
            */
           sslSocket.startHandshake();   
   
  -        return sslSocket;  
  +        return (Socket) sslSocket;  
       }
   
       static private Socket doTunnelHandshake(String tunnelHost, int tunnelPort,
                                               String tunnelAuth,
  -                                            String host, int port,
  +                                            String host, int port, int timeout,
                                               Boolean tcpNoDelay)
               throws IOException {
   
  -        Socket tunnel = new Socket(tunnelHost, tunnelPort);
  +        Socket tunnel = SocketUtils.createSocket(tunnelHost, tunnelPort, timeout);
           if (tunnel != null && tcpNoDelay != null)
               tunnel.setTcpNoDelay(tcpNoDelay.booleanValue());
   
  
  
  
  1.1                  xml-soap/java/src/org/apache/soap/util/net/SocketUtils.java
  
  Index: SocketUtils.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "SOAP" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2000, International
   * Business Machines, Inc., http://www.apache.org.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.soap.util.net;
  
  import java.io.IOException;
  import java.lang.reflect.Constructor;
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import java.net.Socket;
  import java.net.UnknownHostException;
  
  /**
   * Socket utility functions.
   *
   * @author Scott Nichol (snichol@computer.org)
   */
  public class SocketUtils {
      /**
       * Creates a connected TCP socket.
       *
       * @param host The host to which to connect.
       * @param port The port to which to connect.
       * @param timeout The maximum amount of time to wait to connect (0 for no timeout).
       *                The timeout will only be enforced for J2SE 1.4 and later.
       * @exception UnknownHostException
       * @exception IOException
       */
      public static Socket createSocket(String host, int port, int timeout)
              throws UnknownHostException, IOException {
          Socket s;
  
          if (timeout == 0) {
              s = new Socket(host, port);
          } else {
              // for J2SE 1.4 and later, use Socket#connect to implement
              // timeout on the connect
              try {
                  Class socketAddress = Class.forName("java.net.SocketAddress");
                  Method connect = Socket.class.getMethod("connect",
                                          new Class[]{socketAddress, int.class});
                  s = (Socket) Socket.class.newInstance();
                  Class inetSocketAddress = Class.forName("java.net.InetSocketAddress");
                  Constructor ctor = inetSocketAddress.getConstructor(
                                          new Class[]{String.class, int.class});
                  Object address = ctor.newInstance(new Object[]{host, new Integer(port)});
                  connect.invoke(s, new Object[]{address, new Integer(timeout)});
              } catch (ClassNotFoundException e) {
                  s = new Socket(host, port);
              } catch (InstantiationException e) {
                  s = new Socket(host, port);
              } catch (NoSuchMethodException e) {
                  s = new Socket(host, port);
              } catch (InvocationTargetException e) {
                  s = new Socket(host, port);
              } catch (IllegalAccessException e) {
                  s = new Socket(host, port);
              }
          }
  
          return s;
      }
  }
  
  
  

--
To unsubscribe, e-mail:   <ma...@xml.apache.org>
For additional commands, e-mail: <ma...@xml.apache.org>