Package org.browsermob.proxy.jetty.http.ajp

Source Code of org.browsermob.proxy.jetty.http.ajp.AJP13Packet

// ========================================================================
// $Id: AJP13Packet.java,v 1.24 2006/10/08 14:13:05 gregwilkins Exp $
// Copyright 2002-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================

package org.browsermob.proxy.jetty.http.ajp;

import org.apache.commons.logging.Log;
import org.browsermob.proxy.jetty.log.LogFactory;
import org.browsermob.proxy.jetty.util.ByteArrayISO8859Writer;
import org.browsermob.proxy.jetty.util.ByteArrayPool;
import org.browsermob.proxy.jetty.util.LogSupport;
import org.browsermob.proxy.jetty.util.StringUtil;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;

/* ------------------------------------------------------------ */
/**
*
* @version $Id: AJP13Packet.java,v 1.24 2006/10/08 14:13:05 gregwilkins Exp $
* @author Greg Wilkins (gregw)
*/
public abstract class AJP13Packet
{
    private static Log log=LogFactory.getLog(AJP13Packet.class);

    /* ------------------------------------------------------------ */
    public static final int __MAX_BUF=8192;
    public static final int __HDR_SIZE=4;
    public static final int __DATA_HDR=7;
    public static final int __MAX_DATA=__MAX_BUF-__DATA_HDR;

    public static final byte __FORWARD_REQUEST=2, __SHUTDOWN=7, __SEND_BODY_CHUNK=3, __SEND_HEADERS=4, __END_RESPONSE=5, __GET_BODY_CHUNK=6;

    public static final String[] __method=
    { "ERROR", "OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "PROPFIND", "PROPPATCH", "MKCOL", "COPY", "MOVE", "LOCK", "UNLOCK", "ACL", "REPORT",
            "VERSION-CONTROL", "CHECKIN", "CHECKOUT", "UNCHECKOUT", "SEARCH" };

    public String[] __header;

    protected HashMap __headerMap=new HashMap();

    /**
     * Abstract method to populate the header array and hash map.
     *
     */
    abstract public void populateHeaders();

    /* ------------------------------------------------------------ */
    private byte[] _buf;
    private int _bytes;
    private int _pos;
    private ByteArrayISO8859Writer _byteWriter;
    private boolean _ownBuffer;

    /* ------------------------------------------------------------ */
    public AJP13Packet(byte[] buffer, int len)
    {
        populateHeaders();
        _buf=buffer;
        _ownBuffer=false;
        _bytes=len;
    }

    /* ------------------------------------------------------------ */
    public AJP13Packet(byte[] buffer)
    {
        populateHeaders();
        _buf=buffer;
        _ownBuffer=false;
    }

    /* ------------------------------------------------------------ */
    public AJP13Packet(int size)
    {
        populateHeaders();
        _buf=ByteArrayPool.getByteArray(size);
        _ownBuffer=true;
    }

    /* ------------------------------------------------------------ */
    public void prepare()
    {
        _bytes=0;
        _pos=0;
        addByte((byte)'A');
        addByte((byte)'B');
        addInt(0);
    }

    /* ------------------------------------------------------------ */
    public void destroy()
    {
        if (_ownBuffer)
            ByteArrayPool.returnByteArray(_buf);
        _buf=null;
        _byteWriter=null;
    }

    /* ------------------------------------------------------------ */
    public void reset()
    {
        _bytes=0;
        _pos=0;
    }

    /* ------------------------------------------------------------ */
    public byte[] getBuffer()
    {
        return _buf;
    }

    /* ------------------------------------------------------------ */
    public void resetData()
    {
        _bytes=__HDR_SIZE;
        _pos=0;
    }

    /* ------------------------------------------------------------ */
    public int getMark()
    {
        return _bytes;
    }

