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]>