import java.io.PrintStream;
import java.net.Socket;


public class AjpBufferFullException {

    private final static String SERVER_IP = "127.0.0.1";
    
    private final static int SERVER_PORT = 8009;

    public static void send(int bodyLength) throws Exception {
        System.out.println("Sending AJP...." + bodyLength);

        Socket socket = new Socket(SERVER_IP, SERVER_PORT);
        PrintStream p = new PrintStream(socket.getOutputStream());

        int pos = 0;
        byte[] header = new byte[8192];
        header[pos++] = 0x12; //magic code
        header[pos++] = 0x34;
        header[pos++] = 0x00; //no lenght
        header[pos++] = 0x00;
        header[pos++] = 0x02; //forward request
        header[pos++] = 0x04; //POST
        
        pos = appendString(header, pos, "HTTP/1.1"); //protocol
        pos = appendString(header, pos, "/tmp/my.jsp"); //requestURI
        pos = appendString(header, pos, SERVER_IP); //remoteAddr
        pos = appendString(header, pos, ""); //remoteHost
        pos = appendString(header, pos, SERVER_IP); //localName
        pos = appendInt(header, pos, SERVER_PORT); //localPort
        pos = appendByte(header, pos, 0); //isSSL

        pos = appendInt(header, pos, 1); //headers count
        pos = appendByte(header, pos, 0xa0); //content-length
        pos = appendByte(header, pos, 0x08);
        pos = appendString(header, pos, String.valueOf(bodyLength));
        pos = appendByte(header, pos, 0xFF); //end
        
        //set the ajp packet length
        int length = pos - 2 - 2;
        header[2] = (byte) ((length >>> 8) & 0xFF);
        header[3] = (byte) (length & 0xFF);
        p.write(header, 0, pos);
        p.flush();
        
        //post body(bodyLength * 'a')
        for (int i = 0; i < bodyLength; i++) {
            p.write(new byte[]{0x12, 0x34, 0x0, 0x3, 0x0, 0x1, 0x61});
            p.flush();
        }
        
        Thread.sleep(100);
        
        socket.close();
        System.out.println("End.");
    }
    
    private static int appendInt(byte[] buf, int pos, int val) {
        buf[pos++] = (byte) ((val >>> 8) & 0xFF);
        buf[pos++] = (byte) (val & 0xFF);
        
        return pos;
    }
    
    private static int appendByte(byte[] buf, int pos, int val) {
        buf[pos++] = (byte) (val & 0xFF);
        
        return pos;
    }
    
    public static int appendString(byte[] buf, int pos, String str) {
        if (str == null) {
            pos = appendInt(buf, pos, 0xFFFF);
            return pos;
        }
        
        int len = str.length();
        pos = appendInt(buf, pos, len);
        for (int i = 0; i < len; i++) {
            char c = str.charAt(i);
            if ((c <= 31) && (c != 9)) {
                c = ' ';
            } else if (c == 127) {
                c = ' ';
            }
            pos = appendByte(buf, pos, c);
        }
        pos = appendByte(buf, pos, 0);
        
        return pos;
    }
    
    public static void main(String[] args) throws Exception {
        for (int i = 1000; i < 8192; i++) {
            send(i);
        }
        
        System.out.println("Done");
    }
}
