You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by sy...@apache.org on 2005/09/14 23:48:47 UTC

svn commit: r280948 - in /cocoon: blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/ blocks/forms/trunk/samples/forms/ blocks/forms/trunk/samples/messages/ trunk/ trunk/src/java/org/apache/cocoon/servlet/multipart/ trunk/src/webapp/WEB-INF/

Author: sylvain
Date: Wed Sep 14 14:48:24 2005
New Revision: 280948

URL: http://svn.apache.org/viewcvs?rev=280948&view=rev
Log:
When upload size exceeds the configured limit, attach a RejectedPart to the request rather than throwing an exception

Added:
    cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/RejectedPart.java   (with props)
Modified:
    cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/AbstractWidget.java
    cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Upload.java
    cocoon/blocks/forms/trunk/samples/forms/file_explorer_model.xml
    cocoon/blocks/forms/trunk/samples/messages/FormsMessages.xml
    cocoon/blocks/forms/trunk/samples/messages/FormsMessages_fr.xml
    cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/MultipartParser.java
    cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/Part.java
    cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/PartInMemory.java
    cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/PartOnDisk.java
    cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/RequestFactory.java
    cocoon/trunk/src/webapp/WEB-INF/web.xml
    cocoon/trunk/status.xml

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/AbstractWidget.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/AbstractWidget.java?rev=280948&r1=280947&r2=280948&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/AbstractWidget.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/AbstractWidget.java Wed Sep 14 14:48:24 2005
@@ -25,6 +25,7 @@
 import org.apache.cocoon.forms.Constants;
 import org.apache.cocoon.forms.event.CreateEvent;
 import org.apache.cocoon.forms.event.WidgetEvent;
+import org.apache.cocoon.forms.validation.ValidationErrorAware;
 import org.apache.cocoon.forms.validation.WidgetValidator;
 import org.apache.cocoon.xml.AttributesImpl;
 import org.xml.sax.ContentHandler;
@@ -334,23 +335,24 @@
             return false;
         }
         // Definition successful, test local validators
-        if (this.validators == null) {
-            // No local validators
-            this.wasValid = true;
-            return true;
+        if (this.validators != null) {
+            Iterator iter = this.validators.iterator();
+            while(iter.hasNext()) {
+                WidgetValidator validator = (WidgetValidator)iter.next();
+                if (!validator.validate(this)) {
+                    this.wasValid = false;
+                    return false;
+                }
+            }
         }
 
-        // Iterate on local validators
-        Iterator iter = this.validators.iterator();
-        while(iter.hasNext()) {
-            WidgetValidator validator = (WidgetValidator)iter.next();
-            if (!validator.validate(this)) {
-                this.wasValid = false;
-                return false;
-            }
+        // Successful validation
+        
+        if (this instanceof ValidationErrorAware) {
+            // Clear validation error if any
+            ((ValidationErrorAware)this).setValidationError(null);
         }
 
-        // All local iterators successful
         this.wasValid = true;
         return true;
     }

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Upload.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Upload.java?rev=280948&r1=280947&r2=280948&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Upload.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Upload.java Wed Sep 14 14:48:24 2005
@@ -24,6 +24,7 @@
 import org.apache.cocoon.forms.validation.ValidationError;
 import org.apache.cocoon.forms.validation.ValidationErrorAware;
 import org.apache.cocoon.servlet.multipart.Part;
+import org.apache.cocoon.servlet.multipart.RejectedPart;
 import org.apache.cocoon.xml.AttributesImpl;
 import org.apache.cocoon.xml.XMLUtils;
 import org.apache.commons.lang.ObjectUtils;
@@ -64,7 +65,7 @@
     }
 
     public Object getValue() {
-        return this.part;
+        return this.isValid() ? this.part : null;
     }
 
     public void setValue(Object object) {
@@ -94,8 +95,11 @@
             // Keep the request part
             requestPart.setDisposeWithRequest(false);
             this.part = requestPart;
-            this.validationError = null;
             getForm().addWidgetUpdate(this);
+            if (validateOversize()) {
+                // Clear any validation error
+                setValidationError(null);
+            }
 
         // If it's not a part and not null, clear any existing value
         // We also check if we're the submit widget, as a result of clicking the "..." button
@@ -105,7 +109,8 @@
                 this.part.dispose();
                 this.part = null;
             }
-            this.validationError = null;
+            setValidationError(null);
+            // Ensure we redisplay it
             getForm().addWidgetUpdate(this);
         }
 
