Yea. Java does not have all the answers to visibility needs. What we really need is a "jar" access level. Perhaps we'll get that in java version 3 ;-)

Jandalf.

Oleg Kalnichevski wrote:

Jeff,

Wire, WireLogOutputStream, WireLogInputStream classes need to be
accessible by classes from the following packages:
org.apache.commons.httpclient
org.apache.commons.httpclient.methods
org.apache.commons.httpclient.methods.multipart

Making wire logging related classes non-public does not seem feasible
with the present package structure.
Cheers

Oleg

On Tue, 2003-02-11 at 04:19, Jeffrey Dever wrote:

I like the refactoring. Only complaint is that the classes are public. Package access would be prefered, but this may not be possible.


Oleg Kalnichevski wrote:


Fixes the following bugs:

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=14782

Change log:
- MultipartPost related methods clean-up
- Part#send(OutputStream out) & long Part#length() are no more final
- Content encoding can be specified - FilePart's content type can be specified - FilePart's transfer encoding can be specified - Wire logging improvement

While working on multi-part post stuff I have been through many pains
debugging modified classes and trying to figure out what exactly gets
sent to the server. Currently wire logging can be regarded as
inconsistent at best. In those parts where wire logging is implemented I
find it not particularly visually appealing. While "scratching my own
itch" I have taken liberty of rewriting wire logging. Please comment if
you find these changes acceptable. Suggestions on possible improvements
are welcome.

To be done next:

- Fix bug #14036
- Apply new wire logging consistently throughout the HttpClient codebase
(provided new wire logging meets your approval)


------------------------------------------------------------------------

Index: src/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.42
diff -u -r1.42 HttpConnection.java
--- src/java/org/apache/commons/httpclient/HttpConnection.java 8 Feb 2003 19:22:49 -0000 1.42
+++ src/java/org/apache/commons/httpclient/HttpConnection.java 10 Feb 2003 22:02:08 -0000
@@ -75,6 +75,7 @@
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
import org.apache.commons.httpclient.util.TimeoutController;
+import org.apache.commons.httpclient.util.Wire;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

@@ -727,9 +728,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);
@@ -758,9 +758,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);
@@ -786,7 +785,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) {
@@ -871,8 +872,8 @@
buf.append((char) ch);
ch = inputStream.read();
}
- if (WIRE_LOG.isDebugEnabled()) {
- WIRE_LOG.debug("<< \"" + buf.toString() + (ch>0 ? "\" [\\r\\n]" : ""));
+ if (Wire.enabled()) {
+ Wire.input(HttpConstants.getBytes(buf.toString()), HttpConstants.HTTP_ELEMENT_CHARSET);
}
return (buf.toString());
}
@@ -1059,9 +1060,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: src/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.110
diff -u -r1.110 HttpMethodBase.java
--- src/java/org/apache/commons/httpclient/HttpMethodBase.java 8 Feb 2003 19:22:49 -0000 1.110
+++ src/java/org/apache/commons/httpclient/HttpMethodBase.java 10 Feb 2003 22:02:13 -0000
@@ -1752,7 +1752,7 @@
Header transferEncodingHeader = getResponseHeader("Transfer-Encoding");
InputStream is = conn.getResponseInputStream();
if (WIRE_LOG.isDebugEnabled()) {
- is = new WireLogInputStream(is);
+ is = new WireLogInputStream(is, getResponseCharSet());
}
InputStream result = null;
// We use Transfer-Encoding if present and ignore Content-Length.
Index: src/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
--- src/java/org/apache/commons/httpclient/WireLogInputStream.java 31 Jan 2003 00:33:36 -0000 1.8
+++ src/java/org/apache/commons/httpclient/WireLogInputStream.java 10 Feb 2003 22:02:13 -0000
@@ -68,26 +68,38 @@
import java.io.InputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.commons.httpclient.util.Wire;
/**
* 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 +107,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 +119,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 +131,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: src/java/org/apache/commons/httpclient/WireLogOutputStream.java
===================================================================
RCS file: src/java/org/apache/commons/httpclient/WireLogOutputStream.java
diff -N src/java/org/apache/commons/httpclient/WireLogOutputStream.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/java/org/apache/commons/httpclient/WireLogOutputStream.java 10 Feb 2003 22:02:14 -0000
@@ -0,0 +1,132 @@
+/*
+ * ====================================================================
+ *
+ * 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;
+import org.apache.commons.httpclient.util.Wire; +
+/**
+ * Logs all data written to the wire LOG.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]";>Oleg Kalnichevski</a>
+ * + * @since 2.0beta1
+ */
+
+public 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: src/java/org/apache/commons/httpclient/methods/MultipartPostMethod.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/MultipartPostMethod.java,v
retrieving revision 1.8
diff -u -r1.8 MultipartPostMethod.java
--- src/java/org/apache/commons/httpclient/methods/MultipartPostMethod.java 2 Feb 2003 04:30:13 -0000 1.8
+++ src/java/org/apache/commons/httpclient/methods/MultipartPostMethod.java 10 Feb 2003 22:02:15 -0000
@@ -94,6 +94,10 @@
*/
public class MultipartPostMethod extends GetMethod {

+ /** The Content-Type for multipart/form-data. */
+ public static final String MULTIPART_FORM_CONTENT_TYPE = + "multipart/form-data";
+
/** Log object for this class. */
private static final Log LOG = LogFactory.getLog(MultipartPostMethod.class);

@@ -204,6 +208,14 @@
}

