https://bz.apache.org/bugzilla/show_bug.cgi?id=64762

            Bug ID: 64762
           Summary: CoyoteInputStream asynchronous read
           Product: Tomcat 9
           Version: 9.0.31
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: regression
          Priority: P2
         Component: Connectors
          Assignee: dev@tomcat.apache.org
          Reporter: l...@privasphere.com
  Target Milestone: -----

Hi everyone

Since the upgrade from Tomcat 8 to tomcat 9 The
CoyoteInputStream.getInputStream() does not work properly anymore.

We run Debian 10 buster and Tomcat has the following ServerInfo:
Server version: Apache Tomcat/9.0.31 (Debian)
Server built:   Jul 15 2020 11:43:33 UTC
Server number:  9.0.31.0
OS Name:        Linux
OS Version:     4.19.0-10-amd64
Architecture:   amd64
JVM Version:    1.8.0_261-b12
JVM Vendor:     Oracle Corporation

When reading/uploading  larger files (i.e. a HTTPS form-post) it looks like not
everything is copied as it should, we get the following Stack
Trace:
org.apache.commons.fileupload.MultipartStream$MalformedStreamException: Stream
ended unexpectedly
        at
org.apache.commons.fileupload.MultipartStream$ItemInputStream.makeAvailable(MultipartStream.java:1033)
        at
org.apache.commons.fileupload.MultipartStream$ItemInputStream.read(MultipartStream.java:931)
        at java.io.InputStream.read(InputStream.java:101)
        at org.apache.commons.fileupload.util.Streams.copy(Streams.java:98)
        at org.apache.commons.fileupload.util.Streams.copy(Streams.java:68)
        at  …
        at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:191)
        at
org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:305)
        at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:191)
        at …
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
        at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
        at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
        at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at
org.apache.catalina.filters.CorsFilter.handleNonCORS(CorsFilter.java:352)
        at org.apache.catalina.filters.CorsFilter.doFilter(CorsFilter.java:171)
…
        at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at
org.apache.catalina.filters.ExpiresFilter.doFilter(ExpiresFilter.java:1227)
…
        at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
        at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
        at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
        at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
        at
org.apache.catalina.valves.SemaphoreValve.invoke(SemaphoreValve.java:160)
        at
com.privasphere.net.SemaphoreValve5340.invoke(SemaphoreValve5340.java:43)
        at
org.apache.catalina.valves.CrawlerSessionManagerValve.invoke(CrawlerSessionManagerValve.java:235)
        at
com.privasphere.net.CrawlerSessionValve5340.invoke(CrawlerSessionValve5340.java:50)
        at
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:688)
        at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
        at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
        at
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367)
        at
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
        at
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
        at
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1639)
        at
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)


Our (surprising) workaround for now is as follows:. We look at how many bytes
are expected by request.getContentLength() and if what is read does not match
the expected size sleep some milli seconds. We do this in a while loop which is
iterated a maximal number of times or until everything is read. Normally this
solves the problem. So for example for an upload of 230 K, the inputstream
claims done after ~130K, after a few ms wait, another 100K appear and all works
fine.

Could you please have a look into that bug?

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to