KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > winstone > ajp13 > Ajp13IncomingPacket


1 /*
2  * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
3  * Distributed under the terms of either:
4  * - the common development and distribution license (CDDL), v1.0; or
5  * - the GNU Lesser General Public License, v2.1 or later
6  */

7 package winstone.ajp13;
8
9 import java.io.IOException JavaDoc;
10 import java.io.InputStream JavaDoc;
11 import java.io.UnsupportedEncodingException JavaDoc;
12 import java.util.Hashtable JavaDoc;
13 import java.util.Map JavaDoc;
14
15 import winstone.Logger;
16 import winstone.RequestHandlerThread;
17 import winstone.WinstoneException;
18
19 /**
20  * Models a single incoming ajp13 packet.
21  *
22  * @author mailto: <a HREF="rick_knowles@hotmail.com">Rick Knowles</a>
23  * @version $Id: Ajp13IncomingPacket.java,v 1.5 2006/08/10 06:38:31 rickknowles Exp $
24  */

25 public class Ajp13IncomingPacket {
26     // Server originated packet types
27
byte SERVER_FORWARD_REQUEST = 0x02;
28
29     // public static byte SERVER_SHUTDOWN = 0x07; //not implemented
30
// public static byte SERVER_PING = 0x08; //not implemented
31
// public static byte SERVER_CPING = 0x10; //not implemented
32

33     private int packetLength;
34     private byte packetBytes[];
35     private byte packetType;
36     private String JavaDoc method;
37     private String JavaDoc protocol;
38     private String JavaDoc uri;
39     private String JavaDoc remoteAddr;
40     private String JavaDoc remoteHost;
41     private String JavaDoc serverName;
42     private int serverPort;
43     private boolean isSSL;
44     private String JavaDoc headers[];
45     private Map JavaDoc attributes;
46
47     /**
48      * Constructor
49      */

50     public Ajp13IncomingPacket(InputStream JavaDoc in,
51             RequestHandlerThread handler) throws IOException JavaDoc {
52         // Get the incoming packet flag
53
byte headerBuffer[] = new byte[4];
54         int headerBytesRead = in.read(headerBuffer);
55         handler.setRequestStartTime();
56         if (headerBytesRead != 4)
57             throw new WinstoneException(Ajp13Listener.AJP_RESOURCES
58                     .getString("Ajp13IncomingPacket.InvalidHeader"));
59         else if ((headerBuffer[0] != 0x12) || (headerBuffer[1] != 0x34))
60             throw new WinstoneException(Ajp13Listener.AJP_RESOURCES
61                     .getString("Ajp13IncomingPacket.InvalidHeader"));
62
63         // Read in the whole packet
64
packetLength = ((headerBuffer[2] & 0xFF) << 8)
65                 + (headerBuffer[3] & 0xFF);
66         packetBytes = new byte[packetLength];
67         int packetBytesRead = in.read(packetBytes);
68
69         if (packetBytesRead < packetLength)
70             throw new WinstoneException(Ajp13Listener.AJP_RESOURCES
71                     .getString("Ajp13IncomingPacket.ShortPacket"));
72         // Ajp13Listener.packetDump(packetBytes, packetBytesRead);
73
}
74
75     public byte parsePacket(String JavaDoc encoding) throws IOException JavaDoc {
76         int position = 0;
77         this.packetType = packetBytes[position++];
78
79         if (this.packetType != SERVER_FORWARD_REQUEST)
80             throw new WinstoneException(Ajp13Listener.AJP_RESOURCES.getString(
81                     "Ajp13IncomingPacket.UnknownPacketType", this.packetType
82                             + ""));
83
84         // Check for terminator
85
if ((packetBytes[packetLength - 2] != (byte) 0)
86                 || (packetBytes[packetLength - 1] != (byte) 255))
87             throw new WinstoneException(Ajp13Listener.AJP_RESOURCES
88                     .getString("Ajp13IncomingPacket.InvalidTerminator"));
89
90         this.method = decodeMethodType(packetBytes[position++]);
91         Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
92                 "Ajp13IncomingPacket.Method", method);
93
94         // Protocol
95
int protocolLength = readInteger(position, packetBytes, true);
96         position += 2;
97         this.protocol = readString(position, packetBytes, encoding,
98                 protocolLength);
99         position += (protocolLength == 0 ? 0 : protocolLength + 1);
100         Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
101                 "Ajp13IncomingPacket.Protocol", protocol);
102
103         // URI
104
int uriLength = readInteger(position, packetBytes, true);
105         position += 2;
106         this.uri = readString(position, packetBytes, encoding, uriLength);
107         position += (uriLength == 0 ? 0 : uriLength + 1);
108         Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
109                 "Ajp13IncomingPacket.URI", uri);
110
111         // Remote addr
112
int remoteAddrLength = readInteger(position, packetBytes, true);
113         position += 2;
114         this.remoteAddr = readString(position, packetBytes, encoding,
115                 remoteAddrLength);
116         position += (remoteAddrLength == 0 ? 0 : remoteAddrLength + 1);
117         Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
118                 "Ajp13IncomingPacket.RemoteAddress", remoteAddr);
119
120         // Remote host
121
int remoteHostLength = readInteger(position, packetBytes, true);
122         position += 2;
123         this.remoteHost = readString(position, packetBytes, encoding,
124                 remoteHostLength);
125         position += (remoteHostLength == 0 ? 0 : remoteHostLength + 1);
126         Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
127                 "Ajp13IncomingPacket.RemoteHost", remoteHost);
128
129         // Server name
130
int serverNameLength = readInteger(position, packetBytes, true);
131         position += 2;
132         this.serverName = readString(position, packetBytes, encoding,
133                 serverNameLength);
134         position += (serverNameLength == 0 ? 0 : serverNameLength + 1);
135         Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
136                 "Ajp13IncomingPacket.ServerName", serverName);
137
138         this.serverPort = readInteger(position, packetBytes, false);
139         position += 2;
140         Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
141                 "Ajp13IncomingPacket.ServerPort", "" + serverPort);
142
143         this.isSSL = readBoolean(position++, packetBytes);
144         Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
145                 "Ajp13IncomingPacket.SSL", "" + isSSL);
146
147         // Read headers
148
int headerCount = readInteger(position, packetBytes, false);
149         Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
150                 "Ajp13IncomingPacket.HeaderCount", "" + headerCount);
151         position += 2;
152         this.headers = new String JavaDoc[headerCount];
153         for (int n = 0; n < headerCount; n++) {
154             // Header name
155
int headerTypeOrLength = readInteger(position, packetBytes, false);
156             position += 2;
157             String JavaDoc headerName = null;
158             if (packetBytes[position - 2] == (byte) 0xA0)
159                 headerName = decodeHeaderType(headerTypeOrLength);
160             else {
161                 headerName = readString(position, packetBytes, encoding,
162                         headerTypeOrLength);
163                 position += (headerTypeOrLength == 0 ? 0
164                         : headerTypeOrLength + 1);
165             }
166
167             // Header value
168
int headerValueLength = readInteger(position, packetBytes, true);
169             position += 2;
170             this.headers[n] = headerName
171                     + ": "
172                     + readString(position, packetBytes, encoding,
173                             headerValueLength);
174             position += (headerValueLength == 0 ? 0 : headerValueLength + 1);
175             Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
176                     "Ajp13IncomingPacket.Header", this.headers[n]);
177         }
178
179         // Attribute parsing
180
this.attributes = new Hashtable JavaDoc();
181         while (position < packetLength - 2) {
182             String JavaDoc attName = decodeAttributeType(packetBytes[position++]);
183             int attValueLength = readInteger(position, packetBytes, true);
184             position += 2;
185             String JavaDoc attValue = readString(position, packetBytes, encoding,
186                     attValueLength);
187             position += (attValueLength == 0 ? 0 : attValueLength + 1);
188
189             this.attributes.put(attName, attValue);
190             Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
191                     "Ajp13IncomingPacket.Attribute", new String JavaDoc[] { attName,
192                             attValue });
193         }
194         Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
195                 "Ajp13IncomingPacket.SuccessfullyReadRequest", ""
196                         + packetLength);
197         return this.packetType;
198     }
199
200     public int getPacketLength() {
201         return this.packetLength;
202     }
203
204     public String JavaDoc getMethod() {
205         return this.method;
206     }
207
208     public String JavaDoc getProtocol() {
209         return this.protocol;
210     }
211
212     public String JavaDoc getURI() {
213         return this.uri;
214     }
215
216     public String JavaDoc getRemoteAddress() {
217         return this.remoteAddr;
218     }
219
220     public String JavaDoc getRemoteHost() {
221         return this.remoteHost;
222     }
223
224     public String JavaDoc getServerName() {
225         return this.serverName;
226     }
227
228     public int getServerPort() {
229         return this.serverPort;
230     }
231
232     public boolean isSSL() {
233         return this.isSSL;
234     }
235
236     public String JavaDoc[] getHeaders() {
237         return this.headers;
238     }
239
240     public Map JavaDoc getAttributes() {
241         return this.attributes;
242     }
243
244     /**
245      * Read a single integer from the stream
246      */

