Source Code Cross Referenced for Ajp13.java in  » Sevlet-Container » tomcat-connectors » org » apache » ajp » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Sevlet Container » tomcat connectors » org.apache.ajp 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *  Copyright 1999-2004 The Apache Software Foundation
003:         *
004:         *  Licensed under the Apache License, Version 2.0 (the "License");
005:         *  you may not use this file except in compliance with the License.
006:         *  You may obtain a copy of the License at
007:         *
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         *  Unless required by applicable law or agreed to in writing, software
011:         *  distributed under the License is distributed on an "AS IS" BASIS,
012:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         *  See the License for the specific language governing permissions and
014:         *  limitations under the License.
015:         */
016:
017:        package org.apache.ajp;
018:
019:        import java.io.IOException;
020:        import java.io.InputStream;
021:        import java.io.OutputStream;
022:        import java.net.Socket;
023:
024:        import org.apache.tomcat.util.http.BaseRequest;
025:        import org.apache.tomcat.util.http.HttpMessages;
026:        import org.apache.tomcat.util.http.MimeHeaders;
027:
028:        /**
029:         * Represents a single, persistent connection between the web server and
030:         * the servlet container.  Uses the Apache JServ Protocol version 1.3 for
031:         * communication.  Because this protocal does not multiplex requests, this
032:         * connection can only be associated with a single request-handling cycle
033:         * at a time.<P>
034:         *
035:         * This class contains knowledge about how an individual packet is laid out
036:         * (via the <CODE>Ajp13Packet</CODE> class), and also about the
037:         * stages of communicaton between the server and the servlet container.  It
038:         * translates from Tomcat's internal servlet support methods
039:         * (e.g. doWrite) to the correct packets to send to the web server.
040:         *
041:         * @see Ajp13Interceptor 
042:         *
043:         * @author Dan Milstein [danmil@shore.net]
044:         * @author Keith Wannamaker [Keith@Wannamaker.org]
045:         * @author Kevin Seguin [seguin@apache.org]
046:         * @author Henri Gomez [hgomez@apache.org]
047:         * @author Costin Manolache
048:         */
049:        public class Ajp13 {
050:
051:            public static final int MAX_PACKET_SIZE = 8192;
052:            public static final int H_SIZE = 4; // Size of basic packet header
053:
054:            public static final int MAX_READ_SIZE = MAX_PACKET_SIZE - H_SIZE
055:                    - 2;
056:            public static final int MAX_SEND_SIZE = MAX_PACKET_SIZE - H_SIZE
057:                    - 4;
058:
059:            // Error code for Ajp13
060:            public static final int JK_AJP13_BAD_HEADER = -100;
061:            public static final int JK_AJP13_NO_HEADER = -101;
062:            public static final int JK_AJP13_COMM_CLOSED = -102;
063:            public static final int JK_AJP13_COMM_BROKEN = -103;
064:            public static final int JK_AJP13_BAD_BODY = -104;
065:            public static final int JK_AJP13_INCOMPLETE_BODY = -105;
066:
067:            // ============ Instance Properties ====================
068:
069:            OutputStream out;
070:            InputStream in;
071:
072:            // Buffer used of output body and headers
073:            public Ajp13Packet outBuf = new Ajp13Packet(MAX_PACKET_SIZE);
074:            // Buffer used for input body
075:            Ajp13Packet inBuf = new Ajp13Packet(MAX_PACKET_SIZE);
076:            // Buffer used for request head ( and headers )
077:            Ajp13Packet hBuf = new Ajp13Packet(MAX_PACKET_SIZE);
078:
079:            // Holds incoming reads of request body data (*not* header data)
080:            byte[] bodyBuff = new byte[MAX_READ_SIZE];
081:
082:            int blen; // Length of current chunk of body data in buffer
083:            int pos; // Current read position within that buffer
084:
085:            boolean end_of_stream; // true if we've received an empty packet
086:
087:            // Required handler - essential request processing
088:            public RequestHandler reqHandler;
089:            // AJP14 - detect protocol,set communication parameters, login
090:            // If no password is set, use only Ajp13 messaging
091:            boolean backwardCompat = true;
092:            boolean logged = false;
093:            String secret = null;
094:
095:            public Ajp13() {
096:                super ();
097:                initBuf();
098:                reqHandler = new RequestHandler();
099:                reqHandler.init(this );
100:            }
101:
102:            public Ajp13(RequestHandler reqHandler) {
103:                super ();
104:                initBuf();
105:                this .reqHandler = reqHandler;
106:                reqHandler.init(this );
107:            }
108:
109:            /** Will be overriden
110:             */
111:            public void initBuf() {
112:                outBuf = new Ajp13Packet(MAX_PACKET_SIZE);
113:                inBuf = new Ajp13Packet(MAX_PACKET_SIZE);
114:                hBuf = new Ajp13Packet(MAX_PACKET_SIZE);
115:            }
116:
117:            public void recycle() {
118:                if (debug > 0) {
119:                    logger.log("recycle()");
120:                }
121:
122:                // This is a touch cargo-cultish, but I think wise.
123:                blen = 0;
124:                pos = 0;
125:                end_of_stream = false;
126:                logged = false;
127:            }
128:
129:            /**
130:             * Associate an open socket with this instance.
131:             */
132:            public void setSocket(Socket socket) throws IOException {
133:                if (debug > 0) {
134:                    logger.log("setSocket()");
135:                }
136:
137:                socket.setSoLinger(true, 100);
138:                out = socket.getOutputStream();
139:                in = socket.getInputStream();
140:                pos = 0;
141:            }
142:
143:            /**
144:             * Backward compat mode, no login  needed
145:             */
146:            public void setBackward(boolean b) {
147:                backwardCompat = b;
148:            }
149:
150:            public boolean isLogged() {
151:                return logged;
152:            }
153:
154:            void setLogged(boolean b) {
155:                logged = b;
156:            }
157:
158:            public void setSecret(String s) {
159:                secret = s;
160:            }
161:
162:            public String getSecret() {
163:                return secret;
164:            }
165:
166:            // -------------------- Handlers registry --------------------
167:
168:            static final int MAX_HANDLERS = 32;
169:            static final int RESERVED = 16; // reserved names, backward compat
170:
171:            // Note that we don't make distinction between in and out
172:            // messages ( i.e. one id is used only in one direction )
173:            AjpHandler handlers[] = new AjpHandler[MAX_HANDLERS];
174:            String handlerName[] = new String[MAX_HANDLERS];
175:            int currentId = RESERVED;
176:
177:            public int registerMessageType(int id, String name, AjpHandler h,
178:                    String sig[]) {
179:                if (id < 0) {
180:                    // try to find it by name
181:                    for (int i = 0; i < handlerName.length; i++)
182:                        if (name.equals(handlerName[i]))
183:                            return i;
184:                    handlerName[currentId] = name;
185:                    handlers[currentId] = h;
186:                    currentId++;
187:                    return currentId;
188:                }
189:                // fixed id
190:                handlerName[id] = name;
191:                handlers[id] = h;
192:                return id;
193:            }
194:
195:            // -------------------- Main dispatch --------------------
196:
197:            /**
198:             * Read a new packet from the web server and decode it.  If it's a
199:             * forwarded request, store its properties in the passed-in AjpRequest
200:             * object.
201:             *
202:             * @param req An empty (newly-recycled) request object.
203:             * 
204:             * @return 200 in case of a successful read of a forwarded request, 500
205:             * if there were errors in the reading of the request, and -2 if the
206:             * server is asking the container to shut itself down.  
207:             */
208:            public int receiveNextRequest(BaseRequest req) throws IOException {
209:                if (debug > 0) {
210:                    logger.log("receiveNextRequest()");
211:                }
212:
213:                // XXX The return values are awful.
214:
215:                int err = 0;
216:
217:                // if we receive an IOException here, it must be because
218:                // the remote just closed the ajp13 connection, and it's not
219:                // an error, we just need to close the AJP13 connection
220:                try {
221:                    err = receive(hBuf);
222:                } catch (IOException ioe) {
223:                    if (debug > 0)
224:                        logger.log("IOException receiving message ");
225:                    return -1; // Indicate it's a disconnection from the remote end
226:                }
227:
228:                if (err < 0) {
229:                    if (debug > 0)
230:                        logger.log("Error receiving message ");
231:                    return 500;
232:                }
233:
234:                int type = (int) hBuf.getByte();
235:                //        System.out.println("XXX " + this );
236:                return handleMessage(type, hBuf, req);
237:            }
238:
239:            /** Override for ajp14, temporary
240:             */
241:            public int handleMessage(int type, Ajp13Packet hBuf, BaseRequest req)
242:                    throws IOException {
243:                if (type > handlers.length) {
244:                    logger.log("Invalid handler " + type);
245:                    return 500;
246:                }
247:
248:                if (debug > 0)
249:                    logger.log("Received " + type + " " + handlerName[type]);
250:
251:                // Ajp14, unlogged
252:                if (!backwardCompat && !isLogged()) {
253:                    if (type != NegociationHandler.JK_AJP14_LOGINIT_CMD
254:                            && type != NegociationHandler.JK_AJP14_LOGCOMP_CMD) {
255:
256:                        logger.log("Ajp14 error: not logged " + type + " "
257:                                + handlerName[type]);
258:
259:                        return 300;
260:                    }
261:                    // else continue
262:                }
263:
264:                // Ajp13 messages
265:                switch (type) {
266:                case RequestHandler.JK_AJP13_FORWARD_REQUEST:
267:                    return reqHandler.decodeRequest(this , hBuf, req);
268:
269:                case RequestHandler.JK_AJP13_CPING_REQUEST:
270:                    return reqHandler.sendCPong(this , outBuf);
271:
272:                case RequestHandler.JK_AJP13_SHUTDOWN:
273:                    return -2;
274:                }
275:
276:                // logged || loging message
277:                AjpHandler handler = handlers[type];
278:                if (handler == null) {
279:                    logger.log("Unknown message " + type + handlerName[type]);
280:                    return 200;
281:                }
282:
283:                if (debug > 0)
284:                    logger.log("Ajp14 handler " + handler);
285:                return handler.handleAjpMessage(type, this , hBuf, req);
286:            }
287:
288:            // ==================== Servlet Input Support =================
289:
290:            /** @deprecated -- Will use reqHandler, make sure nobody else
291:             calls this */
292:
293:            public int available() throws IOException {
294:                return reqHandler.available(this );
295:            }
296:
297:            public int doRead() throws IOException {
298:                return reqHandler.doRead(this );
299:            }
300:
301:            public int doRead(byte[] b, int off, int len) throws IOException {
302:                return reqHandler.doRead(this , b, off, len);
303:            }
304:
305:            private boolean refillReadBuffer() throws IOException {
306:                return reqHandler.refillReadBuffer(this );
307:            }
308:
309:            public void beginSendHeaders(int status, String statusMessage,
310:                    int numHeaders) throws IOException {
311:                reqHandler.beginSendHeaders(this , outBuf, status,
312:                        statusMessage, numHeaders);
313:            }
314:
315:            public void sendHeader(String name, String value)
316:                    throws IOException {
317:                reqHandler.sendHeader(outBuf, name, value);
318:            }
319:
320:            public void endSendHeaders() throws IOException {
321:                reqHandler.endSendHeaders(this , outBuf);
322:            }
323:
324:            public void sendHeaders(int status, MimeHeaders headers)
325:                    throws IOException {
326:                reqHandler.sendHeaders(this , outBuf, status, HttpMessages
327:                        .getMessage(status), headers);
328:            }
329:
330:            public void sendHeaders(int status, String statusMessage,
331:                    MimeHeaders headers) throws IOException {
332:                reqHandler.sendHeaders(this , outBuf, status, statusMessage,
333:                        headers);
334:            }
335:
336:            public void finish() throws IOException {
337:                reqHandler.finish(this , outBuf);
338:            }
339:
340:            public void doWrite(byte b[], int off, int len) throws IOException {
341:                reqHandler.doWrite(this , outBuf, b, off, len);
342:            }
343:
344:            // ========= Internal Packet-Handling Methods =================
345:
346:            /**
347:             * Read N bytes from the InputStream, and ensure we got them all
348:             * Under heavy load we could experience many fragmented packets
349:             * just read Unix Network Programming to recall that a call to
350:             * read didn't ensure you got all the data you want
351:             *
352:             * from read() Linux manual
353:             *
354:             * On success, the number of bytes read is returned (zero indicates end of file),
355:             * and the file position is advanced by this number.
356:             * It is not an error if this number is smaller than the number of bytes requested;
357:             * this may happen for example because fewer bytes
358:             * are actually available right now (maybe because we were close to end-of-file,
359:             * or because we are reading from a pipe, or  from  a
360:             * terminal),  or  because  read()  was interrupted by a signal.
361:             * On error, -1 is returned, and errno is set appropriately. In this
362:             * case it is left unspecified whether the file position (if any) changes.
363:             *
364:             **/
365:            private int readN(InputStream in, byte[] b, int offset, int len)
366:                    throws IOException {
367:                int pos = 0;
368:                int got;
369:
370:                while (pos < len) {
371:                    got = in.read(b, pos + offset, len - pos);
372:
373:                    if (debug > 10) {
374:                        logger.log("read got # " + got);
375:                    }
376:
377:                    // connection just closed by remote. 
378:                    if (got <= 0) {
379:                        // This happens periodically, as apache restarts
380:                        // periodically.
381:                        // It should be more gracefull ! - another feature for Ajp14 
382:                        return JK_AJP13_COMM_BROKEN;
383:                    }
384:
385:                    pos += got;
386:                }
387:                return pos;
388:            }
389:
390:            /**
391:             * Read in a packet from the web server and store it in the passed-in
392:             * <CODE>Ajp13Packet</CODE> object.
393:             *
394:             * @param msg The object into which to store the incoming packet -- any
395:             * current contents will be overwritten.
396:             *
397:             * @return The number of bytes read on a successful read or -1 if there 
398:             * was an error.
399:             **/
400:            public int receive(Ajp13Packet msg) throws IOException {
401:                if (debug > 0) {
402:                    logger.log("receive()");
403:                }
404:
405:                // XXX If the length in the packet header doesn't agree with the
406:                // actual number of bytes read, it should probably return an error
407:                // value.  Also, callers of this method never use the length
408:                // returned -- should probably return true/false instead.
409:                byte b[] = msg.getBuff();
410:
411:                int rd = readN(in, b, 0, H_SIZE);
412:
413:                // XXX - connection closed (JK_AJP13_COMM_CLOSED)
414:                //     - connection broken (JK_AJP13_COMM_BROKEN)
415:                //
416:                if (rd < 0) {
417:                    // Most likely normal apache restart.
418:                    return rd;
419:                }
420:
421:                int len = msg.checkIn();
422:                if (debug > 5)
423:                    logger.log("Received " + rd + " " + len + " " + b[0]);
424:
425:                // XXX check if enough space - it's assert()-ed !!!
426:
427:                int total_read = 0;
428:
429:                total_read = readN(in, b, H_SIZE, len);
430:
431:                // it's ok to have read 0 bytes when len=0 -- this means
432:                // the end of the stream has been reached.
433:                if (total_read < 0) {
434:                    logger.log("can't read body, waited #" + len);
435:                    return JK_AJP13_BAD_BODY;
436:                }
437:
438:                if (total_read != len) {
439:                    logger.log("incomplete read, waited #" + len + " got only "
440:                            + total_read);
441:                    return JK_AJP13_INCOMPLETE_BODY;
442:                }
443:
444:                if (debug > 0)
445:                    logger.log("receive:  total read = " + total_read);
446:                return total_read;
447:            }
448:
449:            /**
450:             * Send a packet to the web server.  Works for any type of message.
451:             *
452:             * @param msg A packet with accumulated data to send to the server --
453:             * this method will write out the length in the header.  
454:             */
455:            public void send(Ajp13Packet msg) throws IOException {
456:                if (debug > 0) {
457:                    logger.log("send()");
458:                }
459:
460:                msg.end(); // Write the packet header
461:                byte b[] = msg.getBuff();
462:                int len = msg.getLen();
463:
464:                if (debug > 5)
465:                    logger.log("send() " + len + " " + b[0]);
466:
467:                out.write(b, 0, len);
468:            }
469:
470:            /**
471:             * Close the socket connection to the web server.  In general, sockets
472:             * are maintained across many requests, so this will not be called
473:             * after finish().  
474:             *
475:             * @see Ajp13Interceptor#processConnection
476:             */
477:            public void close() throws IOException {
478:                if (debug > 0) {
479:                    logger.log("close()");
480:                }
481:
482:                if (null != out) {
483:                    out.close();
484:                }
485:                if (null != in) {
486:                    in.close();
487:                }
488:                setLogged(false); // no more logged now 
489:            }
490:
491:            // -------------------- Debug --------------------
492:            protected int debug = 0;
493:
494:            public void setDebug(int debug) {
495:                this .debug = debug;
496:                this .reqHandler.setDebug(debug);
497:            }
498:
499:            public void setLogger(Logger l) {
500:                this .logger = l;
501:                this .reqHandler.setLogger(l);
502:            }
503:
504:            /**
505:             * XXX place holder...
506:             */
507:            Logger logger = new Logger();
508:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.