Hi,
I observed another strange problem when using Tomcat 8.0.3 with Java 1.7.0_51
(64-bit) on Windows Server 2012 R2, in conjunction with IIS 8.5 + ISAPI
Redirector 1.2.39 (the problem also happens with 1.2.37). I'm using the AJP NIO
and HTTP NIO connectors, but the problem also happens with AJP BIO and AJP APR.
The problem is: When I have a servlet that directly reads the request body, and
I send a HTTP request to IIS (GET or POST) with Content-Length: 0, Tomcat hangs
trying to read the request body. This does not happen when sending the same
request directly to Tomcat using the HTTP connector.
Consider this example servlet:
[[[
@WebServlet("/Servlet")
public class Servlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
doRequest(request, response, false);
}
protected void doPost(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
doRequest(request, response, true);
}
private void doRequest(HttpServletRequest request, HttpServletResponse
response, boolean isPost) throws ServletException, IOException {
System.out.println("Method: " + (isPost ? "POST" : "GET") + ". Reading
request body...");
long readCount = 0;
try (InputStream s = request.getInputStream()) {
byte[] buf = new byte[4096];
int read;
while ((read = s.read(buf)) > 0)
readCount += read;
}
System.out.println("Reading request body finished, Byte Count: " +
readCount);
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
try (PrintWriter w = response.getWriter()) {
w.println("Method: " + (isPost ? "POST" : "GET") + ". Reading
request body...");
w.println("Request Body length in bytes: " + readCount);
}
}
}
]]]
This servlet directly reads the request InputStream and counts the bytes that
it read.
When I now send the following HTTP requests directly to Tomcat (port 8080),
everything works as expected:
Request:
GET /TestWebapp/Servlet HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 10
0123456789
Response:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/plain;charset=UTF-8
Content-Length: 72
Date: Mon, 03 Mar 2014 15:39:35 GMT
Method: GET. Reading request body...
Request Body length in bytes: 10
Request:
GET /TestWebapp/Servlet HTTP/1.1
Host: localhost
Connection: keep-alive
Response:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/plain;charset=UTF-8
Content-Length: 71
Date: Mon, 03 Mar 2014 15:38:33 GMT
Method: GET. Reading request body...
Request Body length in bytes: 0
However, when I set the ISAPI Redirector for IIS 8.5 to forward every request
to Tomcat, using following worker.properties:
# Define 1 real worker using ajp13
worker.list=worker1
# Set properties for worker1 (ajp13)
worker.worker1.type=ajp13
worker.worker1.host=127.0.0.1
worker.worker1.port=8009
and uriworkermap.properties:
/*=worker1
Then, when I send the same requests to IIS, the one which has a body succeeds,
but the one which doesn't have a body does not finish:
Request:
GET /TestWebapp/Servlet HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 10
0123456789
Response:
HTTP/1.1 200 OK
Content-Length: 72
Content-Type: text/plain;charset=UTF-8
Server: Microsoft-IIS/8.5
X-Powered-By: ASP.NET
Date: Mon, 03 Mar 2014 15:41:49 GMT
Method: GET. Reading request body...
Request Body length in bytes: 10
Request:
GET /TestWebapp/Servlet HTTP/1.1
Host: localhost
Connection: keep-alive
Response:
(waits forever without sending a response...)
The same happens with this request:
POST /TestWebapp/Servlet HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 0
Response:
(waits forever without sending a response...)
In Tomcat's log you can see that Tomcat hangs at s.read(buf), so it seems it
somehow does not notice that the request body length is 0.
Any idea what's going on there?
Note: I do not yet have examined what AJP packets are sent between Tomcat and
ISAPI Redirector.
Regards,
Konstantin Preißer
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]