View | Details | Raw Unified | Return to bug 50673
Collapse All | Expand All

(-)java/org/apache/catalina/core/StandardServer.java (-69 / +121 lines)
Lines 181-188 Link Here
181
     */
181
     */
182
    protected PropertyChangeSupport support = new PropertyChangeSupport(this);
182
    protected PropertyChangeSupport support = new PropertyChangeSupport(this);
183
183
184
    private boolean stopAwait = false;
184
    private volatile boolean stopAwait = false;
185
185
186
    /**
187
     * Thread that currently is inside our await() method.
188
     */
189
    private volatile Thread awaitThread = null;
190
191
    /**
192
     * Server socket that is used to wait for the shutdown command.
193
     */
194
    private volatile ServerSocket awaitSocket = null;
195
186
    // ------------------------------------------------------------- Properties
196
    // ------------------------------------------------------------- Properties
187
197
188
198
Lines 344-349 Link Here
344
354
345
    public void stopAwait() {
355
    public void stopAwait() {
346
        stopAwait=true;
356
        stopAwait=true;
357
        Thread t = awaitThread;
358
        if (t != null) {
359
            ServerSocket s = awaitSocket;
360
            if (s != null) {
361
                awaitSocket = null;
362
                try {
363
                    s.close();
364
                } catch (IOException e) {
365
                    // Ignored
366
                }
367
            }
368
            t.interrupt();
369
            try {
370
                t.join(1000);
371
            } catch (InterruptedException e) {
372
                // Ignored
373
            }
374
        }
347
    }
375
    }
