18. Araxis Merge ファイル比較レポート

このレポートは Araxis Merge2016-08-05 10:05:17 +0000 によって作成されました。Merge に関する情報については http://www.araxis.com/merge/ をご覧ください。このレポートは XHTML と CSS2 を使用し、最新の標準基準に準拠したブラウザでご覧になれます。このレポートを印刷するための最適条件は、背景の色とイメージの印刷を可能にして、印刷の向きは横を使用します。

18.1 ファイルの比較

#ロケーションファイル更新日
1/Merge Test Files/jakarta-tomcat-4.0.6-src/catalina/src/share/org/apache/catalina/connector/http10HttpProcessor.java2002-10-08 14:15:34 +0000
2/Merge Test Files/jakarta-tomcat-4.1.18-src/catalina/src/share/org/apache/catalina/connector/http10HttpProcessor.java2002-12-19 13:49:40 +0000

18.2 比較の概要

説明第1ファイルと第2ファイル
テキスト ブロック
変更なし71820
変更箇所311
挿入箇所322
削除箇所00

18.3 比較のオプション

余白余白の相違を意味のあるものとして扱う
大文字/小文字大文字と小文字の相違を意味のあるものとして扱う
行終端文字行終端文字(CRLF 文字)の相違を意味のあるものとして扱う
CR/LF 文字比較の詳細に示されない

18.4 有効な正規表現

有効な正規表現はありません。

18.5 比較の詳細

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