On 05/13/2011 12:30 AM, Oleg Kalnichevski wrote:
It is hard to tell without seeing a wire log or a code snippet. Is there
any chance you could reproduce the problem with a self contained
application?
Hi Oleg
Its a bit late over here.. so let me attach the raw mock echo server I
am using to test this. When sending the "close-write" header on a
request, it writes one byte back and closes the socket..
However I assume my earlier analysis on the Java Channel.transferFrom()
maybe more useful, as I suspect the issue lies there. If so, we could
expose the fact that a partial response has been received, so that
higher level code can use that instead for error handling?
regards
asankha
--
Asankha C. Perera
AdroitLogic, http://adroitlogic.org
http://esbmagic.blogspot.com
/*
* Copyright (c) 2010 AdroitLogic Private Ltd. All Rights Reserved.
*/
package samples.services.http;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
public class ErrorService implements Runnable {
private volatile boolean stop = false;
private ServerSocket serverSocket = null;
public void stop() {
if (serverSocket != null) {
this.stop = true;
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void start() {
stop = false;
new Thread(this).start();
}
public static void main(String[] args) throws Exception {
ErrorService es = new ErrorService();
es.start();
Thread.sleep(3000);
es.stop();
}
public void run() {
try {
serverSocket = new ServerSocket(9000);
while (!stop) {
Socket socket = serverSocket.accept();
new Thread(new ErrorService.Worker(socket)).start();
}
System.out.println("Stopped..");
} catch (SocketException ignore) {
} catch (Exception e) {
e.printStackTrace();
}
}
class Worker implements Runnable {
final Socket socket;
Worker(Socket socket) {
this.socket = socket;
}
public void run() {
/*try {
socket.setTcpNoDelay(false);
socket.setPerformancePreferences(10, 100, 10);
} catch (SocketException e) {
e.printStackTrace();
}*/
int returnCode = -1, sleepRead = -1, sleepWrite = -1;
boolean closeReading = false, closeWriting = false;
try {
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
String str;
int contentLength = 0;
while ((str = br.readLine()) != null) {
if (str.trim().length() == 0) {
break;
} else if (str.indexOf(":") != -1) {
String header = str.substring(0, str.indexOf(":"));
if ("Content-Length".equalsIgnoreCase(header)) {
String value = str.substring(str.indexOf(":") + 1);
contentLength = Integer.parseInt(value.trim());
} else if ("return-code".equals(header)) {
String value = str.substring(str.indexOf(":") + 1);
returnCode = Integer.parseInt(value.trim());
} else if ("sleep-read".equals(header)) {
String value = str.substring(str.indexOf(":") + 1);
sleepRead = Integer.parseInt(value.trim());
} else if ("sleep-write".equals(header)) {
String value = str.substring(str.indexOf(":") + 1);
sleepWrite = Integer.parseInt(value.trim());
} else if ("close-read".equals(header)) {
String value = str.substring(str.indexOf(":") + 1);
closeReading = Boolean.parseBoolean(value.trim());
} else if ("close-write".equals(header)) {
String value = str.substring(str.indexOf(":") + 1);
closeWriting = Boolean.parseBoolean(value.trim());
}
}
}
//---------- reading request -----------------
boolean slept = false;
ByteBuffer body = ByteBuffer.allocate(4096);
if (contentLength > 0) {
for (int i = 0; i < contentLength; i++) {
body.put((byte) br.read());
// sleep or close after we start reading
if (!slept && sleepRead > 0) {
Thread.sleep(sleepRead);
}
if (closeReading) {
System.out.println("Closing socket while reading");
socket.close();
return;
}
}
} else {
while (true) {
String s = br.readLine();
if (s == null || s.trim().length() == 0) {
continue;
}
int chunkSize = Integer.parseInt(s, 16);
if (chunkSize == 0) {
break;
}
for (int i = 0; i < chunkSize; i++) {
body.put((byte) br.read());
}
//break;
}
}
body.flip();
byte[] bytes = new byte[body.limit()];
body.get(bytes, 0, body.limit());
// ------------ writing response ------------
if (returnCode > 0) {
bw.append("HTTP/1.1 " + returnCode + " Message\r\n");
} else {
bw.append("HTTP/1.1 200 OK\r\n");
}
bw.append("Content-Type: text/xml\r\n");
bw.append("Content-Length: " + body.limit() + "\r\n");
bw.append("Connection: close\r\n\r\n");
bw.flush();
slept = false;
char[] payload = new String(bytes).toCharArray();
for (int i=0; i<payload.length; i++) {
bw.write(payload[i]);
bw.flush();
if (!slept && sleepWrite > 0) {
Thread.sleep(sleepWrite);
}
if (closeWriting) {
System.out.println("Closing socket while writing");
socket.close();
return;
}
}
bw.flush();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]