aevers 2005/03/30 03:19:18
Modified: src/java/org/apache/xmlrpc CommonsXmlRpcTransport.java DefaultXmlRpcTransport.java LiteXmlRpcTransport.java XmlRpc.java XmlRpcClientWorker.java XmlRpcTransport.java Log: Bug 20339: LiteXmlRpcTransport throws IOExcpetion 'socket closed' Fix general resource leaks regarding connections in client side transpot code. There is now an endClientRequest() in the XmlRpcTransport interface. Appropriate implementations have been filled in for all shipped transports. Passes all tests except Base64 (was already broken). Note, for tests to pass you must have commons-logging installed as it is used by commons-httpclient. PR: 20339 Revision Changes Path 1.3 +28 -10 ws-xmlrpc/src/java/org/apache/xmlrpc/CommonsXmlRpcTransport.java Index: CommonsXmlRpcTransport.java =================================================================== RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/CommonsXmlRpcTransport.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- CommonsXmlRpcTransport.java 26 Dec 2003 16:57:51 -0000 1.2 +++ CommonsXmlRpcTransport.java 30 Mar 2005 11:19:18 -0000 1.3 @@ -76,20 +76,28 @@ * @version $Id$ * @since 1.2 */ -public class CommonsXmlRpcTransport implements XmlRpcTransport { +public class CommonsXmlRpcTransport implements XmlRpcTransport +{ + protected PostMethod method; + /** Creates a new instance of CommonsXmlRpcTransport */ - public CommonsXmlRpcTransport(URL url, HttpClient client) { + public CommonsXmlRpcTransport(URL url, HttpClient client) + { this.url = url; - if (client == null) { + if (client == null) + { HttpClient newClient = new HttpClient(); this.client = newClient; - } else { + } + else + { this.client = client; } } - public CommonsXmlRpcTransport(URL url) { + public CommonsXmlRpcTransport(URL url) + { this(url, null); } @@ -98,8 +106,9 @@ private final Header userAgentHeader = new Header("User-Agent", XmlRpc.version); private boolean http11 = false; // defaults to HTTP 1.0 - public InputStream sendXmlRpc(byte[] request) throws IOException, XmlRpcClientException { - PostMethod method = new PostMethod(url.toString()); + public InputStream sendXmlRpc(byte[] request) throws IOException, XmlRpcClientException + { + method = new PostMethod(url.toString()); method.setHttp11(http11); method.setRequestHeader(new Header("Content-Type", "text/xml")); method.setRequestHeader(userAgentHeader); @@ -112,11 +121,20 @@ return method.getResponseBodyAsStream(); } - public void setHttp11(boolean http11) { + public void setHttp11(boolean http11) + { this.http11 = http11; } - public void setUserAgent(String userAgent) { + public void setUserAgent(String userAgent) + { userAgentHeader.setValue(userAgent); } + + public void endClientRequest() + throws XmlRpcClientException + { + // Rlease connection resources + method.releaseConnection(); + } } 1.3 +16 -2 ws-xmlrpc/src/java/org/apache/xmlrpc/DefaultXmlRpcTransport.java Index: DefaultXmlRpcTransport.java =================================================================== RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/DefaultXmlRpcTransport.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- DefaultXmlRpcTransport.java 29 Jan 2003 00:46:37 -0000 1.2 +++ DefaultXmlRpcTransport.java 30 Mar 2005 11:19:18 -0000 1.3 @@ -75,6 +75,7 @@ { protected URL url; protected String auth; + protected URLConnection con; /** * Create a new DefaultXmlRpcTransport with the specified URL and basic @@ -104,7 +105,7 @@ public InputStream sendXmlRpc(byte [] request) throws IOException { - URLConnection con = url.openConnection(); + con = url.openConnection(); con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); @@ -133,4 +134,17 @@ { auth = HttpUtil.encodeBasicAuthentication(user, password); } + + public void endClientRequest() + throws XmlRpcClientException + { + try + { + con.getInputStream().close(); + } + catch (Exception e) + { + throw new XmlRpcClientException("Exception closing URLConnection", e); + } + } } 1.4 +10 -7 ws-xmlrpc/src/java/org/apache/xmlrpc/LiteXmlRpcTransport.java Index: LiteXmlRpcTransport.java =================================================================== RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/LiteXmlRpcTransport.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- LiteXmlRpcTransport.java 1 May 2003 16:53:15 -0000 1.3 +++ LiteXmlRpcTransport.java 30 Mar 2005 11:19:18 -0000 1.4 @@ -147,12 +147,6 @@ } } - // eepalive is always false if XmlRpc.keepalive is false - if (!keepalive) - { - closeConnection (); - } - return in; } catch (IOException iox) @@ -326,6 +320,15 @@ auth = HttpUtil.encodeBasicAuthentication(user, password); } + public void endClientRequest() + { + // eepalive is always false if XmlRpc.keepalive is false + if (!keepalive) + { + closeConnection (); + } + } + /** * * @return 1.38 +41 -2 ws-xmlrpc/src/java/org/apache/xmlrpc/XmlRpc.java Index: XmlRpc.java =================================================================== RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/XmlRpc.java,v retrieving revision 1.37 retrieving revision 1.38 diff -u -r1.37 -r1.38 --- XmlRpc.java 30 Jun 2004 06:11:55 -0000 1.37 +++ XmlRpc.java 30 Mar 2005 11:19:18 -0000 1.38 @@ -56,6 +56,7 @@ */ import java.io.InputStream; +import java.io.InputStreamReader; import java.util.Hashtable; import java.util.Stack; import java.util.Vector; @@ -188,6 +189,15 @@ */ static String encoding = XmlWriter.ISO8859_1; + /** + * Java's name for the input encoding we're using. Defaults to + * <code>null</code>, signifying the platform default. This may + * need to be overridden on platforms where the default encoding + * is not compatible with ASCII (eg. EBCDIC) but the network is + * still ASCII-like. + */ + static String inputEncoding = null; + private TypeFactory typeFactory; /** @@ -342,6 +352,28 @@ } /** + * Set the input encoding of the XML. + * This is used only if set. + * + * @param enc The Java name of the encoding. + */ + public static void setInputEncoding(String enc) + { + inputEncoding = enc; + } + + /** + * Return the input encoding. This may be null. This is always a + * Java encoding name, it is not transformed. + * + * @return the Java encoding name to use, if set, otherwise null. + */ + public static String getInputEncoding () + { + return inputEncoding; + } + + /** * Gets the maximum number of threads used at any given moment. */ public static int getMaxThreads() @@ -440,7 +472,14 @@ } try { - parser.parse(new InputSource (is)); + if(inputEncoding == null) + { + parser.parse(new InputSource (is)); + } + else + { + parser.parse( new InputSource( new InputStreamReader(is, inputEncoding))); + } } finally { 1.2 +8 -0 ws-xmlrpc/src/java/org/apache/xmlrpc/XmlRpcClientWorker.java Index: XmlRpcClientWorker.java =================================================================== RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/XmlRpcClientWorker.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- XmlRpcClientWorker.java 5 Dec 2002 08:49:24 -0000 1.1 +++ XmlRpcClientWorker.java 30 Mar 2005 11:19:18 -0000 1.2 @@ -136,6 +136,14 @@ System.out.println("Spent " + (System.currentTimeMillis() - now) + " millis in request/process/response"); } + try + { + transport.endClientRequest(); + } + catch (RuntimeException re) + { + throw new XmlRpcClientException("Transport exception in endClientRequest()", re); + } } } 1.2 +19 -1 ws-xmlrpc/src/java/org/apache/xmlrpc/XmlRpcTransport.java Index: XmlRpcTransport.java =================================================================== RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/XmlRpcTransport.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- XmlRpcTransport.java 5 Dec 2002 08:49:24 -0000 1.1 +++ XmlRpcTransport.java 30 Mar 2005 11:19:18 -0000 1.2 @@ -68,6 +68,24 @@ */ public interface XmlRpcTransport { + /** + * Send an XML-RPC message. This method is called to send a message to the + * other party. + * + * @param request the request in network encoding. + * + * @throws IOException if an IOException occurs in the IO level of the transport. + * @throws XmlRpcClientException if an exception occurs in the transport. + */ public InputStream sendXmlRpc(byte [] request) throws IOException, XmlRpcClientException; + + /** + * End an XML-RPC request. This method is called by the XmlRpcClient when then + * request has been sent and the response (or an exception) recieved. + * + * @throws XmlRpcClientException if an exception occurs in the transport. + */ + public void endClientRequest() + throws XmlRpcClientException; }