Source Code Cross Referenced for HttpProcessor.java in  » Web-Server » Rimfaxe-Web-Server » org » apache » catalina » connector » http10 » 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 » Web Server » Rimfaxe Web Server » org.apache.catalina.connector.http10 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/http10/HttpProcessor.java,v 1.9 2002/04/04 17:50:34 remm Exp $
003:         * $Revision: 1.9 $
004:         * $Date: 2002/04/04 17:50:34 $
005:         *
006:         * ====================================================================
007:         *
008:         * The Apache Software License, Version 1.1
009:         *
010:         * Copyright (c) 1999 The Apache Software Foundation.  All rights
011:         * reserved.
012:         *
013:         * Redistribution and use in source and binary forms, with or without
014:         * modification, are permitted provided that the following conditions
015:         * are met:
016:         *
017:         * 1. Redistributions of source code must retain the above copyright
018:         *    notice, this list of conditions and the following disclaimer.
019:         *
020:         * 2. Redistributions in binary form must reproduce the above copyright
021:         *    notice, this list of conditions and the following disclaimer in
022:         *    the documentation and/or other materials provided with the
023:         *    distribution.
024:         *
025:         * 3. The end-user documentation included with the redistribution, if
026:         *    any, must include the following acknowlegement:
027:         *       "This product includes software developed by the
028:         *        Apache Software Foundation (http://www.apache.org/)."
029:         *    Alternately, this acknowlegement may appear in the software itself,
030:         *    if and wherever such third-party acknowlegements normally appear.
031:         *
032:         * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
033:         *    Foundation" must not be used to endorse or promote products derived
034:         *    from this software without prior written permission. For written
035:         *    permission, please contact apache@apache.org.
036:         *
037:         * 5. Products derived from this software may not be called "Apache"
038:         *    nor may "Apache" appear in their names without prior written
039:         *    permission of the Apache Group.
040:         *
041:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
042:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
043:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
044:         * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
045:         * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
046:         * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
047:         * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
048:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
049:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
050:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
051:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
052:         * SUCH DAMAGE.
053:         * ====================================================================
054:         *
055:         * This software consists of voluntary contributions made by many
056:         * individuals on behalf of the Apache Software Foundation.  For more
057:         * information on the Apache Software Foundation, please see
058:         * <http://www.apache.org/>.
059:         *
060:         * [Additional notices, if required by prior licensing conditions]
061:         *
062:         */
063:
064:        package org.apache.catalina.connector.http10;
065:
066:        import java.io.BufferedInputStream;
067:        import java.io.InputStream;
068:        import java.io.IOException;
069:        import java.io.OutputStream;
070:        import java.net.InetAddress;
071:        import java.net.Socket;
072:        import java.util.NoSuchElementException;
073:        import java.util.StringTokenizer;
074:        import java.util.Locale;
075:        import java.util.Hashtable;
076:        import java.util.Vector;
077:        import java.util.Enumeration;
078:        import javax.servlet.ServletException;
079:        import javax.servlet.http.Cookie;
080:        import javax.servlet.http.HttpServletRequest;
081:        import javax.servlet.http.HttpServletResponse;
082:        import org.apache.catalina.Connector;
083:        import org.apache.catalina.Container;
084:        import org.apache.catalina.Globals;
085:        import org.apache.catalina.HttpRequest;
086:        import org.apache.catalina.HttpResponse;
087:        import org.apache.catalina.Lifecycle;
088:        import org.apache.catalina.LifecycleEvent;
089:        import org.apache.catalina.LifecycleException;
090:        import org.apache.catalina.LifecycleListener;
091:        import org.apache.catalina.Logger;
092:        import org.apache.catalina.util.RequestUtil;
093:        import org.apache.catalina.util.LifecycleSupport;
094:        import org.apache.catalina.util.ServerInfo;
095:        import org.apache.catalina.util.StringManager;
096:
097:        /**
098:         * Implementation of a request processor (and its associated thread) that may
099:         * be used by an HttpConnector to process individual requests.  The connector
100:         * will allocate a processor from its pool, assign a particular socket to it,
101:         * and the processor will then execute the processing required to complete
102:         * the request.  When the processor is completed, it will recycle itself.
103:         *
104:         * @author Craig R. McClanahan
105:         * @version $Revision: 1.9 $ $Date: 2002/04/04 17:50:34 $
106:         * @deprecated
107:         */
108:
109:        final class HttpProcessor implements  Lifecycle, Runnable {
110:
111:            // ----------------------------------------------------- Manifest Constants
112:
113:            /**
114:             * Server information string for this server.
115:             */
116:            private static final String SERVER_INFO = ServerInfo
117:                    .getServerInfo()
118:                    + " (HTTP/1.0 Connector)";
119:
120:            // ----------------------------------------------------------- Constructors
121:
122:            /**
123:             * Construct a new HttpProcessor associated with the specified connector.
124:             *
125:             * @param connector HttpConnector that owns this processor
126:             * @param id Identifier of this HttpProcessor (unique per connector)
127:             */
128:            public HttpProcessor(HttpConnector connector, int id) {
129:
130:                super ();
131:                this .connector = connector;
132:                this .debug = connector.getDebug();
133:                this .id = id;
134:                this .proxyName = connector.getProxyName();
135:                this .proxyPort = connector.getProxyPort();
136:                this .request = (HttpRequestImpl) connector.createRequest();
137:                this .response = (HttpResponseImpl) connector.createResponse();
138:                this .serverPort = connector.getPort();
139:                this .threadName = "HttpProcessor[" + connector.getPort() + "]["
140:                        + id + "]";
141:
142:            }
143:
144:            // ----------------------------------------------------- Instance Variables
145:
146:            /**
147:             * Is there a new socket available?
148:             */
149:            private boolean available = false;
150:
151:            /**
152:             * The HttpConnector with which this processor is associated.
153:             */
154:            private HttpConnector connector = null;
155:
156:            /**
157:             * The debugging detail level for this component.
158:             */
159:            private int debug = 0;
160:
161:            /**
162:             * The identifier of this processor, unique per connector.
163:             */
164:            private int id = 0;
165:
166:            /**
167:             * The lifecycle event support for this component.
168:             */
169:            private LifecycleSupport lifecycle = new LifecycleSupport(this );
170:
171:            /**
172:             * The match string for identifying a session ID parameter.
173:             */
174:            private static final String match = ";"
175:                    + Globals.SESSION_PARAMETER_NAME + "=";
176:
177:            /**
178:             * The proxy server name for our Connector.
179:             */
180:            private String proxyName = null;
181:
182:            /**
183:             * The proxy server port for our Connector.
184:             */
185:            private int proxyPort = 0;
186:
187:            /**
188:             * The HTTP request object we will pass to our associated container.
189:             */
190:            private HttpRequestImpl request = null;
191:
192:            /**
193:             * The HTTP response object we will pass to our associated container.
194:             */
195:            private HttpResponseImpl response = null;
196:
197:            /**
198:             * The actual server port for our Connector.
199:             */
200:            private int serverPort = 0;
201:
202:            /**
203:             * The string manager for this package.
204:             */
205:            protected StringManager sm = StringManager
206:                    .getManager(Constants.Package);
207:
208:            /**
209:             * The socket we are currently processing a request for.  This object
210:             * is used for inter-thread communication only.
211:             */
212:            private Socket socket = null;
213:
214:            /**
215:             * Has this component been started yet?
216:             */
217:            private boolean started = false;
218:
219:            /**
220:             * The shutdown signal to our background thread
221:             */
222:            private boolean stopped = false;
223:
224:            /**
225:             * The background thread.
226:             */
227:            private Thread thread = null;
228:
229:            /**
230:             * The name to register for the background thread.
231:             */
232:            private String threadName = null;
233:
234:            /**
235:             * The thread synchronization object.
236:             */
237:            private Object threadSync = new Object();
238:
239:            // -------------------------------------------------------- Package Methods
240:
241:            /**
242:             * Process an incoming TCP/IP connection on the specified socket.  Any
243:             * exception that occurs during processing must be logged and swallowed.
244:             * <b>NOTE</b>:  This method is called from our Connector's thread.  We
245:             * must assign it to our own thread so that multiple simultaneous
246:             * requests can be handled.
247:             *
248:             * @param socket TCP socket to process
249:             */
250:            synchronized void assign(Socket socket) {
251:
252:                // Wait for the Processor to get the previous Socket
253:                while (available) {
254:                    try {
255:                        wait();
256:                    } catch (InterruptedException e) {
257:                    }
258:                }
259:
260:                // Store the newly available Socket and notify our thread
261:                this .socket = socket;
262:                available = true;
263:                notifyAll();
264:
265:                if ((debug >= 1) && (socket != null))
266:                    log(" An incoming request is being assigned");
267:
268:            }
269:
270:            // -------------------------------------------------------- Private Methods
271:
272:            /**
273:             * Await a newly assigned Socket from our Connector, or <code>null</code>
274:             * if we are supposed to shut down.
275:             */
276:            private synchronized Socket await() {
277:
278:                // Wait for the Connector to provide a new Socket
279:                while (!available) {
280:                    try {
281:                        wait();
282:                    } catch (InterruptedException e) {
283:                    }
284:                }
285:
286:                // Notify the Connector that we have received this Socket
287:                Socket socket = this .socket;
288:                available = false;
289:                notifyAll();
290:
291:                if ((debug >= 1) && (socket != null))
292:                    log("  The incoming request has been awaited");
293:
294:                return (socket);
295:
296:            }
297:
298:            /**
299:             * Log a message on the Logger associated with our Container (if any)
300:             *
301:             * @param message Message to be logged
302:             */
303:            private void log(String message) {
304:
305:                Logger logger = connector.getContainer().getLogger();
306:                if (logger != null)
307:                    logger.log(threadName + " " + message);
308:
309:            }
310:
311:            /**
312:             * Log a message on the Logger associated with our Container (if any)
313:             *
314:             * @param message Message to be logged
315:             * @param throwable Associated exception
316:             */
317:            private void log(String message, Throwable throwable) {
318:
319:                Logger logger = connector.getContainer().getLogger();
320:                if (logger != null)
321:                    logger.log(threadName + " " + message, throwable);
322:
323:            }
324:
325:            /**
326:             * Parse and record the connection parameters related to this request.
327:             *
328:             * @param socket The socket on which we are connected
329:             *
330:             * @exception IOException if an input/output error occurs
331:             * @exception ServletException if a parsing error occurs
332:             */
333:            private void parseConnection(Socket socket) throws IOException,
334:                    ServletException {
335:
336:                if (debug >= 2)
337:                    log("  parseConnection: address=" + socket.getInetAddress()
338:                            + ", port=" + connector.getPort());
339:                ((HttpRequestImpl) request).setInet(socket.getInetAddress());
340:                if (proxyPort != 0)
341:                    request.setServerPort(proxyPort);
342:                else
343:                    request.setServerPort(serverPort);
344:                request.setSocket(socket);
345:
346:            }
347:
348:            /**
349:             * Parse the incoming HTTP request headers, and set the appropriate
350:             * request headers.
351:             *
352:             * @param input The input stream connected to our socket
353:             *
354:             * @exception IOException if an input/output error occurs
355:             * @exception ServletException if a parsing error occurs
356:             */
357:            private void parseHeaders(InputStream input) throws IOException,
358:                    ServletException {
359:
360:                while (true) {
361:
362:                    // Read the next header line
363:                    String line = read(input);
364:                    if ((line == null) || (line.length() < 1))
365:                        break;
366:
367:                    // Parse the header name and value
368:                    int colon = line.indexOf(':');
369:                    if (colon < 0)
370:                        throw new ServletException(sm
371:                                .getString("httpProcessor.parseHeaders.colon"));
372:                    String name = line.substring(0, colon).trim();
373:                    String match = name.toLowerCase();
374:                    String value = line.substring(colon + 1).trim();
375:                    if (debug >= 1)
376:                        log(" Header " + name + " = " + value);
377:
378:                    // Set the corresponding request headers
379:                    if (match.equals("authorization")) {
380:                        request.setAuthorization(value);
381:                        request.addHeader(name, value);
382:                    } else if (match.equals("accept-language")) {
383:                        request.addHeader(name, value);
384:                        //
385:                        // Adapted from old code perhaps maybe optimized
386:                        //
387:                        //
388:                        Hashtable languages = new Hashtable();
389:                        StringTokenizer languageTokenizer = new StringTokenizer(
390:                                value, ",");
391:
392:                        while (languageTokenizer.hasMoreTokens()) {
393:                            String language = languageTokenizer.nextToken()
394:                                    .trim();
395:                            int qValueIndex = language.indexOf(';');
396:                            int qIndex = language.indexOf('q');
397:                            int equalIndex = language.indexOf('=');
398:                            Double qValue = new Double(1);
399:
400:                            if (qValueIndex > -1 && qValueIndex < qIndex
401:                                    && qIndex < equalIndex) {
402:                                String qValueStr = language
403:                                        .substring(qValueIndex + 1);
404:                                language = language.substring(0, qValueIndex);
405:                                qValueStr = qValueStr.trim().toLowerCase();
406:                                qValueIndex = qValueStr.indexOf('=');
407:                                qValue = new Double(0);
408:                                if (qValueStr.startsWith("q")
409:                                        && qValueIndex > -1) {
410:                                    qValueStr = qValueStr
411:                                            .substring(qValueIndex + 1);
412:                                    try {
413:                                        qValue = new Double(qValueStr.trim());
414:                                    } catch (NumberFormatException nfe) {
415:                                    }
416:                                }
417:                            }
418:                            // XXX
419:                            // may need to handle "*" at some point in time
420:                            if (!language.equals("*")) {
421:                                String key = qValue.toString();
422:                                Vector v = (Vector) ((languages
423:                                        .containsKey(key)) ? languages.get(key)
424:                                        : new Vector());
425:                                v.addElement(language);
426:                                languages.put(key, v);
427:                            }
428:                        }
429:                        Vector l = new Vector();
430:                        Enumeration e = languages.keys();
431:                        while (e.hasMoreElements()) {
432:                            String key = (String) e.nextElement();
433:                            Vector v = (Vector) languages.get(key);
434:                            Enumeration le = v.elements();
435:                            while (le.hasMoreElements()) {
436:                                String language = (String) le.nextElement();
437:                                String country = "";
438:                                String variant = "";
439:                                int countryIndex = language.indexOf('-');
440:                                if (countryIndex > -1) {
441:                                    country = language.substring(
442:                                            countryIndex + 1).trim();
443:                                    language = language.substring(0,
444:                                            countryIndex).trim();
445:                                    int vDash = country.indexOf("-");
446:                                    if (vDash > 0) {
447:                                        String cTemp = country.substring(0,
448:                                                vDash);
449:                                        variant = country.substring(vDash + 1);
450:                                        country = cTemp;
451:                                    }
452:                                }
453:                                request.addLocale(new Locale(language, country,
454:                                        variant));
455:                            }
456:                        }
457:                    } else if (match.equals("cookie")) {
458:                        Cookie cookies[] = RequestUtil.parseCookieHeader(value);
459:                        for (int i = 0; i < cookies.length; i++) {
460:                            if (cookies[i].getName().equals(
461:                                    Globals.SESSION_COOKIE_NAME)) {
462:                                // Override anything requested in the URL
463:                                if (!request.isRequestedSessionIdFromCookie()) {
464:                                    // Accept only the first session id cookie
465:                                    request.setRequestedSessionId(cookies[i]
466:                                            .getValue());
467:                                    request.setRequestedSessionCookie(true);
468:                                    request.setRequestedSessionURL(false);
469:                                    if (debug >= 1)
470:                                        log(" Requested cookie session id is "
471:                                                + ((HttpServletRequest) request
472:                                                        .getRequest())
473:                                                        .getRequestedSessionId());
474:                                }
475:                            }
476:                            request.addCookie(cookies[i]);
477:                        }
478:                        // Keep Watchdog from whining by adding the header as well
479:                        // (GetHeaderTest, GetIntHeader_1Test)
480:                        request.addHeader(name, value);
481:                    } else if (match.equals("content-length")) {
482:                        int n = -1;
483:                        try {
484:                            n = Integer.parseInt(value);
485:                        } catch (Exception e) {
486:                            throw new ServletException(
487:                                    sm
488:                                            .getString("httpProcessor.parseHeaders.contentLength"));
489:                        }
490:                        request.setContentLength(n);
491:                        request.addHeader(name, value);
492:                    } else if (match.equals("content-type")) {
493:                        request.setContentType(value);
494:                        request.addHeader(name, value);
495:                    } else if (match.equals("host")) {
496:                        int n = value.indexOf(':');
497:                        if (n < 0)
498:                            request.setServerName(value);
499:                        else {
500:                            request.setServerName(value.substring(0, n).trim());
501:                            int port = 80;
502:                            try {
503:                                port = Integer.parseInt(value.substring(n + 1)
504:                                        .trim());
505:                            } catch (Exception e) {
506:                                throw new ServletException(
507:                                        sm
508:                                                .getString("httpProcessor.parseHeaders.portNumber"));
509:                            }
510:                            request.setServerPort(port);
511:                        }
512:                        request.addHeader(name, value);
513:                    } else {
514:                        request.addHeader(name, value);
515:                    }
516:                }
517:
518:            }
519:
520:            /**
521:             * Parse the incoming HTTP request and set the corresponding HTTP request
522:             * properties.
523:             *
524:             * @param input The input stream attached to our socket
525:             *
526:             * @exception IOException if an input/output error occurs
527:             * @exception ServletException if a parsing error occurs
528:             */
529:            private void parseRequest(InputStream input) throws IOException,
530:                    ServletException {
531:
532:                // Parse the incoming request line
533:                String line = read(input);
534:                if (line == null)
535:                    throw new ServletException(sm
536:                            .getString("httpProcessor.parseRequest.read"));
537:                StringTokenizer st = new StringTokenizer(line);
538:
539:                String method = null;
540:                try {
541:                    method = st.nextToken();
542:                } catch (NoSuchElementException e) {
543:                    method = null;
544:                }
545:
546:                String uri = null;
547:                try {
548:                    uri = st.nextToken();
549:                    ; // FIXME - URL decode the URI?
550:                } catch (NoSuchElementException e) {
551:                    uri = null;
552:                }
553:
554:                String protocol = null;
555:                try {
556:                    protocol = st.nextToken();
557:                } catch (NoSuchElementException e) {
558:                    protocol = "HTTP/0.9";
559:                }
560:
561:                // Validate the incoming request line
562:                if (method == null) {
563:                    throw new ServletException(sm
564:                            .getString("httpProcessor.parseRequest.method"));
565:                } else if (uri == null) {
566:                    throw new ServletException(sm
567:                            .getString("httpProcessor.parseRequest.uri"));
568:                }
569:
570:                // Parse any query parameters out of the request URI
571:                int question = uri.indexOf('?');
572:                if (question >= 0) {
573:                    request.setQueryString(uri.substring(question + 1));
574:                    if (debug >= 1)
575:                        log(" Query string is "
576:                                + ((HttpServletRequest) request.getRequest())
577:                                        .getQueryString());
578:                    uri = uri.substring(0, question);
579:                } else
580:                    request.setQueryString(null);
581:
582:                // Parse any requested session ID out of the request URI
583:                int semicolon = uri.indexOf(match);
584:                if (semicolon >= 0) {
585:                    String rest = uri.substring(semicolon + match.length());
586:                    int semicolon2 = rest.indexOf(';');
587:                    if (semicolon2 >= 0) {
588:                        request.setRequestedSessionId(rest.substring(0,
589:                                semicolon2));
590:                        rest = rest.substring(semicolon2);
591:                    } else {
592:                        request.setRequestedSessionId(rest);
593:                        rest = "";
594:                    }
595:                    request.setRequestedSessionURL(true);
596:                    uri = uri.substring(0, semicolon) + rest;
597:                    if (debug >= 1)
598:                        log(" Requested URL session id is "
599:                                + ((HttpServletRequest) request.getRequest())
600:                                        .getRequestedSessionId());
601:                } else {
602:                    request.setRequestedSessionId(null);
603:                    request.setRequestedSessionURL(false);
604:                }
605:
606:                // Set the corresponding request properties
607:                ((HttpRequest) request).setMethod(method);
608:                request.setProtocol(protocol);
609:                ((HttpRequest) request).setRequestURI(uri);
610:                request.setSecure(false); // No SSL support
611:                request.setScheme("http"); // No SSL support
612:
613:                if (debug >= 1)
614:                    log(" Request is " + method + " for " + uri);
615:
616:            }
617:
618:            /**
619:             * Process an incoming HTTP request on the Socket that has been assigned
620:             * to this Processor.  Any exceptions that occur during processing must be
621:             * swallowed and dealt with.
622:             *
623:             * @param socket The socket on which we are connected to the client
624:             */
625:            private void process(Socket socket) {
626:
627:                boolean ok = true;
628:                InputStream input = null;
629:                OutputStream output = null;
630:
631:                // Construct and initialize the objects we will need
632:                try {
633:                    input = new BufferedInputStream(socket.getInputStream(),
634:                            connector.getBufferSize());
635:                    request.setStream(input);
636:                    request.setResponse(response);
637:                    output = socket.getOutputStream();
638:                    response.setStream(output);
639:                    response.setRequest(request);
640:                    ((HttpServletResponse) response.getResponse()).setHeader(
641:                            "Server", SERVER_INFO);
642:                } catch (Exception e) {
643:                    log("process.create", e);
644:                    ok = false;
645:                }
646:
647:                // Parse the incoming request
648:                try {
649:                    if (ok) {
650:                        parseConnection(socket);
651:                        parseRequest(input);
652:                        if (!request.getRequest().getProtocol().startsWith(
653:                                "HTTP/0"))
654:                            parseHeaders(input);
655:                    }
656:                } catch (Exception e) {
657:                    try {
658:                        log("process.parse", e);
659:                        ((HttpServletResponse) response.getResponse())
660:                                .sendError(HttpServletResponse.SC_BAD_REQUEST);
661:                    } catch (Exception f) {
662:                        ;
663:                    }
664:                }
665:
666:                // Ask our Container to process this request
667:                try {
668:                    if (ok) {
669:                        connector.getContainer().invoke(request, response);
670:                    }
671:                } catch (ServletException e) {
672:                    log("process.invoke", e);
673:                    try {
674:                        ((HttpServletResponse) response.getResponse())
675:                                .sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
676:                    } catch (Exception f) {
677:                        ;
678:                    }
679:                    ok = false;
680:                } catch (Throwable e) {
681:                    log("process.invoke", e);
682:                    try {
683:                        ((HttpServletResponse) response.getResponse())
684:                                .sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
685:                    } catch (Exception f) {
686:                        ;
687:                    }
688:                    ok = false;
689:                }
690:
691:                // Finish up the handling of the response
692:                try {
693:                    if (ok)
694:                        response.finishResponse();
695:                } catch (IOException e) {
696:                    log("FIXME-Exception from finishResponse", e);
697:                }
698:                try {
699:                    if (output != null)
700:                        output.flush();
701:                } catch (IOException e) {
702:                    log("FIXME-Exception flushing output", e);
703:                }
704:                try {
705:                    if (output != null)
706:                        output.close();
707:                } catch (IOException e) {
708:                    log("FIXME-Exception closing output", e);
709:                }
710:
711:                // Finish up the handling of the request
712:                try {
713:                    if (ok)
714:                        request.finishRequest();
715:                } catch (IOException e) {
716:                    log("FIXME-Exception from finishRequest", e);
717:                }
718:                try {
719:                    if (input != null)
720:                        input.close();
721:                } catch (IOException e) {
722:                    log("FIXME-Exception closing input", e);
723:                }
724:
725:                // Finish up the handling of the socket connection itself
726:                try {
727:                    socket.close();
728:                } catch (IOException e) {
729:                    log("FIXME-Exception closing socket", e);
730:                }
731:                socket = null;
732:
733:            }
734:
735:            /**
736:             * Read a line from the specified input stream, and strip off the
737:             * trailing carriage return and newline (if any).  Return the remaining
738:             * characters that were read as a String.
739:             *
740:             * @param input The input stream connected to our socket
741:             *
742:             * @returns The line that was read, or <code>null</code> if end-of-file
743:             *  was encountered
744:             *
745:             * @exception IOException if an input/output error occurs
746:             */
747:            private String read(InputStream input) throws IOException {
748:
749:                StringBuffer sb = new StringBuffer();
750:                while (true) {
751:                    int ch = input.read();
752:                    if (ch < 0) {
753:                        if (sb.length() == 0) {
754:                            return (null);
755:                        } else {
756:                            break;
757:                        }
758:                    } else if (ch == '\r') {
759:                        continue;
760:                    } else if (ch == '\n') {
761:                        break;
762:                    }
763:                    sb.append((char) ch);
764:                }
765:                if (debug >= 2)
766:                    log("  Read: " + sb.toString());
767:                return (sb.toString());
768:
769:            }
770:
771:            // ---------------------------------------------- Background Thread Methods
772:
773:            /**
774:             * The background thread that listens for incoming TCP/IP connections and
775:             * hands them off to an appropriate processor.
776:             */
777:            public void run() {
778:
779:                // Process requests until we receive a shutdown signal
780:                while (!stopped) {
781:
782:                    // Wait for the next socket to be assigned
783:                    Socket socket = await();
784:                    if (socket == null)
785:                        continue;
786:
787:                    // Process the request from this socket
788:                    process(socket);
789:
790:                    // Finish up this request
791:                    request.recycle();
792:                    response.recycle();
793:                    connector.recycle(this );
794:
795:                }
796:
797:                // Tell threadStop() we have shut ourselves down successfully
798:                synchronized (threadSync) {
799:                    threadSync.notifyAll();
800:                }
801:
802:            }
803:
804:            /**
805:             * Start the background processing thread.
806:             */
807:            private void threadStart() {
808:
809:                log(sm.getString("httpProcessor.starting"));
810:
811:                thread = new Thread(this , threadName);
812:                thread.setDaemon(true);
813:                thread.start();
814:
815:                if (debug >= 1)
816:                    log(" Background thread has been started");
817:
818:            }
819:
820:            /**
821:             * Stop the background processing thread.
822:             */
823:            private void threadStop() {
824:
825:                log(sm.getString("httpProcessor.stopping"));
826:
827:                stopped = true;
828:                assign(null);
829:                synchronized (threadSync) {
830:                    try {
831:                        threadSync.wait(5000);
832:                    } catch (InterruptedException e) {
833:                        ;
834:                    }
835:                }
836:                thread = null;
837:
838:            }
839:
840:            // ------------------------------------------------------ Lifecycle Methods
841:
842:            /**
843:             * Add a lifecycle event listener to this component.
844:             *
845:             * @param listener The listener to add
846:             */
847:            public void addLifecycleListener(LifecycleListener listener) {
848:
849:                lifecycle.addLifecycleListener(listener);
850:
851:            }
852:
853:            /**
854:             * Get the lifecycle listeners associated with this lifecycle. If this 
855:             * Lifecycle has no listeners registered, a zero-length array is returned.
856:             */
857:            public LifecycleListener[] findLifecycleListeners() {
858:
859:                return lifecycle.findLifecycleListeners();
860:
861:            }
862:
863:            /**
864:             * Remove a lifecycle event listener from this component.
865:             *
866:             * @param listener The listener to add
867:             */
868:            public void removeLifecycleListener(LifecycleListener listener) {
869:
870:                lifecycle.removeLifecycleListener(listener);
871:
872:            }
873:
874:            /**
875:             * Start the background thread we will use for request processing.
876:             *
877:             * @exception LifecycleException if a fatal startup error occurs
878:             */
879:            public void start() throws LifecycleException {
880:
881:                if (started)
882:                    throw new LifecycleException(sm
883:                            .getString("httpProcessor.alreadyStarted"));
884:                lifecycle.fireLifecycleEvent(START_EVENT, null);
885:                started = true;
886:
887:                threadStart();
888:
889:            }
890:
891:            /**
892:             * Stop the background thread we will use for request processing.
893:             *
894:             * @exception LifecycleException if a fatal shutdown error occurs
895:             */
896:            public void stop() throws LifecycleException {
897:
898:                if (!started)
899:                    throw new LifecycleException(sm
900:                            .getString("httpProcessor.notStarted"));
901:                lifecycle.fireLifecycleEvent(STOP_EVENT, null);
902:                started = false;
903:
904:                threadStop();
905:
906:            }
907:
908:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.