1 16 package org.mortbay.http.ajp; 17 18 import java.io.IOException ; 19 import java.io.InputStream ; 20 import java.io.OutputStream ; 21 import java.io.UnsupportedEncodingException ; 22 import java.util.HashMap ; 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 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 [] __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 [] __header; 54 55 protected HashMap __headerMap=new HashMap (); 56 57 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 150 public int unconsumedData() 151 { 152 return _bytes-_pos; 153 } 154 155 156 159 public int unconsumedCapacity() 160 { 161 return _buf.length-_bytes; 162 } 163 164 165 public boolean read(InputStream in) throws IOException 166 { 167 _bytes=0; 168 _pos=0; 169 170 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 int magic=getInt(); 182 if (magic!=0x1234) 183 throw new IOException ("Bad JSP13 rcv packet:"+magic+" "+this); 184 int len=getInt(); 185 186 int packetLength=__HDR_SIZE+len; 188 if (packetLength>_buf.length) 189 throw new IOException ("AJP13 packet ("+packetLength+"bytes) too large for buffer ("+_buf.length+" bytes)"); 190 191 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 206 return true; 207 } 208 209 210 public void write(OutputStream out) throws IOException 211 { 212 if (log.isTraceEnabled()) 213 log.trace("AJP13 snd: "+this.toString(64)); 214 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 getString() 251 { 252 int len=getInt(); 253 if (len==0xFFFF) 254 return null; 255 try 256 { 257 String s=new String (_buf,_pos,len,StringUtil.__ISO_8859_1); 258 _pos+=len+1; 259 return s; 260 } 261 catch (IndexOutOfBoundsException e) 262 { 263 LogSupport.ignore(log,e); 265 return null; 266 } 267 catch (UnsupportedEncodingException e) 268 { 269 log.fatal(e); 270 System.exit(1); 271 return null; 272 } 273 } 274 275 276 public String getMethod() 277 { 278 return __method[getByte()]; 279 } 280 281 282 public String 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 s) throws IOException 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 s) throws IOException 353 { 354 Integer h=(Integer )__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 toString() 394 { 395 return toString(-1); 396 } 397 398 399 public String toString(int max) 400 { 401 StringBuffer b=new StringBuffer (); 402 StringBuffer a=new StringBuffer (); 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 |