247     private int readInteger(int position, byte packet[], boolean forStringLength) {
248         if (forStringLength && (packet[position] == (byte) 0xFF)
249                 && (packet[position + 1] == (byte) 0xFF))
250             return 0;
251         else
252             return ((packet[position] & 0xFF) << 8)
253                     + (packet[position + 1] & 0xFF);
254     }
255
256     /**
257      * Read a single boolean from the stream
258      */

259     private boolean readBoolean(int position, byte packet[]) {
260         return (packet[position] == (byte) 1);
261     }
262
263     /**
264      * Read a single string from the stream
265      */

266     private String JavaDoc readString(int position, byte packet[], String JavaDoc encoding,
267             int length) throws UnsupportedEncodingException JavaDoc {
268 // System.out.println("Reading string length: " + length +
269
// " position=" + position + " packetLength=" + packet.length);
270
return length == 0 ? ""
271                 : new String JavaDoc(packet, position, length, encoding);
272     }
273
274     /**
275      * Decodes the method types into Winstone HTTP method strings
276      */

277     private String JavaDoc decodeMethodType(byte methodType) {
278         switch (methodType) {
279         case 1:
280             return "OPTIONS";
281         case 2:
282             return "GET";
283         case 3:
284             return "HEAD";
285         case 4:
286             return "POST";
287         case 5:
288             return "PUT";
289         case 6:
290             return "DELETE";
291         case 7:
292             return "TRACE";
293         case 8:
294             return "PROPFIND";
295         case 9:
296             return "PROPPATCH";
297         case 10:
298             return "MKCOL";
299         case 11:
300             return "COPY";
301         case 12:
302             return "MOVE";
303         case 13:
304             return "LOCK";
305         case 14:
306             return "UNLOCK";
307         case 15:
308             return "ACL";
309         case 16:
310             return "REPORT";
311         case 17:
312             return "VERSION-CONTROL";
313         case 18:
314             return "CHECKIN";
315         case 19:
316             return "CHECKOUT";
317         case 20:
318             return "UNCHECKOUT";
319         case 21:
320             return "SEARCH";
321         case 22:
322             return "MKWORKSPACE";
323         case 23:
324             return "UPDATE";
325         case 24:
326             return "LABEL";
327         case 25:
328             return "MERGE";
329         case 26:
330             return "BASELINE_CONTROL";
331         case 27:
332             return "MKACTIVITY";
333         default:
334             return "UNKNOWN";
335         }
336     }
337
338     /**
339      * Decodes the header types into Winstone HTTP header strings
340      */

