public boolean read(InputStream in) throws IOException
    {
        _bytes=0;
        _pos=0;

        // read header
        do
        {
            int l=in.read(_buf,_bytes,__HDR_SIZE-_bytes);
            if (l<0)
                return false;
            _bytes+=l;
        }
        while (_bytes<__HDR_SIZE);

        // decode header
        int magic=getInt();
        if (magic!=0x1234)
            throw new IOException("Bad JSP13 rcv packet:"+magic+" "+this);
        int len=getInt();

        // check packet fits into the buffer
        int packetLength=__HDR_SIZE+len;
        if (packetLength>_buf.length)
            throw new IOException("AJP13 packet ("+packetLength+"bytes) too large for buffer ("+_buf.length+" bytes)");

        // read packet
        do
        {
            int l=in.read(_buf,_bytes,packetLength-_bytes);
            if (l<0)
                return false;
            _bytes+=l;
        }
        while (_bytes<packetLength);

        if (log.isTraceEnabled())
            log.trace("AJP13 rcv: "+this.toString(64));
        // System.err.println(Thread.currentThread()+" AJP13 rcv
        // "+this.toString());

        return true;
    }