You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xmlrpc-dev@ws.apache.org by jo...@apache.org on 2005/05/24 23:05:39 UTC

cvs commit: ws-xmlrpc/src/java/org/apache/xmlrpc/server XmlRpcStreamServer.java

jochen      2005/05/24 14:05:39

  Modified:    src/java/org/apache/xmlrpc/util Tag: b20050512_streaming
                        HttpUtil.java
               src/java/org/apache/xmlrpc/client Tag: b20050512_streaming
                        XmlRpcLocalStreamTransport.java
               .        Tag: b20050512_streaming .classpath
               src/java/org/apache/xmlrpc/webserver Tag:
                        b20050512_streaming ConnectionServer.java
                        Connection.java
               src/java/org/apache/xmlrpc Tag: b20050512_streaming
                        XmlRpcException.java
               src/test/org/apache/xmlrpc/test Tag: b20050512_streaming
                        BaseTest.java
               src/java/org/apache/xmlrpc/server Tag: b20050512_streaming
                        XmlRpcStreamServer.java
  Added:       src/java/org/apache/xmlrpc/webserver Tag:
                        b20050512_streaming XmlRpcServletServer.java
                        XmlRpcServlet.java
  Log:
  Created the (yet untested) XmlRpcServlet.
  
  Revision  Changes    Path
  No                   revision
  No                   revision
  1.4.2.4   +55 -1     ws-xmlrpc/src/java/org/apache/xmlrpc/util/HttpUtil.java
  
  Index: HttpUtil.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/util/HttpUtil.java,v
  retrieving revision 1.4.2.3
  retrieving revision 1.4.2.4
  diff -u -r1.4.2.3 -r1.4.2.4
  --- HttpUtil.java	22 May 2005 20:52:27 -0000	1.4.2.3
  +++ HttpUtil.java	24 May 2005 21:05:38 -0000	1.4.2.4
  @@ -18,9 +18,11 @@
   import java.io.IOException;
   import java.io.InputStream;
   import java.io.UnsupportedEncodingException;
  +import java.util.Enumeration;
   import java.util.StringTokenizer;
   
   import org.apache.ws.commons.util.Base64;
  +import org.apache.xmlrpc.common.XmlRpcHttpRequestConfigImpl;
   import org.apache.xmlrpc.common.XmlRpcStreamConfig;
   
   
  @@ -47,7 +49,7 @@
   
   	/** Returns, whether the HTTP header value <code>pHeaderValue</code>
   	 * indicates, that GZIP encoding is used or may be used.
  -	 * @param pHeaderValue The HTTP header value being parser. This is typically
  +	 * @param pHeaderValue The HTTP header value being parsed. This is typically
   	 * the value of "Content-Encoding", or "Accept-Encoding".
   	 * @return True, if the header value suggests that GZIP encoding is or may
   	 * be used.
  @@ -69,6 +71,24 @@
           return false;
       }
   
  +	/** Returns, whether the HTTP header values in <code>pValues</code>
  +	 * indicate, that GZIP encoding is used or may be used.
  +	 * @param pValues The HTTP header values being parsed. These are typically
  +	 * the values of "Content-Encoding", or "Accept-Encoding".
  +	 * @return True, if the header values suggests that GZIP encoding is or may
  +	 * be used.
  +	 */
  +	public static boolean isUsingGzipEncoding(Enumeration pValues) {
  +		if (pValues != null) {
  +			while (pValues.hasMoreElements()) {
  +				if (isUsingGzipEncoding((String) pValues.nextElement())) {
  +					return true;
  +				}
  +			}
  +		}
  +		return false;
  +    }
  +
   	/** Reads a header line from the input stream <code>pIn</code>
   	 * and converts it into a string.
   	 * @param pIn The input stream being read.
  @@ -95,4 +115,38 @@
           }
           return new String(pBuffer, 0, count);
       }
  +
  +	/** Parses an "Authorization" header and adds the username and password
  +	 * to <code>pConfig</code>.
  +	 * @param pConfig The request configuration being created.
  +	 * @param pLine The header being parsed, including the "basic" part.
  +	 */
  +	public static void parseAuthorization(XmlRpcHttpRequestConfigImpl pConfig, String pLine) {
  +		if (pLine == null) {
  +			return;
  +		}
  +		pLine = pLine.trim();
  +		StringTokenizer st = new StringTokenizer(pLine);
  +		if (!st.hasMoreTokens()) {
  +			return;
  +		}
  +		String type = st.nextToken();
  +		if (!"basic".equalsIgnoreCase(type)) {
  +			return;
  +		}
  +		if (!st.hasMoreTokens()) {
  +			return;
  +		}
  +		String auth = st.nextToken();
  +	    try {
  +	        byte[] c = Base64.decode(auth.toCharArray(), 0, auth.length());
  +	        String str = new String(c, pConfig.getBasicEncoding());
  +	        int col = str.indexOf(':');
  +			if (col >= 0) {
  +				pConfig.setBasicUserName(str.substring(0, col));
  +				pConfig.setBasicPassword(str.substring(col+1));
  +			}
  +	    } catch (Throwable ignore) {
  +	    }
  +	}
   }
  
  
  
  No                   revision
  No                   revision
  1.1.2.3   +2 -2      ws-xmlrpc/src/java/org/apache/xmlrpc/client/Attic/XmlRpcLocalStreamTransport.java
  
  Index: XmlRpcLocalStreamTransport.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/client/Attic/XmlRpcLocalStreamTransport.java,v
  retrieving revision 1.1.2.2
  retrieving revision 1.1.2.3
  diff -u -r1.1.2.2 -r1.1.2.3
  --- XmlRpcLocalStreamTransport.java	21 May 2005 02:37:08 -0000	1.1.2.2
  +++ XmlRpcLocalStreamTransport.java	24 May 2005 21:05:38 -0000	1.1.2.3
  @@ -43,11 +43,11 @@
   			XmlRpcServer server = ((XmlRpcLocalClientConfig) pRequest.getConfig()).getXmlRpcServer();
   			return server.execute(pRequest);
   		}
  -		protected InputStream getInputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws IOException {
  +		protected InputStream newInputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws IOException {
   			LocalStreamConnection lsc = (LocalStreamConnection) pConnection;
   			return new ByteArrayInputStream(lsc.ostream.toByteArray());
   		}
  -		protected OutputStream getOutputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws IOException {
  +		protected OutputStream newOutputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws IOException {
   			LocalStreamConnection lsc = (LocalStreamConnection) pConnection;
   			lsc.istream = new ByteArrayOutputStream();
   			return lsc.istream;
  
  
  
  No                   revision
  No                   revision
  1.4.2.4   +1 -0      ws-xmlrpc/.classpath
  
  Index: .classpath
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/.classpath,v
  retrieving revision 1.4.2.3
  retrieving revision 1.4.2.4
  diff -u -r1.4.2.3 -r1.4.2.4
  --- .classpath	21 May 2005 22:01:24 -0000	1.4.2.3
  +++ .classpath	24 May 2005 21:05:38 -0000	1.4.2.4
  @@ -9,5 +9,6 @@
   	<classpathentry kind="lib" path="lib/commons-httpclient-2.0.2.jar"/>
   	<classpathentry kind="lib" path="lib/commons-logging.jar"/>
   	<classpathentry kind="lib" path="lib/jaxmeapi-0.4.jar"/>
  +	<classpathentry kind="lib" path="lib/servletapi-2.2.jar"/>
   	<classpathentry kind="output" path="bin"/>
   </classpath>
  
  
  
  No                   revision
  No                   revision
  1.1.2.2   +2 -2      ws-xmlrpc/src/java/org/apache/xmlrpc/webserver/Attic/ConnectionServer.java
  
  Index: ConnectionServer.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/webserver/Attic/ConnectionServer.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- ConnectionServer.java	12 May 2005 01:58:53 -0000	1.1.2.1
  +++ ConnectionServer.java	24 May 2005 21:05:38 -0000	1.1.2.2
  @@ -58,11 +58,11 @@
   		}
   	}
   
  -	protected InputStream getInputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws IOException {
  +	protected InputStream newInputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws IOException {
   		return ((Connection) pConnection).getInputStream((RequestData) pConfig);
   	}
   
  -	protected OutputStream getOutputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws IOException {
  +	protected OutputStream newOutputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws IOException {
   		return ((Connection) pConnection).getOutputStream(pConfig);
   	}
   
  
  
  
  1.1.2.5   +7 -23     ws-xmlrpc/src/java/org/apache/xmlrpc/webserver/Attic/Connection.java
  
  Index: Connection.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/webserver/Attic/Connection.java,v
  retrieving revision 1.1.2.4
  retrieving revision 1.1.2.5
  diff -u -r1.1.2.4 -r1.1.2.5
  --- Connection.java	22 May 2005 20:52:27 -0000	1.1.2.4
  +++ Connection.java	24 May 2005 21:05:38 -0000	1.1.2.5
  @@ -25,13 +25,14 @@
   import java.net.Socket;
   import java.util.StringTokenizer;
   
  -import org.apache.ws.commons.util.Base64;
  +import javax.servlet.http.HttpUtils;
  +
   import org.apache.xmlrpc.common.XmlRpcHttpRequestConfig;
  -import org.apache.xmlrpc.common.XmlRpcHttpRequestConfigImpl;
   import org.apache.xmlrpc.common.XmlRpcNotAuthorizedException;
   import org.apache.xmlrpc.common.XmlRpcStreamRequestConfig;
   import org.apache.xmlrpc.server.XmlRpcHttpServerConfig;
   import org.apache.xmlrpc.server.XmlRpcStreamServer;
  +import org.apache.xmlrpc.util.HttpUtil;
   import org.apache.xmlrpc.util.LimitedInputStream;
   import org.apache.xmlrpc.util.ThreadPool;
   
  @@ -148,9 +149,9 @@
   				} else if (lineLower.startsWith("connection:")) {
   					result.setKeepAlive(serverConfig.isKeepAliveEnabled()
   										&&  lineLower.indexOf("keep-alive") > -1);
  -				} else if (lineLower.startsWith("authorization: basic ")) {
  -					String credentials = line.substring("authorization: basic ".length());
  -					parseAuth(result, credentials);
  +				} else if (lineLower.startsWith("authorization:")) {
  +					String credentials = line.substring("authorization:".length());
  +					HttpUtil.parseAuthorization(result, credentials);
   				}
   			}
   		}
  @@ -200,24 +201,7 @@
           return new String(buffer, 0, count, US_ASCII);
       }
   
  -    /**
  -     *
  -     * @param line
  -     */
  -    private void parseAuth(XmlRpcHttpRequestConfigImpl pConfig, String pLine) {
  -        try {
  -            byte[] c = Base64.decode(pLine.toCharArray(), 0, pLine.length());
  -            String str = new String(c, pConfig.getBasicEncoding());
  -            int col = str.indexOf(':');
  -			if (col >= 0) {
  -				pConfig.setBasicUserName(str.substring(0, col));
  -				pConfig.setBasicPassword(str.substring(col+1));
  -			}
  -        } catch (Throwable ignore) {
  -        }
  -    }
  -
  -	/** Returns the contents input stream.
  +    /** Returns the contents input stream.
   	 * @param pData The request data
   	 * @return The contents input stream.
   	 */
  
  
  
  No                   revision
  
  Index: Connection.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/webserver/Attic/Connection.java,v
  retrieving revision 1.1.2.4
  retrieving revision 1.1.2.5
  diff -u -r1.1.2.4 -r1.1.2.5
  --- Connection.java	22 May 2005 20:52:27 -0000	1.1.2.4
  +++ Connection.java	24 May 2005 21:05:38 -0000	1.1.2.5
  @@ -25,13 +25,14 @@
   import java.net.Socket;
   import java.util.StringTokenizer;
   
  -import org.apache.ws.commons.util.Base64;
  +import javax.servlet.http.HttpUtils;
  +
   import org.apache.xmlrpc.common.XmlRpcHttpRequestConfig;
  -import org.apache.xmlrpc.common.XmlRpcHttpRequestConfigImpl;
   import org.apache.xmlrpc.common.XmlRpcNotAuthorizedException;
   import org.apache.xmlrpc.common.XmlRpcStreamRequestConfig;
   import org.apache.xmlrpc.server.XmlRpcHttpServerConfig;
   import org.apache.xmlrpc.server.XmlRpcStreamServer;
  +import org.apache.xmlrpc.util.HttpUtil;
   import org.apache.xmlrpc.util.LimitedInputStream;
   import org.apache.xmlrpc.util.ThreadPool;
   
  @@ -148,9 +149,9 @@
   				} else if (lineLower.startsWith("connection:")) {
   					result.setKeepAlive(serverConfig.isKeepAliveEnabled()
   										&&  lineLower.indexOf("keep-alive") > -1);
  -				} else if (lineLower.startsWith("authorization: basic ")) {
  -					String credentials = line.substring("authorization: basic ".length());
  -					parseAuth(result, credentials);
  +				} else if (lineLower.startsWith("authorization:")) {
  +					String credentials = line.substring("authorization:".length());
  +					HttpUtil.parseAuthorization(result, credentials);
   				}
   			}
   		}
  @@ -200,24 +201,7 @@
           return new String(buffer, 0, count, US_ASCII);
       }
   
  -    /**
  -     *
  -     * @param line
  -     */
  -    private void parseAuth(XmlRpcHttpRequestConfigImpl pConfig, String pLine) {
  -        try {
  -            byte[] c = Base64.decode(pLine.toCharArray(), 0, pLine.length());
  -            String str = new String(c, pConfig.getBasicEncoding());
  -            int col = str.indexOf(':');
  -			if (col >= 0) {
  -				pConfig.setBasicUserName(str.substring(0, col));
  -				pConfig.setBasicPassword(str.substring(col+1));
  -			}
  -        } catch (Throwable ignore) {
  -        }
  -    }
  -
  -	/** Returns the contents input stream.
  +    /** Returns the contents input stream.
   	 * @param pData The request data
   	 * @return The contents input stream.
   	 */
  
  
  
  No                   revision
  
  Index: Connection.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/webserver/Attic/Connection.java,v
  retrieving revision 1.1.2.4
  retrieving revision 1.1.2.5
  diff -u -r1.1.2.4 -r1.1.2.5
  --- Connection.java	22 May 2005 20:52:27 -0000	1.1.2.4
  +++ Connection.java	24 May 2005 21:05:38 -0000	1.1.2.5
  @@ -25,13 +25,14 @@
   import java.net.Socket;
   import java.util.StringTokenizer;
   
  -import org.apache.ws.commons.util.Base64;
  +import javax.servlet.http.HttpUtils;
  +
   import org.apache.xmlrpc.common.XmlRpcHttpRequestConfig;
  -import org.apache.xmlrpc.common.XmlRpcHttpRequestConfigImpl;
   import org.apache.xmlrpc.common.XmlRpcNotAuthorizedException;
   import org.apache.xmlrpc.common.XmlRpcStreamRequestConfig;
   import org.apache.xmlrpc.server.XmlRpcHttpServerConfig;
   import org.apache.xmlrpc.server.XmlRpcStreamServer;
  +import org.apache.xmlrpc.util.HttpUtil;
   import org.apache.xmlrpc.util.LimitedInputStream;
   import org.apache.xmlrpc.util.ThreadPool;
   
  @@ -148,9 +149,9 @@
   				} else if (lineLower.startsWith("connection:")) {
   					result.setKeepAlive(serverConfig.isKeepAliveEnabled()
   										&&  lineLower.indexOf("keep-alive") > -1);
  -				} else if (lineLower.startsWith("authorization: basic ")) {
  -					String credentials = line.substring("authorization: basic ".length());
  -					parseAuth(result, credentials);
  +				} else if (lineLower.startsWith("authorization:")) {
  +					String credentials = line.substring("authorization:".length());
  +					HttpUtil.parseAuthorization(result, credentials);
   				}
   			}
   		}
  @@ -200,24 +201,7 @@
           return new String(buffer, 0, count, US_ASCII);
       }
   
  -    /**
  -     *
  -     * @param line
  -     */
  -    private void parseAuth(XmlRpcHttpRequestConfigImpl pConfig, String pLine) {
  -        try {
  -            byte[] c = Base64.decode(pLine.toCharArray(), 0, pLine.length());
  -            String str = new String(c, pConfig.getBasicEncoding());
  -            int col = str.indexOf(':');
  -			if (col >= 0) {
  -				pConfig.setBasicUserName(str.substring(0, col));
  -				pConfig.setBasicPassword(str.substring(col+1));
  -			}
  -        } catch (Throwable ignore) {
  -        }
  -    }
  -
  -	/** Returns the contents input stream.
  +    /** Returns the contents input stream.
   	 * @param pData The request data
   	 * @return The contents input stream.
   	 */
  
  
  
  1.1.2.1   +128 -0    ws-xmlrpc/src/java/org/apache/xmlrpc/webserver/Attic/XmlRpcServletServer.java
  
  
  
  
  1.1.2.1   +82 -0     ws-xmlrpc/src/java/org/apache/xmlrpc/webserver/Attic/XmlRpcServlet.java
  
  
  
  
  No                   revision
  No                   revision
  1.3.2.2   +8 -0      ws-xmlrpc/src/java/org/apache/xmlrpc/XmlRpcException.java
  
  Index: XmlRpcException.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/XmlRpcException.java,v
  retrieving revision 1.3.2.1
  retrieving revision 1.3.2.2
  diff -u -r1.3.2.1 -r1.3.2.2
  --- XmlRpcException.java	12 May 2005 01:58:52 -0000	1.3.2.1
  +++ XmlRpcException.java	24 May 2005 21:05:38 -0000	1.3.2.2
  @@ -58,6 +58,14 @@
   		this(0, pMessage, pLinkedException);
       }
   
  +    /** Creates a new instance with the given error message
  +     * and error code 0.
  +     * @param pMessage Detail message.
  +     */
  +    public XmlRpcException(String pMessage) {
  +		this(0, pMessage, null);
  +    }
  +
       /** Creates a new instance with the given error code, error message
        * and cause.
        * @param pCode Error code.
  
  
  
  No                   revision
  No                   revision
  1.1.2.5   +0 -1      ws-xmlrpc/src/test/org/apache/xmlrpc/test/Attic/BaseTest.java
  
  Index: BaseTest.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/test/org/apache/xmlrpc/test/Attic/BaseTest.java,v
  retrieving revision 1.1.2.4
  retrieving revision 1.1.2.5
  diff -u -r1.1.2.4 -r1.1.2.5
  --- BaseTest.java	23 May 2005 06:11:14 -0000	1.1.2.4
  +++ BaseTest.java	24 May 2005 21:05:39 -0000	1.1.2.5
  @@ -17,7 +17,6 @@
   
   import java.io.IOException;
   import java.io.StringReader;
  -import java.text.DateFormat;
   import java.text.DecimalFormat;
   import java.text.NumberFormat;
   import java.util.Arrays;
  
  
  
  No                   revision
  No                   revision
  1.1.2.5   +79 -8     ws-xmlrpc/src/java/org/apache/xmlrpc/server/Attic/XmlRpcStreamServer.java
  
  Index: XmlRpcStreamServer.java
  ===================================================================
  RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/server/Attic/XmlRpcStreamServer.java,v
  retrieving revision 1.1.2.4
  retrieving revision 1.1.2.5
  diff -u -r1.1.2.4 -r1.1.2.5
  --- XmlRpcStreamServer.java	14 May 2005 21:17:49 -0000	1.1.2.4
  +++ XmlRpcStreamServer.java	24 May 2005 21:05:39 -0000	1.1.2.5
  @@ -15,10 +15,13 @@
    */
   package org.apache.xmlrpc.server;
   
  +import java.io.ByteArrayOutputStream;
   import java.io.IOException;
   import java.io.InputStream;
   import java.io.OutputStream;
   import java.util.List;
  +import java.util.zip.GZIPInputStream;
  +import java.util.zip.GZIPOutputStream;
   
   import javax.xml.parsers.ParserConfigurationException;
   import javax.xml.parsers.SAXParserFactory;
  @@ -133,18 +136,55 @@
   
   	/** Returns the connections input stream.
   	 */
  -	protected abstract InputStream getInputStream(XmlRpcStreamRequestConfig pConfig,
  +	protected abstract InputStream newInputStream(XmlRpcStreamRequestConfig pConfig,
   												  Object pConnection) throws IOException;
   
  -	/** Returns the connections output stream.
  +	protected InputStream getInputStream(XmlRpcStreamRequestConfig pConfig,
  +										 Object pConnection) throws IOException {
  +		InputStream istream = newInputStream(pConfig, pConnection);
  +		if (pConfig.isEnabledForExtensions()  &&  pConfig.isGzipCompressing()) {
  +			istream = new GZIPInputStream(istream);
  +		}
  +		return istream;
  +	}
  +
  +	/** Creates the connections output stream.
   	 */
  -	protected abstract OutputStream getOutputStream(XmlRpcStreamRequestConfig pConfig,
  +	protected abstract OutputStream newOutputStream(XmlRpcStreamRequestConfig pConfig,
   												    Object pConnection) throws IOException;
   
  +	/** Called to prepare the output stream. Typically used for enabling
  +	 * compression, or similar filters.
  +	 */
  +	protected OutputStream getOutputStream(XmlRpcStreamRequestConfig pConfig,
  +										   OutputStream pStream) throws IOException {
  +		if (pConfig.isEnabledForExtensions()  &&  pConfig.isGzipRequesting()) {
  +			return new GZIPOutputStream(pStream);
  +		} else {
  +			return pStream;
  +		}
  +	}
  +
  +	/** Called to prepare the output stream, if content length is
  +	 * required.
  +	 */
  +	protected OutputStream getOutputStream(XmlRpcStreamRequestConfig pConfig,
  +										   Object pConnection,
  +										   int pSize) throws IOException {
  +		return newOutputStream(pConfig, pConnection);
  +	}
  +
  +	/** Returns, whether the requests content length is required.
  +	 */
  +	protected boolean isContentLengthRequired(XmlRpcStreamRequestConfig pConfig) {
  +		return false;
  +	}
  +
   	/** Closes the connection, releasing all resources.
   	 */
   	protected abstract void closeConnection(Object pConnection) throws IOException;
   
  +	/** Returns, whether the 
   	/** Processes a "connection". The "connection" is an opaque object, which is
   	 * being handled by the subclasses.
   	 * @param pConfig The request configuration.
  @@ -158,20 +198,51 @@
   		try {
   			Object result;
   			Throwable error;
  +			InputStream istream = null;
   			try {
  -				InputStream istream = getInputStream(pConfig, pConnection);
  +				istream = getInputStream(pConfig, pConnection);
   				XmlRpcRequest request = getRequest(pConfig, istream);
   				result = execute(request);
  +				istream.close();
  +				istream = null;
   				error = null;
   			} catch (Throwable t) {
   				result = null;
   				error = t;
  +			} finally {
  +				if (istream != null) { try { istream.close(); } catch (Throwable ignore) {} }
   			}
  -			OutputStream ostream = getOutputStream(pConfig, pConnection);
  -			if (error == null) {
  -				writeResponse(pConfig, ostream, result);
  +			boolean contentLengthRequired = isContentLengthRequired(pConfig);
  +			ByteArrayOutputStream baos;
  +			OutputStream ostream;
  +			if (contentLengthRequired) {
  +				baos = new ByteArrayOutputStream();
  +				ostream = baos;
   			} else {
  -				writeError(pConfig, ostream, error);
  +				baos = null;
  +				ostream = newOutputStream(pConfig, pConnection);
  +			}
  +			ostream = getOutputStream(pConfig, ostream);
  +			try {
  +				if (error == null) {
  +					writeResponse(pConfig, ostream, result);
  +				} else {
  +					writeError(pConfig, ostream, error);
  +				}
  +				ostream.close();
  +				ostream = null;
  +			} finally {
  +				if (ostream != null) { try { ostream.close(); } catch (Throwable ignore) {} }
  +			}
  +			if (baos != null) {
  +				OutputStream dest = getOutputStream(pConfig, pConnection, baos.size());
  +				try {
  +					baos.writeTo(dest);
  +					dest.close();
  +					dest = null;
  +				} finally {
  +					if (dest != null) { try { dest.close(); } catch (Throwable ignore) {} }
  +				}
   			}
   			closeConnection(pConnection);
   			pConnection = null;