Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java3
-rw-r--r--jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java68
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java26
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java32
4 files changed, 124 insertions, 5 deletions
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java
index 623a0af6c0..4a5c483586 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java
@@ -104,6 +104,7 @@ public class MultiPartFilter implements Filter
private boolean _deleteFiles;
private ServletContext _context;
private int _fileOutputBuffer = 0;
+ private boolean _writeFilesWithFilenames = false;
private long _maxFileSize = -1L;
private long _maxRequestSize = -1L;
private int _maxFormKeys = Integer.getInteger("org.eclipse.jetty.server.Request.maxFormKeys", 1000);
@@ -130,6 +131,7 @@ public class MultiPartFilter implements Filter
String mfks = filterConfig.getInitParameter("maxFormKeys");
if (mfks!=null)
_maxFormKeys=Integer.parseInt(mfks);
+ _writeFilesWithFilenames = "true".equalsIgnoreCase(filterConfig.getInitParameter("writeFilesWithFilenames"));
}
/* ------------------------------------------------------------------------------- */
@@ -164,6 +166,7 @@ public class MultiPartFilter implements Filter
MultipartConfigElement config = new MultipartConfigElement(tempdir.getCanonicalPath(), _maxFileSize, _maxRequestSize, _fileOutputBuffer);
MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(in, content_type, config, tempdir);
mpis.setDeleteOnExit(_deleteFiles);
+ mpis.setWriteFilesWithFilenames(_writeFilesWithFilenames);
request.setAttribute(MULTIPART, mpis);
try
{
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java
index 01cdb45637..c3b43e4750 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java
@@ -54,7 +54,17 @@ public class MultipartFilterTest
{
private File _dir;
private ServletTester tester;
-
+ FilterHolder multipartFilter;
+
+ public static class FilenameServlet extends TestServlet
+ {
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+ {
+ assertNotNull(req.getAttribute("fileup"));
+ super.doPost(req, resp);
+ }
+ }
public static class BoundaryServlet extends TestServlet
{
@@ -113,7 +123,7 @@ public class MultipartFilterTest
tester.getContext().setResourceBase(_dir.getCanonicalPath());
tester.getContext().addServlet(TestServlet.class, "/");
tester.getContext().setAttribute("javax.servlet.context.tempdir", _dir);
- FilterHolder multipartFilter = tester.getContext().addFilter(MultiPartFilter.class,"/*", EnumSet.of(DispatcherType.REQUEST));
+ multipartFilter = tester.getContext().addFilter(MultiPartFilter.class,"/*", EnumSet.of(DispatcherType.REQUEST));
multipartFilter.setInitParameter("deleteFiles", "true");
multipartFilter.setInitParameter("fileOutputBuffer", "1"); //write a file if there's more than 1 byte content
tester.start();
@@ -885,6 +895,60 @@ public class MultipartFilterTest
response = HttpTester.parseResponse(tester.getResponses(request.generate()));
}
+
+ @Test
+ public void testFilesWithFilenames ()
+ throws Exception
+ {
+ multipartFilter.setInitParameter("fileOutputBuffer", "0");
+ multipartFilter.setInitParameter("writeFilesWithFilenames", "true");
+
+
+ String boundary="XyXyXy";
+ HttpTester.Request request = HttpTester.newRequest();
+ HttpTester.Response response;
+ tester.addServlet(FilenameServlet.class,"/testf");
+ // test GET
+ request.setMethod("POST");
+ request.setVersion("HTTP/1.0");
+ request.setHeader("Host","tester");
+ request.setURI("/context/testf");
+ request.setHeader("Content-Type","multipart/form-data; boundary="+boundary);
+
+ String content = "--XyXyXy\r"+
+ "Content-Disposition: form-data; name=\"fileName\"\r"+
+ "Content-Type: text/plain; charset=US-ASCII\r"+
+ "Content-Transfer-Encoding: 8bit\r"+
+ "\r"+
+ "abc\r"+
+ "--XyXyXy\r"+
+ "Content-Disposition: form-data; name=\"desc\"\r"+
+ "Content-Type: text/plain; charset=US-ASCII\r"+
+ "Content-Transfer-Encoding: 8bit\r"+
+ "\r"+
+ "123\r"+
+ "--XyXyXy\r"+
+ "Content-Disposition: form-data; name=\"title\"\r"+
+ "Content-Type: text/plain; charset=US-ASCII\r"+
+ "Content-Transfer-Encoding: 8bit\r"+
+ "\r"+
+ "ttt\r"+
+ "--XyXyXy\r"+
+ "Content-Disposition: form-data; name=\"fileup\"; filename=\"test.upload\"\r"+
+ "Content-Type: application/octet-stream\r"+
+ "Content-Transfer-Encoding: binary\r"+
+ "\r"+
+ "000\r"+
+ "--XyXyXy--\r";
+ request.setContent(content);
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+ assertEquals(HttpServletResponse.SC_OK,response.getStatus());
+ assertTrue(response.getContent().indexOf("000")>=0);
+ }
+
+
+
public static class DumpServlet extends HttpServlet
{
private static final long serialVersionUID = 201012011130L;
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java
index 946d708c30..7703835ce0 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java
@@ -63,6 +63,7 @@ public class MultiPartInputStreamParser
protected File _tmpDir;
protected File _contextTmpDir;
protected boolean _deleteOnExit;
+ protected boolean _writeFilesWithFilenames;
@@ -94,9 +95,19 @@ public class MultiPartInputStreamParser
protected void open()
throws IOException
{
- //Write to a buffer in memory until we discover we've exceed the
- //MultipartConfig fileSizeThreshold
- _out = _bout= new ByteArrayOutputStream2();
+ //We will either be writing to a file, if it has a filename on the content-disposition
+ //and otherwise a byte-array-input-stream, OR if we exceed the getFileSizeThreshold, we
+ //will need to change to write to a file.
+ if (isWriteFilesWithFilenames() && _filename != null && _filename.trim().length() > 0)
+ {
+ createFile();
+ }
+ else
+ {
+ //Write to a buffer in memory until we discover we've exceed the
+ //MultipartConfig fileSizeThreshold
+ _out = _bout= new ByteArrayOutputStream2();
+ }
}
protected void close()
@@ -744,6 +755,15 @@ public class MultiPartInputStreamParser
_deleteOnExit = deleteOnExit;
}
+ public void setWriteFilesWithFilenames (boolean writeFilesWithFilenames)
+ {
+ _writeFilesWithFilenames = writeFilesWithFilenames;
+ }
+
+ public boolean isWriteFilesWithFilenames ()
+ {
+ return _writeFilesWithFilenames;
+ }
public boolean isDeleteOnExit()
{
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java
index 6f164620b9..293fb3d6de 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/MultiPartInputStreamTest.java
@@ -657,6 +657,38 @@ public class MultiPartInputStreamTest
}
+ @Test
+ public void testWriteFilesIfContentDispositionFilename ()
+ throws Exception
+ {
+ String s = "--AaB03x\r\n"+
+ "content-disposition: form-data; name=\"field1\"; filename=\"frooble.txt\"\r\n"+
+ "\r\n"+
+ "Joe Blow\r\n"+
+ "--AaB03x\r\n"+
+ "content-disposition: form-data; name=\"stuff\"\r\n"+
+ "Content-Type: text/plain\r\n"+
+ "\r\n"+"sss"+
+ "aaa"+"\r\n" +
+ "--AaB03x--\r\n";
+ //all default values for multipartconfig, ie file size threshold 0
+ MultipartConfigElement config = new MultipartConfigElement(_dirname);
+ MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(s.getBytes()),
+ _contentType,
+ config,
+ _tmpDir);
+ mpis.setDeleteOnExit(true);
+ mpis.setWriteFilesWithFilenames(true);
+ Collection<Part> parts = mpis.getParts();
+ assertThat(parts.size(), is(2));
+ Part field1 = mpis.getPart("field1"); //has a filename, should be written to a file
+ File f = ((MultiPartInputStreamParser.MultiPart)field1).getFile();
+ assertThat(f,notNullValue()); // longer than 100 bytes, should already be a tmp file
+
+ Part stuff = mpis.getPart("stuff");
+ f = ((MultiPartInputStreamParser.MultiPart)stuff).getFile(); //should only be in memory, no filename
+ assertThat(f, nullValue());
+ }
private void testMulti(String filename) throws IOException, ServletException, InterruptedException

Back to the top