Source Code Cross Referenced for Ajp13Processor.java in  » Sevlet-Container » tomcat-connectors » org » apache » ajp » tomcat4 » 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.tomcat4 
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.tomcat4;
018:
019:        import java.io.IOException;
020:        import java.net.Socket;
021:
022:        import javax.servlet.ServletException;
023:        import javax.servlet.http.HttpServletResponse;
024:
025:        import org.apache.ajp.Ajp13;
026:        import org.apache.catalina.Lifecycle;
027:        import org.apache.catalina.LifecycleException;
028:        import org.apache.catalina.LifecycleListener;
029:        import org.apache.catalina.util.LifecycleSupport;
030:        import org.apache.catalina.util.StringManager;
031:        import org.apache.tomcat.util.http.BaseRequest;
032:
033:        /**
034:         * @author Kevin Seguin
035:         * @version $Revision: 1.14 $ $Date: 2004/02/24 08:48:41 $
036:         */
037:
038:        final class Ajp13Processor implements  Lifecycle, Runnable {
039:
040:            /**
041:             * A simple class to provide synchronized access
042:             * to a boolean.
043:             */
044:            private class Bool {
045:
046:                private boolean b = false;
047:
048:                Bool() {
049:                }
050:
051:                Bool(boolean b) {
052:                    this .b = b;
053:                }
054:
055:                synchronized boolean value() {
056:                    return b;
057:                }
058:
059:                synchronized void set(boolean b) {
060:                    this .b = b;
061:                }
062:            }
063:
064:            // ----------------------------------------------------------- Constructors
065:
066:            /**
067:             * Construct a new Ajp13Processor associated with the specified connector.
068:             *
069:             * @param connector Ajp13Connector that owns this processor
070:             * @param id Identifier of this Ajp13Processor (unique per connector)
071:             * @param threadGroup The thread group any threads created by the processor
072:             *        should be in.
073:             */
074:            public Ajp13Processor(Ajp13Connector connector, int id,
075:                    ThreadGroup threadGroup) {
076:
077:                super ();
078:                this .connector = connector;
079:                this .debug = connector.getDebug();
080:                this .id = id;
081:                this .request = (Ajp13Request) connector.createRequest();
082:                this .request.setConnector(connector);
083:                this .request.setConnector(connector);
084:                this .response = (Ajp13Response) connector.createResponse();
085:                this .response.setConnector(connector);
086:                this .threadName = "Ajp13Processor[" + connector.getPort()
087:                        + "][" + id + "]";
088:                this .threadGroup = threadGroup;
089:
090:                this .logger.setConnector(connector);
091:                this .logger.setName(this .threadName);
092:            }
093:
094:            // ----------------------------------------------------- Instance Variables
095:
096:            private Ajp13Logger logger = new Ajp13Logger();
097:            private BaseRequest ajpRequest = new BaseRequest();
098:
099:            /**
100:             * Is there a new socket available?
101:             */
102:            private boolean available = false;
103:
104:            /**
105:             * The Ajp13Connector with which this processor is associated.
106:             */
107:            private Ajp13Connector connector = null;
108:
109:            /**
110:             * The debugging detail level for this component.
111:             */
112:            private int debug = 0;
113:
114:            /**
115:             * The identifier of this processor, unique per connector.
116:             */
117:            private int id = 0;
118:
119:            /**
120:             * The lifecycle event support for this component.
121:             */
122:            private LifecycleSupport lifecycle = new LifecycleSupport(this );
123:
124:            /**
125:             * The AJP13 request object we will pass to our associated container.
126:             */
127:            private Ajp13Request request = null;
128:
129:            /**
130:             * The AJP13 response object we will pass to our associated container.
131:             */
132:            private Ajp13Response response = null;
133:
134:            /**
135:             * The string manager for this package.
136:             */
137:            protected StringManager sm = StringManager
138:                    .getManager(Constants.PACKAGE);
139:
140:            /**
141:             * The socket we are currently processing a request for.  This object
142:             * is used for inter-thread communication only.
143:             */
144:            private Socket socket = null;
145:
146:            /**
147:             * Has this component been started yet?
148:             */
149:            private boolean started = false;
150:
151:            /**
152:             * The shutdown signal to our background thread
153:             */
154:            private Bool stopped = new Bool(true);
155:
156:            /**
157:             * Are we currently handling a request?
158:             */
159:            private Bool handlingRequest = new Bool(false);
160:
161:            /**
162:             * The background thread.
163:             */
164:            private Thread thread = null;
165:
166:            /**
167:             * The name to register for the background thread.
168:             */
169:            private String threadName = null;
170:
171:            /**
172:             * This processor's thread group.
173:             */
174:            private ThreadGroup threadGroup = null;
175:
176:            /**
177:             * The thread synchronization object.
178:             */
179:            private Object threadSync = new Object();
180:
181:            // -------------------------------------------------------- Package Methods
182:
183:            /**
184:             * Process an incoming TCP/IP connection on the specified socket.  Any
185:             * exception that occurs during processing must be logged and swallowed.
186:             * <b>NOTE</b>:  This method is called from our Connector's thread.  We
187:             * must assign it to our own thread so that multiple simultaneous
188:             * requests can be handled.
189:             *
190:             * @param socket TCP socket to process
191:             */
192:            synchronized void assign(Socket socket) {
193:
194:                // Wait for the Processor to get the previous Socket
195:                while (available) {
196:                    try {
197:                        wait();
198:                    } catch (InterruptedException e) {
199:                    }
200:                }
201:
202:                // Store the newly available Socket and notify our thread
203:                this .socket = socket;
204:                available = true;
205:                notifyAll();
206:
207:                if ((debug > 0) && (socket != null))
208:                    logger.log(" An incoming request is being assigned");
209:
210:            }
211:
212:            // -------------------------------------------------------- Private Methods
213:
214:            /**
215:             * Await a newly assigned Socket from our Connector, or <code>null</code>
216:             * if we are supposed to shut down.
217:             */
218:            private synchronized Socket await() {
219:
220:                // Wait for the Connector to provide a new Socket
221:                while (!available) {
222:                    try {
223:                        wait();
224:                    } catch (InterruptedException e) {
225:                    }
226:                }
227:
228:                // Notify the Connector that we have received this Socket
229:                Socket socket = this .socket;
230:                available = false;
231:                notifyAll();
232:
233:                if ((debug > 0) && (socket != null))
234:                    logger.log("  The incoming request has been awaited");
235:
236:                return (socket);
237:
238:            }
239:
240:            /**
241:             * Parse and record the connection parameters related to this request.
242:             *
243:             * @param socket The socket on which we are connected
244:             *
245:             * @exception IOException if an input/output error occurs
246:             * @exception ServletException if a parsing error occurs
247:             */
248:            private void parseConnection(Socket socket) throws IOException,
249:                    ServletException {
250:
251:                if (debug > 1)
252:                    logger.log("  parseConnection: address="
253:                            + socket.getInetAddress() + ", port="
254:                            + connector.getPort());
255:                request.setServerPort(connector.getPort());
256:                request.setSocket(socket);
257:
258:            }
259:
260:            /**
261:             * Process an incoming AJP13 request on the Socket that has been assigned
262:             * to this Processor.  Any exceptions that occur during processing must be
263:             * swallowed and dealt with.
264:             *
265:             * @param socket The socket on which we are connected to the client
266:             */
267:            private void process(Socket socket) {
268:
269:                Ajp13 ajp13 = new Ajp13();
270:                ajp13.setDebug(debug);
271:                ajp13.setLogger(new org.apache.ajp.Logger() {
272:                    public void log(String msg) {
273:                        logger.log("[Ajp13] " + msg);
274:                    }
275:
276:                    public void log(String msg, Throwable t) {
277:                        logger.log("[Ajp13] " + msg, t);
278:                    }
279:                });
280:
281:                Ajp13InputStream input = new Ajp13InputStream(ajp13);
282:                Ajp13OutputStream output = new Ajp13OutputStream(ajp13);
283:                response.setAjp13(ajp13);
284:
285:                try {
286:                    ajp13.setSocket(socket);
287:                } catch (IOException e) {
288:                    logger.log("process: ajp13.setSocket", e);
289:                }
290:
291:                boolean moreRequests = true;
292:                String expectedSecret = connector.getSecret();
293:
294:                boolean needAuth = (expectedSecret != null);
295:
296:                while (moreRequests && !stopped.value()) {
297:
298:                    int status = 0;
299:                    try {
300:                        if (debug > 0) {
301:                            logger.log("waiting on next request...");
302:                        }
303:
304:                        status = ajp13.receiveNextRequest(ajpRequest);
305:
306:                        if (debug > 0) {
307:                            logger.log("received next request, status="
308:                                    + status);
309:                        }
310:                    } catch (IOException e) {
311:                        logger.log("process: ajp13.receiveNextRequest", e);
312:                    }
313:
314:                    if (needAuth) {
315:                        String connSecret = ajp13.getSecret();
316:                        if (connSecret == null) {
317:                            logger.log("Connection without password, "
318:                                    + "tomcat is configured to require one");
319:                            break;
320:                        }
321:                        if (!connSecret.equals(expectedSecret)) {
322:                            logger.log("Connection with wrong password");
323:                            break;
324:                        }
325:
326:                        needAuth = false;
327:                    }
328:
329:                    if (stopped.value()) {
330:                        if (debug > 0) {
331:                            logger
332:                                    .log("process:  received request, but we're stopped");
333:                        }
334:                        break;
335:                    }
336:
337:                    if (status == -2) {
338:                        // special case - shutdown
339:                        // XXX need better communication, refactor it
340:                        //                  if( !doShutdown(socket.getLocalAddress(),
341:                        //                                  socket.getInetAddress())) {
342:                        //                      moreRequests = false;
343:                        //                      continue;
344:                        //                  }
345:                        break;
346:                    }
347:
348:                    // Allready handled by low level proto, don't go farther
349:                    if (status == 999) {
350:                        ajpRequest.recycle();
351:                        request.recycle();
352:
353:                        // recycle ajp13 object
354:                        ajp13.recycle();
355:
356:                        continue;
357:                    }
358:
359:                    if (status != 200)
360:                        break;
361:
362:                    try {
363:                        // set flag
364:                        handlingRequest.set(true);
365:
366:                        boolean bad_request = false;
367:
368:                        // set up request
369:                        try {
370:                            request.setAjpRequest(ajpRequest);
371:                        } catch (IllegalArgumentException e) {
372:                            bad_request = true;
373:                        }
374:                        request.setResponse(response);
375:                        request.setStream(input);
376:
377:                        // setup response
378:                        response.setRequest(request);
379:                        response.setStream(output);
380:
381:                        if (debug > 0) {
382:                            logger.log("invoking...");
383:                        }
384:
385:                        if (!bad_request) {
386:                            try {
387:                                connector.getContainer().invoke(request,
388:                                        response);
389:                            } catch (IOException ioe) {
390:                                // Pass the IOException through
391:                                throw ioe;
392:                            } catch (Throwable e) {
393:                                // A throwable here could be caused by a Valve,
394:                                // Filter, or other component in the chain.
395:                                // Processing of the request failed, return an
396:                                // Internal Server Error
397:                                logger.log("process: invoke", e);
398:                                response
399:                                        .sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
400:                            }
401:                        } else {
402:                            response
403:                                    .sendError(HttpServletResponse.SC_BAD_REQUEST);
404:                        }
405:
406:                        if (debug > 0) {
407:                            logger
408:                                    .log("done invoking, finishing request/response....");
409:                        }
410:
411:                        response.finishResponse();
412:                        request.finishRequest();
413:
414:                        if (debug > 0) {
415:                            logger.log("finished handling request.");
416:                        }
417:
418:                    } catch (IOException ioe) {
419:                        // Normally this catches a socket Broken Pipe caused by the
420:                        // remote client aborting the request. Don't print the stack
421:                        // trace in this case. Then let the Processor recycle.
422:                        logger.log("process: IOException " + ioe.getMessage());
423:                        moreRequests = false;
424:                    } catch (Throwable e) {
425:                        // Processing the request and sending the response failed.
426:                        // We don't know what the state of the Ajp Connector socket
427:                        // is in. Bail out and recycle the Processor.
428:                        logger.log("process: finish", e);
429:                        moreRequests = false;
430:                    }
431:
432:                    // Recycling the request and the response objects
433:                    if (debug > 0) {
434:                        logger.log("recyling objects ...");
435:                    }
436:
437:                    ajpRequest.recycle();
438:                    request.recycle();
439:                    response.recycle();
440:
441:                    // recycle ajp13 object
442:                    ajp13.recycle();
443:
444:                    // reset flag
445:                    handlingRequest.set(false);
446:                }
447:
448:                try {
449:                    if (debug > 0) {
450:                        logger.log("closing ajp13 object...");
451:                    }
452:
453:                    ajp13.close();
454:
455:                    if (debug > 0) {
456:                        logger.log("ajp13 object closed.");
457:                    }
458:                } catch (IOException e) {
459:                    logger.log("process: ajp13.close", e);
460:                }
461:
462:                try {
463:                    if (debug > 0) {
464:                        logger.log("closing socket...");
465:                    }
466:
467:                    socket.close();
468:
469:                    if (debug > 0) {
470:                        logger.log("socket closed.");
471:                    }
472:                } catch (IOException e) {
473:                    logger.log("process: socket.close", e);
474:                }
475:                socket = null;
476:
477:                if (debug > 0) {
478:                    logger.log("process:  done");
479:                }
480:            }
481:
482:            // ---------------------------------------------- Background Thread Methods
483:
484:            /**
485:             * The background thread that listens for incoming TCP/IP connections and
486:             * hands them off to an appropriate processor.
487:             */
488:            public void run() {
489:
490:                // Process requests until we receive a shutdown signal
491:                while (!stopped.value()) {
492:
493:                    // Wait for the next socket to be assigned
494:                    if (debug > 0) {
495:                        logger.log("waiting for next socket to be assigned...");
496:                    }
497:                    Socket socket = await();
498:                    if (socket == null)
499:                        continue;
500:
501:                    if (debug > 0) {
502:                        logger.log("socket assigned.");
503:                    }
504:
505:                    // Process the request from this socket
506:                    process(socket);
507:
508:                    // Finish up this request
509:                    if (debug > 0) {
510:                        logger.log("recycling myself ...");
511:                    }
512:                    connector.recycle(this );
513:                }
514:
515:                // Tell threadStop() we have shut ourselves down successfully
516:                synchronized (threadSync) {
517:                    threadSync.notifyAll();
518:                }
519:
520:            }
521:
522:            /**
523:             * Start the background processing thread.
524:             */
525:            private void threadStart() {
526:
527:                logger.log(sm.getString("ajp13Processor.starting"));
528:
529:                stopped.set(false);
530:                thread = new Thread(threadGroup, this , threadName);
531:                thread.setDaemon(true);
532:                thread.start();
533:
534:                if (debug > 0)
535:                    logger.log(" Background thread has been started");
536:
537:            }
538:
539:            /**
540:             * Stop the background processing thread.
541:             */
542:            private void threadStop() {
543:
544:                logger.log(sm.getString("ajp13Processor.stopping"));
545:
546:                stopped.set(true);
547:                assign(null);
548:                synchronized (threadSync) {
549:                    try {
550:                        if (handlingRequest.value()) {
551:                            if (debug > 0) {
552:                                logger
553:                                        .log("currentling handling a request, so waiting....");
554:                            }
555:                            threadSync.wait(5000);
556:                        } else {
557:                            if (debug > 0) {
558:                                logger
559:                                        .log("not currently handling a request, not waiting.");
560:                            }
561:                        }
562:                    } catch (InterruptedException e) {
563:                        ;
564:                    }
565:                }
566:                thread = null;
567:
568:            }
569:
570:            // ------------------------------------------------------ Lifecycle Methods
571:
572:            /**
573:             * Add a lifecycle event listener to this component.
574:             *
575:             * @param listener The listener to add
576:             */
577:            public void addLifecycleListener(LifecycleListener listener) {
578:
579:                lifecycle.addLifecycleListener(listener);
580:
581:            }
582:
583:            /**
584:             * Get the lifecycle listeners associated with this lifecycle. If this
585:             * Lifecycle has no listeners registered, a zero-length array is returned.
586:             */
587:            public LifecycleListener[] findLifecycleListeners() {
588:                return null; // FIXME: lifecycle.findLifecycleListeners();
589:            }
590:
591:            /**
592:             * Remove a lifecycle event listener from this component.
593:             *
594:             * @param listener The listener to add
595:             */
596:            public void removeLifecycleListener(LifecycleListener listener) {
597:
598:                lifecycle.removeLifecycleListener(listener);
599:
600:            }
601:
602:            /**
603:             * Start the background thread we will use for request processing.
604:             *
605:             * @exception LifecycleException if a fatal startup error occurs
606:             */
607:            public void start() throws LifecycleException {
608:
609:                if (started)
610:                    throw new LifecycleException(sm
611:                            .getString("ajp13Processor.alreadyStarted"));
612:                lifecycle.fireLifecycleEvent(START_EVENT, null);
613:                started = true;
614:
615:                threadStart();
616:
617:            }
618:
619:            /**
620:             * Stop the background thread we will use for request processing.
621:             *
622:             * @exception LifecycleException if a fatal shutdown error occurs
623:             */
624:            public void stop() throws LifecycleException {
625:
626:                if (!started)
627:                    throw new LifecycleException(sm
628:                            .getString("ajp13Processor.notStarted"));
629:                lifecycle.fireLifecycleEvent(STOP_EVENT, null);
630:                started = false;
631:
632:                threadStop();
633:
634:            }
635:
636:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.