@@ -117,39 +122,54 @@
         if (mimeTypes != null) {
             StringTokenizer tok = new StringTokenizer(mimeTypes, ", ");
             String contentType = this.part.getMimeType();
-            boolean found = false;
             while(tok.hasMoreTokens()) {
                 if (tok.nextToken().equals(contentType)) {
                     return true;
                 }
             }
+            setValidationError(new ValidationError(new I18nMessage("upload.invalid-type", Constants.I18N_CATALOGUE)));
             return false;
         }
 
         // No mime type restriction
         return true;
     }
+    
+    /**
+     * Check if the part is oversized, and if yes sets the validation error accordingly
+     */
+    private boolean validateOversize() {
+        if (this.part.isRejected()) {
+            // Set a validation error indicating the sizes in kbytes (rounded)
+            RejectedPart rjp = (RejectedPart)this.part;
+            int size = (rjp.getContentLength() + 512) / 1024;
+            int maxSize = (rjp.getMaxContentLength() + 512) / 1024;
+            setValidationError(new ValidationError(new I18nMessage(
+                    "upload.rejected",
+                    new String[] { String.valueOf(size), String.valueOf(maxSize) },
+                    Constants.I18N_CATALOGUE))
+            );
+            return false;
+        } else {
+            return false;
+        }
+    }
 
     public boolean validate() {
         if (!getCombinedState().isValidatingValues()) {
             this.wasValid = true;
             return true;
         }
-        ValidationError newError = null;
 
         if (this.part == null) {
             if (this.uploadDefinition.isRequired()) {
-                newError = new ValidationError(new I18nMessage("general.field-required", Constants.I18N_CATALOGUE));
-                getForm().addWidgetUpdate(this);
+                setValidationError(new ValidationError(new I18nMessage("general.field-required", Constants.I18N_CATALOGUE)));
             }
-        } else if (!validateMimeType()) {
-            newError = new ValidationError(new I18nMessage("upload.invalid-type", Constants.I18N_CATALOGUE));
+        } else if (validateOversize() && validateMimeType()) {
+            super.validate();
         }
 
-        if (!ObjectUtils.equals(this.validationError, newError)) {
-            setValidationError(newError);
-        }
-        this.wasValid = validationError == null ? super.validate() : false;
+        this.wasValid = validationError == null;
         return this.wasValid;
     }
 