348
376
349
    /**
377
    /**
Lines 358-449 Link Here
358
            return;
386
            return;
359
        }
387
        }
360
        if( port==-1 ) {
388
        if( port==-1 ) {
361
            while( true ) {
389
            try {
362
                try {
390
                awaitThread = Thread.currentThread();
363
                    Thread.sleep( 10000 );
391
                while(!stopAwait) {
364
                } catch( InterruptedException ex ) {
392
                    try {
393
                        Thread.sleep( 10000 );
394
                    } catch( InterruptedException ex ) {
395
                        // continue and check the flag
396
                    }
365
                }
397
                }
366
                if( stopAwait ) return;
398
            } finally {
399
                awaitThread = null;
367
            }
400
            }
401
            return;
368
        }
402
        }
369
        
403
370
        // Set up a server socket to wait on
404
        // Set up a server socket to wait on
371
        ServerSocket serverSocket = null;
372
        try {
405
        try {
373
            serverSocket =
406
            awaitSocket =
374
                new ServerSocket(port, 1,
407
                new ServerSocket(port, 1,
375
                                 InetAddress.getByName("localhost"));
408
                                 InetAddress.getByName("localhost"));
376
        } catch (IOException e) {
409
        } catch (IOException e) {
377
            log.error("StandardServer.await: create[" + port
410
            log.error("StandardServer.await: create[" + port
378
                               + "]: ", e);
411
                               + "]: ", e);
379
            System.exit(1);
412
            return;
380
        }
413
        }
381
414
382
        // Loop waiting for a connection and a valid command
415
        try {
383
        while (true) {
416
            awaitThread = Thread.currentThread();
384
417
385
            // Wait for the next connection
418
            // Loop waiting for a connection and a valid command
386
            Socket socket = null;
419
            while (!stopAwait) {
387
            InputStream stream = null;
420
                ServerSocket serverSocket = awaitSocket;
388
            try {
421
                if (serverSocket == null) {
389
                socket = serverSocket.accept();
422
                    break;
390
                socket.setSoTimeout(10 * 1000);  // Ten seconds
423
                }
391
                stream = socket.getInputStream();
424
    
392
            } catch (AccessControlException ace) {
425
                // Wait for the next connection
393
                log.warn("StandardServer.accept security exception: "
426
                Socket socket = null;
394
                                   + ace.getMessage(), ace);
427
                StringBuilder command = new StringBuilder();
395
                continue;
428
                try {
396
            } catch (IOException e) {
429
                    InputStream stream = null;
397
                log.error("StandardServer.await: accept: ", e);
430
                    try {
398
                System.exit(1);
431
                        socket = serverSocket.accept();
432
                        socket.setSoTimeout(10 * 1000);  // Ten seconds
433
                        stream = socket.getInputStream();
434
                    } catch (AccessControlException ace) {
435
                        log.warn("StandardServer.accept security exception: "
436
                                           + ace.getMessage(), ace);
437
                        continue;
438
                    } catch (IOException e) {
439
                        if (stopAwait) {
440
                            // Wait was aborted with socket.close()
441
                            break;
442
                        }
443
                        log.error("StandardServer.await: accept: ", e);
444
                        break;
445
                    }
446
447
                    // Read a set of characters from the socket
448
                    int expected = 1024; // Cut off to avoid DoS attack
449
                    while (expected < shutdown.length()) {
450
                        if (random == null)
451
                            random = new Random();
452
                        expected += (random.nextInt() % 1024);
453
                    }
454
                    while (expected > 0) {
455
                        int ch = -1;
456
                        try {
457
                            ch = stream.read();
458
                        } catch (IOException e) {
459
                            log.warn("StandardServer.await: read: ", e);
460
                            ch = -1;
461
                        }
462
                        if (ch < 32)  // Control character or EOF terminates loop
463
                            break;
464
                        command.append((char) ch);
465
                        expected--;
466
                    }
467
                } finally {
468
                    // Close the socket now that we are done with it
469
                    try {
470
                        if (socket != null) {
471
                            socket.close();
472
                        }
473
                    } catch (IOException e) {
474
                        // Ignore
475
                    }
476
                }
477
478
                // Match against our command string
479
                boolean match = command.toString().equals(shutdown);
480
                if (match) {
481
                    break;
482
                } else
483
                    log.warn("StandardServer.await: Invalid command '" +
484
                                       command.toString() + "' received");
399
            }
485
            }
486
        } finally {
487
            ServerSocket serverSocket = awaitSocket;
488
            awaitThread = null;
489
            awaitSocket = null;
400
490
401
            // Read a set of characters from the socket
491
            // Close the server socket and return
402
            StringBuffer command = new StringBuffer();
492
            if (serverSocket != null) {
403
            int expected = 1024; // Cut off to avoid DoS attack
404
            while (expected < shutdown.length()) {
405
                if (random == null)
406
                    random = new Random();
407
                expected += (random.nextInt() % 1024);
408
            }
409
            while (expected > 0) {
410
                int ch = -1;
411
                try {
493
                try {
412
                    ch = stream.read();
494
                    serverSocket.close();
413
                } catch (IOException e) {
495
                } catch (IOException e) {
414
                    log.warn("StandardServer.await: read: ", e);
496
                    // Ignore
415
                    ch = -1;
416
                }
497
                }
417
                if (ch < 32)  // Control character or EOF terminates loop
418
                    break;
419
                command.append((char) ch);
420
                expected--;
421
            }
498
            }
422
423
            // Close the socket now that we are done with it
424
            try {
425
                socket.close();
426
            } catch (IOException e) {
427
                ;
428
            }
429
430
            // Match against our command string
431
            boolean match = command.toString().equals(shutdown);
432
            if (match) {
433
                break;
434
            } else
435
                log.warn("StandardServer.await: Invalid command '" +
436
                                   command.toString() + "' received");
437
438
        }
499
        }
439
440
        // Close the server socket and return
441
        try {
442
            serverSocket.close();
443
        } catch (IOException e) {
444
            ;
445
        }
446
447
    }
500
    }
448
501
449
502
Lines 738-745 Link Here
738
        // Notify our interested LifecycleListeners
791
        // Notify our interested LifecycleListeners
739
        lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
792
        lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
740
793
741
        if (port == -1)
794
        stopAwait();
742
            stopAwait();
743
795
744
    }
796
    }
745
797
(-)java/org/apache/catalina/startup/Catalina.java (-5 / +15 lines)
Lines 34-39 Link Here
34
import org.apache.catalina.Container;
34
import org.apache.catalina.Container;
35
import org.apache.catalina.Lifecycle;
35
import org.apache.catalina.Lifecycle;
36
import org.apache.catalina.LifecycleException;
36
import org.apache.catalina.LifecycleException;
37
import org.apache.catalina.Server;
37
import org.apache.catalina.core.StandardServer;
38
import org.apache.catalina.core.StandardServer;
38
import org.apache.juli.ClassLoaderLogManager;
39
import org.apache.juli.ClassLoaderLogManager;
39
import org.apache.tomcat.util.digester.Digester;
40
import org.apache.tomcat.util.digester.Digester;
Lines 382-388 Link Here
382
            arguments(arguments);
383
            arguments(arguments);
383
        }
384
        }
384
385
385
        if( getServer() == null ) {
386
        Server s = getServer();
387
        if( s == null ) {
386
            // Create and execute our Digester
388
            // Create and execute our Digester
387
            Digester digester = createStopDigester();
389
            Digester digester = createStopDigester();
388
            digester.setClassLoader(Thread.currentThread().getContextClassLoader());
390
            digester.setClassLoader(Thread.currentThread().getContextClassLoader());
Lines 401-417 Link Here
401
            }
403
            }
402
        } else {
404
        } else {
403
            // Server object already present. Must be running as a service
405
            // Server object already present. Must be running as a service
404
            // Shutdown hook will take care of clean-up
406
            if (s instanceof Lifecycle) {
405
            System.exit(0);
407
                try {
408
                    ((Lifecycle) s).stop();
409
                } catch (LifecycleException e) {
410
                    log.error("Catalina.stop: ", e);
411
                }
412
                return;
413
            }
414
            // else fall down
406
        }
415
        }
407
416
408
        // Stop the existing server
417
        // Stop the existing server
418
        s = getServer();
409
        try {
419
        try {
410
            if (getServer().getPort()>0) { 
420
            if (s.getPort()>0) { 
411
                String hostAddress = InetAddress.getByName("localhost").getHostAddress();
421
                String hostAddress = InetAddress.getByName("localhost").getHostAddress();
412
                Socket socket = new Socket(hostAddress, getServer().getPort());
422
                Socket socket = new Socket(hostAddress, getServer().getPort());
413
                OutputStream stream = socket.getOutputStream();
423
                OutputStream stream = socket.getOutputStream();
414
                String shutdown = getServer().getShutdown();
424
                String shutdown = s.getShutdown();
415
                for (int i = 0; i < shutdown.length(); i++)
425
                for (int i = 0; i < shutdown.length(); i++)
416
                    stream.write(shutdown.charAt(i));
426
                    stream.write(shutdown.charAt(i));
417
                stream.flush();
427
                stream.flush();

Return to bug 50673