commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From joc...@apache.org
Subject svn commit: r415180 - in /jakarta/commons/proper/fileupload/trunk: .classpath .project src/java/org/apache/commons/fileupload/MultipartStream.java src/test/org/apache/commons/fileupload/SizesTest.java
Date Sun, 18 Jun 2006 19:19:47 GMT
Author: jochen
Date: Sun Jun 18 12:19:46 2006
New Revision: 415180

URL: http://svn.apache.org/viewvc?rev=415180&view=rev
Log:
Added the ItemInputStream.

Added:
    jakarta/commons/proper/fileupload/trunk/.classpath
    jakarta/commons/proper/fileupload/trunk/.project
    jakarta/commons/proper/fileupload/trunk/src/test/org/apache/commons/fileupload/SizesTest.java
Modified:
    jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/MultipartStream.java

Added: jakarta/commons/proper/fileupload/trunk/.classpath
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/.classpath?rev=415180&view=auto
==============================================================================
--- jakarta/commons/proper/fileupload/trunk/.classpath (added)
+++ jakarta/commons/proper/fileupload/trunk/.classpath Sun Jun 18 12:19:46 2006
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<classpath>
+  <classpathentry excluding="" kind="src" path="src/java">
+  </classpathentry>
+  <classpathentry output="target/test-classes" kind="src" path="src/test">
+  </classpathentry>
+  <classpathentry kind="var" path="MAVEN_REPO/junit/jars/junit-3.8.1.jar">
+  </classpathentry>
+  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
+  </classpathentry>
+  <classpathentry kind="var" path="MAVEN_REPO/commons-io/jars/commons-io-1.1.jar">
+  </classpathentry>
+  <classpathentry kind="var" path="MAVEN_REPO/javax.servlet/jars/servlet-api-2.3.jar">
+  </classpathentry>
+  <classpathentry kind="var" path="MAVEN_REPO/javax.portlet/jars/portlet-api-1.0.jar">
+  </classpathentry>
+  <classpathentry kind="output" path="target/classes">
+  </classpathentry>
+</classpath>
\ No newline at end of file

Added: jakarta/commons/proper/fileupload/trunk/.project
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/.project?rev=415180&view=auto
==============================================================================
--- jakarta/commons/proper/fileupload/trunk/.project (added)
+++ jakarta/commons/proper/fileupload/trunk/.project Sun Jun 18 12:19:46 2006
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<projectDescription>
+  <name>commons-fileupload</name>
+  <comment>The FileUpload component provides a simple yet flexible means of adding
support for multipart file upload functionality to servlets and web applications.</comment>
+  <projects>
+  </projects>
+  <buildSpec>
+    <buildCommand>
+      <name>org.eclipse.jdt.core.javabuilder</name>
+      <arguments>
+      </arguments>
+    </buildCommand>
+  </buildSpec>
+  <natures>
+    <nature>org.eclipse.jdt.core.javanature</nature>
+  </natures>
+</projectDescription>
\ No newline at end of file

Modified: jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/MultipartStream.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/MultipartStream.java?rev=415180&r1=415179&r2=415180&view=diff
==============================================================================
--- jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/MultipartStream.java
(original)
+++ jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/MultipartStream.java
Sun Jun 18 12:19:46 2006
@@ -496,64 +496,22 @@
     public int readBodyData(OutputStream output)
         throws MalformedStreamException,
                IOException {
-        boolean done = false;
-        int pad;
-        int pos;
-        int bytesRead;
-        int total = 0;
-        while (!done) {
-            // Is boundary token present somewere in the buffer?
-            pos = findSeparator();
-            if (pos != -1) {
-                // Write the rest of the data before the boundary.
+        final ItemInputStream istream = new ItemInputStream();
+        final byte[] bytes = new byte[8192];
+        for (;;) {
+            int res = istream.read(bytes);
+            if (res == -1) {
                 if (output != null) {
-                    output.write(buffer, head, pos - head);
-                }
-                total += pos - head;
-                head = pos;
-                done = true;
-            } else {
-                // Determine how much data should be kept in the
-                // buffer.
-                if (tail - head > keepRegion) {
-                    pad = keepRegion;
-                } else {
-                    pad = tail - head;
+                    output.flush();
                 }
-                // Write out the data belonging to the body-data.
+                return (int) istream.getBytesRead();
+            }
+            if (res > 0  &&  output != null) {
                 if (output != null) {
-                    output.write(buffer, head, tail - head - pad);
-                }
-
-                // Move the data to the beginning of the buffer.
-                total += tail - head - pad;
-                System.arraycopy(buffer, tail - pad, buffer, 0, pad);
-
-                // Refill buffer with new data.
-                head = 0;
-                bytesRead = input.read(buffer, pad, bufSize - pad);
-
-                // [pprrrrrrr]
-                if (bytesRead != -1) {
-                    tail = pad + bytesRead;
-                } else {
-                    // The last pad amount is left in the buffer.
-                    // Boundary can't be in there so write out the
-                    // data you have and signal an error condition.
-                    if (output != null) {
-                        output.write(buffer, 0, pad);
-                        output.flush();
-                    }
-                    total += pad;
-                    throw new MalformedStreamException(
-                            "Stream ended unexpectedly");
+                    output.write(bytes, 0, res);
                 }
             }
         }
-        if (output != null) {
-            output.flush();
-        }
-        return total;
     }
 
 
@@ -748,6 +706,122 @@
         }
     }
 
