net.lightbody.bmp.proxy.jetty.http.ajp.AJP13Packet Maven / Gradle / Ivy
// ========================================================================
// $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 net.lightbody.bmp.proxy.jetty.http.ajp;
import net.lightbody.bmp.proxy.jetty.log.LogFactory;
import net.lightbody.bmp.proxy.jetty.util.ByteArrayISO8859Writer;
import net.lightbody.bmp.proxy.jetty.util.ByteArrayPool;
import net.lightbody.bmp.proxy.jetty.util.LogSupport;
import net.lightbody.bmp.proxy.jetty.util.StringUtil;
import org.apache.commons.logging.Log;
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 (_bytesunconsumedData())
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();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy