Summary: | mod_jk/ajp13 returns wrong response after bad chunk-encoding request | ||
---|---|---|---|
Product: | Tomcat Connectors | Reporter: | Dan Chow <dchow> |
Component: | Common | Assignee: | Tomcat Developers Mailing List <dev> |
Status: | RESOLVED WORKSFORME | ||
Severity: | major | ||
Priority: | P3 | ||
Version: | unspecified | ||
Target Milestone: | --- | ||
Hardware: | PC | ||
OS: | Linux |
Description
Dan Chow
2002-11-06 00:17:26 UTC
Just to clarify the behavior that we are seeing is that the request/response pairs are being mixed up. There was some fixes recently in the ajp13 java code, so could you try with a TC 4 from CVS ? I didn't see such behaviour, Apache 1.3 return me error 400, Bad request. I mark this to WORKSFORME until someone provide a reproductable test pattern.... I will try the latest tomcat and let you know if I still have this problem. Here is how we are able to reproduce it: I have a servlet: import javax.servlet.http.HttpServlet; import java.io.PrintWriter; import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import org.apache.log4j.Category; import java.util.Enumeration; public class LoadServlet extends HttpServlet { public void init(ServletConfig config) throws ServletException { Category logger = Category.getRoot(); logger.info("LoadServlet::init(): Loading LoadServlet!"); } public void service(HttpServletRequest request, HttpServletResponse response) { Category logger = Category.getRoot(); StringBuffer url = new StringBuffer(); url.append("LoadServlet::service(): Request URL (" + ((HttpServletRequest) request).getRequestURI() + "?"); Enumeration enum = request.getParameterNames(); while (enum.hasMoreElements()) { String key = (String) enum.nextElement(); url.append(key + "=" + request.getParameter(key)); } logger.info(url.toString() + ")"); // Take the request and response to it. String id = request.getParameter("ID"); logger.info("LoadServlet::service(): Got ID parameter(" + id + ")"); StringBuffer responseString = new StringBuffer().append("<HTML>The ID you p assed in is: " + id + "</HTML>\n"); logger.info("LoadServlet::service(): Response (" + responseString + ")"); response.addHeader("ID" , java.net.URLEncoder.encode(id)); try { PrintWriter pw = response.getWriter(); pw.write(responseString.toString()); } catch(IOException e) { logger.error(e.getMessage(), e); } } } running on tomcat that just returns the parameter(ID) in both the header and the body of the response. I also have a perl script: #!/usr/local/bin/perl -w use IO::Socket; unless (@ARGV > 1) { die "Usage: ./syncsvt.pl: <host> <port>\n";} ($host) = $ARGV[0]; ($port) = $ARGV[1]; $remote = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $host, PeerPort => "$port", ); unless ($remote) { die "Cannot connect to $host\n" } $remote->autoflush(1); print $remote "GET /index.jsp HTTP/1.1\x0d\x0aHost: host1.foo.com\x0d\x0aTransfer-Encoding: Chunked\x0d\x0a\x0d\x0aAAAAAAAA\x0d\x0a\x0d\x0a"; while ( <$remote> ) { print } close $remote; that invokes my chunked encoding request. To reproduce the problem, I first run the perl script and hit the apache server on port 80 and get back the 404 response saying index.jsp is not found. Then with two browsers open, I invoke the LoadServlet servlet with the parameter ID=<value> through apache using HTTPS 4-5 times on each browser repeatedly. After a while, one of my requests will return the 404 response for the chunked-encoding request I made earlier from my perl script. After that, every once in a while, I will get back the response of one of my previous requests. A tcpdump of my tomcat server on port 8009 shows that it is writing the correct response back, but the mod_jk log in debug mode shows that it receieved the response of a previous request. Modifying the mod_jk shared lib to close the socket in ajp_done(): // close the socket jk_close_socket(p->sd, l); p->sd = -1; seems to fix this problem because the socket is no longer reused, but I'm still not sure what causes the problem and closing the socket each time takes away the advantages of reusing the socket. The latest version of mod_jk in CVS seems to fix this behavior. I no longer see the mixed request response pairs during my test. However, my chunked encoding request now hangs. I have to either ctrl-c the request or wait for the socket timeout to close the connection. |