@@ -168,8 +188,10 @@
      * @param error the validation error
      */
     public void setValidationError(ValidationError error) {
-        this.validationError = error;
-        getForm().addWidgetUpdate(this);
+        if(!ObjectUtils.equals(this.validationError, error)) {
+            this.validationError = error;
+            getForm().addWidgetUpdate(this);
+        }
     }
 
     /**

Modified: cocoon/blocks/forms/trunk/samples/forms/file_explorer_model.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/forms/file_explorer_model.xml?rev=280948&r1=280947&r2=280948&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/samples/forms/file_explorer_model.xml (original)
+++ cocoon/blocks/forms/trunk/samples/forms/file_explorer_model.xml Wed Sep 14 14:48:24 2005
@@ -37,6 +37,8 @@
 			   var source = event.tree.model.getNode(event.path);
                 var filesPanel = event.source.lookupWidget("../files");
 			   filesPanel.model.setRootSource(source);
+                // Clear the message in the status bar
+                event.source.lookupWidget("../messages").value = "";
 		    }
 		 </fd:javascript>
 	  </fd:on-selection-changed>

Modified: cocoon/blocks/forms/trunk/samples/messages/FormsMessages.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/messages/FormsMessages.xml?rev=280948&r1=280947&r2=280948&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/samples/messages/FormsMessages.xml (original)
+++ cocoon/blocks/forms/trunk/samples/messages/FormsMessages.xml Wed Sep 14 14:48:24 2005
@@ -53,5 +53,6 @@
    <message key="aggregatedfield.split-failed">Content of this field does not
       match the following regular expression: {0}</message>
    <message key="upload.invalid-type">Invalid content type.</message>
+   <message key="upload.rejected">Upload size too large ({0} kbytes). Only {1} kbytes are allowed.</message>
    <message key="calendar.alt">Calendar</message>
 </catalogue>

Modified: cocoon/blocks/forms/trunk/samples/messages/FormsMessages_fr.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/messages/FormsMessages_fr.xml?rev=280948&r1=280947&r2=280948&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/samples/messages/FormsMessages_fr.xml (original)
+++ cocoon/blocks/forms/trunk/samples/messages/FormsMessages_fr.xml Wed Sep 14 14:48:24 2005
@@ -54,5 +54,6 @@
 
   <message key="aggregatedfield.split-failed">Ne correspond pas à l'expression régulière: {0}</message>
   <message key="upload.invalid-type">Type de fichier incorrect.</message>
+  <message key="upload.rejected">Téléchargement trop gros ({0} ko). Un maximum de {1} ko est autorisé.</message>
   <message key="calendar.alt">Calendrier</message>
 </catalogue>

Modified: cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/MultipartParser.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/MultipartParser.java?rev=280948&r1=280947&r2=280948&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/MultipartParser.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/MultipartParser.java Wed Sep 14 14:48:24 2005
@@ -31,6 +31,8 @@
 
 import javax.servlet.http.HttpServletRequest;
 
+import org.apache.cocoon.util.NullOutputStream;
+
 /**
  * This class is used to implement a multipart request wrapper.
  * It will parse the http post stream and and fill it's hashtable with values.
@@ -62,6 +64,10 @@
     
     private Hashtable parts;
     
+    private boolean oversized = false;
+    
+    private int contentLength;
+    
     /**
      * Constructor, parses given request
      *
@@ -90,8 +96,9 @@
 
     private void parseParts(int contentLength, String contentType, InputStream requestStream)
     throws IOException, MultipartException {
+        this.contentLength = contentLength;
         if (contentLength > this.maxUploadSize) {
-            throw new IOException("Content length exceeds maximum upload size");
+            this.oversized = true;
         }
 
         BufferedInputStream bufferedStream = new BufferedInputStream(requestStream);
@@ -213,10 +220,12 @@
             throws IOException, MultipartException {
 
         byte[] buf = new byte[FILE_BUFFER_SIZE];
-        OutputStream out = null;
+        OutputStream out;
         File file = null;
 
-        if (!saveUploadedFilesToDisk) {
+        if (oversized) {
+            out = new NullOutputStream();
+        } else if (!saveUploadedFilesToDisk) {
             out = new ByteArrayOutputStream();
         } else {
             String fileName = (String) headers.get("filename");
@@ -232,7 +241,6 @@
             if (!allowOverwrite && !file.createNewFile()) {
                 if (silentlyRename) {
                     int c = 0;
-
                     do {
                         file = new File(filePath + c++ + "_" + fileName);
                     } while (!file.createNewFile());
@@ -245,11 +253,13 @@
             out = new FileOutputStream(file);
         }
 
+        int length = 0; // Track length for OversizedPart
         try {
             int read = 0;
             while (in.getState() == TokenStream.STATE_READING) {
                 // read data
                 read = in.read(buf);
+                length += read;
                 out.write(buf, 0, read);
             }
         } catch (IOException ioe) {
@@ -262,14 +272,15 @@
         } finally {
             if ( out!=null ) out.close();
         }
-
-        if (file == null) {
+        
+        String name = (String)headers.get("name");
+        if (oversized) {
+            this.parts.put(name, new RejectedPart(headers, length, this.contentLength, this.maxUploadSize));
+        } else if (file == null) {
             byte[] bytes = ((ByteArrayOutputStream) out).toByteArray();
-
-            this.parts.put(headers.get("name"),
-                    new PartInMemory(headers, new ByteArrayInputStream(bytes),bytes.length));
+            this.parts.put(name, new PartInMemory(headers, new ByteArrayInputStream(bytes), bytes.length));
         } else {
-            this.parts.put(headers.get("name"), new PartOnDisk(headers, file));
+            this.parts.put(name, new PartOnDisk(headers, file));
         }
     }
 

Modified: cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/Part.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/Part.java?rev=280948&r1=280947&r2=280948&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/Part.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/Part.java Wed Sep 14 14:48:24 2005
@@ -15,17 +15,28 @@
  */
 package org.apache.cocoon.servlet.multipart;
 
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.Map;
 
+import org.apache.avalon.excalibur.io.IOUtil;
 import org.apache.avalon.framework.activity.Disposable;
