https://bz.apache.org/bugzilla/show_bug.cgi?id=62614
Bug ID: 62614
Summary: Async servlet over HTTP/2 WriteListener does not work
because outputstream.write is hanging even it's ready
Product: Tomcat 9
Version: 9.0.10
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P2
Component: Servlet
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: -----
Steps to reproduce:
1. Enable HTTP/2 for Tomcat
<Connector port="8080" protocol="HTTP/1.1">
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol"/>
</Connector>
2. Deploy the following Servlet
@WebServlet(urlPatterns = {"/asyncwrite"}, asyncSupported = true)
public class AsyncWrite extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse
response)
throws IOException {
final AsyncContext asyncContext = request.startAsync();
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType("application/binary");
final ServletOutputStream output = response.getOutputStream();
output.setWriteListener(new WriteListener() {
int i;
byte[] bytes = new byte[0x10000];
@Override
public void onWritePossible() throws IOException {
i++;
System.out.println("onWritePossible called " + i + " times");
if (i > 3) {
System.out.println("complete");
asyncContext.complete();
return;
}
while(output.isReady()) {
output.write(bytes);
}
System.out.println("output.isReady() = " + false);
}
@Override
public void onError(Throwable t) {
t.printStackTrace();
}
});
}
}
3. Make sure the curl command supports HTTP/2
$ curl --version
curl 7.60.0
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL
libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy PSL
4. Run the following curl command over HTTP/1.1
$ curl "http://127.0.0.1:8080/asyncwrite" -v --output - -w 'received
%{size_download} bytes\n'
No error happens. Check "logs/catalina.out" we can see
onWritePossible called 1 times
output.isReady() = false
onWritePossible called 2 times
output.isReady() = false
onWritePossible called 3 times
output.isReady() = false
onWritePossible called 4 times
complete
5. Run the following curl command over HTTP/2
$ curl --http2 --http2-prior-knowledge "http://127.0.0.1:8080/asyncwrite" -v
--output - -w 'received %{size_download} bytes\n'
The client hangs. Check "logs/catalina.out" we can only see
onWritePossible called 1 times
Actually output.write(bytes) is hanging.
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]