FYI, this addresses the connect timeout question raised by Mike Ladwig. Scott Nichol
----- Original Message ----- From: <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Friday, December 20, 2002 4:40 PM Subject: 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 [EMAIL PROTECTED] > * > * 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 ([EMAIL PROTECTED]) > */ > 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: <mailto:[EMAIL PROTECTED]> > For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> > > -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>