diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormInputStream.java b/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormInputStream.java index 08f1e0b96e6e..f1deb18681b7 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormInputStream.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormInputStream.java @@ -60,10 +60,10 @@ public class MultiPartFormInputStream { private static final Logger LOG = Log.getLogger(MultiPartFormInputStream.class); private static final MultiMap EMPTY_MAP = new MultiMap<>(Collections.emptyMap()); + private final MultiMap _parts; private InputStream _in; private MultipartConfigElement _config; private String _contentType; - private MultiMap _parts; private Throwable _err; private File _tmpDir; private File _contextTmpDir; @@ -341,16 +341,19 @@ public MultiPartFormInputStream(InputStream in, String contentType, MultipartCon if (_config == null) _config = new MultipartConfigElement(_contextTmpDir.getAbsolutePath()); + MultiMap parts = new MultiMap(); + if (in instanceof ServletInputStream) { if (((ServletInputStream)in).isFinished()) { - _parts = EMPTY_MAP; + parts = EMPTY_MAP; _parsed = true; - return; } } - _in = new BufferedInputStream(in); + if (!_parsed) + _in = new BufferedInputStream(in); + _parts = parts; } /** @@ -397,13 +400,6 @@ public Collection getParsedParts() */ public void deleteParts() { - if (_parts == null) - { - // If we call deleteParts at this point, we are considered CLOSED - _err = new IllegalStateException("CLOSED via call to deleteParts()"); - return; - } - MultiException err = null; for (List parts : _parts.values()) { @@ -439,6 +435,9 @@ public Collection getParts() throws IOException parse(); throwIfError(); + if (_parts.isEmpty()) + return Collections.emptyList(); + Collection> values = _parts.values(); List parts = new ArrayList<>(); for (List o : values) @@ -499,9 +498,6 @@ protected void parse() Handler handler = new Handler(); try { - // initialize - _parts = new MultiMap<>(); - // if its not a multipart request, don't parse it if (_contentType == null || !_contentType.startsWith("multipart/form-data")) return; diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/MultiPartFormInputStreamTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/MultiPartFormInputStreamTest.java index 2e7062c4c631..f2f96a7a8c21 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/MultiPartFormInputStreamTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/MultiPartFormInputStreamTest.java @@ -510,17 +510,13 @@ public void testPartTmpFileDeletion() throws Exception } @Test - public void testParseAfterCleanUp() throws Exception + public void testDeleteNPE() { final InputStream input = new ByteArrayInputStream(createMultipartRequestString("myFile").getBytes()); MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 1024, 50); MultiPartFormInputStream mpis = new MultiPartFormInputStream(input, _contentType, config, _tmpDir); - mpis.deleteParts(); - - // The call to getParts should throw because we have already cleaned up the parts. - Throwable error = assertThrows(IllegalStateException.class, mpis::getParts); - assertThat(error.getMessage(), containsString("CLOSED")); + mpis.deleteParts(); // this should not be an NPE } @Test