This is the case where the message has a Content-Length header specifying 0 octets. I create the byte array of that length, but there is no reason to read, since I want 0 bytes, which is what I already have.
Scott Nichol ----- Original Message ----- From: "Pavel Ausianik" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Tuesday, November 12, 2002 10:53 AM Subject: RE: cvs commit: xml-soap/java/src/org/apache/soap/transport/http SOAPHTTPConnection.java > Scott, > > i don't know if this makes sence, but logic little bit strange, in case > contentLength=0. See buffer has been created, but as I can see it is not > used anymore since the following block finishes at the end. Should be there > condition to go inside and read from buffer? > > bytes = new byte[contentLength >= 0 ? contentLength : 4096]; > if (contentLength != 0) { > > Pavel > > > -----Original Message----- > > From: [EMAIL PROTECTED] [mailto:snichol@;apache.org] > > Sent: Tuesday, November 12, 2002 4:16 PM > > To: [EMAIL PROTECTED] > > Subject: cvs commit: xml-soap/java/src/org/apache/soap/transport/http > > SOAPHTTPConnection.java > > > > > > snichol 2002/11/12 06:15:38 > > > > Modified: java/src/org/apache/soap/util/net HTTPUtils.java > > java/src/org/apache/soap/transport > > TransportMessage.java > > java/src/org/apache/soap/transport/http > > SOAPHTTPConnection.java > > Log: > > Reduce the number of times a response is copied in part or in whole. > > Improve error reporting during response parsing. > > Support services that shutdown the write half of the socket > > rather than > > provide a Content-Length header. > > Add getEnvelope to SOAPHTTPConnection. (The method will > > also be added > > to SOAPTransport soon.) > > > > Revision Changes Path > > 1.36 +104 -82 > > 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.35 > > retrieving revision 1.36 > > diff -u -r1.35 -r1.36 > > --- HTTPUtils.java 18 Oct 2002 20:30:54 -0000 1.35 > > +++ HTTPUtils.java 12 Nov 2002 14:15:38 -0000 1.36 > > @@ -57,21 +57,30 @@ > > > > package org.apache.soap.util.net; > > > > -import java.io.*; > > -import java.lang.reflect.*; > > -import java.net.*; > > -import java.util.*; > > - > > -import javax.mail.*; > > -import javax.mail.internet.*; > > -import javax.activation.*; > > +import java.io.BufferedInputStream; > > +import java.io.BufferedOutputStream; > > +import java.io.BufferedReader; > > +import java.io.InputStream; > > +import java.io.IOException; > > +import java.io.OutputStream; > > +import java.io.UnsupportedEncodingException; > > +import java.lang.reflect.InvocationTargetException; > > +import java.lang.reflect.Method; > > +import java.net.HttpURLConnection; > > +import java.net.Socket; > > +import java.net.URL; > > +import java.util.Enumeration; > > +import java.util.Hashtable; > > +import java.util.StringTokenizer; > > > > -import org.apache.soap.*; > > +import javax.mail.MessagingException; > > + > > +import org.apache.soap.Constants; > > +import org.apache.soap.SOAPException; > > import org.apache.soap.encoding.soapenc.Base64; > > -import org.apache.soap.rpc.*; > > -import org.apache.soap.transport.*; > > +import org.apache.soap.rpc.SOAPContext; > > +import org.apache.soap.transport.TransportMessage; > > import org.apache.soap.util.MutableBoolean; > > -import org.apache.soap.util.mime.*; > > > > /** > > * A bunch of utility stuff for doing HTTP things. > > @@ -91,6 +100,7 @@ > > private static final String HTTP_VERSION = "1.0"; > > private static final int HTTP_DEFAULT_PORT = 80; > > private static final int HTTPS_DEFAULT_PORT = 443; > > + private static final String ISO_8859_1 = "8859_1"; > > > > public static final int DEFAULT_OUTPUT_BUFFER_SIZE = > > 8 * 1024; > > > > @@ -100,7 +110,7 @@ > > public static String encodeAuth(String userName, String password) > > throws SOAPException { > > try { > > - return Base64.encode((userName + ":" + > > password).getBytes("8859_1")); > > + return Base64.encode((userName + ":" + > > password).getBytes(ISO_8859_1)); > > } catch (UnsupportedEncodingException e) { > > throw new SOAPException > > (Constants.FAULT_CODE_CLIENT, e.getMessage(), e); > > } > > @@ -482,65 +492,93 @@ > > bOutStream.flush(); > > > > BufferedInputStream bInStream = new > > BufferedInputStream(inStream); > > + byte[] linebuf = new byte[1024]; > > + int count = 0; > > + int b; > > + > > /* Read the response status line. */ > > + String versionString = null; > > int statusCode = 0; > > String statusString = null; > > - StringBuffer linebuf = new StringBuffer(128); > > - int b = 0; > > - while (b != '\n' && b != -1) { > > - b = bInStream.read(); > > - if (b != '\n' && b != '\r' && b != -1) > > - linebuf.append((char)b); > > - } > > - String line = linebuf.toString(); > > + > > try { > > - StringTokenizer st = new StringTokenizer(line); > > - st.nextToken(); // ignore version part > > - statusCode = Integer.parseInt (st.nextToken()); > > - StringBuffer sb = new StringBuffer(128); > > - while (st.hasMoreTokens()) { > > - sb.append (st.nextToken()); > > - if (st.hasMoreTokens()) { > > - sb.append(" "); > > + int versionEnd = -1; > > + int codeStart = -1; > > + int codeEnd = -1; > > + int stringStart = -1; > > + > > + for (count = 0, b = bInStream.read(); b != '\n' > > && b != -1; b = bInStream.read()) { > > + if (b != '\r') { > > + if (b == ' ') { > > + if (versionEnd == -1) { > > + versionEnd = count; > > + } else if (codeStart != -1 && > > codeEnd == -1) { > > + codeEnd = count; > > + } > > + } else { > > + if (versionEnd != -1 && codeStart == -1) { > > + codeStart = count; > > + } else if (codeEnd != -1 && > > stringStart == -1) { > > + stringStart = count; > > + } > > + } > > + if (count >= linebuf.length) { > > + byte[] newbuf = new byte[linebuf.length * 2]; > > + System.arraycopy(linebuf, 0, newbuf, > > 0, linebuf.length); > > + linebuf = newbuf; > > + } > > + linebuf[count++] = (byte) b; > > } > > } > > - statusString = sb.toString(); > > - } > > - catch (Exception e) { > > + if (b == -1) > > + throw new Exception("Reached end of stream > > while reading HTTP response status"); > > + versionString = new String(linebuf, 0, > > versionEnd, ISO_8859_1); > > + statusCode = Integer.parseInt(new > > String(linebuf, codeStart, codeEnd - codeStart, ISO_8859_1)); > > + statusString = new String(linebuf, stringStart, > > count - stringStart, ISO_8859_1); > > + } catch (Exception e) { > > throw new SOAPException(Constants.FAULT_CODE_CLIENT, > > - "Error parsing HTTP status line \"" + line + > > "\": " + e, e); > > + "Error parsing HTTP status line \"" + new > > String(linebuf, 0, count, ISO_8859_1) + "\": " + e, e); > > } > > > > - /* Read the entire response (following the status line) > > - * into a byte array. */ > > - ByteArrayDataSource ds = new ByteArrayDataSource(bInStream, > > - Constants.HEADERVAL_DEFAULT_CHARSET); > > - > > - /* Extract the headers, content type and content length. */ > > - byte[] bytes = ds.toByteArray(); > > + /* Read the HTTP headers. */ > > Hashtable respHeaders = new Hashtable(); > > int respContentLength = -1; > > String respContentType = null; > > > > - int nameStart = 0; > > - int nameEnd = 0; > > - int valStart = 0; > > - boolean parsingName = true; > > - int offset; > > - > > - for (offset = 0; offset < bytes.length; offset++) { > > - if (bytes[offset] == '\n') { > > - if (nameStart >= nameEnd) > > + try { > > + // Read all headers > > + for (;;) { > > + // Read and parse one header > > + int nameEnd = -1; > > + int valStart = -1; > > + for (count = 0, b = bInStream.read(); b != > > '\n' && b != -1; b = bInStream.read()) { > > + if (b != '\r') { > > + if (nameEnd == -1 && b == ':') { > > + nameEnd = count; > > + } else if (nameEnd != -1 && valStart > > == -1 && b != ' ' & b != '\t') { > > + valStart = count; > > + } > > + if (count >= linebuf.length) { > > + byte[] newbuf = new > > byte[linebuf.length * 2]; > > + System.arraycopy(linebuf, 0, > > newbuf, 0, linebuf.length); > > + linebuf = newbuf; > > + } > > + linebuf[count++] = (byte) b; > > + } > > + } > > + if (b == -1) > > + throw new Exception("Reached end of > > stream while reading HTTP response header"); > > + if (count == 0) // Read the header/entity separator > > break; > > - String name = new String(bytes, nameStart, > > nameEnd-nameStart+1); > > - > > - // Remove trailing ; to prevent ContextType > > from throwing exception > > - int valueLen = offset - valStart -1; > > + if (nameEnd == -1 || valStart == -1) > > + throw new Exception("Incorrectly formed > > HTTP response header"); > > > > - if (valueLen > 0 && bytes[offset-1] == ';') > > - valueLen--; > > + String name = new String(linebuf, 0, > > nameEnd, ISO_8859_1); > > + // Remove trailing ; to prevent ContentType > > from throwing exception > > + if (linebuf[count - 1] == ';') > > + --count; > > + String value = new String(linebuf, valStart, > > count - valStart, ISO_8859_1); > > > > - String value = new String(bytes, valStart, valueLen); > > if > > (name.equalsIgnoreCase(Constants.HEADER_CONTENT_LENGTH)) > > respContentLength = Integer.parseInt(value); > > else if > > (name.equalsIgnoreCase(Constants.HEADER_CONTENT_TYPE)) > > @@ -556,27 +594,11 @@ > > } > > } > > } > > - parsingName = true; > > - nameStart = offset+1; > > } > > - else if (bytes[offset] != '\r') { > > - if (parsingName) { > > - if (bytes[offset] == ':') { > > - parsingName = false; > > - nameEnd = offset - 1; > > - if ((offset != bytes.length-1) && > > - bytes[offset+1] == ' ') > > - offset++; > > - valStart = offset+1; > > - } > > - } > > - } > > - } // End of for > > - > > - InputStream is = ds.getInputStream(); > > - is.skip(offset + 1); > > - if (respContentLength < 0) > > - respContentLength = ds.getSize() - offset - 1; > > + } catch (Exception e) { > > + throw new SOAPException(Constants.FAULT_CODE_CLIENT, > > + "Error parsing HTTP header line \"" + new > > String(linebuf, 0, count, ISO_8859_1) + "\": " + e, e); > > + } > > > > /* Handle redirect here */ > > if (statusCode >= HttpURLConnection.HTTP_MULT_CHOICE && > > @@ -595,11 +617,6 @@ > > } > > } > > > > - /* If required, capture a copy of the response. */ > > - if (responseCopy != null) { > > - > > responseCopy.append(line).append("\r\n").append(new > > String(bytes)); /* May get junk due to actual encoding */ > > - } > > - > > // TODO: process differently depending on statusCode > > and respContentLength > > // (TransportMessage does not even get statusCode) > > // e.g. statusCode 401 is Unauthorized > > @@ -612,13 +629,18 @@ > > // Create response SOAPContext. > > ctx = new SOAPContext(); > > // Read content. > > - response = new TransportMessage(is, respContentLength, > > + response = new TransportMessage(bInStream, > > respContentLength, > > respContentType, > > ctx, respHeaders); > > // Extract envelope and SOAPContext > > response.read(); > > } catch (MessagingException me) { > > throw new SOAPException(Constants.FAULT_CODE_CLIENT, > > "Error parsing response: > > " + me, me); > > + } > > + > > + /* If required, capture a copy of the response. */ > > + if (responseCopy != null) { > > + responseCopy.append(new > > String(response.getBytes())); /* May get junk due to actual > > encoding */ > > } > > > > /* All done here! */ > > > > > > > > 1.17 +51 -37 > > xml-soap/java/src/org/apache/soap/transport/TransportMessage.java > > > > Index: TransportMessage.java > > =================================================================== > > RCS file: > > /home/cvs/xml-soap/java/src/org/apache/soap/transport/Transpor > tMessage.java,v > > retrieving revision 1.16 > > retrieving revision 1.17 > > diff -u -r1.16 -r1.17 > > --- TransportMessage.java 6 Sep 2002 17:02:58 -0000 1.16 > > +++ TransportMessage.java 12 Nov 2002 14:15:38 -0000 1.17 > > @@ -128,25 +128,36 @@ > > this.ctx = ctx; > > this.contentType = contentType; > > > > - if (contentLength < 0) > > - throw new SOAPException (Constants.FAULT_CODE_PROTOCOL, > > - "Content length must > > be specified."); > > - > > - bytes = new byte[contentLength]; > > - int offset = 0; > > - int bytesRead = 0; > > - > > - // We're done reading when we get all the content > > OR when the stream > > - // returns a -1. > > - while ((offset < contentLength) && (bytesRead >= 0)) { > > - bytesRead = is.read(bytes, offset, > > contentLength - offset); > > - offset += bytesRead; > > - } > > - if (offset < contentLength) > > - throw new SOAPException (Constants.FAULT_CODE_PROTOCOL, > > - "Premature end of stream. Data is > > truncated. Read " > > - + offset + " bytes successfully, expected " > > - + contentLength); > > + bytes = new byte[contentLength >= 0 ? > > contentLength : 4096]; > > + if (contentLength != 0) { > > + int offset = 0; > > + int bytesRead = 0; > > + > > + // We're done reading when we get all the > > content OR when the stream > > + // returns a -1. > > + while ((contentLength < 0 || offset < > > contentLength) && (bytesRead >= 0)) { > > + bytesRead = is.read(bytes, offset, > > bytes.length - offset); > > + offset += bytesRead; > > + if (contentLength < 0 && offset >= bytes.length) { > > + byte[] newbuf = new byte[bytes.length * 2]; > > + System.arraycopy(bytes, 0, newbuf, 0, > > bytes.length); > > + bytes = newbuf; > > + } > > + } > > + > > + if (contentLength < 0) { > > + if (offset < bytes.length) { > > + byte[] newbuf = new byte[offset]; > > + System.arraycopy(bytes, 0, newbuf, 0, offset); > > + bytes = newbuf; > > + } > > + } else if (offset < contentLength) { > > + throw new SOAPException > > (Constants.FAULT_CODE_PROTOCOL, > > + "Premature end of stream. Data > > is truncated. Read " > > + + offset + " bytes > > successfully, expected " > > + + contentLength); > > + } > > + } > > } > > > > /** > > @@ -284,7 +295,7 @@ > > } > > > > // If the root part is text, extract it as a String. > > - // Note that we could use JAF's help to do this > > (see getEnvelope()) > > + // Note that we could use JAF's help to do this > > (see save()) > > // but implementing it ourselves is safer and faster. > > if (rootContentType.match("text/*")) { > > String charset = > > rootContentType.getParameter("charset"); > > @@ -323,9 +334,11 @@ > > */ > > public void save() > > throws MessagingException, IOException { > > - /* If an envelope was provided as a string, set it > > as the root part. > > - * Otherwise, assume that the SOAPContext already > > has a root part. > > + /* > > + * If an envelope was provided as a string, set it > > as the root part. > > * If there was already a root part, preserve its > > content-type. > > + * Otherwise, assume that the SOAPContext already > > has a root part, > > + * and try to use it as the envelope. > > */ > > String rootContentType = null; > > if (ctx.isRootPartSet()) { > > @@ -339,8 +352,18 @@ > > } > > if (rootContentType == null) > > rootContentType = > > Constants.HEADERVAL_CONTENT_TYPE_UTF8; > > - if (getEnvelope() != null) > > + if (getEnvelope() != null) { > > ctx.setRootPart(envelope, rootContentType); > > + } else { > > + MimeBodyPart rootPart = ctx.getRootPart(); > > + if (rootPart != null) { > > + if (rootPart.isMimeType("text/*")) { > > + ByteArrayDataSource ds = new > > ByteArrayDataSource( > > + rootPart.getInputStream(), > > rootPart.getContentType()); > > + envelope = ds.getText(); > > + } > > + } > > + } > > > > // Print the whole response to a byte array. > > ByteArrayOutputStream payload = > > @@ -428,20 +451,9 @@ > > } > > > > /** > > - * Get SOAP Envelope/root part as a String. > > - * This method will extract the root part from the > > SOAPContext as a String > > - * if there is no SOAP Envelope. > > + * Get SOAP Envelope as a String. > > */ > > - public String getEnvelope() throws MessagingException, > > IOException { > > - if (envelope == null) { > > - MimeBodyPart rootPart = ctx.getRootPart(); > > - if (rootPart != null) > > - if (rootPart.isMimeType("text/*")) { > > - ByteArrayDataSource ds = new > > ByteArrayDataSource( > > - rootPart.getInputStream(), > > rootPart.getContentType()); > > - envelope = ds.getText(); > > - } > > - } > > + public String getEnvelope() { > > return envelope; > > } > > > > @@ -449,7 +461,7 @@ > > * Get SOAP Envelope/root part as a Reader. Returns > > null if the root part > > * is not text. > > */ > > - public Reader getEnvelopeReader() throws > > MessagingException, IOException { > > + public Reader getEnvelopeReader() { > > if (getEnvelope() == null) > > return null; > > else > > @@ -530,6 +542,8 @@ > > > > /** > > * Set the byte array of the response. > > + * > > + * @deprecated After 2.3.1 > > */ > > public void readFully(InputStream is) throws IOException { > > offset = 0; > > > > > > > > 1.29 +19 -16 > > xml-soap/java/src/org/apache/soap/transport/http/SOAPHTTPConne > > ction.java > > > > Index: SOAPHTTPConnection.java > > =================================================================== > > RCS file: > > /home/cvs/xml-soap/java/src/org/apache/soap/transport/http/SOA > PHTTPConnection.java,v > > retrieving revision 1.28 > > retrieving revision 1.29 > > diff -u -r1.28 -r1.29 > > --- SOAPHTTPConnection.java 16 Oct 2002 04:16:15 -0000 1.28 > > +++ SOAPHTTPConnection.java 12 Nov 2002 14:15:38 -0000 1.29 > > @@ -84,9 +84,7 @@ > > * @author Arek Wnukowski ([EMAIL PROTECTED]) > > */ > > public class SOAPHTTPConnection implements SOAPTransport { > > - private BufferedReader responseReader; > > - private Hashtable responseHeaders; > > - private SOAPContext responseSOAPContext; > > + private TransportMessage response; > > > > private String httpProxyHost; > > private int httpProxyPort = 80; > > @@ -369,7 +367,6 @@ > > "Basic " + > > HTTPUtils.encodeAuth(proxyUserName, proxyPassword)); > > } > > > > - TransportMessage response; > > try > > { > > TransportMessage msg = new > > TransportMessage(payload, ctx, headers); > > @@ -385,18 +382,12 @@ > > throw new IOException ("Failed to encode mime > > multipart: " + uee); > > } > > > > - Reader envReader = response.getEnvelopeReader(); > > - if (envReader != null) > > - responseReader = new BufferedReader(envReader); > > - else > > - responseReader = null; > > - responseSOAPContext = response.getSOAPContext(); > > - responseHeaders = response.getHeaders(); > > if (maintainSession) { > > // look for Set-Cookie2 and Set-Cookie headers and > > save them. > > // Only update my state iff the header is there .. > > otherwise > > // leave the current > > // Note: Header is case-insensitive > > + Hashtable responseHeaders = response.getHeaders(); > > String hdr; > > > > hdr = HTTPUtils.getHeaderValue (responseHeaders, > > "Set-Cookie2"); > > @@ -421,8 +412,6 @@ > > } > > } catch (IllegalArgumentException e) { > > throw new SOAPException > > (Constants.FAULT_CODE_CLIENT, e.getMessage(), e); > > - } catch (MessagingException e) { > > - throw new SOAPException > > (Constants.FAULT_CODE_CLIENT, e.getMessage(), e); > > } catch (IOException e) { > > throw new SOAPException > > (Constants.FAULT_CODE_CLIENT, e.getMessage(), e); > > } > > @@ -436,7 +425,21 @@ > > * possible. > > */ > > public BufferedReader receive () { > > - return responseReader; > > + if (response != null) { > > + Reader envReader = response.getEnvelopeReader(); > > + if (envReader != null) > > + return new BufferedReader(envReader); > > + } > > + return null; > > + } > > + > > + /** > > + * Returns the SOAP envelope. > > + * > > + * @return The SOAP envelope. > > + */ > > + public String getEnvelope() { > > + return response != null ? response.getEnvelope() : null; > > } > > > > /** > > @@ -445,7 +448,7 @@ > > * @return a hashtable containing all the headers > > */ > > public Hashtable getHeaders () { > > - return responseHeaders; > > + return response != null ? response.getHeaders() : null; > > } > > > > /** > > @@ -454,6 +457,6 @@ > > * @return response SOAPContext > > */ > > public SOAPContext getResponseSOAPContext () { > > - return responseSOAPContext; > > + return response != null ? response.getSOAPContext() : null; > > } > > } > > > > > > > > > > -- > > To unsubscribe, e-mail: <mailto:soap-dev-unsubscribe@;xml.apache.org> > > For additional commands, e-mail: <mailto:soap-dev-help@;xml.apache.org> > > > > -- > To unsubscribe, e-mail: <mailto:soap-dev-unsubscribe@;xml.apache.org> > For additional commands, e-mail: <mailto:soap-dev-help@;xml.apache.org> > > -- To unsubscribe, e-mail: <mailto:soap-dev-unsubscribe@;xml.apache.org> For additional commands, e-mail: <mailto:soap-dev-help@;xml.apache.org>