struts-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mschach...@apache.org
Subject cvs commit: jakarta-struts/src/share/org/apache/struts/upload MultipartIterator.java BufferedMultipartInputStream.java
Date Fri, 05 Oct 2001 20:26:09 GMT
mschachter    01/10/05 13:26:09

  Modified:    src/share/org/apache/struts/upload Tag: STRUTS_1_0_BRANCH
                        MultipartIterator.java
                        BufferedMultipartInputStream.java
  Log:
   - Hopefully this commit will address bugs #3702, #3828, and #2683; a unit test
     for MultipartIterator is in the works to prevent these bugs from cropping
     up again and again...  I'll close the bugs on Bugzilla when the unit test is
     done and I'm sure these problems no longer exists.
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.13.2.5  +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.13.2.4
  retrieving revision 1.13.2.5
  diff -u -r1.13.2.4 -r1.13.2.5
  --- MultipartIterator.java	2001/09/24 16:52:58	1.13.2.4
  +++ MultipartIterator.java	2001/10/05 20:26:09	1.13.2.5
  @@ -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;
      }
   
   }
  
  
  
  1.3.2.3   +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.3.2.2
  retrieving revision 1.3.2.3
  diff -u -r1.3.2.2 -r1.3.2.3
  --- BufferedMultipartInputStream.java	2001/09/24 16:52:58	1.3.2.2
  +++ BufferedMultipartInputStream.java	2001/10/05 20:26:09	1.3.2.3
  @@ -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();
       }
   
  
  
  

Mime
View raw message