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]

Reply via email to