/**
+ * Return all parts.
+ * + * @return an array of containing all parts
+ */
+ public Part[] getParts() {
+ return (Part[])parameters.toArray(new Part[parameters.size()]);
+ }
+ /**
* Add a request header.
* * @param state the client state
@@ -218,8 +230,12 @@
super.addRequestHeaders(state, conn);
if (!parameters.isEmpty()) {
- setRequestHeader("Content-Type", - "multipart/form-data; boundary=" + Part.getBoundary());
+ StringBuffer buffer = new StringBuffer(MULTIPART_FORM_CONTENT_TYPE);
+ if (Part.getBoundary() != null) {
+ buffer.append("; boundary=");
+ buffer.append(Part.getBoundary());
+ }
+ setRequestHeader("Content-Type", buffer.toString());
}
}

@@ -237,16 +253,7 @@
throws IOException, HttpException {
LOG.trace("enter writeRequestBody(HttpState state, HttpConnection conn)");
OutputStream out = conn.getRequestOutputStream();
- - for (Iterator it = parameters.iterator(); it.hasNext();) {
- final Part part = (Part) it.next();
- part.send(out);
- }
- - Part.sendLastBoundary(out);
-
- out.flush();
- + Part.sendParts(out, getParts());
return true;
}

@@ -260,26 +267,17 @@
*/
protected int getRequestContentLength() {
LOG.trace("enter getRequestContentLength()");
- long length = 0;
- try {
- for (Iterator it = parameters.iterator(); it.hasNext();) {
- final Part part = (Part) it.next();
- - length += part.length();
+ long len = Part.getLengthOfParts(getParts());
+ // Chop the length to the max int value.
+ if (len <= Integer.MAX_VALUE) {
+ return (int)len;
+ } else {
+ return (Integer.MAX_VALUE);
}
- length += Part.lengthOfLastBoundary();
-
} catch (IOException e) {
// Can't throw an IOException and still override
throw new RuntimeException(e.toString());
- }
- - // Chop the length to the max int value.
- if (length <= Integer.MAX_VALUE) {
- return ((new Long(length)).intValue());
- } else {
- return (Integer.MAX_VALUE);
}
}
}
Index: src/java/org/apache/commons/httpclient/methods/multipart/FilePart.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/multipart/FilePart.java,v
retrieving revision 1.10
diff -u -r1.10 FilePart.java
--- src/java/org/apache/commons/httpclient/methods/multipart/FilePart.java 28 Jan 2003 22:25:31 -0000 1.10
+++ src/java/org/apache/commons/httpclient/methods/multipart/FilePart.java 10 Feb 2003 22:02:15 -0000
@@ -82,27 +82,84 @@
* @author <a href="mailto:[EMAIL PROTECTED]";>Michael Becke</a>
* @author <a href="mailto:[EMAIL PROTECTED]";>Mark Diggory</a>
* @author <a href="mailto:[EMAIL PROTECTED]";>Mike Bowler</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]";>Oleg Kalnichevski</a>
* * @since 2.0 *
*/
public class FilePart extends Part {

+ /** Default content encoding of file attachments. */
+ public static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";
+
+ /** Default charset of file attachments. */
+ public static final String DEFAULT_CHARSET = HttpConstants.DEFAULT_CONTENT_CHARSET;
+
+ /** Default transfer encoding of file attachments. */
+ public static final String DEFAULT_TRANSFER_ENCODING = "binary";
+
/** Log object for this class. */
private static final Log LOG = LogFactory.getLog(FilePart.class);

- /**
- * <p>The maximum buffer size.</p>
- * TODO: make this configurable
- */
- private static final int MAX_BUFF_SIZE = 1 * 1024 * 1024; // 1 MiBs
- +
+ /** Attachment's file name */
+ protected static final String FILE_NAME = "; filename=";
+
+ /** Attachment's file name as a byte array */
+ protected static final byte[] FILE_NAME_BYTES = + HttpConstants.getAsciiBytes(FILE_NAME);
+
/** Name of the file part. */
private String name;

/** Source of the file part. */
private PartSource source;
+ /** Content type of the file part. */
+ private String contentType;
+
+ /** Content encoding of the file part. */
+ private String charset;
+
+ /**
+ * FilePart Constructor.
+ *
+ * @param name the name for this part
+ * @param partSource the source for this part
+ * @param contentType the content type for this part
+ * @param charset the charset encoding for this part
+ */
+ public FilePart(String name, PartSource partSource, String contentType, String charset) {
+ LOG.trace("enter FilePart(String, PartSource, String, String)");
+ if (name == null) {
+ throw new IllegalArgumentException("Name may not be null");
+ }
+ this.name = name;
+ if (partSource == null) {
+ throw new IllegalArgumentException("Source may not be null");
+ }
+ if (partSource.getLength() < 0) {
+ throw new IllegalArgumentException("Source length must be >= 0");
+ }
+ this.source = partSource;
+ if (contentType != null) {
+ this.contentType = contentType;
+ } else {
+ this.contentType = DEFAULT_CONTENT_TYPE;
+ }
+ this.charset = charset;
+ }
+ + /**
+ * FilePart Constructor.
+ *
+ * @param name the name for this part
+ * @param partSource the source for this part
+ */
+ public FilePart(String name, PartSource partSource) {
+ this(name, partSource, null, null);
+ }
+
/**
* FilePart Constructor.
*
@@ -114,7 +171,23 @@
*/
public FilePart(String name, File file) throws FileNotFoundException {
- this(name, new FilePartSource(file));
+ this(name, new FilePartSource(file), null, null);
+ }
+
+ /**
+ * FilePart Constructor.
+ *
+ * @param name the name of the file part
+ * @param file the file to post
+ * @param contentType the content type for the file
+ * @param charset the charset encoding of the file
+ *
+ * @throws FileNotFoundException if the <i>file</i> is not a normal
+ * file or if it is not readable.
+ */
+ public FilePart(String name, File file, String contentType, String charset) + throws FileNotFoundException {
+ this(name, new FilePartSource(file), contentType, charset);
}

/**
@@ -129,71 +202,77 @@
*/
public FilePart(String name, String fileName, File file) throws FileNotFoundException {
- this(name, new FilePartSource(fileName, file));
+ this(name, new FilePartSource(fileName, file), null, null);
}
- /**
+ /**
* FilePart Constructor.
*
- * @param name the name for this part
- * @param partSource the source for this part
+ * @param name the name of the file part
+ * @param fileName the file name + * @param file the file to post
+ * @param contentType the content type for the file
+ * @param charset the charset encoding of the file
+ *
+ * @throws FileNotFoundException if the <i>file</i> is not a normal
+ * file or if it is not readable.
*/
- public FilePart(String name, PartSource partSource) {
-
- if (partSource.getLength() < 0) {
- throw new IllegalArgumentException("fileLength must be >= 0");
- }
-
- this.name = name;
- this.source = partSource;
-
+ public FilePart(String name, String fileName, File file, String contentType, String charset) + throws FileNotFoundException {
+ this(name, new FilePartSource(fileName, file), contentType, charset);
}
- + /**
- * Write the header to the output stream
- * @param out The output stream
- * @throws IOException If an IO problem occurs
- * @see org.apache.commons.httpclient.methods.multipart.Part#sendHeader(OutputStream)
+ * Return the name.
+ * @return The name.
+ * @see org.apache.commons.httpclient.methods.multipart.Part#getName()
*/
- protected void sendHeader(OutputStream out) - throws IOException {
- LOG.trace("enter sendHeader(OutputStream out)");
- super.sendHeader(out);
- sendFilename(out);
- sendContentType(out);
+ public String getName() { + return this.name; }
- +
/**
- * Write the filename to the output stream
- * @param out The output stream
- * @throws IOException If an IO problem occurs
+ * Return the content type of this part.
+ * @return String The name.
*/
- protected void sendFilename(OutputStream out) - throws IOException {
- LOG.trace("enter sendFilename(OutputStream out)");
- String filename = "; filename=\"" + source.getFileName() + "\"";
- out.write(HttpConstants.getBytes(filename));
+ public String getContentType() {
+ return this.contentType;
}

/**
- * Write the Content-Type header to the output stream
- * @param out The output stream.
- * @throws IOException If an IO problem occurs
+ * Return the character encoding of this part.
+ * @return String The name.
*/
- protected void sendContentType(OutputStream out) - throws IOException {
- LOG.trace("enter sendContentType(OutputStream out)");
- out.write(CRLF_BYTES);
- out.write(HttpConstants.getBytes("Content-Type: application/octet-stream"));
- } + public String getCharSet() {
+ return this.charset;
+ }

/**
- * Return the name.
- * @return The name.
- * @see org.apache.commons.httpclient.methods.multipart.Part#getName()
+ * Return the transfer encoding of this part.
+ * @return String The name.
*/
- public String getName() { - return name; +
+ public String getTransferEncoding() {
+ return DEFAULT_TRANSFER_ENCODING;
+ }
+ + /**
+ * Write the disposition header to the output stream
+ * @param out The output stream
+ * @throws IOException If an IO problem occurs
+ * @see org.apache.commons.httpclient.methods.multipart.Part#sendHeader(OutputStream)
+ */
+ protected void sendDispositionHeader(OutputStream out) + throws IOException {
+ LOG.trace("enter sendDispositionHeader(OutputStream out)");
+ super.sendDispositionHeader(out);
+ String filename = this.source.getFileName();
+ if (filename != null) {
+ out.write(FILE_NAME_BYTES);
+ out.write(QUOTE_BYTES);
+ out.write(HttpConstants.getAsciiBytes(filename));
+ out.write(QUOTE_BYTES);
+ }
}
/**
@@ -204,9 +283,6 @@
*/
protected void sendData(OutputStream out) throws IOException {
LOG.trace("enter sendData(OutputStream out)");
- - byte[] buff;
- if (lengthOfData() == 0) {
// this file contains no data, so there is nothing to send.
@@ -214,20 +290,15 @@
// cause an infinite loop when reading.
LOG.debug("No data to send.");
return;
- - } else if (lengthOfData() > MAX_BUFF_SIZE) {
- buff = new byte[MAX_BUFF_SIZE];
- } else {
- buff = new byte[(new Long(lengthOfData())).intValue()];
}
- InputStream is = source.createInputStream();
+ byte[] tmp = new byte[4096];
+ InputStream instream = source.createInputStream();

int len;
- while ((len = is.read(buff)) != -1) {
- out.write(buff, 0, len);
+ while ((len = instream.read(tmp)) >= 0) {
+ out.write(tmp, 0, len);
}
-
}

/**
@@ -237,8 +308,8 @@
* @see org.apache.commons.httpclient.methods.multipart.Part#lengthOfData()
*/ protected long lengthOfData() throws IOException {
+ LOG.trace("enter lengthOfData()");
return source.getLength();
}
-}
-
+}
\ No newline at end of file
Index: src/java/org/apache/commons/httpclient/methods/multipart/Part.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/multipart/Part.java,v
retrieving revision 1.7
diff -u -r1.7 Part.java
--- src/java/org/apache/commons/httpclient/methods/multipart/Part.java 28 Jan 2003 22:25:31 -0000 1.7
+++ src/java/org/apache/commons/httpclient/methods/multipart/Part.java 10 Feb 2003 22:02:16 -0000
@@ -63,10 +63,13 @@

package org.apache.commons.httpclient.methods.multipart;

+import java.io.IOException;
import java.io.OutputStream;
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
-import java.io.IOException;
+
import org.apache.commons.httpclient.HttpConstants;
+import org.apache.commons.httpclient.WireLogOutputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

@@ -77,6 +80,7 @@
* @author <a href="mailto:[EMAIL PROTECTED]";>Jeff Dever</a>
* @author <a href="mailto:[EMAIL PROTECTED]";>Adrian Sutton</a>
* @author <a href="mailto:[EMAIL PROTECTED]";>Mike Bowler</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]";>Oleg Kalnichevski</a>
*
* @since 2.0
*/
@@ -85,26 +89,65 @@
/** Log object for this class. */
private static final Log LOG = LogFactory.getLog(Part.class);

+ /** Log for any wire messages. */
+ private static final Log WIRE_LOG = LogFactory.getLog("httpclient.wire");
+
//TODO: Make this configurable
/** The boundary */
- private static final String BOUNDARY = "----------------314159265358979323846";
+ protected static final String BOUNDARY = "----------------314159265358979323846";
/** The boundary as a byte array */
- private static final byte[] BOUNDARY_BYTES = HttpConstants.getBytes(BOUNDARY);
+ protected static final byte[] BOUNDARY_BYTES = HttpConstants.getAsciiBytes(BOUNDARY);
/** Carriage return/linefeed */
- private static final String CRLF = "\r\n";
+ protected static final String CRLF = "\r\n";
/** Carriage return/linefeed as a byte array */
- protected static final byte[] CRLF_BYTES = HttpConstants.getBytes(CRLF);
+ protected static final byte[] CRLF_BYTES = HttpConstants.getAsciiBytes(CRLF);
+ /** Content dispostion characters */
+ protected static final String QUOTE = "\"";
+ + /** Content dispostion as a byte array */
+ protected static final byte[] QUOTE_BYTES = + HttpConstants.getAsciiBytes(QUOTE);
+
/** Extra characters */
- private static final String EXTRA = "--";
+ protected static final String EXTRA = "--";
/** Extra characters as a byte array */
- private static final byte[] EXTRA_BYTES = HttpConstants.getBytes(EXTRA);
+ protected static final byte[] EXTRA_BYTES = + HttpConstants.getAsciiBytes(EXTRA);
+ + /** Content dispostion characters */
+ protected static final String CONTENT_DISPOSITION = "Content-Disposition: form-data; name=";
+ /** Content dispostion as a byte array */
+ protected static final byte[] CONTENT_DISPOSITION_BYTES = + HttpConstants.getAsciiBytes(CONTENT_DISPOSITION);
+
+ /** Content type header */
+ protected static final String CONTENT_TYPE = "Content-Type: ";
+
+ /** Content type header as a byte array */
+ protected static final byte[] CONTENT_TYPE_BYTES = + HttpConstants.getAsciiBytes(CONTENT_TYPE);
+
+ /** Content charset */
+ protected static final String CHARSET = "; charset=";
+
+ /** Content charset as a byte array */
+ protected static final byte[] CHARSET_BYTES = + HttpConstants.getAsciiBytes(CHARSET);
+
+ /** Content type header */
+ protected static final String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding: ";
+
+ /** Content type header as a byte array */
+ protected static final byte[] CONTENT_TRANSFER_ENCODING_BYTES = + HttpConstants.getAsciiBytes(CONTENT_TRANSFER_ENCODING);
+
/**
* Return the boundary string.
* @return the boundary string
@@ -114,40 +157,29 @@
}
/**
- * Write the last boundary to the specified output stream
- * @param out The output stream
- * @throws IOException If an IO problem occurs.
+ * Return the name of this part.
+ * @return String The name.
*/
- public static void sendLastBoundary(OutputStream out)
- throws IOException {
- LOG.trace("enter sendLastBoundary(OutputStream out)");
- out.write(EXTRA_BYTES);
- out.write(BOUNDARY_BYTES);
- out.write(EXTRA_BYTES);
- out.write(CRLF_BYTES);
- }
+ public abstract String getName();
/**
- * Return the length of the last boundary string
- * - * @return int The length of the last boundary string
- * @throws IOException If an IO problem occurs
+ * Return the content type of this part.
+ * @return String The name.
*/
- public static int lengthOfLastBoundary() throws IOException {
- LOG.trace("enter lengthOfLastBoundary()");
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- - sendLastBoundary(out);
- - return out.size();
- }
- + public abstract String getContentType();
+
/**
- * Return the name of this part.
+ * Return the character encoding of this part.
* @return String The name.
*/
- public abstract String getName();
- + public abstract String getCharSet();
+
+ /**
+ * Return the transfer encoding of this part.
+ * @return String The name.
+ */
+ public abstract String getTransferEncoding();
+
/**
* Write the start to the specified output stream
* @param out The output stream
@@ -161,44 +193,58 @@
}
/**
- * Return the length of the starting data
- * @return int The length of the data
- * @throws IOException If an IO problem occurs
+ * Write the content disposition header to the specified output stream
+ * + * @param out The output stream
+ * @throws IOException If an IO problem occurs.
*/
- protected int lengthOfStart() throws IOException {
- LOG.trace("enter lengthOfStart()");
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- sendStart(out);
- return out.size();
+ protected void sendDispositionHeader(OutputStream out) throws IOException {
+ LOG.trace("enter sendDispositionHeader(OutputStream out)");
+ out.write(CONTENT_DISPOSITION_BYTES);
+ out.write(QUOTE_BYTES);
+ out.write(HttpConstants.getAsciiBytes(getName()));
+ out.write(QUOTE_BYTES);
}
/**
- * Write the header to the specified output stream
+ * Write the content type header to the specified output stream
* @param out The output stream
* @throws IOException If an IO problem occurs.
*/
- protected void sendHeader(OutputStream out) throws IOException {
- LOG.trace("enter sendHeader(OutputStream out)");
- String contentDisposition = "Content-Disposition: form-data; name=\"" - + getName() + "\"";
- - out.write(HttpConstants.getBytes(contentDisposition));
+ + protected void sendContentTypeHeader(OutputStream out) throws IOException {
+ LOG.trace("enter sendContentTypeHeader(OutputStream out)");
+ String contentType = getContentType();
+ if (contentType != null) {
+ out.write(CRLF_BYTES);
+ out.write(CONTENT_TYPE_BYTES);
+ out.write(HttpConstants.getAsciiBytes(contentType));
+ String charSet = getCharSet();
+ if (charSet != null) {
+ out.write(CHARSET_BYTES);
+ out.write(HttpConstants.getAsciiBytes(charSet));
+ }
+ }
}
- +
/**
- * Return the length of the header
+ * Write the content transfer encoding header to the specified + * output stream
* - * @return long The length.
- * @throws IOException If an IO problem occurs
+ * @param out The output stream
+ * @throws IOException If an IO problem occurs.
*/
- protected int lengthOfHeader() throws IOException {
- LOG.trace("enter lengthOfHeader()");
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- sendHeader(out);
- return (out.size());
+ + protected void sendTransferEncodingHeader(OutputStream out) throws IOException {
+ LOG.trace("enter sendTransferEncodingHeader(OutputStream out)");
+ String transferEncoding = getTransferEncoding();
+ if (transferEncoding != null) {
+ out.write(CRLF_BYTES);
+ out.write(CONTENT_TRANSFER_ENCODING_BYTES);
+ out.write(HttpConstants.getAsciiBytes(transferEncoding));
+ }
}
- - +
/**
* Write the end of the header to the output stream
* @param out The output stream
@@ -211,20 +257,6 @@
}
/**
- * Return the length of the end of header
- * - * @return long The length.
- * @throws IOException If an IO problem occurs
- */
- protected int lengthOfEndOfHeader() throws IOException {
- LOG.trace("enter lengthOfEndOfHeader()");
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- sendEndOfHeader(out);
- return out.size();
- }
- - - /**
* Write the data to the specified output stream
* @param out The output stream
* @throws IOException If an IO problem occurs.
@@ -249,51 +281,60 @@
out.write(CRLF_BYTES);
}
- /**
- * Return the length of the end data
- * - * @return long The length.
- * @throws IOException If an IO problem occurs
- */
- protected int lengthOfEnd() throws IOException {
- LOG.trace("enter lengthOfEnd()");
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- sendEnd(out);
- return out.size();
- }
- - /* The following 2 methods don't need to be final, but they DO need
- * to be overridden as a pair, and the only way to make sure of that
- * is to make sure they AREN'T overridden. - */
-
+/*
+ protected static void byteArrayToWire(final byte[] rawdata, final String charset) + throws IOException {
+ Reader reader = null;
+ try {
+ reader = new InputStreamReader(new ByteArrayInputStream(rawdata), charset);
+ } catch (UnsupportedEncodingException e) {
+ reader = new InputStreamReader(new ByteArrayInputStream(rawdata));
+ }
+ BufferedReader in = new BufferedReader(reader);
+ String line;
+ while( (line = in.readLine()) != null ) {
+ WIRE_LOG.debug(">> \"" + line + "\" [\\r\\n]");
+ }
+ } + */ /**
* Write all the data to the output stream.
+ * If you override this method make sure to override + * #length() as well
+ * * @param out The output stream
* @throws IOException If an IO problem occurs.
*/
- public final void send(OutputStream out) throws IOException {
+ public void send(OutputStream out) throws IOException {
LOG.trace("enter send(OutputStream out)");
sendStart(out);
- sendHeader(out);
+ sendDispositionHeader(out);
+ sendContentTypeHeader(out);
+ sendTransferEncodingHeader(out);
sendEndOfHeader(out);
sendData(out);
sendEnd(out);
}
- +
+
/**
* Return the full length of all the data.
+ * If you override this method make sure to override + * #send(OutputStream) as well
* * @return long The length.
* @throws IOException If an IO problem occurs
*/
- public final long length() throws IOException {
+ public long length() throws IOException {
LOG.trace("enter length()");
- return lengthOfStart()
- + lengthOfHeader()
- + lengthOfEndOfHeader()
- + lengthOfData()
- + lengthOfEnd();
+ ByteArrayOutputStream overhead = new ByteArrayOutputStream();
+ sendStart(overhead);
+ sendDispositionHeader(overhead);
+ sendContentTypeHeader(overhead);
+ sendTransferEncodingHeader(overhead);
+ sendEndOfHeader(overhead);
+ sendEnd(overhead);
+ return overhead.size() + lengthOfData();
}

/**
@@ -304,4 +345,55 @@
public String toString() {
return this.getName();
}
+
+
+ /**
+ * Write all parts and the last boundary to the specified output stream
+ * + * @param out The output stream
+ * @param parts The array of parts to be sent
+ * + * @throws IOException If an IO problem occurs.
+ */
+ public static void sendParts(OutputStream out, final Part[] parts)
+ throws IOException {
+ LOG.trace("enter sendParts(OutputStream out, Parts[])");
+ if (parts == null) {
+ throw new IllegalArgumentException("Parts may not be null"); + }
+ if (WIRE_LOG.isDebugEnabled()) {
+ out = new WireLogOutputStream(out, "US-ACSII"); + }
+ for (int i = 0; i < parts.length; i++) {
+ parts[i].send(out);
+ }
+ out.write(EXTRA_BYTES);
+ out.write(BOUNDARY_BYTES);
+ out.write(EXTRA_BYTES);
+ out.write(CRLF_BYTES);
+ }
+
+ /**
+ * Return the total sum of all parts and that of the last boundary
+ * + * @param parts The array of parts
+ * + * @throws IOException If an IO problem occurs.
+ */
+ public static long getLengthOfParts(final Part[] parts)
+ throws IOException {
+ LOG.trace("getLengthOfParts(Parts[])");
+ if (parts == null) {
+ throw new IllegalArgumentException("Parts may not be null"); + }
+ long total = 0;
+ for (int i = 0; i < parts.length; i++) {
+ total += parts[i].length();
+ }
+ total += EXTRA_BYTES.length;
+ total += BOUNDARY_BYTES.length;
+ total += EXTRA_BYTES.length;
+ total += CRLF_BYTES.length;
+ return total;
+ } }
Index: src/java/org/apache/commons/httpclient/methods/multipart/StringPart.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/multipart/StringPart.java,v
retrieving revision 1.5
diff -u -r1.5 StringPart.java
--- src/java/org/apache/commons/httpclient/methods/multipart/StringPart.java 28 Jan 2003 22:25:31 -0000 1.5
+++ src/java/org/apache/commons/httpclient/methods/multipart/StringPart.java 10 Feb 2003 22:02:17 -0000
@@ -66,6 +66,8 @@
import java.io.OutputStream;
import java.io.IOException;
import org.apache.commons.httpclient.HttpConstants;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;

/**
* Simple string parameter for a multipart post
@@ -73,26 +75,69 @@
* @author <a href="mailto:[EMAIL PROTECTED]";>Matthew Albright</a>
* @author <a href="mailto:[EMAIL PROTECTED]";>Jeff Dever</a>
* @author <a href="mailto:[EMAIL PROTECTED]";>Mike Bowler</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]";>Oleg Kalnichevski</a>
*
* @since 2.0
*/
public class StringPart extends Part {

+ /** Log object for this class. */
+ private static final Log LOG = LogFactory.getLog(StringPart.class);
+
+ /** Default content encoding of string parameters. */
+ public static final String DEFAULT_CONTENT_TYPE = "text/plain";
+
+ /** Default charset of string parameters*/
+ public static final String DEFAULT_CHARSET = "US-ASCII";
+
+ /** Default transfer encoding of string parameters*/
+ public static final String DEFAULT_TRANSFER_ENCODING = "8bit";
+
/** Name of this StringPart. */
private String name;

/** Contents of this StringPart. */
- private String value;
+ private byte[] content;
+
+ /** Charset of this StringPart. */
+ private String charset;
/**
* Constructor.
*
* @param name The name of the part
* @param value the string to post
+ * @param charset the charset to be used to encode the string
*/
- public StringPart(String name, String value) {
+ public StringPart(String name, String value, String charset) {
+ LOG.trace("enter StringPart(String, String, String)");
+ if (name == null) {
+ throw new IllegalArgumentException("Name may not be null");
+ }
this.name = name;
- this.value = value;
+ if (charset != null) {
+ this.charset = charset;
+ } else {
+ this.charset = DEFAULT_CHARSET;
+ }
+ if (value == null) {
+ throw new IllegalArgumentException("Value may not be null");
+ }
+ if (value.indexOf(0) != -1) {
+ // See RFC 2048, 2.8. "8bit Data"
+ throw new IllegalArgumentException("NULs may not be present in string parts");
+ }
+ this.content = HttpConstants.getContentBytes(value, this.charset);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param name The name of the part
+ * @param value the string to post
+ */
+ public StringPart(String name, String value) {
+ this(name, value, null);
}

/**
@@ -102,15 +147,35 @@
public String getName() {
return name; }
- +
/**
- * Write the data to the specified output stream
- * @param out The output stream.
- * @throws IOException If an IO problem occurs
- * @see org.apache.commons.httpclient.methods.multipart.Part#sendData(OutputStream)
+ * Return the content type of this part.
+ * @return String The name.
+ */
+ public String getContentType() {
+ return DEFAULT_CONTENT_TYPE;
+ }
+
+ /**
+ * Return the character encoding of this part.
+ * @return String The name.
*/
+ public String getCharSet() {
+ return this.charset;
+ }
+
+ /**
+ * Return the transfer encoding of this part.
+ * @return String The name.
+ */
+
+ public String getTransferEncoding() {
+ return DEFAULT_TRANSFER_ENCODING;
+ }
+ protected void sendData(OutputStream out) throws IOException {
- out.write(HttpConstants.getBytes(value)); + LOG.trace("enter sendData(OutputStream)");
+ out.write(this.content);
}
/**
@@ -120,6 +185,7 @@
* @see org.apache.commons.httpclient.methods.multipart.Part#lengthOfData()
*/
protected long lengthOfData() throws IOException {
- return HttpConstants.getBytes(value).length;
+ LOG.trace("enter lengthOfData()");
+ return this.content.length;
}
}
Index: src/java/org/apache/commons/httpclient/util/Wire.java
===================================================================
RCS file: src/java/org/apache/commons/httpclient/util/Wire.java
diff -N src/java/org/apache/commons/httpclient/util/Wire.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/java/org/apache/commons/httpclient/util/Wire.java 10 Feb 2003 22:02:14 -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.util;
+
+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
+ */
+
+public 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: src/test/org/apache/commons/httpclient/TestWebapp.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestWebapp.java,v
retrieving revision 1.6
diff -u -r1.6 TestWebapp.java
--- src/test/org/apache/commons/httpclient/TestWebapp.java 1 Feb 2003 16:10:48 -0000 1.6
+++ src/test/org/apache/commons/httpclient/TestWebapp.java 10 Feb 2003 22:02:05 -0000
@@ -1,5 +1,5 @@
/*
- * $Header: /home/cvspublic/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestWebapp.java,v 1.6 2003/02/01 16:10:48 olegk Exp $
+ * $Header: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestWebapp.java,v 1.6 2003/02/01 16:10:48 olegk Exp $
* $Revision: 1.6 $
* $Date: 2003/02/01 16:10:48 $
* ====================================================================
@@ -100,6 +100,7 @@
suite.addTest(TestWebappBasicAuth.suite());
suite.addTest(TestWebappCookie.suite());
suite.addTest(TestWebappPostMethod.suite());
+ suite.addTest(TestWebappMultiPostMethod.suite());
suite.addTest(TestWebappNoncompliant.suite());
return suite;
}
Index: src/test/org/apache/commons/httpclient/TestWebappMultiPostMethod.java
===================================================================
RCS file: src/test/org/apache/commons/httpclient/TestWebappMultiPostMethod.java
diff -N src/test/org/apache/commons/httpclient/TestWebappMultiPostMethod.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/test/org/apache/commons/httpclient/TestWebappMultiPostMethod.java 10 Feb 2003 22:02:06 -0000
@@ -0,0 +1,146 @@
+/*
+ * $Header: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestWebappPostMethod.java,v 1.2 2003/02/03 21:21:19 olegk Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/02/03 21:21:19 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 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 junit.framework.*;
+import org.apache.commons.httpclient.methods.*;
+import org.apache.commons.httpclient.methods.multipart.*;
+import java.io.*;
+
+/**
+ * Webapp tests specific to the MultiPostMethod.
+ *
+ * @author <a href="[EMAIL PROTECTED]">Oleg Kalnichevski</a>
+ */
+public class TestWebappMultiPostMethod extends TestWebappBase {
+
+ HttpClient httpClient; + final static String paramsUrl = "http://"; + host + ":" + port
+ + "/" + context + "/params";
+ final static String bodyUrl = "http://"; + host + ":" + port
+ + "/" + context + "/body";
+
+ public TestWebappMultiPostMethod(String testName) {
+ super(testName);
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite(TestWebappMultiPostMethod.class);
+ return suite;
+ }
+
+ public static void main(String args[]) {
+ String[] testCaseName = { TestWebappMultiPostMethod.class.getName() };
+ junit.textui.TestRunner.main(testCaseName);
+ }
+
+ public void setUp() {
+ httpClient = new HttpClient();
+ }
+
+ // ------------------------------------------------------------------ Tests
+ + /**
+ * Test that the body consisting of a string part can be posted.
+ */
+
+ public void testPostStringPart() throws Exception {
+ MultipartPostMethod method = new MultipartPostMethod(bodyUrl);
+ method.addPart(new StringPart("param", "Hello", "ISO-8859-1"));
+
+ httpClient.executeMethod(method);
+
+ assertEquals(200,method.getStatusCode());
+ String body = method.getResponseBodyAsString();
+ assertTrue(body.indexOf("Content-Disposition: form-data; name=\"param\"") >= 0);
+ assertTrue(body.indexOf("Content-Type: text/plain; charset=ISO-8859-1") >= 0);
+ assertTrue(body.indexOf("Content-Transfer-Encoding: 8bit") >= 0);
+ assertTrue(body.indexOf("Hello") >= 0);
+ }
+
+
+ /**
+ * Test that the body consisting of a file part can be posted.
+ */
+ public void testPostFilePart() throws Exception {
+ MultipartPostMethod method = new MultipartPostMethod(bodyUrl);
+ byte[] content = new byte[] {'H', 'e', 'l', 'l', 'o' };
+ method.addPart(
+ new FilePart(
+ "param1", + new ByteArrayPartSource("filename.txt", content), + "text/plain", + "ISO-8859-1"));
+
+ httpClient.executeMethod(method);
+
+ assertEquals(200,method.getStatusCode());
+ String body = method.getResponseBodyAsString();
+ assertTrue(body.indexOf("Content-Disposition: form-data; name=\"param1\"; filename=\"filename.txt\"") >= 0);
+ assertTrue(body.indexOf("Content-Type: text/plain; charset=ISO-8859-1") >= 0);
+ assertTrue(body.indexOf("Content-Transfer-Encoding: binary") >= 0);
+ assertTrue(body.indexOf("Hello") >= 0);
+ }
+}
+



------------------------------------------------------------------------

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to