    /* ------------------------------------------------------------ */
    public int getBufferSize()
    {
        return _buf.length;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return Bytes of data remaining
     */
    public int unconsumedData()
    {
        return _bytes-_pos;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return Bytes of capacity remaining
     */
    public int unconsumedCapacity()
    {
        return _buf.length-_bytes;
    }

    /* ------------------------------------------------------------ */
    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;
    }

    /* ------------------------------------------------------------ */
    public void write(OutputStream out) throws IOException
    {
        if (log.isTraceEnabled())
            log.trace("AJP13 snd: "+this.toString(64));
        // System.err.println(Thread.currentThread()+" AJP13 snd
        // "+this.toString());
        out.write(_buf,0,_bytes);
    }

    /* ------------------------------------------------------------ */
    public byte getByte()
    {
        return _buf[_pos++];
    }

    /* ------------------------------------------------------------ */
    public int getBytes(byte[] buf, int offset, int length)
    {
        if (length>unconsumedData())
            length=unconsumedData();
        System.arraycopy(_buf,_pos,buf,offset,length);
        _pos+=length;
        return length;
    }

    /* ------------------------------------------------------------ */
    public boolean getBoolean()
    {
        return _buf[_pos++]!=0;
    }

    /* ------------------------------------------------------------ */
    public int getInt()
    {
        int i=_buf[_pos++]&0xFF;
        i=(i<<8)+(_buf[_pos++]&0xFF);
        return i;
    }

    /* ------------------------------------------------------------ */
    public String getString()
    {
        int len=getInt();
        if (len==0xFFFF)
            return null;
        try
        {
            String s=new String(_buf,_pos,len,StringUtil.__ISO_8859_1);
            _pos+=len+1;
            return s;
        }
        catch (IndexOutOfBoundsException e)
        {
            // Bad request!!!
            LogSupport.ignore(log,e);
            return null;
        }
        catch (UnsupportedEncodingException e)
        {
            log.fatal(e);
            System.exit(1);
            return null;
        }
    }

    /* ------------------------------------------------------------ */
    public String getMethod()
    {
        return __method[getByte()];
    }

    /* ------------------------------------------------------------ */
    public String getHeader()
    {
        if ((0xFF&_buf[_pos])==0xA0)
        {
            _pos++;

            return __header[_buf[_pos++]];
        }
        return getString();
    }

    /* ------------------------------------------------------------ */
    public void addByte(byte b)
    {
        _buf[_bytes++]=b;
    }

    /* ------------------------------------------------------------ */
    public int addBytes(byte[] buf, int offset, int length)
    {
        if (length>unconsumedCapacity())
            length=unconsumedCapacity();
        System.arraycopy(buf,offset,_buf,_bytes,length);
        _bytes+=length;
        return length;
    }

    /* ------------------------------------------------------------ */
    public void addBoolean(boolean b)
    {
        _buf[_bytes++]=(byte)(b?1:0);
    }

    /* ------------------------------------------------------------ */
    public void addInt(int i)
    {
        _buf[_bytes++]=(byte)((i>>8)&0xFF);
        _buf[_bytes++]=(byte)(i&0xFF);
    }

    /* ------------------------------------------------------------ */
    public void setInt(int mark, int i)
    {
        _buf[mark]=(byte)((i>>8)&0xFF);
        _buf[mark+1]=(byte)(i&0xFF);
    }

    /* ------------------------------------------------------------ */
    public void addString(String s) throws IOException
    {
        if (s==null)
        {
            addInt(0xFFFF);
            return;
        }

        if (_byteWriter==null)
            _byteWriter=new ByteArrayISO8859Writer(_buf);

        int p=_bytes+2;
        _byteWriter.setLength(p);
        _byteWriter.write(s);
        int l=_byteWriter.size()-p;

        addInt(l);
        _bytes+=l;
        _buf[_bytes++]=(byte)0;
    }

    /* ------------------------------------------------------------ */
    public void addHeader(String s) throws IOException
    {
        Integer h=(Integer)__headerMap.get(s);
        if (h!=null)
            addInt(h.intValue());
        else
            addString(s);
    }

    /* ------------------------------------------------------------ */
    public int getDataSize()
    {
        return _bytes-__HDR_SIZE;
    }

    /* ------------------------------------------------------------ */
    public void setDataSize()
    {
        setDataSize(_bytes-__HDR_SIZE);
    }

    /* ------------------------------------------------------------ */
    public void setDataSize(int s)
    {
        _bytes=s+__HDR_SIZE;

        if (_buf[4]==__SEND_BODY_CHUNK)
            s=s+1;

        _buf[2]=(byte)((s>>8)&0xFF);
        _buf[3]=(byte)(s&0xFF);

        if (_buf[4]==__SEND_BODY_CHUNK)
        {
            s=s-4;
            _buf[5]=(byte)((s>>8)&0xFF);
            _buf[6]=(byte)(s&0xFF);
        }
    }

    /* ------------------------------------------------------------ */
    public String toString()
    {
        return toString(-1);
    }

    /* ------------------------------------------------------------ */
    public String toString(int max)
    {
        StringBuffer b=new StringBuffer();
        StringBuffer a=new StringBuffer();

        b.append(_bytes);
        b.append('/');
        b.append(_buf.length);
        b.append('[');
        b.append(_pos);
        b.append("]: ");

        switch (_buf[__HDR_SIZE])
        {
            case __FORWARD_REQUEST:
                b.append("FORWARD_REQUEST{:");
                break;
            case __SHUTDOWN:
                b.append("SHUTDOWN        :");
                break;
            case __SEND_BODY_CHUNK:
                b.append("SEND_BODY_CHUNK :");
                break;
            case __SEND_HEADERS:
                b.append("SEND_HEADERS  ( :");
                break;
            case __END_RESPONSE:
                b.append("END_RESPONSE  )}:");
                break;
            case __GET_BODY_CHUNK:
                b.append("GET_BODY_CHUNK  :");
                break;
        }

        if (max==0)
            return b.toString();

        b.append("\n");

        for (int i=0; i<_bytes; i++)
        {
            int d=_buf[i]&0xFF;
            if (d<16)
                b.append('0');
            b.append(Integer.toString(d,16));

            char c=(char)d;

            if (Character.isLetterOrDigit(c))
                a.append(c);
            else
                a.append('.');

            if (i%32==31||i==(_bytes-1))
            {
                b.append(" : ");
                b.append(a.toString());
                a.setLength(0);
                b.append("\n");
                if (max>0&&(i+1)>=max)
                    break;
            }
            else
                b.append(",");
        }

        return b.toString();
    }
}
TOP

Related Classes of org.browsermob.proxy.jetty.http.ajp.AJP13Packet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.