You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by bu...@apache.org on 2003/04/29 14:56:32 UTC
DO NOT REPLY [Bug 13463] -
Request/Response race condition when doing multiple requests on the same connection.
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=13463>.
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=13463
Request/Response race condition when doing multiple requests on the same connection.
erik.van.oosten@backstream.com changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|RESOLVED |REOPENED
Resolution|FIXED |
------- Additional Comments From erik.van.oosten@backstream.com 2003-04-29 12:56 -------
The following program produces the bug almost always. It uses the
util.concurrent package to let 2 threads start simultaneously.
I tried the program with the nightly build 20030429 and release 2 Alpha 1.
The program is a rewrite of mike.vannoord@brainna.com's program. But only the
main method has been changed.
import java.io.*;
import java.net.*;
import java.util.*;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
import EDU.oswego.cs.dl.util.concurrent.Latch;
/**
*
* <br>
* @version $Revision: $
*/
public class HttpClientRaceBug {
/** Source control revision number */
public static final String RCS_VERSION = "$Revision: $";
public static void main(String[] args) {
try {
SimpleHttpServer.listen(8987);
final HttpClient client = new HttpClient();
client.startSession("localhost", 8987);
client.getState().setCredentials("Test Realm",
new UsernamePasswordCredentials("foo", "bar"));
final Latch go = new Latch();
Thread thread1 = new Thread("1") {
public void run() {
try {
go.acquire();
GetMethod meth = new GetMethod();
int lState = client.executeMethod(meth);
byte[] aData = meth.getResponseBody();
System.out.println("String 1: " + new String(aData));
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
Thread thread2 = new Thread("2") {
public void run() {
try {
go.acquire();
GetMethod meth = new GetMethod();
int lState = client.executeMethod(meth);
byte[] aData = meth.getResponseBody();
System.out.println("String 2: " + new String(aData));
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
thread1.start();
thread2.start();
Thread.sleep( 1000L ); /* sleep 1s */
go.release();
Thread.sleep( 3000L ); /* sleep 3s */
} catch (Exception e) {
e.printStackTrace();
}
}
private static final class SimpleHttpServer implements Runnable {
private Socket socket;
public SimpleHttpServer(Socket socket) {
this.socket = socket;
}
public static void listen(final int port) {
Thread server = new Thread() {
public void run() {
try {
ServerSocket ss = new ServerSocket(port);
while (true) {
new Thread(new
SimpleHttpServer(ss.accept())).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
server.setDaemon(true);
server.start();
}
public void run() {
try {
BufferedReader in = new BufferedReader(new
InputStreamReader(this.socket.getInputStream()));
int len = 0;
boolean auth = false;
String line;
while ((line = in.readLine()) != null) {
System.out.println("> " + line);
if (line.trim().equals("")) {
in.read(new char[len]);
doOutput(auth);
auth = false;
len = 0;
} else if (line.indexOf(':') > -1) {
StringTokenizer tok = new StringTokenizer(line, ":");
String key = tok.nextToken().toLowerCase();
if (key.equals("content-length")) {
len = Integer.parseInt(tok.nextToken().trim());
} else if (key.equals("authorization")) {
auth = true;
}
}
}
} catch (Exception e) {}
}
private static int count = 0;
public void doOutput(boolean authorized) throws IOException {
Writer out = new OutputStreamWriter(this.socket.getOutputStream());
count++;
String id = (count < 100) ?
((count < 10) ? "00" + count : "0" + count) : "" + count;
if (authorized) {
write(out, "HTTP/1.1 200 OK\r\n");
} else {
write(out, "HTTP/1.1 401 Unauthorized\r\n");
}
write(out, "WWW-Authenticate: Basic realm=\"Test Realm\"\r\n");
write(out, "Response-Id: " + id + "\r\n");
write(out, "Content-Type: text/html; charset=iso-8859-1\r\n");
write(out, "Content-Length: 17\r\n\r\n");
write(out, "My Response (" + id + ")");
out.close();
}
private void write(Writer out, String text) throws IOException {
System.out.print("< " + text);
out.write(text);
}
}
}