I found my project unexpectedly stuck for 30 seconds in the middle of a test using CTS(Compatibility Test Suite). This is the code from com.sun.ts.tests.servlet.api.jakarta_servlet_http.httpservletrequest40 in CTS (original source link)
try {
url = new URL("http://" hostname ":" portnum CONTEXT_ROOT
"/TrailerTestServlet");
socket = new Socket(url.getHost(), url.getPort());
socket.setKeepAlive(true);
output = socket.getOutputStream();
String path = url.getPath();
StringBuffer outputBuffer = new StringBuffer();
outputBuffer.append("POST " path " HTTP/1.1" DELIMITER);
outputBuffer.append("Host: " url.getHost() DELIMITER);
outputBuffer.append("Connection: keep-alive" DELIMITER);
outputBuffer.append("Content-Type: text/plain" DELIMITER);
...
byte[] outputBytes = outputBuffer.toString().getBytes(ENCODING);
output.write(outputBytes);
output.flush();
input = socket.getInputStream();
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
int read = 0;
**while ((read = input.read()) >= 0)** {
bytes.write(read);
}
String response = new String(bytes.toByteArray());
As mentioned in the title, a thread is blocked at "while((read = input.read()) >= 0)" after a server(my code) finished responding to this request. In my understand, the request includes "Connection: keep-alive", the server dose not close this connection after the response, and the connection is finally closed in (server-side) SocketTimeout.
I think this flow seems reasonable because a request says "keep this connection alive" and it does not let input.read() reach the end of stream before SocketTimeout or any exceptions.
Going back to my question.. What is intended for "while(inputStream.read()) >=0)" with "keep-alive"?
Thanks.
I checked the original code from a github (https://github.com/jakartaee/platform-tck/blame/484ce8691c41dde5ab2648f1c9e056487c36775c/src/com/sun/ts/tests/servlet/api/jakarta_servlet_http/httpservletrequest40/Client.java#L269) but cannot find a reasonable reason.
CodePudding user response:
You are right. This loop waits for the server to close the connection, but the server has been told to please not close the connection if possible. It is clearly a bug, or maybe the timeout is intended and it's very lazy coding.
However, this looks like test code for a particular web server, so it might be intended that something on the server prevents the connection from being kept alive. The connection will be closed after the first request and response if either the client or the server demands it. I don't see anything in TrailerTestServlet that would force the server to close the connection.