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>