341     private String JavaDoc decodeHeaderType(int headerType) {
342         switch (headerType) {
343         case 0xA001:
344             return "Accept";
345         case 0xA002:
346             return "Accept-Charset";
347         case 0xA003:
348             return "Accept-Encoding";
349         case 0xA004:
350             return "Accept-Language";
351         case 0xA005:
352             return "Authorization";
353         case 0xA006:
354             return "Connection";
355         case 0xA007:
356             return "Content-Type";
357         case 0xA008:
358             return "Content-Length";
359         case 0xA009:
360             return "Cookie";
361         case 0xA00A:
362             return "Cookie2";
363         case 0xA00B:
364             return "Host";
365         case 0xA00C:
366             return "Pragma";
367         case 0xA00D:
368             return "Referer";
369         case 0xA00E:
370             return "User-Agent";
371         default:
372             return null;
373         }
374     }
375
376     /**
377      * Decodes the header types into Winstone HTTP header strings
378      */

379     private String JavaDoc decodeAttributeType(byte attributeType) {
380         switch (attributeType) {
381         case 0x01:
382             return "context";
383         case 0x02:
384             return "servlet_path";
385         case 0x03:
386             return "remote_user";
387         case 0x04:
388             return "auth_type";
389         case 0x05:
390             return "query_string";
391         case 0x06:
392             return "jvm_route";
393         case 0x07:
394             return "ssl_cert";
395         case 0x08:
396             return "ssl_cipher";
397         case 0x09:
398             return "ssl_session";
399         case 0x0A:
400             return "req_attribute";
401         default:
402             return null;
403         }
404     }
405 }
406
Popular Tags