+import org.apache.excalibur.source.ModifiableSource;
 
 
 /**
- * This (abstract) class represents a file part parsed from a http post stream.
+ * This abstract class represents a file part parsed from a http post stream. The concrete
+ * class, {@link PartOnDisk} or {@link PartInMemory} that is used depends on the upload configuration
+ * in <code>web.xml</code>.
+ * <p>
+ * If uploaded data size exceeds the maximum allowed upload size (also specified in <code>web.xml</code>),
+ * then an {@link RejectedPart} is used, from which no data can be obtained, but which gives some
+ * information on the rejected uploads.
  *
  * @author <a href="mailto:j.tervoorde@home.nl">Jeroen ter Voorde</a>
- * @version CVS $Id: Part.java,v 1.4 2004/03/05 13:02:58 bdelacretaz Exp $
+ * @version CVS $Id$
  */
 public abstract class Part implements Disposable {
 
@@ -61,6 +72,16 @@
      * Returns the length of the file content
      */
     public abstract int getSize();
+    
+    /**
+     * Is this part a rejected part? Provided as an alternative to <code>instanceof RejectedPart</code>
+     * in places where it's not convenient such as flowscript.
+     * 
+     * @return <code>true</code> if this part was rejected
+     */
+    public boolean isRejected() {
+        return false;
+    }
 
     /**
      * Returns the mime type (or null if unknown)
@@ -92,5 +113,43 @@
      * Returns an InputStream containing the file data
      * @throws Exception
      */
-    public abstract InputStream getInputStream() throws Exception;
+    public abstract InputStream getInputStream() throws IOException;
+
+    /**
+     * Convenience method to copy a part to a modifiable source.
+     * 
+     * @param source the modifiable source to write to
+     * @throws IOException
+     * @since 2.1.8
+     */
+    public void copyToSource(ModifiableSource source) throws IOException {
+        InputStream is = getInputStream();
+        OutputStream os = source.getOutputStream();
+        IOUtil.copy(is, os);
+        is.close();
+        os.close();
+    }
+    
+    /**
+     * Convenience method to copy a part to a file.
+     * 
+     * @param filename name of the file to write to
+     * @throws IOException
+     * @since 2.1.8
+     */
+    public void copyToFile(String filename) throws IOException {
+        InputStream is = getInputStream();
+        OutputStream os = new FileOutputStream(filename);
+        IOUtil.copy(is, os);
+        is.close();
+        os.close();
+    }
+    
+    /**
+     * Dispose any resources held by this part, such as a file or memory buffer.
+     * <p>
+     * Disposal occurs in all cases when the part is garbage collected, but calling it explicitely
+     * allows to cleanup resources more quickly.
+     */
+    public abstract void dispose();
 }

Modified: cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/PartInMemory.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/PartInMemory.java?rev=280948&r1=280947&r2=280948&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/PartInMemory.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/PartInMemory.java Wed Sep 14 14:48:24 2005
@@ -15,6 +15,7 @@
  */
 package org.apache.cocoon.servlet.multipart;
 
+import java.io.IOException;
 import java.io.InputStream;
 import java.util.Map;
 
@@ -62,11 +63,12 @@
      *
      * @throws Exception
      */
