Changelog:
- Wire logging is now performed exclusively by HttpConnection class
- All data retrieved or sent through an HttpConnection instance is
captured in the wire log (when logging is activated)
- Request/response headers content is correctly encoded/decoded using
conversion routines of the HttpConstants class
- Primitive parsing methods moved into one class named HttpParser
You are welcome to start throwing bad tomatoes at me
Cheers
Oleg
Index: java/org/apache/commons/httpclient/ChunkedInputStream.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/ChunkedInputStream.java,v
retrieving revision 1.13
diff -u -r1.13 ChunkedInputStream.java
--- java/org/apache/commons/httpclient/ChunkedInputStream.java 11 Feb 2003 03:23:05 -0000 1.13
+++ java/org/apache/commons/httpclient/ChunkedInputStream.java 12 Feb 2003 14:15:45 -0000
@@ -63,11 +63,11 @@
package org.apache.commons.httpclient;
+import java.util.ArrayList;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import org.apache.commons.httpclient.util.HeaderParser;
/**
* <p>Transparently coalesces chunks of a HTTP stream that uses
@@ -315,7 +315,16 @@
* @throws IOException If an IO problem occurs
*/
private void parseTrailerHeaders() throws IOException {
- Header[] footers = HeaderParser.parseHeaders(in);
+ ArrayList lines = new ArrayList();
+ for (; ;) {
+ String line = HttpParser.readLine(in);
+ if ((line == null) || (line.length() < 1)) {
+ break;
+ }
+ lines.add(line);
+ }
+ Header[] footers = HttpParser.parseHeaders(
+ (String[])lines.toArray(new String[lines.size()]));
for (int i = 0; i < footers.length; i++) {
method.addResponseFooter(footers[i]);
Index: java/org/apache/commons/httpclient/ChunkedOutputStream.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/ChunkedOutputStream.java,v
retrieving revision 1.8
diff -u -r1.8 ChunkedOutputStream.java
--- java/org/apache/commons/httpclient/ChunkedOutputStream.java 8 Feb 2003 19:22:49 -0000 1.8
+++ java/org/apache/commons/httpclient/ChunkedOutputStream.java 12 Feb 2003 14:15:46 -0000
@@ -103,9 +103,6 @@
/** Log object for this class. */
private static final Log LOG = LogFactory.getLog(ChunkedOutputStream.class);
- /** Log for any wire messages. */
- private static final Log WIRE_LOG = LogFactory.getLog("httpclient.wire");
-
// ----------------------------------------------------- Instance Variables
/** Has this stream been closed? */
@@ -190,10 +187,6 @@
stream.write(CRLF, 0, CRLF.length);
stream.write(b);
stream.write(ENDCHUNK, 0, ENDCHUNK.length);
- if (WIRE_LOG.isDebugEnabled()) {
- WIRE_LOG.debug(">> byte 1 \\r\\n (chunk length \"header\")");
- WIRE_LOG.debug(">> byte " + b + "\\r\\n (chunked byte)");
- }
}
/**
@@ -215,12 +208,6 @@
stream.write(chunkHeader, 0, chunkHeader.length);
stream.write(b, off, len);
stream.write(ENDCHUNK, 0, ENDCHUNK.length);
- if (WIRE_LOG.isDebugEnabled()) {
- WIRE_LOG.debug(">> byte(s)" + len + " \\r\\n (chunk length "
- + "\"header\")");
- WIRE_LOG.debug(">> \"" + new String(b, off, len)
- + "\"\\r\\n (chunked bytes)");
- }
}
/**
@@ -239,7 +226,6 @@
stream.write(ZERO, 0, ZERO.length);
stream.write(CRLF, 0, CRLF.length);
stream.write(ENDCHUNK, 0, ENDCHUNK.length);
- WIRE_LOG.debug(">> byte 0 \\r\\n\\r\\n (final chunk)");
} catch (IOException e) {
LOG.debug("Unexpected exception caught when closing "
+ "output stream", e);
Index: java/org/apache/commons/httpclient/HttpConnection.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnection.java,v
retrieving revision 1.43
diff -u -r1.43 HttpConnection.java
--- java/org/apache/commons/httpclient/HttpConnection.java 11 Feb 2003 03:23:05 -0000 1.43
+++ java/org/apache/commons/httpclient/HttpConnection.java 12 Feb 2003 14:15:44 -0000
@@ -110,42 +110,6 @@
*/
public class HttpConnection {
- /**
- * Read up to <tt>"\r\n"</tt> from an (unchunked) input stream.
- * If the stream ends before the line terminator is found,
- * the last part of the string will still be returned.
- * '\r' and '\n' are allowed to appear individually in the stream.
- *
- * @param inputStream the stream to read from
- *
- * @throws IOException if an I/O problem occurs
- * @return a line from the stream
- *
- * @since 2.0beta1
- */
- public static String readLine(InputStream inputStream) throws IOException {
- LOG.trace("enter HttpConnection.readLine()");
-
- StringBuffer buf = new StringBuffer();
- int ch = inputStream.read();
- while (ch >= 0) {
- if (ch == '\r') {
- ch = inputStream.read();
- if (ch == '\n') {
- break;
- } else {
- buf.append('\r');
- }
- }
- buf.append((char) ch);
- ch = inputStream.read();
- }
- if (WIRE_LOG.isDebugEnabled()) {
- WIRE_LOG.debug("<< \"" + buf.toString() + (ch>0 ? "\" [\\r\\n]" : ""));
- }
- return (buf.toString());
- }
-
// ----------------------------------------------------------- Constructors
/**
@@ -631,7 +595,11 @@
throws IOException, IllegalStateException {
LOG.trace("enter HttpConnection.getRequestOutputStream()");
assertOpen();
- return outputStream;
+ OutputStream out = this.outputStream;
+ if (Wire.enabled()) {
+ out = new WireLogOutputStream(out, HttpConstants.HTTP_ELEMENT_CHARSET);
+ }
+ return out;
}
/**
@@ -650,11 +618,14 @@
LOG.trace("enter HttpConnection.getRequestOutputStream(boolean)");
assertOpen();
+ OutputStream out = this.outputStream;
+ if (Wire.enabled()) {
+ out = new WireLogOutputStream(out, HttpConstants.HTTP_ELEMENT_CHARSET);
+ }
if (useChunking) {
- return new ChunkedOutputStream(outputStream);
- } else {
- return outputStream;
+ out = new ChunkedOutputStream(out);
}
+ return out;
}
/**
@@ -688,7 +659,11 @@
throws IOException, IllegalStateException {
LOG.trace("enter HttpConnection.getResponseInputStream()");
assertOpen();
- return inputStream;
+ InputStream in = this.inputStream;
+ if (Wire.enabled()) {
+ in = new WireLogInputStream(in, HttpConstants.HTTP_ELEMENT_CHARSET);
+ }
+ return in;
}
/**
@@ -764,9 +739,8 @@
assertOpen();
- if (WIRE_LOG.isDebugEnabled()) {
- String dataString = new String(data, offset, length, "ISO-8859-1");
- WIRE_LOG.debug(">> \"" + dataString + "\" [\\r\\n]");
+ if (Wire.enabled()) {
+ Wire.output(data, offset, length, HttpConstants.HTTP_ELEMENT_CHARSET);
}
try {
outputStream.write(data, offset, length);
@@ -795,9 +769,8 @@
LOG.trace("enter HttpConnection.writeLine(byte[])");
assertOpen();
- if (WIRE_LOG.isDebugEnabled() && (data.length > 0)) {
- String dataString = HttpConstants.getContentString(data);
- WIRE_LOG.debug(">> \"" + dataString.trim() + "\" [\\r\\n]");
+ if (Wire.enabled()) {
+ Wire.output(data, HttpConstants.HTTP_ELEMENT_CHARSET);
}
try {
outputStream.write(data);
@@ -823,7 +796,9 @@
throws IOException, IllegalStateException, HttpRecoverableException {
LOG.trace("enter HttpConnection.writeLine()");
- WIRE_LOG.debug(">> [\\r\\n]");
+ if (Wire.enabled()) {
+ Wire.output(CRLF, HttpConstants.HTTP_ELEMENT_CHARSET);
+ }
try {
outputStream.write(CRLF);
} catch (SocketException se) {
@@ -894,9 +869,18 @@
LOG.trace("enter HttpConnection.readLine()");
assertOpen();
- return HttpConnection.readLine(inputStream);
+ byte[] rawdata = HttpParser.readRawLine(inputStream);
+ if (Wire.enabled()) {
+ Wire.input(rawdata, HttpConstants.HTTP_ELEMENT_CHARSET);
+ }
+ if ((rawdata.length >= 2) && (rawdata[0] == '\r') && (rawdata[1] == '\n')) {
+ return HttpConstants.getString(rawdata, 0, rawdata.length - 2);
+ } else {
+ return HttpConstants.getString(rawdata);
+ }
}
+
/**
* Shutdown my {@link Socket}'s output, via {@link Socket#shutdownOutput}.
*/
@@ -1079,9 +1063,6 @@
/** Log object for this class. */
private static final Log LOG = LogFactory.getLog(HttpConnection.class);
-
- /** Log for any wire messages. */
- private static final Log WIRE_LOG = LogFactory.getLog("httpclient.wire");
// ----------------------------------------------------- Instance Variables
/** My host. */
Index: java/org/apache/commons/httpclient/HttpMethodBase.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodBase.java,v
retrieving revision 1.111
diff -u -r1.111 HttpMethodBase.java
--- java/org/apache/commons/httpclient/HttpMethodBase.java 11 Feb 2003 03:23:05 -0000 1.111
+++ java/org/apache/commons/httpclient/HttpMethodBase.java 12 Feb 2003 14:15:53 -0000
@@ -71,11 +71,11 @@
import java.net.URL;
import java.util.HashSet;
import java.util.Set;
+import java.util.ArrayList;
import java.util.StringTokenizer;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.cookie.CookieSpec;
-import org.apache.commons.httpclient.util.HeaderParser;
import org.apache.commons.httpclient.util.URIUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -147,9 +147,6 @@
/** Log object for this class. */
private static final Log LOG = LogFactory.getLog(HttpMethod.class);
- /** Log for any wire messages. */
- private static final Log WIRE_LOG = LogFactory.getLog("httpclient.wire");
-
/** The User-Agent header sent on every request. */
protected static final Header USER_AGENT;
@@ -1777,9 +1774,6 @@
Header lengthHeader = getResponseHeader("Content-Length");
Header transferEncodingHeader = getResponseHeader("Transfer-Encoding");
InputStream is = conn.getResponseInputStream();
- if (WIRE_LOG.isDebugEnabled()) {
- is = new WireLogInputStream(is);
- }
InputStream result = null;
// We use Transfer-Encoding if present and ignore Content-Length.
// RFC2616, 4.4 item number 3
@@ -1861,8 +1855,17 @@
LOG.trace("enter HttpMethodBase.readResponseHeaders(HttpState,"
+ "HttpConnection)");
+ ArrayList lines = new ArrayList();
+ for (; ;) {
+ String line = conn.readLine();
+ if ((line == null) || (line.length() < 1)) {
+ break;
+ }
+ lines.add(line);
+ }
getResponseHeaderGroup().clear();
- Header[] headers = HeaderParser.parseHeaders(conn.getResponseInputStream());
+ Header[] headers = HttpParser.parseHeaders(
+ (String[])lines.toArray(new String[lines.size()]));
getResponseHeaderGroup().setHeaders(headers);
}
Index: java/org/apache/commons/httpclient/HttpParser.java
===================================================================
RCS file: java/org/apache/commons/httpclient/HttpParser.java
diff -N java/org/apache/commons/httpclient/HttpParser.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ java/org/apache/commons/httpclient/HttpParser.java 12 Feb 2003 14:15:46 -0000
@@ -0,0 +1,136 @@
+package org.apache.commons.httpclient;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * A utility class for parsing http header values.
+ *
+ * @author Michael Becke
+ * @author <a href="mailto:[EMAIL PROTECTED]">Oleg Kalnichevski</a>
+ *
+ * @since 2.0beta1
+ */
+public class HttpParser {
+
+ /** Log object for this class. */
+ private static final Log LOG = LogFactory.getLog(HttpParser.class);
+
+ /**
+ * Constructor for HttpParser.
+ */
+ private HttpParser() {}
+
+
+ /**
+ * Return byte array from an (unchunked) input stream.
+ * Stop reading when <tt>"\r\n"</tt> terminator encountered
+ * If the stream ends before the line terminator is found,
+ * the last part of the string will still be returned.
+ * '\r' and '\n' are allowed to appear individually in the stream.
+ *
+ * @param inputStream the stream to read from
+ *
+ * @throws IOException if an I/O problem occurs
+ * @return a byte array from the stream
+ */
+ public static byte[] readRawLine(InputStream inputStream) throws IOException {
+ LOG.trace("enter HttpConnection.readRawLine()");
+
+ ByteArrayOutputStream buf = new ByteArrayOutputStream();
+ int ch;
+ while ((ch = inputStream.read()) >= 0) {
+ buf.write(ch);
+ if (ch == '\r') {
+ ch = inputStream.read();
+ if (ch < 0) {
+ break;
+ }
+ buf.write(ch);
+ if (ch == '\n') {
+ break;
+ }
+ }
+ }
+ return buf.toByteArray();
+ }
+
+ /**
+ * Read up to <tt>"\r\n"</tt> from an (unchunked) input stream.
+ * If the stream ends before the line terminator is found,
+ * the last part of the string will still be returned.
+ * '\r' and '\n' are allowed to appear individually in the stream.
+ *
+ * @param inputStream the stream to read from
+ *
+ * @throws IOException if an I/O problem occurs
+ * @return a line from the stream
+ */
+
+ public static String readLine(InputStream inputStream) throws IOException {
+ LOG.trace("enter HttpConnection.readLine()");
+ byte[] rawdata = readRawLine(inputStream);
+ if ((rawdata.length >= 2) && (rawdata[0] == '\r') && (rawdata[1] == '\n')) {
+ return HttpConstants.getString(rawdata, 0, rawdata.length - 2);
+ } else {
+ return HttpConstants.getString(rawdata);
+ }
+ }
+
+ /**
+ * Parses headers from the given array of strings.
+ * Headers with the same name are not combined.
+ *
+ * @param an array of strings to be parsed
+ *
+ * @return an array of headers in the order in which they were parsed
+ *
+ * @throws HttpException if there is an error parsing a header value
+ */
+ public static Header[] parseHeaders(String[] lines) throws HttpException {
+ LOG.trace("enter HeaderParser.parseHeaders(HttpConnection, HeaderGroup)");
+
+ ArrayList headers = new ArrayList();
+ String name = null;
+ StringBuffer value = null;
+ for (int i = 0; i < lines.length; i++) {
+ String line = lines[i];
+ // Parse the header name and value
+ // Check for folded headers first
+ // Detect LWS-char see HTTP/1.0 or HTTP/1.1 Section 2.2
+ // discussion on folded headers
+ if ((line.charAt(0) == ' ') || (line.charAt(0) == '\t')) {
+ // we have continuation folded header
+ // so append value
+ value.append(' ');
+ value.append(line.trim());
+ } else {
+ // make sure we save the previous name,value pair if present
+ if (name != null) {
+ headers.add(new Header(name, value.toString()));
+ }
+
+ // Otherwise we should have normal HTTP header line
+ // Parse the header name and value
+ int colon = line.indexOf(":");
+ if (colon < 0) {
+ throw new HttpException("Unable to parse header: " + line);
+ }
+ name = line.substring(0, colon).trim();
+ value = new StringBuffer(line.substring(colon + 1).trim());
+ }
+
+ }
+
+ // make sure we save the last name,value pair if present
+ if (name != null) {
+ headers.add(new Header(name, value.toString()));
+ }
+
+ return (Header[]) headers.toArray(new Header[headers.size()]);
+ }
+}
Index: java/org/apache/commons/httpclient/Wire.java
===================================================================
RCS file: java/org/apache/commons/httpclient/Wire.java
diff -N java/org/apache/commons/httpclient/Wire.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ java/org/apache/commons/httpclient/Wire.java 12 Feb 2003 14:15:46 -0000
@@ -0,0 +1,167 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 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 acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", 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 names without prior written
+ * permission of the Apache Group.
+ *
+ * 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. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.apache.commons.httpclient;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.io.Reader;
+import java.io.InputStreamReader;
+import java.io.BufferedReader;
+import java.io.UnsupportedEncodingException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Logs data to the wire LOG.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Oleg Kalnichevski</a>
+ *
+ * @since 2.0beta1
+ */
+
+class Wire {
+
+ /** Log for any wire messages. */
+ private static final Log WIRE_LOG = LogFactory.getLog("httpclient.wire");
+
+ private static void wire(String header, InputStream instream, String charset)
+ throws IOException {
+ if (charset == null) {
+ charset = "US-ASCII";
+ }
+ Reader reader = null;
+ try {
+ reader = new InputStreamReader(instream, charset);
+ } catch (UnsupportedEncodingException e) {
+ reader = new InputStreamReader(instream);
+ }
+ StringBuffer buffer = new StringBuffer();
+ int ch;
+ while ((ch = reader.read()) != -1) {
+ if (ch == 13) {
+ buffer.append("[\\r]");
+ } else if (ch == 10){
+ buffer.append("[\\n]\"");
+ buffer.insert(0, "\"");
+ buffer.insert(0, header);
+ WIRE_LOG.debug(buffer.toString());
+ buffer.setLength(0);
+ } else if ((ch < 32) || (ch > 127)) {
+ buffer.append("[0x");
+ buffer.append(Integer.toHexString(ch));
+ buffer.append("]");
+ } else {
+ buffer.append((char)ch);
+ }
+ }
+ if (buffer.length() > 0) {
+ buffer.append("\"");
+ buffer.insert(0, "\"");
+ buffer.insert(0, header);
+ WIRE_LOG.debug(buffer.toString());
+ }
+ }
+
+
+ public static final boolean enabled() {
+ return WIRE_LOG.isDebugEnabled();
+ }
+
+ public static final void output(InputStream instream, String charset)
+ throws IOException {
+ wire(">> ", instream, charset);
+ }
+
+ public static final void input(InputStream instream, String charset)
+ throws IOException {
+ wire("<< ", instream, charset);
+ }
+
+ public static final void output(byte[] b, int off, int len, String charset)
+ throws IOException {
+ wire(">> ", new ByteArrayInputStream(b, off, len), charset);
+ }
+
+ public static final void input(byte[] b, int off, int len, String charset)
+ throws IOException {
+ wire("<< ", new ByteArrayInputStream(b, off, len), charset);
+ }
+
+ public static final void output(byte[] b, String charset)
+ throws IOException {
+ wire(">> ", new ByteArrayInputStream(b), charset);
+ }
+
+ public static final void input(byte[] b, String charset)
+ throws IOException {
+ wire("<< ", new ByteArrayInputStream(b), charset);
+ }
+
+ public static final void output(int b, String charset)
+ throws IOException {
+ output(new byte[] {(byte)b}, charset);
+ }
+
+ public static final void input(int b, String charset)
+ throws IOException {
+ input(new byte[] {(byte)b}, charset);
+ }
+}
Index: java/org/apache/commons/httpclient/WireLogInputStream.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/WireLogInputStream.java,v
retrieving revision 1.8
diff -u -r1.8 WireLogInputStream.java
--- java/org/apache/commons/httpclient/WireLogInputStream.java 31 Jan 2003 00:33:36 -0000 1.8
+++ java/org/apache/commons/httpclient/WireLogInputStream.java 12 Feb 2003 14:15:47 -0000
@@ -67,27 +67,38 @@
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.logging.LogFactory;
/**
* Logs all data read to the wire LOG.
*
* @author Ortwin Gl�
* @author <a href="mailto:[EMAIL PROTECTED]">Mike Bowler</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Oleg Kalnichevski</a>
*
* @since 2.0
*/
class WireLogInputStream extends FilterInputStream {
+
/** Log for any wire messages. */
private static final Log WIRE_LOG = LogFactory.getLog("httpclient.wire");
+ /** Content encoding. */
+ private String charset = "US-ASCII";
+
+ /** Original input stream. */
+ private InputStream in;
/**
* Create an instance that wraps the specified input stream.
* @param in The input stream.
*/
- public WireLogInputStream(InputStream in) {
+ public WireLogInputStream(InputStream in, String charset) {
super(in);
+ if (charset != null) {
+ this.charset = charset;
+ }
+ this.in = in;
}
/**
@@ -95,8 +106,10 @@
* @see java.io.InputStream#read(byte[], int, int)
*/
public int read(byte[] b, int off, int len) throws IOException {
- int l = super.read(b, off, len);
- WIRE_LOG.debug("<< " + new String(b, off, len));
+ int l = this.in.read(b, off, len);
+ if (l > 0) {
+ Wire.input(b, off, len, null);
+ }
return l;
}
@@ -105,9 +118,9 @@
* @see java.io.InputStream#read()
*/
public int read() throws IOException {
- int l = super.read();
+ int l = this.in.read();
if (l > 0) {
- WIRE_LOG.debug("<< " + (char) l);
+ Wire.input(l, null);
}
return l;
}
@@ -117,8 +130,10 @@
* @see java.io.InputStream#read(byte[])
*/
public int read(byte[] b) throws IOException {
- int l = super.read(b);
- WIRE_LOG.debug("<< " + HttpConstants.getString(b));
+ int l = this.in.read(b);
+ if (l > 0) {
+ Wire.input(b, null);
+ }
return l;
}
}
Index: java/org/apache/commons/httpclient/WireLogOutputStream.java
===================================================================
RCS file: java/org/apache/commons/httpclient/WireLogOutputStream.java
diff -N java/org/apache/commons/httpclient/WireLogOutputStream.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ java/org/apache/commons/httpclient/WireLogOutputStream.java 12 Feb 2003 14:15:53 -0000
@@ -0,0 +1,131 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 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 acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", 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 names without prior written
+ * permission of the Apache Group.
+ *
+ * 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. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.apache.commons.httpclient;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.Reader;
+import java.io.InputStreamReader;
+import java.io.BufferedReader;
+import java.io.UnsupportedEncodingException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Logs all data written to the wire LOG.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Oleg Kalnichevski</a>
+ *
+ * @since 2.0beta1
+ */
+
+class WireLogOutputStream extends FilterOutputStream {
+
+ /** Log for any wire messages. */
+ private static final Log WIRE_LOG = LogFactory.getLog("httpclient.wire");
+
+ /** Content encoding. */
+ private String charset = "US-ASCII";
+
+ /** Original input stream. */
+ private OutputStream out;
+
+ /**
+ * Create an instance that wraps the specified output stream.
+ * @param out The output stream.
+ */
+ public WireLogOutputStream(OutputStream out, String charset) {
+ super(out);
+ if (charset != null) {
+ this.charset = charset;
+ }
+ this.out = out;
+ }
+
+ /**
+ *
+ * @see java.io.OutputStream#write(byte[], int, int)
+ */
+ public void write(byte[] b, int off, int len) throws IOException {
+ this.out.write(b, off, len);
+ Wire.output(b, off, len, this.charset);
+ }
+
+ /**
+ *
+ * @see java.io.OutputStream#write()
+ */
+ public void write(int b) throws IOException {
+ this.out.write(b);
+ Wire.output(b, this.charset);
+ }
+
+ /**
+ *
+ * @see java.io.OutputStream#write(byte[])
+ */
+ public void write(byte[] b) throws IOException {
+ this.out.write(b);
+ Wire.output(b, this.charset);
+ }
+}
Index: java/org/apache/commons/httpclient/util/HeaderParser.java
===================================================================
RCS file: java/org/apache/commons/httpclient/util/HeaderParser.java
diff -N java/org/apache/commons/httpclient/util/HeaderParser.java
--- java/org/apache/commons/httpclient/util/HeaderParser.java 11 Feb 2003 05:04:10 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,88 +0,0 @@
-package org.apache.commons.httpclient.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-
-import org.apache.commons.httpclient.Header;
-import org.apache.commons.httpclient.HttpConnection;
-import org.apache.commons.httpclient.HttpException;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * A utility class for parsing http header values.
- *
- * @author Michael Becke
- *
- * @since 2.0beta1
- */
-public class HeaderParser {
-
- /** Log object for this class. */
- private static final Log LOG = LogFactory.getLog(HeaderParser.class);
-
- /**
- * Constructor for HeaderParser.
- */
- private HeaderParser() {}
-
- /**
- * Parses headers from the given stream. Headers with the same name are not
- * combined.
- *
- * @param is the stream to read headers from
- *
- * @return an array of headers in the order in which they were parsed
- *
- * @throws IOException if an IO error occurs while reading from the stream
- * @throws HttpException if there is an error parsing a header value
- */
- public static Header[] parseHeaders(InputStream is) throws IOException, HttpException {
- LOG.trace("enter HeaderParser.parseHeaders(HttpConnection, HeaderGroup)");
-
- ArrayList headers = new ArrayList();
- String name = null;
- StringBuffer value = null;
- for (; ;) {
- String line = HttpConnection.readLine(is);
- if ((line == null) || (line.length() < 1)) {
- break;
- }
-
- // Parse the header name and value
- // Check for folded headers first
- // Detect LWS-char see HTTP/1.0 or HTTP/1.1 Section 2.2
- // discussion on folded headers
- if ((line.charAt(0) == ' ') || (line.charAt(0) == '\t')) {
- // we have continuation folded header
- // so append value
- value.append(' ');
- value.append(line.trim());
- } else {
- // make sure we save the previous name,value pair if present
- if (name != null) {
- headers.add(new Header(name, value.toString()));
- }
-
- // Otherwise we should have normal HTTP header line
- // Parse the header name and value
- int colon = line.indexOf(":");
- if (colon < 0) {
- throw new HttpException("Unable to parse header: " + line);
- }
- name = line.substring(0, colon).trim();
- value = new StringBuffer(line.substring(colon + 1).trim());
- }
-
- }
-
- // make sure we save the last name,value pair if present
- if (name != null) {
- headers.add(new Header(name, value.toString()));
- }
-
- return (Header[]) headers.toArray(new Header[headers.size()]);
- }
-
-}
Index: test/org/apache/commons/httpclient/SimpleHttpConnection.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/SimpleHttpConnection.java,v
retrieving revision 1.9
diff -u -r1.9 SimpleHttpConnection.java
--- test/org/apache/commons/httpclient/SimpleHttpConnection.java 11 Feb 2003 03:23:05 -0000 1.9
+++ test/org/apache/commons/httpclient/SimpleHttpConnection.java 12 Feb 2003 14:15:41 -0000
@@ -186,7 +186,7 @@
public String readLine()
throws IOException, IllegalStateException {
- String str = HttpConnection.readLine(inputStream);
+ String str = HttpParser.readLine(inputStream);
log.debug("read: " + str);
return str;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]