You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by Ted Husted <hu...@apache.org> on 2001/11/02 11:32:33 UTC
Re: cvs commit: jakarta-struts/src/share/org/apache/struts/upload
BufferedMultipartInputStream.java MultipartIterator.java
Are 3702 and 3828 resolved now?
Or are they being held open pending the unit test?
mschachter@apache.org wrote:
>
> mschachter 01/10/11 09:28:17
>
> Modified: src/share/org/apache/struts/upload
> BufferedMultipartInputStream.java
> MultipartIterator.java
> Log:
> - port from 1.0 branch to address bugs #3702, #3828, and #2683
>
> Revision Changes Path
> 1.6 +7 -4 jakarta-struts/src/share/org/apache/struts/upload/BufferedMultipartInputStream.java
>
> Index: BufferedMultipartInputStream.java
> ===================================================================
> RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/upload/BufferedMultipartInputStream.java,v
> retrieving revision 1.5
> retrieving revision 1.6
> diff -u -r1.5 -r1.6
> --- BufferedMultipartInputStream.java 2001/09/24 16:41:37 1.5
> +++ BufferedMultipartInputStream.java 2001/10/11 16:28:17 1.6
> @@ -218,13 +218,16 @@
>
> int read = read();
> ByteArrayOutputStream baos = new ByteArrayOutputStream();
> - while (read != -1) {
> - if (read == '\n') {
> - return baos.toByteArray();
> - }
> +
> + // return null if there are no more bytes to read
> + if( -1 == read )
> + return null;
> +
> + while ((read != -1) && (read != '\n')) {
> baos.write(read);
> read = read();
> }
> +
> return baos.toByteArray();
> }
>
>
>
>
> 1.18 +95 -90 jakarta-struts/src/share/org/apache/struts/upload/MultipartIterator.java
>
> Index: MultipartIterator.java
> ===================================================================
> RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/upload/MultipartIterator.java,v
> retrieving revision 1.17
> retrieving revision 1.18
> diff -u -r1.17 -r1.18
> --- MultipartIterator.java 2001/09/24 16:41:37 1.17
> +++ MultipartIterator.java 2001/10/11 16:28:17 1.18
> @@ -21,7 +21,7 @@
> * <pre>
> * MultipartIterator iterator = new MultipartIterator(request);
> * MultipartElement element;
> - *
> + *
> * while ((element = iterator.getNextElement()) != null) {
> * //do something with element
> * }
> @@ -31,64 +31,64 @@
> * @author Mike Schachter
> */
> public class MultipartIterator {
> -
> +
> /**
> * The maximum size in bytes of the buffer used to read lines [4K]
> */
> public static int MAX_LINE_SIZE = 4096;
> -
> +
> /**
> * The request instance for this class
> */
> protected HttpServletRequest request;
> -
> +
> /**
> * The input stream instance for this class
> */
> protected BufferedMultipartInputStream inputStream;
> -
> +
> /**
> * The boundary for this multipart request
> */
> protected String boundary;
> -
> +
> /**
> * The byte array representing the boundary for this multipart request
> */
> protected byte[] boundaryBytes;
> -
> +
> /**
> * Whether or not the input stream is finished
> */
> protected boolean contentRead = false;
> -
> +
> /**
> * The maximum file size in bytes allowed. Ignored if -1
> */
> protected long maxSize = -1;
> -
> +
> /**
> * The total bytes read from this request
> */
> protected long totalLength = 0;
> -
> +
> /**
> * The content length of this request
> */
> protected int contentLength;
> -
> +
> /**
> * The size in bytes written to the filesystem at a time [20K]
> */
> protected int diskBufferSize = 2 * 10240;
> -
> +
> /**
> * The amount of data read from a request at a time.
> * This also represents the maximum size in bytes of
> * a line read from the request [4KB]
> */
> protected int bufferSize = 4096;
> -
> +
> /**
> * The temporary directory to store files
> */
> @@ -97,13 +97,13 @@
> /**
> * Constructs a MultipartIterator with a default buffer size and no file size
> * limit
> - *
> + *
> * @param request The multipart request to iterate
> */
> public MultipartIterator(HttpServletRequest request) throws ServletException{
> this(request, -1);
> }
> -
> +
> /**
> * Constructs a MultipartIterator with the specified buffer size and
> * no file size limit
> @@ -112,10 +112,10 @@
> * @param bufferSize The size in bytes that should be read from the input
> * stream at a times
> */
> - public MultipartIterator(HttpServletRequest request, int bufferSize) throws ServletException {
> + public MultipartIterator(HttpServletRequest request, int bufferSize) throws ServletException {
> this (request, bufferSize, -1);
> }
> -
> +
> /**
> * Constructs a MultipartIterator with the specified buffer size and
> * the specified file size limit in bytes
> @@ -125,18 +125,18 @@
> * stream at a times
> * @param maxSize The maximum size in bytes allowed for a multipart element's data
> */
> - public MultipartIterator(HttpServletRequest request, int bufferSize, long maxSize)
> + public MultipartIterator(HttpServletRequest request, int bufferSize, long maxSize)
> throws ServletException {
> -
> - this(request, bufferSize, maxSize, null);
> -
> +
> + this(request, bufferSize, maxSize, null);
> +
> }
> -
> +
> public MultipartIterator(HttpServletRequest request,
> int bufferSize,
> long maxSize,
> String tempDir) throws ServletException {
> -
> +
> this.request = request;
> this.maxSize = maxSize;
> if (bufferSize > -1) {
> @@ -151,7 +151,7 @@
> }
> parseRequest();
> }
> -
> +
> /**
> * Retrieves the next element in the iterator if one exists.
> *
> @@ -166,18 +166,18 @@
> //retrieve the "Content-Disposition" header
> //and parse
> String disposition = readLine();
> -
> -
> +
> +
> if ((disposition != null) && (disposition.startsWith("Content-Disposition"))) {
> String name = parseDispositionName(disposition);
> String filename = parseDispositionFilename(disposition);
> -
> +
> String contentType = null;
> boolean isFile = (filename != null);
> -
> +
> if (isFile) {
> filename = new File(filename).getName();
> -
> +
> //check for windows filenames,
> //from linux jdk's the entire filepath
> //isn't parsed correctly from File.getName()
> @@ -187,29 +187,29 @@
> colonIndex = filename.indexOf("\\\\");
> }
> int slashIndex = filename.lastIndexOf("\\");
> -
> +
> if ((colonIndex > -1) && (slashIndex > -1)) {
> //then consider this filename to be a full
> //windows filepath, and parse it accordingly
> //to retrieve just the file name
> filename = filename.substring(slashIndex+1, filename.length());
> }
> -
> +
> //get the content type
> contentType = readLine();
> contentType = parseContentType(contentType);
> }
> -
> -
> -
> +
> +
> +
> //ignore next line (whitespace) (unless it's a file
> //without content-type)
> if (! ((isFile) && contentType == null)) {
> readLine();
> }
> -
> +
> MultipartElement element = null;
> -
> +
> //process a file element
> if (isFile) {
> try {
> @@ -218,6 +218,7 @@
>
> element = new MultipartElement(name, filename, contentType, elementFile);
> } catch (IOException ioe) {
> + ioe.printStackTrace(System.err);
> throw new ServletException("IOException while reading file element: " + ioe.getMessage(), ioe);
> }
> }
> @@ -240,13 +241,13 @@
> textData.setLength(textData.length()-1);
> }
> }
> -
> +
> //create the element
> element = new MultipartElement(name, textData.toString());
> }
> return element;
> - }
> -
> + }
> +
> //reset stream
> if (inputStream.markSupported()) {
> try {
> @@ -257,9 +258,9 @@
> ioe.getMessage());
> }
> }
> - return null;
> + return null;
> }
> -
> +
> /**
> * Set the maximum amount of bytes read from a line at one time
> *
> @@ -268,7 +269,7 @@
> public void setBufferSize(int bufferSize) {
> this.bufferSize = bufferSize;
> }
> -
> +
> /**
> * Get the maximum amount of bytes read from a line at one time
> *
> @@ -277,7 +278,7 @@
> public int getBufferSize() {
> return bufferSize;
> }
> -
> +
> /**
> * Set the maximum post data size allowed for a multipart request
> * @param maxSize The maximum post data size in bytes, set to <code>-1</code>
> @@ -286,26 +287,26 @@
> public void setMaxSize(long maxSize) {
> this.maxSize = maxSize;
> }
> -
> - /**
> +
> + /**
> * Get the maximum post data size allowed for a multipart request
> * @return The maximum post data size in bytes
> */
> public long getMaxSize() {
> return maxSize;
> }
> -
> +
> /**
> * Handles retrieving the boundary and setting the input stream
> */
> protected void parseRequest() throws ServletException {
> -
> +
> contentLength = request.getContentLength();
> -
> +
> //set boundary
> boundary = parseBoundary(request.getContentType());
> boundaryBytes = boundary.getBytes();
> -
> +
> try {
> //set the input stream
> inputStream = new BufferedMultipartInputStream(request.getInputStream(),
> @@ -316,23 +317,23 @@
> if (inputStream.markSupported()) {
> inputStream.mark(contentLength+1);
> }
> -
> +
> }
> catch (IOException ioe) {
> - throw new ServletException("Problem while reading request: " +
> + throw new ServletException("Problem while reading request: " +
> ioe.getMessage(), ioe);
> }
> -
> +
> if ((boundary == null) || (boundary.length() < 1)) {
> //try retrieving the header through more "normal" means
> boundary = parseBoundary(request.getHeader("Content-type"));
> }
> -
> +
> if ((boundary == null) || (boundary.length() < 1)) {
> throw new ServletException("MultipartIterator: cannot retrieve boundary " +
> "for multipart request");
> }
> -
> +
> //read first line
> try {
> String firstLine = readLine();
> @@ -350,37 +351,39 @@
> throw new ServletException("MultipartIterator: encoding \"ISO-8859-1\" not supported");
> }
> }
> -
> +
> /**
> - * Parses a content-type String for the boundary. Appends a
> + * Parses a content-type String for the boundary. Appends a
> * "--" to the beginning of the boundary, because thats the
> * real boundary as opposed to the shortened one in the
> * content type.
> */
> public static String parseBoundary(String contentType) {
> if (contentType.lastIndexOf("boundary=") != -1) {
> - String _boundary = "--" +
> + String _boundary = "--" +
> contentType.substring(contentType.lastIndexOf("boundary=")+9);
> if (_boundary.endsWith("\n")) {
> //strip it off
> return _boundary.substring(0, _boundary.length()-1);
> }
> - return _boundary;
> + return _boundary;
> }
> - return null;
> + return null;
> }
> -
> +
> /**
> * Parses the "Content-Type" line of a multipart form for a content type
> *
> - * @param contentTypeString A String reprsenting the Content-Type line,
> + * @param contentTypeString A String reprsenting the Content-Type line,
> * with a trailing "\n"
> * @return The content type specified, or <code>null</code> if one can't be
> * found.
> */
> public static String parseContentType(String contentTypeString) {
> int nameIndex = contentTypeString.indexOf("Content-Type: ");
> -
> + if (nameIndex == -1)
> + nameIndex = contentTypeString.indexOf("\n");
> +
> if (nameIndex != -1) {
> int endLineIndex = contentTypeString.indexOf("\n");
> if (endLineIndex == -1) {
> @@ -390,10 +393,10 @@
> }
> return null;
> }
> -
> +
> /**
> * Retrieves the "name" attribute from a content disposition line
> - *
> + *
> * @param dispositionString The entire "Content-disposition" string
> * @return <code>null</code> if no name could be found, otherwise,
> * returns the name
> @@ -402,8 +405,8 @@
> public static String parseDispositionName(String dispositionString) {
> return parseForAttribute("name", dispositionString);
> }
> -
> - /**
> +
> + /**
> * Retrieves the "filename" attribute from a content disposition line
> *
> * @param dispositionString The entire "Content-disposition" string
> @@ -414,8 +417,8 @@
> public static String parseDispositionFilename(String dispositionString) {
> return parseForAttribute("filename", dispositionString);
> }
> -
> -
> +
> +
> /**
> * Parses a string looking for a attribute-value pair, and returns the value.
> * For example:
> @@ -424,7 +427,7 @@
> * MultipartIterator.parseForAttribute(parseString, "name");
> * </pre>
> * That will return "bob".
> - *
> + *
> * @param attribute The name of the attribute you're trying to get
> * @param parseString The string to retrieve the value from
> * @return The value of the attribute, or <code>null</code> if none could be found
> @@ -432,17 +435,17 @@
> public static String parseForAttribute(String attribute, String parseString) {
> int nameIndex = parseString.indexOf(attribute + "=\"");
> if (nameIndex != -1) {
> -
> +
> int endQuoteIndex = parseString.indexOf("\"", nameIndex+attribute.length()+3);
> -
> +
> if (endQuoteIndex != -1) {
> return parseString.substring(nameIndex+attribute.length()+2, endQuoteIndex);
> }
> return "";
> - }
> + }
> return null;
> }
> -
> +
> /**
> * Reads the input stream until it reaches a new line
> */
> @@ -450,42 +453,44 @@
>
> byte[] bufferByte;
> int bytesRead;
> -
> +
> if (totalLength >= contentLength) {
> return null;
> }
> -
> +
> try {
> bufferByte = inputStream.readLine();
> + if (bufferByte == null)
> + return null;
> bytesRead = bufferByte.length;
> }
> catch (IOException ioe) {
> - throw new ServletException("IOException while reading multipart request: " +
> + throw new ServletException("IOException while reading multipart request: " +
> ioe.getMessage());
> }
> if (bytesRead == -1) {
> return null;
> }
> -
> +
> totalLength += bytesRead;
> return new String(bufferByte, 0, bytesRead, "ISO-8859-1");
> }
> -
> +
> /**
> * Creates a file on disk from the current mulitpart element
> * @param fileName the name of the multipart file
> */
> protected File createLocalFile() throws IOException {
> -
> +
> File tempFile = File.createTempFile("strts", null, new File(tempDir));
> BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile),
> diskBufferSize);
> byte[] lineBuffer = inputStream.readLine();
> int bytesRead = lineBuffer.length;
> -
> +
> boolean cutCarriage = false;
> boolean cutNewline = false;
> -
> +
> try {
> while ((bytesRead != -1) && (!equals(lineBuffer, 0, boundaryBytes.length,
> boundaryBytes))) {
> @@ -514,12 +519,12 @@
> tempFile.delete();
> throw ioe;
> }
> -
> - fos.flush();
> +
> + fos.flush();
> fos.close();
> return tempFile;
> }
> -
> +
> /**
> * Checks bytes for equality. Two byte arrays are equal if
> * each of their elements are the same. This method checks
> @@ -528,21 +533,21 @@
> * @param comp The byte to compare to <code>source</code>
> * @param offset The offset to start at in <code>comp</code>
> * @param length The length of <code>comp</code> to compare to
> - * @param source The reference byte to test for equality
> + * @param source The reference byte array to test for equality
> */
> public static boolean equals(byte[] comp, int offset, int length,
> byte[] source) {
> -
> - if (length != source.length) {
> - return false;
> +
> + if ((length != source.length) || (comp.length - offset < length)) {
> + return false;
> }
> -
> +
> for (int i = 0; i < length; i++) {
> if (comp[offset+i] != source[i]) {
> return false;
> }
> }
> - return true;
> + return true;
> }
>
> }
>
>
>
-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Custom Software ~ Technical Services.
-- Tel +1 716 737-3463
-- http://www.husted.com/struts/
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>