-    public InputStream getInputStream() throws Exception {
+    public InputStream getInputStream() throws IOException {
         if (this.in != null) {
             return this.in;
+        } else {
+            throw new IllegalStateException("This part has already been disposed.");
         }
-        throw new IllegalStateException("This part has already been disposed.");
     }
     
     /**

Modified: cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/PartOnDisk.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/PartOnDisk.java?rev=280948&r1=280947&r2=280948&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/PartOnDisk.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/PartOnDisk.java Wed Sep 14 14:48:24 2005
@@ -17,6 +17,7 @@
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.util.Map;
 
@@ -74,7 +75,7 @@
      *
      * @throws Exception
      */
-    public InputStream getInputStream() throws Exception {
+    public InputStream getInputStream() throws IOException {
         if (this.file != null) {
             return new FileInputStream(file);
         }
@@ -88,6 +89,9 @@
         return file.getPath();
     }
     
+    /**
+     * Delete the underlying file.
+     */
     public void dispose() {
         if (this.file != null) {
             this.file.delete();
@@ -95,6 +99,9 @@
         }
     }
     
+    /**
+     * Ensures the underlying file has been deleted
+     */
     public void finalize() throws Throwable {
         // Ensure the file has been deleted
         dispose();

Added: cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/RejectedPart.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/RejectedPart.java?rev=280948&view=auto
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/RejectedPart.java (added)
+++ cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/RejectedPart.java Wed Sep 14 14:48:24 2005
@@ -0,0 +1,94 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.servlet.multipart;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+/**
+ * An upload part that was rejected because request length exceeded the maximum upload size.
+ * 
+ * @version $Id$
+ * @since 2.1.8
+ */
+public class RejectedPart extends Part {
+    
+    private int size;
+    public int contentLength;
+    public int maxContentLength;
+
+    public RejectedPart(Map headers, int partSize, int contentLength, int maxContentLength) {
+        super(headers);
+        this.size = partSize;
+        this.contentLength = contentLength;
+        this.maxContentLength = maxContentLength;
+    }
+
+    public String getFileName() {
+        return (String) headers.get("filename");
+    }
+
+    /**
+     * Get the size of this part.
+     * 
+     * @return the size in bytes
+     */
+    public int getSize() {
+        return this.size;
+    }
+    
+    /**
+     * Get the maximum allowed upload size. Not that this applies to the full request content length,
+     * including multipart boundaries and other form data values.
+     * <p>
+     * This means that an upload part can be rejected although it's individual size is (a bit) smaller
+     * than the maximum size. It is therefore advisable to use {@link #getContentLength()} to build
+     * error messages rather than {@link #getSize()}.
+     * 
+     * @return the maximum content length in bytes
+     */
+    public int getMaxContentLength() {
+        return this.maxContentLength;
+    }
+
+    /**
+     * Get the content length of the request that cause this part to be rejected.
+     * 
+     * @return the content length in bytes
+     */
+    public int getContentLength() {
+        return this.contentLength;
+    }
+    /**
+     * Always throw an <code>IOException</code> as this part was rejected.
+     */
+    public InputStream getInputStream() throws IOException {
+        throw new IOException("Multipart element '" + getFileName() + "' is too large (" +
+                this.size + " bytes) and was discarded.");
+    }
+
+    /**
+     * Always return <code>true</code>
+     */
+    public boolean isRejected() {
+        return true;
+    }
+
+    public void dispose() {
+        // nothing
+    }
+}

Propchange: cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/RejectedPart.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/RejectedPart.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/RequestFactory.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/RequestFactory.java?rev=280948&r1=280947&r2=280948&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/RequestFactory.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/servlet/multipart/RequestFactory.java Wed Sep 14 14:48:24 2005
@@ -26,7 +26,7 @@
  * This is the interface of Request Wrapper in Cocoon.
  *
  * @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a>
- * @version CVS $Id: RequestFactory.java,v 1.3 2004/03/05 13:02:58 bdelacretaz Exp $
+ * @version CVS $Id$
  */
 public class RequestFactory {
 
@@ -74,9 +74,6 @@
         String contentType = request.getContentType();
         
         if ((contentType != null) && (contentType.toLowerCase().indexOf("multipart/form-data") > -1)) {
-            if (request.getContentLength() > maxUploadSize) {
-                throw new IOException("Content length exceeds maximum upload size.");
-            }
  
             String charEncoding = request.getCharacterEncoding();
             if (charEncoding == null || charEncoding.equals("")) {

Modified: cocoon/trunk/src/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/webapp/WEB-INF/web.xml?rev=280948&r1=280947&r2=280948&view=diff
==============================================================================
--- cocoon/trunk/src/webapp/WEB-INF/web.xml (original)
+++ cocoon/trunk/src/webapp/WEB-INF/web.xml Wed Sep 14 14:48:24 2005
@@ -189,12 +189,12 @@
 
     <!--
       Causes all files in multipart requests to be processed.
-      Default is false for security reasons.
+      Default is true but the maximum allowed size is kept small for security reasons.
       Unsupported values will be interpreted as false.
     -->
     <init-param>
       <param-name>enable-uploads</param-name>
-      <param-value>false</param-value>
+      <param-value>true</param-value>
     </init-param>
 
     <!--
@@ -234,12 +234,12 @@
 
     <!--
       Specify maximum allowed size of the upload. Defaults to 10 Mb.
-
+      Set here to a very low 100 kb to allow samples to run.
+    -->
     <init-param>
       <param-name>upload-max-size</param-name>
-      <param-value>10000000</param-value>
+      <param-value>102400</param-value>
     </init-param>
-    -->
 
     <!--
       This parameter allows to specify where Cocoon should create its page

Modified: cocoon/trunk/status.xml
URL: http://svn.apache.org/viewcvs/cocoon/trunk/status.xml?rev=280948&r1=280947&r2=280948&view=diff
==============================================================================
--- cocoon/trunk/status.xml (original)
+++ cocoon/trunk/status.xml Wed Sep 14 14:48:24 2005
@@ -561,6 +561,15 @@
    </action>
   </release>
   <release version="2.1.8" date="TBD">
+    <action dev="SW" type="update">
+      When the upload size exceeds the configured limit, an RejectedPart is associated to the request
+      rather than throwing a exception at the servlet level. This allows the application to handle
+      oversized uploads and provide meaningful messages. The upload widget in CForms has been updated
+      to use this new feature.
+      <br/>
+      Uploads are now allowed in the provided web.xml, but with a low 100 kbytes limit to allow samples
+      to be functional without endangering security.
+    </action>
     <action dev="AG" type="update">
       Updated log4j to 1.2.12, asm to 2.0, asm-util to 2.0,
        groovy to 1.0-jsr-03.