Skip to content

Commit

Permalink
Issue #240
Browse files Browse the repository at this point in the history
No error if no parts because input stream already consumed.
  • Loading branch information
janbartel committed Nov 2, 2016
1 parent 2061227 commit ca882c8
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ public void doFilter(ServletRequest request,ServletResponse response,FilterChain
return;
}

InputStream in = new BufferedInputStream(request.getInputStream());
String content_type=srequest.getContentType();

//Get current parameters so we can merge into them
Expand All @@ -164,12 +163,12 @@ public void doFilter(ServletRequest request,ServletResponse response,FilterChain
}

MultipartConfigElement config = new MultipartConfigElement(tempdir.getCanonicalPath(), _maxFileSize, _maxRequestSize, _fileOutputBuffer);
MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(in, content_type, config, tempdir);
MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(request.getInputStream(), content_type, config, tempdir);
mpis.setDeleteOnExit(_deleteFiles);
mpis.setWriteFilesWithFilenames(_writeFilesWithFilenames);
request.setAttribute(MULTIPART, mpis);
try
{
{
Collection<Part> parts = mpis.getParts();
if (parts != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,34 @@
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.EnumSet;
import java.util.Map;

import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.FilterMapping;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletTester;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.MultiPartInputStreamParser;
import org.eclipse.jetty.util.ReadLineInputStream;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.log.StacklessLogging;
Expand All @@ -64,6 +73,33 @@ public class MultipartFilterTest
private ServletTester tester;
FilterHolder multipartFilter;

public static class ReadAllFilter implements Filter
{

@Override
public void init(FilterConfig filterConfig) throws ServletException
{
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
ServletInputStream is = request.getInputStream();
ReadLineInputStream rlis = new ReadLineInputStream(request.getInputStream());
String line = "";
while (line != null)
{
line = rlis.readLine();
}
chain.doFilter(request, response);
}

@Override
public void destroy()
{
}
}


public static class NullServlet extends HttpServlet
{
Expand Down Expand Up @@ -705,6 +741,42 @@ public void testNoBody()
assertTrue(response.getContent().indexOf("Missing content")>=0);
}
}


@Test
public void testBodyAlreadyConsumed()
throws Exception
{
tester.addServlet(NullServlet.class,"/null");

FilterHolder holder = new FilterHolder();
holder.setName("reader");
holder.setFilter(new ReadAllFilter());
tester.getContext().getServletHandler().addFilter(holder);
FilterMapping mapping = new FilterMapping();
mapping.setFilterName("reader");
mapping.setPathSpec("/*");
tester.getContext().getServletHandler().prependFilterMapping(mapping);
String boundary="XyXyXy";
// generated and parsed test
HttpTester.Request request = HttpTester.newRequest();
HttpTester.Response response;

request.setMethod("POST");
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
request.setURI("/context/null");
request.setHeader("Content-Type","multipart/form-data; boundary="+boundary);
request.setContent("How now brown cow");

try(StacklessLogging stackless = new StacklessLogging(ServletHandler.class))
{
response = HttpTester.parseResponse(tester.getResponses(request.generate()));
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
}
}



@Test
public void testWhitespaceBodyWithCRLF()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Part;

import org.eclipse.jetty.util.log.Log;
Expand All @@ -56,6 +58,7 @@ public class MultiPartInputStreamParser
{
private static final Logger LOG = Log.getLogger(MultiPartInputStreamParser.class);
public static final MultipartConfigElement __DEFAULT_MULTIPART_CONFIG = new MultipartConfigElement(System.getProperty("java.io.tmpdir"));
public static final MultiMap<Part> EMPTY_MAP = new MultiMap(Collections.emptyMap());
protected InputStream _in;
protected MultipartConfigElement _config;
protected String _contentType;
Expand Down Expand Up @@ -353,15 +356,24 @@ public String getContentDispositionFilename ()
*/
public MultiPartInputStreamParser (InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir)
{
_contentType = contentType;
_config = config;
_contextTmpDir = contextTmpDir;
if (_contextTmpDir == null)
_contextTmpDir = new File (System.getProperty("java.io.tmpdir"));

if (_config == null)
_config = new MultipartConfigElement(_contextTmpDir.getAbsolutePath());

if (in instanceof ServletInputStream)
{
if (((ServletInputStream)in).isFinished())
{
_parts = EMPTY_MAP;
return;
}
}
_in = new ReadLineInputStream(in);
_contentType = contentType;
_config = config;
_contextTmpDir = contextTmpDir;
if (_contextTmpDir == null)
_contextTmpDir = new File (System.getProperty("java.io.tmpdir"));

if (_config == null)
_config = new MultipartConfigElement(_contextTmpDir.getAbsolutePath());
}

/**
Expand Down Expand Up @@ -477,6 +489,7 @@ protected void parse ()
if (_parts != null || _err != null)
return;


//initialize
long total = 0; //keep running total of size of bytes read from input and throw an exception if exceeds MultipartConfigElement._maxRequestSize
_parts = new MultiMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
import java.util.Collection;

import javax.servlet.MultipartConfigElement;
import javax.servlet.ReadListener;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Part;

import org.eclipse.jetty.util.MultiPartInputStreamParser.MultiPart;
Expand Down Expand Up @@ -237,6 +239,50 @@ public void testNoBody()
}
}


@Test
public void testBodyAlreadyConsumed()
throws Exception
{
ServletInputStream is = new ServletInputStream() {

@Override
public boolean isFinished()
{
return true;
}

@Override
public boolean isReady()
{
return false;
}

@Override
public void setReadListener(ReadListener readListener)
{
}

@Override
public int read() throws IOException
{
return 0;
}

};

MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(is,
_contentType,
config,
_tmpDir);
mpis.setDeleteOnExit(true);
Collection<Part> parts = mpis.getParts();
assertEquals(0, parts.size());
}



@Test
public void testWhitespaceBodyWithCRLF()
throws Exception
Expand Down

0 comments on commit ca882c8

Please sign in to comment.