KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > http > ajp > AJP13Packet


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

16 package org.mortbay.http.ajp;
17
18 import java.io.IOException JavaDoc;
19 import java.io.InputStream JavaDoc;
20 import java.io.OutputStream JavaDoc;
21 import java.io.UnsupportedEncodingException JavaDoc;
22 import java.util.HashMap JavaDoc;
23
24 import org.apache.commons.logging.Log;
25 import org.mortbay.log.LogFactory;
26 import org.mortbay.util.ByteArrayISO8859Writer;
27 import org.mortbay.util.ByteArrayPool;
28 import org.mortbay.util.LogSupport;
29 import org.mortbay.util.StringUtil;
30
31 /* ------------------------------------------------------------ */
32 /**
33  *
34  * @version $Id: AJP13Packet.java,v 1.24 2006/10/08 14:13:05 gregwilkins Exp $
35  * @author Greg Wilkins (gregw)
36  */

37 public abstract class AJP13Packet
38 {
39     private static Log log=LogFactory.getLog(AJP13Packet.class);
40
41     /* ------------------------------------------------------------ */
42     public static final int __MAX_BUF=8192;
43     public static final int __HDR_SIZE=4;
44     public static final int __DATA_HDR=7;
45     public static final int __MAX_DATA=__MAX_BUF-__DATA_HDR;
46
47     public static final byte __FORWARD_REQUEST=2, __SHUTDOWN=7, __SEND_BODY_CHUNK=3, __SEND_HEADERS=4, __END_RESPONSE=5, __GET_BODY_CHUNK=6;
48
49     public static final String JavaDoc[] __method=
50     { "ERROR", "OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "PROPFIND", "PROPPATCH", "MKCOL", "COPY", "MOVE", "LOCK", "UNLOCK", "ACL", "REPORT",
51             "VERSION-CONTROL", "CHECKIN", "CHECKOUT", "UNCHECKOUT", "SEARCH" };
52
53     public String JavaDoc[] __header;
54
55     protected HashMap JavaDoc __headerMap=new HashMap JavaDoc();
56
57     /**
58      * Abstract method to populate the header array and hash map.
59      *
60      */

61     abstract public void populateHeaders();
62
63     /* ------------------------------------------------------------ */
64     private byte[] _buf;
65     private int _bytes;
66     private int _pos;
67     private ByteArrayISO8859Writer _byteWriter;
68     private boolean _ownBuffer;
69
70     /* ------------------------------------------------------------ */
71     public AJP13Packet(byte[] buffer, int len)
72     {
73         populateHeaders();
74         _buf=buffer;
75         _ownBuffer=false;
76         _bytes=len;
77     }
78
79     /* ------------------------------------------------------------ */
80     public AJP13Packet(byte[] buffer)
81     {
82         populateHeaders();
83         _buf=buffer;
84         _ownBuffer=false;
85     }
86
87     /* ------------------------------------------------------------ */
88     public AJP13Packet(int size)
89     {
90         populateHeaders();
91         _buf=ByteArrayPool.getByteArray(size);
92         _ownBuffer=true;
93     }
94
95     /* ------------------------------------------------------------ */
96     public void prepare()
97     {
98         _bytes=0;
99         _pos=0;
100         addByte((byte)'A');
101         addByte((byte)'B');
102         addInt(0);
103     }
104
105     /* ------------------------------------------------------------ */
106     public void destroy()
107     {
108         if (_ownBuffer)
109             ByteArrayPool.returnByteArray(_buf);
110         _buf=null;
111         _byteWriter=null;
112     }
113
114     /* ------------------------------------------------------------ */
115     public void reset()
116     {
117         _bytes=0;
118         _pos=0;
119     }
120
121     /* ------------------------------------------------------------ */
122     public byte[] getBuffer()
123     {
124         return _buf;
125     }
126
127     /* ------------------------------------------------------------ */
128     public void resetData()
129     {
130         _bytes=__HDR_SIZE;
131         _pos=0;
132     }
133
134     /* ------------------------------------------------------------ */
135     public int getMark()
136     {
137         return _bytes;
138     }
139
140     /* ------------------------------------------------------------ */
141     public int getBufferSize()
142     {
143         return _buf.length;
144     }
145
146     /* ------------------------------------------------------------ */
147     /**
148      * @return Bytes of data remaining
149      */

150     public int unconsumedData()
151     {
152         return _bytes-_pos;
153     }
154
155     /* ------------------------------------------------------------ */
156     /**
157      * @return Bytes of capacity remaining
158      */

159     public int unconsumedCapacity()
160     {
161         return _buf.length-_bytes;
162     }
163
164     /* ------------------------------------------------------------ */
165     public boolean read(InputStream JavaDoc in) throws IOException JavaDoc
166     {
167         _bytes=0;
168         _pos=0;
169
170         // read header
171
do
172         {
173             int l=in.read(_buf,_bytes,__HDR_SIZE-_bytes);
174             if (l<0)
175                 return false;
176             _bytes+=l;
177         }
178         while (_bytes<__HDR_SIZE);
179
180         // decode header
181
int magic=getInt();
182         if (magic!=0x1234)
183             throw new IOException JavaDoc("Bad JSP13 rcv packet:"+magic+" "+this);
184         int len=getInt();
185
186         // check packet fits into the buffer
187
int packetLength=__HDR_SIZE+len;
188         if (packetLength>_buf.length)
189             throw new IOException JavaDoc("AJP13 packet ("+packetLength+"bytes) too large for buffer ("+_buf.length+" bytes)");
190
191         // read packet
192
do
193         {
194             int l=in.read(_buf,_bytes,packetLength-_bytes);
195             if (l<0)
196                 return false;
197             _bytes+=l;
198         }
199         while (_bytes<packetLength);
200
201         if (log.isTraceEnabled())
202             log.trace("AJP13 rcv: "+this.toString(64));
203         // System.err.println(Thread.currentThread()+" AJP13 rcv
204
// "+this.toString());
205

206         return true;
207     }
208
209     /* ------------------------------------------------------------ */
210     public void write(OutputStream JavaDoc out) throws IOException JavaDoc
211     {
212         if (log.isTraceEnabled())
213             log.trace("AJP13 snd: "+this.toString(64));
214         // System.err.println(Thread.currentThread()+" AJP13 snd
215
// "+this.toString());
216
out.write(_buf,0,_bytes);
217     }
218
219     /* ------------------------------------------------------------ */
220     public byte getByte()
221     {
222         return _buf[_pos++];
223     }
224
225     /* ------------------------------------------------------------ */
226     public int getBytes(byte[] buf, int offset, int length)
227     {
228         if (length>unconsumedData())
229             length=unconsumedData();
230         System.arraycopy(_buf,_pos,buf,offset,length);
231         _pos+=length;
232         return length;
233     }
234
235     /* ------------------------------------------------------------ */
236     public boolean getBoolean()
237     {
238         return _buf[_pos++]!=0;
239     }
240
241     /* ------------------------------------------------------------ */
242     public int getInt()
243     {
244         int i=_buf[_pos++]&0xFF;
245         i=(i<<8)+(_buf[_pos++]&0xFF);
246         return i;
247     }
248
249     /* ------------------------------------------------------------ */
250     public String JavaDoc getString()
251     {
252         int len=getInt();
253         if (len==0xFFFF)
254             return null;
255         try
256         {
257             String JavaDoc s=new String JavaDoc(_buf,_pos,len,StringUtil.__ISO_8859_1);
258             _pos+=len+1;
259             return s;
260         }
261         catch (IndexOutOfBoundsException JavaDoc e)
262         {
263             // Bad request!!!
264
LogSupport.ignore(log,e);
265             return null;
266         }
267         catch (UnsupportedEncodingException JavaDoc e)
268         {
269             log.fatal(e);
270             System.exit(1);
271             return null;
272         }
273     }
274
275     /* ------------------------------------------------------------ */
276     public String JavaDoc getMethod()
277     {
278         return __method[getByte()];
279     }
280
281     /* ------------------------------------------------------------ */
282     public String JavaDoc getHeader()
283     {
284         if ((0xFF&_buf[_pos])==0xA0)
285         {
286             _pos++;
287
288             return __header[_buf[_pos++]];
289         }
290         return getString();
291     }
292
293     /* ------------------------------------------------------------ */
294     public void addByte(byte b)
295     {
296         _buf[_bytes++]=b;
297     }
298
299     /* ------------------------------------------------------------ */
300     public int addBytes(byte[] buf, int offset, int length)
301     {
302         if (length>unconsumedCapacity())
303             length=unconsumedCapacity();
304         System.arraycopy(buf,offset,_buf,_bytes,length);
305         _bytes+=length;
306         return length;
307     }
308
309     /* ------------------------------------------------------------ */
310     public void addBoolean(boolean b)
311     {
312         _buf[_bytes++]=(byte)(b?1:0);
313     }
314
315     /* ------------------------------------------------------------ */
316     public void addInt(int i)
317     {
318         _buf[_bytes++]=(byte)((i>>8)&0xFF);
319         _buf[_bytes++]=(byte)(i&0xFF);
320     }
321
322     /* ------------------------------------------------------------ */
323     public void setInt(int mark, int i)
324     {
325         _buf[mark]=(byte)((i>>8)&0xFF);
326         _buf[mark+1]=(byte)(i&0xFF);
327     }
328
329     /* ------------------------------------------------------------ */
330     public void addString(String JavaDoc s) throws IOException JavaDoc
331     {
332         if (s==null)
333         {
334             addInt(0xFFFF);
335             return;
336         }
337
338         if (_byteWriter==null)
339             _byteWriter=new ByteArrayISO8859Writer(_buf);
340
341         int p=_bytes+2;
342         _byteWriter.setLength(p);
343         _byteWriter.write(s);
344         int l=_byteWriter.size()-p;
345
346         addInt(l);
347         _bytes+=l;
348         _buf[_bytes++]=(byte)0;
349     }
350
351     /* ------------------------------------------------------------ */
352     public void addHeader(String JavaDoc s) throws IOException JavaDoc
353     {
354         Integer JavaDoc h=(Integer JavaDoc)__headerMap.get(s);
355         if (h!=null)
356             addInt(h.intValue());
357         else
358             addString(s);
359     }
360
361     /* ------------------------------------------------------------ */
362     public int getDataSize()
363     {
364         return _bytes-__HDR_SIZE;
365     }
366
367     /* ------------------------------------------------------------ */
368     public void setDataSize()
369     {
370         setDataSize(_bytes-__HDR_SIZE);
371     }
372
373     /* ------------------------------------------------------------ */
374     public void setDataSize(int s)
375     {
376         _bytes=s+__HDR_SIZE;
377
378         if (_buf[4]==__SEND_BODY_CHUNK)
379             s=s+1;
380
381         _buf[2]=(byte)((s>>8)&0xFF);
382         _buf[3]=(byte)(s&0xFF);
383
384         if (_buf[4]==__SEND_BODY_CHUNK)
385         {
386             s=s-4;
387             _buf[5]=(byte)((s>>8)&0xFF);
388             _buf[6]=(byte)(s&0xFF);
389         }
390     }
391
392     /* ------------------------------------------------------------ */
393     public String JavaDoc toString()
394     {
395         return toString(-1);
396     }
397
398     /* ------------------------------------------------------------ */
399     public String JavaDoc toString(int max)
400     {
401         StringBuffer JavaDoc b=new StringBuffer JavaDoc();
402         StringBuffer JavaDoc a=new StringBuffer JavaDoc();
403
404         b.append(_bytes);
405         b.append('/');
406         b.append(_buf.length);
407         b.append('[');
408         b.append(_pos);
409         b.append("]: ");
410
411         switch (_buf[__HDR_SIZE])
412         {
413             case __FORWARD_REQUEST:
414                 b.append("FORWARD_REQUEST{:");
415                 break;
416             case __SHUTDOWN:
417                 b.append("SHUTDOWN :");
418                 break;
419             case __SEND_BODY_CHUNK:
420                 b.append("SEND_BODY_CHUNK :");
421                 break;
422             case __SEND_HEADERS:
423                 b.append("SEND_HEADERS ( :");
424                 break;
425             case __END_RESPONSE:
426                 b.append("END_RESPONSE )}:");
427                 break;
428             case __GET_BODY_CHUNK:
429                 b.append("GET_BODY_CHUNK :");
430                 break;
431         }
432
433         if (max==0)
434             return b.toString();
435
436         b.append("\n");
437
438         for (int i=0; i<_bytes; i++)
439         {
440             int d=_buf[i]&0xFF;
441             if (d<16)
442                 b.append('0');
443             b.append(Integer.toString(d,16));
444
445             char c=(char)d;
446
447             if (Character.isLetterOrDigit(c))
448                 a.append(c);
449             else
450                 a.append('.');
451
452             if (i%32==31||i==(_bytes-1))
453             {
454                 b.append(" : ");
455                 b.append(a.toString());
456                 a.setLength(0);
457                 b.append("\n");
458                 if (max>0&&(i+1)>=max)
459                     break;
460             }
461             else
462                 b.append(",");
463         }
464
465         return b.toString();
466     }
467 }
468
Popular Tags