You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Geoff Howard <co...@leverageweb.com> on 2003/03/22 17:20:33 UTC

Temp Upload start (See also [RT] pipeline aspects)

> -----Original Message-----
> From: Stefano Mazzocchi [mailto:stefano@apache.org]
> Sent: Saturday, March 22, 2003 4:38 AM
> To: cocoon-dev@xml.apache.org
> Subject: [RT] pipeline aspects
>
>
> Geoff Howard wrote:
>
> > Obviously, if my
> > application doesn't use any uploads I should disable them in web.xml.
> > But right now, it's all or nothing: I either allow all users to upload
> > _on any page_ (if they create a form that posts to any url in cocoon's
> > space), or I totally disallow uploads.  I've been thinking through
> > enabling configs for resource-based, or even authentication-based
> > restrictions for uploads.  What would others think?
>
> I've been thinking about this for a while and I thought about waiting
> for 2.1 before sending these RT, but I just wanted to introduce them
> briefly before a quick-hack solution is implemented.
>

I printed the rest out to read carefully offline, but in the meantime I have
already started on the "quick-hack" you feared. ;)  I'd love to see a real
solution like you propose post-2.1, but this could work for 2.1.

Actually, this doesn't get
at the restrictions I mentioned above, but to the temp-upload option Vadim
asked for volunteers on.  I've attached a patch which includes the changes
below
to MultiPartParser and a quick change to upload.xsp.  This is meant only to
give the general idea of what would make cleaning up uploads at the end of
service() more feasible.

If no one likes it, I don't want to put any more time in, but if this looks
OK, I can make the changes to CocoonServlet and work on a good way to
provide the configuration option.  Unfortunately, as currently implemented,
autosave-uploads
is boolean and this would introduce a third state.  Options to deal with
that are:
1) modify autosave-uploads from boolean to numeric/string or
2) add temp-uploads boolean.
I'm kind of leaning to 2, but totally open to suggestions.

See also:
http://marc.theaimsgroup.com/?t=104387868200007&r=1&w=2 and
http://marc.theaimsgroup.com/?t=103478709700005&r=1&w=2

Index:
src/java/org/apache/cocoon/components/request/multipart/MultipartParser.java
===================================================================
RCS file:
/home/cvspublic/cocoon-2.1/src/java/org/apache/cocoon/components/request/mul
tipart/MultipartParser.java,v
retrieving revision 1.1
diff -u -r1.1 MultipartParser.java
---
src/java/org/apache/cocoon/components/request/multipart/MultipartParser.java
9 Mar 2003 00:09:10 -0000	1.1
+++
src/java/org/apache/cocoon/components/request/multipart/MultipartParser.java
22 Mar 2003 15:23:43 -0000
@@ -59,6 +59,7 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PushbackInputStream;
+import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.StringTokenizer;
 import java.util.Vector;
@@ -99,6 +100,10 @@

     /** Field characterEncoding       */
     private String characterEncoding;
+
+	/** Field UPLOAD_ATTRIBUTE - name of request attribute storing
+     * keys to uploaded files placed in the request */
+    private final static String UPLOAD_ATTRIBUTE = "cocoon-uploads";
     /**
      * Constructor, parses given request
      *
@@ -136,7 +141,7 @@
                 new TokenStream(
                         new PushbackInputStream(
                                 new
BufferedInputStream(request.getInputStream()),
-                                MAX_BOUNDARY_SIZE)),
getBoundary(request.getContentType()));
+                                MAX_BOUNDARY_SIZE)),
getBoundary(request.getContentType()), request);
     }

     /**
@@ -148,7 +153,7 @@
      * @throws IOException
      * @throws MultipartException
      */
-    private void parseMultiPart(TokenStream ts, String boundary)
+    private void parseMultiPart(TokenStream ts, String boundary,
HttpServletRequest request)
             throws IOException, MultipartException {

         ts.setBoundary(boundary.getBytes());
@@ -157,7 +162,7 @@

         while (ts.getState() == TokenStream.STATE_NEXTPART) {
             ts.nextPart();
-            parsePart(ts);
+            parsePart(ts, request);
         }

         if (ts.getState() != TokenStream.STATE_ENDMULTIPART) {    // sanity
check
@@ -173,7 +178,7 @@
      * @throws IOException
      * @throws MultipartException
      */
-    private void parsePart(TokenStream ts)
+    private void parsePart(TokenStream ts, HttpServletRequest request)
             throws IOException, MultipartException {

         Hashtable headers = new Hashtable();
@@ -181,7 +186,7 @@
         try {
             if (headers.containsKey("filename")) {
 		        if (!"".equals(headers.get("filename"))) {
-                	parseFilePart(ts, headers);
+                	parseFilePart(ts, headers, request);
 		        } else {
         			// IE6 sends an empty part with filename="" for
         			// empty upload fields. Just parse away the part
@@ -198,7 +203,7 @@
             else if (((String)
headers.get("content-disposition")).toLowerCase()
                     .indexOf("multipart") > -1) {
                 parseMultiPart(new TokenStream(ts, MAX_BOUNDARY_SIZE),
-                        "--" + (String) headers.get("boundary"));
+                        "--" + (String) headers.get("boundary"), request);
                 ts.read();    // read past boundary
             } else {
                 throw new MultipartException("Unknown part type");
@@ -219,7 +224,7 @@
      * @throws IOException
      * @throws MultipartException
      */
-    private void parseFilePart(TokenStream in, Hashtable headers)
+    private void parseFilePart(TokenStream in, Hashtable headers,
HttpServletRequest request)
             throws IOException, MultipartException {

         byte[] buf = new byte[FILE_BUFFER_SIZE];
@@ -241,6 +246,7 @@

             if (file.exists()) {
                 if (!allowOverwrite) {
+                    // FIXME: race condition if simultaneous threads upload
a file of the same name
                     if (silentlyRename) {
                         int c = 0;

@@ -272,6 +278,13 @@
         } else {
             put(headers.get("name"), new FilePartFile(headers, file));
         }
+
+        ArrayList uploads =
(ArrayList)request.getAttribute(UPLOAD_ATTRIBUTE);;
+        if (uploads == null) {
+            uploads = new ArrayList();
+        }
+        uploads.add(headers.get("name"));
+        request.setAttribute(UPLOAD_ATTRIBUTE,uploads);
     }

     /**