https://issues.apache.org/bugzilla/show_bug.cgi?id=54711
--- Comment #2 from Nick Williams <nicho...@nicholaswilliams.net> --- Created attachment 30061 --> https://issues.apache.org/bugzilla/attachment.cgi?id=30061&action=edit Patch to resolve issue Fixed with attached patch! Woohoo! This was a doozy. There were several problems cause a myriad of issues here: - WsRemoteEndpointImplBase.WsOutputStream was not flipping the underlying buffer before calling endpoint.sendPartialBytes(buffer, boolean), hence the endless blocking seen in the attached thread dump. - java.io.Closeable#close() documentation says "If the stream is already closed then invoking this method has no effect." Both WsOutputStream and WsRemoteEndpointImplBase.WsWriter violated this contract. If WsOutputStream or WsWriter were used in a try-with-resources block, close() would get called twice, and thus sendPartialBytes/sendPartialString would get called twice. This resulted in two messages getting sent: one with the payload and one empty. - Calls to flush() and write() methods on WsOutputStream and WsWriter should not be allowed after close is called. - Both WsOutputStream#write(byte[] b, int off, int len) and WsWriter#write(char[] c, int off, int len) would loop forever if len was greater than 8192 (not difficult). - Both WsOutputStream#write(byte[] b, int off, int len) and WsWriter#write(char[] c, int off, int len) were susceptible to unclean input. - Unrelated but found while debugging: o.a.t.websocket.WsRemoteEndpointImplClient#doWrite was calling getSendTimeout() and then setting the returned value to Long.MAX_VALUE if it was less than 1, but then it was never using that returned value; it was calling getSendTimeout() again. -- 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