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 dad32740ab71..0f611f396d0e 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 @@ -35,6 +35,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; import javax.servlet.MultipartConfigElement; import javax.servlet.ServletInputStream; import javax.servlet.http.Part; @@ -339,29 +340,33 @@ public MultiPartFormInputStream(InputStream in, String contentType, MultipartCon if (in instanceof ServletInputStream) { if (((ServletInputStream)in).isFinished()) - { _parsed = true; - return; - } } } /** * @return whether the list of parsed parts is empty + * @deprecated use getParts().isEmpty() */ + @Deprecated public boolean isEmpty() { - if (_parts.isEmpty()) - return true; - - Collection> values = _parts.values(); - for (List partList : values) + synchronized (this) { - if (!partList.isEmpty()) - return false; - } + if (!_parsed) + throw new IllegalStateException(); + + if (_parts.isEmpty()) + return true; - return true; + for (List partList : _parts.values()) + { + if (!partList.isEmpty()) + return false; + } + + return true; + } } /** @@ -390,27 +395,31 @@ public Collection getParsedParts() */ public void deleteParts() { - MultiException err = null; - for (List parts : _parts.values()) + // TODO: Can we cancel parsing somehow instead of blocking. + synchronized (this) { - for (Part p : parts) + MultiException err = null; + for (List parts : _parts.values()) { - try + for (Part p : parts) { - ((MultiPart)p).cleanUp(); - } - catch (Exception e) - { - if (err == null) - err = new MultiException(); - err.add(e); + try + { + ((MultiPart)p).cleanUp(); + } + catch (Exception e) + { + if (err == null) + err = new MultiException(); + err.add(e); + } } } - } - _parts.clear(); + _parts.clear(); - if (err != null) - err.ifExceptionThrowRuntime(); + if (err != null) + err.ifExceptionThrowRuntime(); + } } /** @@ -421,18 +430,13 @@ public void deleteParts() */ public Collection getParts() throws IOException { - if (!_parsed) - parse(); - throwIfError(); - - Collection> values = _parts.values(); - List parts = new ArrayList<>(); - for (List o : values) + synchronized (this) { - List asList = LazyList.getList(o, false); - parts.addAll(asList); + if (!_parsed) + parse(); + throwIfError(); + return _parts.values().stream().flatMap(List::stream).collect(Collectors.toList()); } - return parts; } /** @@ -444,10 +448,13 @@ public Collection getParts() throws IOException */ public Part getPart(String name) throws IOException { - if (!_parsed) - parse(); - throwIfError(); - return _parts.getValue(name, 0); + synchronized (this) + { + if (!_parsed) + parse(); + throwIfError(); + return _parts.getValue(name, 0); + } } /** @@ -522,7 +529,6 @@ else if ("".equals(_config.getLocation())) while (true) { - len = _in.read(data); if (len > 0) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java b/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java index 9a1f20d65cd1..c5cfb3447be8 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java @@ -46,6 +46,7 @@ public interface MultiParts extends Closeable Part getPart(String name) throws IOException; + @Deprecated boolean isEmpty(); ContextHandler.Context getContext(); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java index f02ad81dbdab..1727d40ee6ee 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java @@ -2310,7 +2310,7 @@ public Collection getParts() throws IOException, ServletException return getParts(null); } - private Collection getParts(MultiMap params) throws IOException + private synchronized Collection getParts(MultiMap params) throws IOException { if (_multiParts == null) _multiParts = (MultiParts)getAttribute(MULTIPARTS); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java index d5ac2ed0ea81..1b3bc6557261 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java @@ -351,16 +351,23 @@ public void testMultiPart() throws Exception @Override public void requestDestroyed(ServletRequestEvent sre) { - MultiParts m = (MultiParts)sre.getServletRequest().getAttribute(Request.MULTIPARTS); - assertNotNull(m); - ContextHandler.Context c = m.getContext(); - assertNotNull(c); - assertTrue(c == sre.getServletContext()); - assertTrue(!m.isEmpty()); - assertTrue(testTmpDir.list().length == 2); - super.requestDestroyed(sre); - String[] files = testTmpDir.list(); - assertTrue(files.length == 0); + try + { + MultiParts m = (MultiParts)sre.getServletRequest().getAttribute(Request.MULTIPARTS); + assertNotNull(m); + ContextHandler.Context c = m.getContext(); + assertNotNull(c); + assertTrue(c == sre.getServletContext()); + assertTrue(!m.getParts().isEmpty()); + assertTrue(testTmpDir.list().length == 2); + super.requestDestroyed(sre); + String[] files = testTmpDir.list(); + assertTrue(files.length == 0); + } + catch (IOException e) + { + throw new RuntimeException(e); + } } }); _server.stop(); @@ -411,16 +418,23 @@ public void testUtilMultiPart() throws Exception @Override public void requestDestroyed(ServletRequestEvent sre) { - MultiParts m = (MultiParts)sre.getServletRequest().getAttribute(Request.MULTIPARTS); - assertNotNull(m); - ContextHandler.Context c = m.getContext(); - assertNotNull(c); - assertTrue(c == sre.getServletContext()); - assertTrue(!m.isEmpty()); - assertTrue(testTmpDir.list().length == 2); - super.requestDestroyed(sre); - String[] files = testTmpDir.list(); - assertTrue(files.length == 0); + try + { + MultiParts m = (MultiParts)sre.getServletRequest().getAttribute(Request.MULTIPARTS); + assertNotNull(m); + ContextHandler.Context c = m.getContext(); + assertNotNull(c); + assertTrue(c == sre.getServletContext()); + assertTrue(!m.getParts().isEmpty()); + assertTrue(testTmpDir.list().length == 2); + super.requestDestroyed(sre); + String[] files = testTmpDir.list(); + assertTrue(files.length == 0); + } + catch (IOException t) + { + throw new RuntimeException(t); + } } }); _server.stop();