447627 MultiPart file always created when "filename" set in Content-Disposition

This commit is contained in:
Jan Bartel 2014-10-22 12:56:10 +11:00
parent 8bf6b2c62c
commit 592265c21f
4 changed files with 35 additions and 22 deletions

View File

@ -60,6 +60,10 @@ import org.eclipse.jetty.util.log.Logger;
/**
* Multipart Form Data Filter.
* <p>
* This class is ONLY needed if you cannot use the Servlet 3.0 APIs for
* configuring and handling multipart requests. See javax.servlet.http.HttpServletRequest.getParts(). If
* you use the new servlet apis then you should REMOVE this filter from your webapp.
* <p>
* This class decodes the <code>multipart/form-data</code> stream sent by a HTML form that uses a file input
* item. Any files sent are stored to a temporary file and a File object added to the request
* as an attribute. All other values are made available via the normal getParameter API and
@ -89,6 +93,7 @@ import org.eclipse.jetty.util.log.Logger;
* To limit the size of the multipart request.
* </dd>
* </dl>
* @deprecated See servlet 3.0 apis like javax.servlet.http.HttpServletRequest.getParts()
*/
public class MultiPartFilter implements Filter
{

View File

@ -23,6 +23,7 @@ import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
@ -60,12 +61,24 @@ public class MultipartFilterTest
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
assertNotNull(req.getParameter("fileName"));
assertEquals(getServletContext().getAttribute("fileName"), req.getParameter("fileName"));
assertNotNull(req.getParameter("desc"));
assertEquals(getServletContext().getAttribute("desc"), req.getParameter("desc"));
assertNotNull(req.getParameter("title"));
assertEquals(getServletContext().getAttribute("title"), req.getParameter("title"));
//we have configured the multipart filter to always store to disk (file size threshold == 1)
//but fileName has no filename param, so only the attribute should be set
assertNull(req.getParameter("fileName"));
assertNotNull(req.getAttribute("fileName"));
File f = (File)req.getAttribute("fileName");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
IO.copy(new FileInputStream(f), baos);
assertEquals(getServletContext().getAttribute("fileName"), baos.toString());
assertNull(req.getParameter("desc"));
assertNotNull(req.getAttribute("desc"));
baos = new ByteArrayOutputStream();
IO.copy(new FileInputStream((File)req.getAttribute("desc")), baos);
assertEquals(getServletContext().getAttribute("desc"), baos.toString());
assertNull(req.getParameter("title"));
assertNotNull(req.getAttribute("title"));
baos = new ByteArrayOutputStream();
IO.copy(new FileInputStream((File)req.getAttribute("title")), baos);
assertEquals(getServletContext().getAttribute("title"), baos.toString());
super.doPost(req, resp);
}
}
@ -77,6 +90,7 @@ public class MultipartFilterTest
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
assertNotNull(req.getParameter("fileup"));
System.err.println("Fileup="+req.getParameter("fileup"));
assertNotNull(req.getParameter("fileup"+MultiPartFilter.CONTENT_TYPE_SUFFIX));
assertEquals(req.getParameter("fileup"+MultiPartFilter.CONTENT_TYPE_SUFFIX), "application/octet-stream");
super.doPost(req, resp);
@ -101,6 +115,7 @@ public class MultipartFilterTest
tester.getContext().setAttribute("javax.servlet.context.tempdir", _dir);
FilterHolder 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();
}

View File

@ -92,19 +92,9 @@ public class MultiPartInputStreamParser
protected void open()
throws IOException
{
//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 (_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();
}
//Write to a buffer in memory until we discover we've exceed the
//MultipartConfig fileSizeThreshold
_out = _bout= new ByteArrayOutputStream2();
}
protected void close()
@ -122,6 +112,7 @@ public class MultiPartInputStreamParser
if (MultiPartInputStreamParser.this._config.getFileSizeThreshold() > 0 && _size + 1 > MultiPartInputStreamParser.this._config.getFileSizeThreshold() && _file==null)
createFile();
_out.write(b);
_size ++;
}
@ -134,7 +125,7 @@ public class MultiPartInputStreamParser
if (MultiPartInputStreamParser.this._config.getFileSizeThreshold() > 0 && _size + length > MultiPartInputStreamParser.this._config.getFileSizeThreshold() && _file==null)
createFile();
_out.write(bytes, offset, length);
_size += length;
}
@ -143,6 +134,7 @@ public class MultiPartInputStreamParser
throws IOException
{
_file = File.createTempFile("MultiPart", "", MultiPartInputStreamParser.this._tmpDir);
if (_deleteOnExit)
_file.deleteOnExit();
FileOutputStream fos = new FileOutputStream(_file);

View File

@ -659,7 +659,7 @@ public class MultiPartInputStreamTest
private void testMulti(String filename) throws IOException, ServletException
private void testMulti(String filename) throws IOException, ServletException, InterruptedException
{
MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(createMultipartRequestString(filename).getBytes()),
@ -699,6 +699,7 @@ public class MultiPartInputStreamTest
assertThat(stuff.getHeader("content-disposition"),is("form-data; name=\"stuff\"; filename=\"" + filename + "\""));
assertThat(stuff.getHeaderNames().size(),is(2));
assertThat(stuff.getSize(),is(51L));
File tmpfile = ((MultiPartInputStreamParser.MultiPart)stuff).getFile();
assertThat(tmpfile,notNullValue()); // longer than 100 bytes, should already be a tmp file
assertThat(((MultiPartInputStreamParser.MultiPart)stuff).getBytes(),nullValue()); //not in an internal buffer
@ -859,7 +860,7 @@ public class MultiPartInputStreamTest
}
return "--AaB03x\r\n"+
"content-disposition: form-data; name=\"field1\"\r\n"+
"content-disposition: form-data; name=\"field1\"; filename=\"frooble.txt\"\r\n"+
"\r\n"+
"Joe Blow\r\n"+
"--AaB03x\r\n"+