DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13869>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13869 mod_jk2 becomes confused when client breaks the connection Summary: mod_jk2 becomes confused when client breaks the connection Product: Tomcat 4 Version: 4.1.12 Platform: All OS/Version: All Status: NEW Severity: Blocker Priority: Other Component: Connector:Coyote JK 2 AssignedTo: [EMAIL PROTECTED] ReportedBy: [EMAIL PROTECTED] When the connection between mod_jk2 and a client browser gets interrupted, e.g. because the client closed the connection, the communication link between mod_jk2 and tomcat gets into an illegal state. mod_jk2 will send the remaining part of tomcats response to some other client, e.g., clients will receive (parts of) responses to requests they have not sent. Users may consequently slip into sessions of other user. Note that besides of the fact the users' requests are not served the right way this is a major security issue. Once this happend the server becomes largely unusable until it is shutdown and restarted. Reproducing the problem is somewhat tricky. You have to cut the connection at the right time. The script below tries to read parts of varying size before it closes the connection to increase the likelyhood that it eventually hits the right time. On the systems I have tried the error will occure almost instantly, but that might not be the case on your system. Here is the script: ---------------------------------------------------------------- #!/usr/bin/perl -w use Socket; ################################################## # adjust this to your tomcat / apache installation $host = "localhost"; $port = 9600; $doc = "/erfx/const.jsp"; ################################################## $count = 0; $read_lines = 1; sub request { my ($doc) = @_; start: $count++; my $iaddr = inet_aton($host) or die "unknown host\n"; my $paddr = sockaddr_in($port, $iaddr); my $proto = getprotobyname('tcp'); socket(SOCK, PF_INET, SOCK_STREAM, $proto) or die "socket failed\n"; connect(SOCK, $paddr) or die "connect failed\n"; select SOCK; $| = 1; select STDOUT; print SOCK <<END GET $doc HTTP/1.0\r User-Agent: test\r Host: $host\r \r END ; my $result = ""; while(<SOCK>) { if ($count % 2 == 0 && $read_lines == $.) { $read_lines = 1 + ($read_lines + 1) % 20; close(SOCK); goto start; } $result .= $_; } close(SOCK); return $result; } $result = request $doc; $result =~ /value:\s*(\d+)(.|[\n\r])*href=\"([^\"]+)\"/m or die "$result\nBad response\n"; $value = $1; $url = $3; print "$value $url\n"; $|=1; for ($i = 0; ; $i++) { $result = request $url; $result =~ /value:\s*(\d+)(.|[\n\r])*href=\"([^\"]+)\"/m or die "$result\nBad response\n" ; $my_value = $1; $my_url = $3; $my_url eq $url or die "Got wrong URL: $my_url $url\n"; $my_value eq $value or die "Got wrong value: $my_value $value\n"; print "$i ok\r"; } </pre> ---------------------------------------------------------------- and the test JSP the script requests: ---------------------------------------------------------------- <html> <head><title>Test Page</title></head> <body> <p>HI THERE!</p> <jsp:useBean id="date" scope="session" class="java.util.Date"/> <p>value: <jsp:getProperty name="date" property="time"/></p> <p><a href="<%= response.encodeURL(request.getRequestURI()) %>">again</a></p> <% for (int y = 0; y < 50; y++) { %> <p> <% for (int i = 0; i < 1000; i++) { %> test <% } %> <p> <% } %> </body> </html> ---------------------------------------------------------------- Put that somewhere into your installation and adjust the marked lines in the script to point to the right location. The script might detect the error different ways. Usually it will fail with "Bad response" because it receives the remaining part of a terminated response missing the lines at the beginning the script looks for. May may also try running multiple instances of the script. You may then get parts of responses to requests of another instance. The following patch provides a simple fix for the problem: ---------------------------------------------------------------- -- jk/native2/common/jk_worker_ajp13.c_old 2002-10-23 06:42:33.000000000 +0200 +++ jk/native2/common/jk_worker_ajp13.c 2002-10-23 06:29:48.000000000 +0200 @@ -394,6 +394,7 @@ * upload data and we must consider that operation is no more recoverable */ if (err!=JK_OK && ! e->recoverable ) { + e->worker->in_error_state=JK_TRUE; s->is_recoverable_error = JK_FALSE; env->l->jkLog(env, env->l, JK_LOG_ERROR, "ajp13.service() ajpGetReply unrecoverable error %d\n", ---------------------------------------------------------------- This way mod_jk2 will close the connection to tomcat and reconnect, thereby dumping the part of tomcats response which can no longer be forwarded to the client. Note: I did not look much at the AJP13 protocol and the sources. There may be better ways to fix this. -- To unsubscribe, e-mail: <mailto:tomcat-dev-unsubscribe@;jakarta.apache.org> For additional commands, e-mail: <mailto:tomcat-dev-help@;jakarta.apache.org>