+    /**
+     * An {@link InputStream} for reading an items contents.
+     */
+    public class ItemInputStream extends InputStream {
+        private long total;
+        private int pad, pos;
+
+        ItemInputStream() {
+            findSeparator();
+        }
+
+        private void findSeparator() {
+            pos = MultipartStream.this.findSeparator();
+            if (pos == -1) {
+                if (tail - head > keepRegion) {
+                    pad = keepRegion;
+                } else {
+                    pad = tail - head;
+                }
+            }
+        }
+
+        /** Returns the number of bytes, which have been read
+         * by the stream.
+         */
+        public long getBytesRead() {
+            return total;
+        }
+
+        public int available() throws IOException {
+            if (pos == -1) {
+                return tail - head - pad;
+            } else {
+                return pos - head;
+            }
+        }
+
+        public int read() throws IOException {
+            if (available() == 0) {
+                if (makeAvailable() == 0) {
+                    return -1;
+                }
+            }
+            ++total;
+            int b = buffer[head++];
+            return b >= 0 ? b : b + 256;
+        }
+
+        public int read(byte[] b, int off, int len) throws IOException {
+            if (len == 0) {
+                return 0;
+            }
+            int res = available();
+            if (res == 0) {
+                res = makeAvailable();
+                if (res == 0) {
+                    return -1;
+                }
+            }
+            res = Math.min(res, len);
+            System.arraycopy(buffer, head, b, off, res);
+            head += res;
+            total += res;
+            return res;
+        }
+
+        public void close() throws IOException {
+            for (;;) {
+                int av = available();
+                if (av == 0) {
+                    av = makeAvailable();
+                    if (av == 0) {
+                        break;
+                    }
+                }
+                skip(av);
+            }
+        }
+
+        public long skip(long bytes) throws IOException {
+            int av = available();
+            if (av == 0) {
+                av = makeAvailable();
+                if (av == 0) {
+                    return 0;
+                }
+            }
+            long res = Math.min(av, bytes);
+            head += res;
+            return res;
+        }
+
+        private int makeAvailable() throws IOException {
+            if (pos != -1) {
+                return 0;
+            }
+
+            // Move the data to the beginning of the buffer.
+            total += tail - head - pad;
+            System.arraycopy(buffer, tail - pad, buffer, 0, pad);
+
+            // Refill buffer with new data.
+            head = 0;
+            int bytesRead = input.read(buffer, pad, bufSize - pad);
+            if (bytesRead == -1) {
+                // The last pad amount is left in the buffer.
+                // Boundary can't be in there so signal an error
+                // condition.
+                throw new MalformedStreamException(
+                        "Stream ended unexpectedly");
+            }
+            tail = pad + bytesRead;
+            findSeparator();
+            return available();
+        }
+    }
 
     // ------------------------------------------------------ Debugging methods
 

Added: jakarta/commons/proper/fileupload/trunk/src/test/org/apache/commons/fileupload/SizesTest.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/src/test/org/apache/commons/fileupload/SizesTest.java?rev=415180&view=auto
==============================================================================
--- jakarta/commons/proper/fileupload/trunk/src/test/org/apache/commons/fileupload/SizesTest.java
(added)
+++ jakarta/commons/proper/fileupload/trunk/src/test/org/apache/commons/fileupload/SizesTest.java
Sun Jun 18 12:19:46 2006
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2001-2004 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.commons.fileupload;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import javax.servlet.http.HttpServletRequest;
+import junit.framework.TestCase;
+
+
+/**
+ * Unit test for items with varying sizes.
+ */
+public class SizesTest extends TestCase
+{
+    public void testFileUpload()
+            throws IOException, FileUploadException
+    {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        int add = 16;
+        int num = 0;
+        for (int i = 0;  i < 16384;  i += add) {
+            if (++add == 32) {
+                add = 16;
+            }
+            String header = "-----1234\r\n"
+                + "Content-Disposition: form-data; name=\"field" + (num++) + "\"\r\n"
+                + "\r\n";
+            baos.write(header.getBytes("US-ASCII"));
+            for (int j = 0;  j < i;  j++) {
+                baos.write((byte) j);
+            }
+            baos.write("\r\n".getBytes("US-ASCII"));
+        }
+        baos.write("-----1234--\r\n".getBytes("US-ASCII"));
+
+        List fileItems = parseUpload(baos.toByteArray());
+        Iterator fileIter = fileItems.iterator();
+        add = 16;
+        num = 0;
+        for (int i = 0;  i < 16384;  i += add) {
+            if (++add == 32) {
+                add = 16;
+            }
+            FileItem item = (FileItem) fileIter.next();
+            assertEquals("field" + (num++), item.getFieldName());
+            byte[] bytes = item.get();
+            assertEquals(i, bytes.length);
+            for (int j = 0;  j < i;  j++) {
+                assertEquals((byte) j, bytes[j]);
+            }
+        }
+        assertTrue(!fileIter.hasNext());
+    }
+
+    private List parseUpload(byte[] bytes) throws FileUploadException {
+        String contentType = "multipart/form-data; boundary=---1234";
+
+        FileUploadBase upload = new DiskFileUpload();
+        HttpServletRequest request = new MockHttpServletRequest(bytes, contentType);
+
+        List fileItems = upload.parseRequest(request);
+        return fileItems;
+    }
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message