alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (ServerImpl.java)

This example Java source code file (ServerImpl.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

dispatcher, httpconnection, httpcontextimpl, httpserver, inetsocketaddress, ioexception, linkedlist, log, logging, max_req_time, max_rsp_time, net, network, nullpointerexception, security, selectionkey, set, socketchannel, string, util

The ServerImpl.java Java example source code

/*
 * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.net.httpserver;

import java.net.*;
import java.io.*;
import java.nio.channels.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.logging.Logger;
import java.util.logging.Level;
import javax.net.ssl.*;
import com.sun.net.httpserver.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.net.httpserver.HttpConnection.State;

/**
 * Provides implementation for both HTTP and HTTPS
 */
class ServerImpl implements TimeSource {

    private String protocol;
    private boolean https;
    private Executor executor;
    private HttpsConfigurator httpsConfig;
    private SSLContext sslContext;
    private ContextList contexts;
    private InetSocketAddress address;
    private ServerSocketChannel schan;
    private Selector selector;
    private SelectionKey listenerKey;
    private Set<HttpConnection> idleConnections;
    private Set<HttpConnection> allConnections;
    /* following two are used to keep track of the times
     * when a connection/request is first received
     * and when we start to send the response
     */
    private Set<HttpConnection> reqConnections;
    private Set<HttpConnection> rspConnections;
    private List<Event> events;
    private Object lolock = new Object();
    private volatile boolean finished = false;
    private volatile boolean terminating = false;
    private boolean bound = false;
    private boolean started = false;
    private volatile long time;  /* current time */
    private volatile long subticks = 0;
    private volatile long ticks; /* number of clock ticks since server started */
    private HttpServer wrapper;

    final static int CLOCK_TICK = ServerConfig.getClockTick();
    final static long IDLE_INTERVAL = ServerConfig.getIdleInterval();
    final static int MAX_IDLE_CONNECTIONS = ServerConfig.getMaxIdleConnections();
    final static long TIMER_MILLIS = ServerConfig.getTimerMillis ();
    final static long MAX_REQ_TIME=getTimeMillis(ServerConfig.getMaxReqTime());
    final static long MAX_RSP_TIME=getTimeMillis(ServerConfig.getMaxRspTime());
    final static boolean timer1Enabled = MAX_REQ_TIME != -1 || MAX_RSP_TIME != -1;

    private Timer timer, timer1;
    private Logger logger;

    ServerImpl (
        HttpServer wrapper, String protocol, InetSocketAddress addr, int backlog
    ) throws IOException {

        this.protocol = protocol;
        this.wrapper = wrapper;
        this.logger = Logger.getLogger ("com.sun.net.httpserver");
        ServerConfig.checkLegacyProperties (logger);
        https = protocol.equalsIgnoreCase ("https");
        this.address = addr;
        contexts = new ContextList();
        schan = ServerSocketChannel.open();
        if (addr != null) {
            ServerSocket socket = schan.socket();
            socket.bind (addr, backlog);
            bound = true;
        }
        selector = Selector.open ();
        schan.configureBlocking (false);
        listenerKey = schan.register (selector, SelectionKey.OP_ACCEPT);
        dispatcher = new Dispatcher();
        idleConnections = Collections.synchronizedSet (new HashSet<HttpConnection>());
        allConnections = Collections.synchronizedSet (new HashSet<HttpConnection>());
        reqConnections = Collections.synchronizedSet (new HashSet<HttpConnection>());
        rspConnections = Collections.synchronizedSet (new HashSet<HttpConnection>());
        time = System.currentTimeMillis();
        timer = new Timer ("server-timer", true);
        timer.schedule (new ServerTimerTask(), CLOCK_TICK, CLOCK_TICK);
        if (timer1Enabled) {
            timer1 = new Timer ("server-timer1", true);
            timer1.schedule (new ServerTimerTask1(),TIMER_MILLIS,TIMER_MILLIS);
            logger.config ("HttpServer timer1 enabled period in ms:  "+TIMER_MILLIS);
            logger.config ("MAX_REQ_TIME:  "+MAX_REQ_TIME);
            logger.config ("MAX_RSP_TIME:  "+MAX_RSP_TIME);
        }
        events = new LinkedList<Event>();
        logger.config ("HttpServer created "+protocol+" "+ addr);
    }

    public void bind (InetSocketAddress addr, int backlog) throws IOException {
        if (bound) {
            throw new BindException ("HttpServer already bound");
        }
        if (addr == null) {
            throw new NullPointerException ("null address");
        }
        ServerSocket socket = schan.socket();
        socket.bind (addr, backlog);
        bound = true;
    }

    public void start () {
        if (!bound || started || finished) {
            throw new IllegalStateException ("server in wrong state");
        }
        if (executor == null) {
            executor = new DefaultExecutor();
        }
        Thread t = new Thread (dispatcher);
        started = true;
        t.start();
    }

    public void setExecutor (Executor executor) {
        if (started) {
            throw new IllegalStateException ("server already started");
        }
        this.executor = executor;
    }

    private static class DefaultExecutor implements Executor {
        public void execute (Runnable task) {
            task.run();
        }
    }

    public Executor getExecutor () {
        return executor;
    }

    public void setHttpsConfigurator (HttpsConfigurator config) {
        if (config == null) {
            throw new NullPointerException ("null HttpsConfigurator");
        }
        if (started) {
            throw new IllegalStateException ("server already started");
        }
        this.httpsConfig = config;
        sslContext = config.getSSLContext();
    }

    public HttpsConfigurator getHttpsConfigurator () {
        return httpsConfig;
    }

    public void stop (int delay) {
        if (delay < 0) {
            throw new IllegalArgumentException ("negative delay parameter");
        }
        terminating = true;
        try { schan.close(); } catch (IOException e) {}
        selector.wakeup();
        long latest = System.currentTimeMillis() + delay * 1000;
        while (System.currentTimeMillis() < latest) {
            delay();
            if (finished) {
                break;
            }
        }
        finished = true;
        selector.wakeup();
        synchronized (allConnections) {
            for (HttpConnection c : allConnections) {
                c.close();
            }
        }
        allConnections.clear();
        idleConnections.clear();
        timer.cancel();
        if (timer1Enabled) {
            timer1.cancel();
        }
    }

    Dispatcher dispatcher;

    public synchronized HttpContextImpl createContext (String path, HttpHandler handler) {
        if (handler == null || path == null) {
            throw new NullPointerException ("null handler, or path parameter");
        }
        HttpContextImpl context = new HttpContextImpl (protocol, path, handler, this);
        contexts.add (context);
        logger.config ("context created: " + path);
        return context;
    }

    public synchronized HttpContextImpl createContext (String path) {
        if (path == null) {
            throw new NullPointerException ("null path parameter");
        }
        HttpContextImpl context = new HttpContextImpl (protocol, path, null, this);
        contexts.add (context);
        logger.config ("context created: " + path);
        return context;
    }

    public synchronized void removeContext (String path) throws IllegalArgumentException {
        if (path == null) {
            throw new NullPointerException ("null path parameter");
        }
        contexts.remove (protocol, path);
        logger.config ("context removed: " + path);
    }

    public synchronized void removeContext (HttpContext context) throws IllegalArgumentException {
        if (!(context instanceof HttpContextImpl)) {
            throw new IllegalArgumentException ("wrong HttpContext type");
        }
        contexts.remove ((HttpContextImpl)context);
        logger.config ("context removed: " + context.getPath());
    }

    public InetSocketAddress getAddress() {
        return AccessController.doPrivileged(
                new PrivilegedAction<InetSocketAddress>() {
                    public InetSocketAddress run() {
                        return
                            (InetSocketAddress)schan.socket()
                                .getLocalSocketAddress();
                    }
                });
    }

    Selector getSelector () {
        return selector;
    }

    void addEvent (Event r) {
        synchronized (lolock) {
            events.add (r);
            selector.wakeup();
        }
    }

    /* main server listener task */

    class Dispatcher implements Runnable {

        private void handleEvent (Event r) {
            ExchangeImpl t = r.exchange;
            HttpConnection c = t.getConnection();
            try {
                if (r instanceof WriteFinishedEvent) {

                    int exchanges = endExchange();
                    if (terminating && exchanges == 0) {
                        finished = true;
                    }
                    responseCompleted (c);
                    LeftOverInputStream is = t.getOriginalInputStream();
                    if (!is.isEOF()) {
                        t.close = true;
                    }
                    if (t.close || idleConnections.size() >= MAX_IDLE_CONNECTIONS) {
                        c.close();
                        allConnections.remove (c);
                    } else {
                        if (is.isDataBuffered()) {
                            /* don't re-enable the interestops, just handle it */
                            requestStarted (c);
                            handle (c.getChannel(), c);
                        } else {
                            connsToRegister.add (c);
                        }
                    }
                }
            } catch (IOException e) {
                logger.log (
                    Level.FINER, "Dispatcher (1)", e
                );
                c.close();
            }
        }

        final LinkedList<HttpConnection> connsToRegister =
                new LinkedList<HttpConnection>();

        void reRegister (HttpConnection c) {
            /* re-register with selector */
            try {
                SocketChannel chan = c.getChannel();
                chan.configureBlocking (false);
                SelectionKey key = chan.register (selector, SelectionKey.OP_READ);
                key.attach (c);
                c.selectionKey = key;
                c.time = getTime() + IDLE_INTERVAL;
                idleConnections.add (c);
            } catch (IOException e) {
                dprint(e);
                logger.log(Level.FINER, "Dispatcher(8)", e);
                c.close();
            }
        }

        public void run() {
            while (!finished) {
                try {
                    List<Event> list = null;
                    synchronized (lolock) {
                        if (events.size() > 0) {
                            list = events;
                            events = new LinkedList<Event>();
                        }
                    }

                    if (list != null) {
                        for (Event r: list) {
                            handleEvent (r);
                        }
                    }

                    for (HttpConnection c : connsToRegister) {
                        reRegister(c);
                    }
                    connsToRegister.clear();

                    selector.select(1000);

                    /* process the selected list now  */
                    Set<SelectionKey> selected = selector.selectedKeys();
                    Iterator<SelectionKey> iter = selected.iterator();
                    while (iter.hasNext()) {
                        SelectionKey key = iter.next();
                        iter.remove ();
                        if (key.equals (listenerKey)) {
                            if (terminating) {
                                continue;
                            }
                            SocketChannel chan = schan.accept();

                            // Set TCP_NODELAY, if appropriate
                            if (ServerConfig.noDelay()) {
                                chan.socket().setTcpNoDelay(true);
                            }

                            if (chan == null) {
                                continue; /* cancel something ? */
                            }
                            chan.configureBlocking (false);
                            SelectionKey newkey = chan.register (selector, SelectionKey.OP_READ);
                            HttpConnection c = new HttpConnection ();
                            c.selectionKey = newkey;
                            c.setChannel (chan);
                            newkey.attach (c);
                            requestStarted (c);
                            allConnections.add (c);
                        } else {
                            try {
                                if (key.isReadable()) {
                                    boolean closed;
                                    SocketChannel chan = (SocketChannel)key.channel();
                                    HttpConnection conn = (HttpConnection)key.attachment();

                                    key.cancel();
                                    chan.configureBlocking (true);
                                    if (idleConnections.remove(conn)) {
                                        // was an idle connection so add it
                                        // to reqConnections set.
                                        requestStarted (conn);
                                    }
                                    handle (chan, conn);
                                } else {
                                    assert false;
                                }
                            } catch (CancelledKeyException e) {
                                handleException(key, null);
                            } catch (IOException e) {
                                handleException(key, e);
                            }
                        }
                    }
                    // call the selector just to process the cancelled keys
                    selector.selectNow();
                } catch (IOException e) {
                    logger.log (Level.FINER, "Dispatcher (4)", e);
                } catch (Exception e) {
                    logger.log (Level.FINER, "Dispatcher (7)", e);
                }
            }
            try {selector.close(); } catch (Exception e) {}
        }

        private void handleException (SelectionKey key, Exception e) {
            HttpConnection conn = (HttpConnection)key.attachment();
            if (e != null) {
                logger.log (Level.FINER, "Dispatcher (2)", e);
            }
            closeConnection(conn);
        }

        public void handle (SocketChannel chan, HttpConnection conn)
        throws IOException
        {
            try {
                Exchange t = new Exchange (chan, protocol, conn);
                executor.execute (t);
            } catch (HttpError e1) {
                logger.log (Level.FINER, "Dispatcher (4)", e1);
                closeConnection(conn);
            } catch (IOException e) {
                logger.log (Level.FINER, "Dispatcher (5)", e);
                closeConnection(conn);
            }
        }
    }

    static boolean debug = ServerConfig.debugEnabled ();

    static synchronized void dprint (String s) {
        if (debug) {
            System.out.println (s);
        }
    }

    static synchronized void dprint (Exception e) {
        if (debug) {
            System.out.println (e);
            e.printStackTrace();
        }
    }

    Logger getLogger () {
        return logger;
    }

    private void closeConnection(HttpConnection conn) {
        conn.close();
        allConnections.remove(conn);
        switch (conn.getState()) {
        case REQUEST:
            reqConnections.remove(conn);
            break;
        case RESPONSE:
            rspConnections.remove(conn);
            break;
        case IDLE:
            idleConnections.remove(conn);
            break;
        }
        assert !reqConnections.remove(conn);
        assert !rspConnections.remove(conn);
        assert !idleConnections.remove(conn);
    }

        /* per exchange task */

    class Exchange implements Runnable {
        SocketChannel chan;
        HttpConnection connection;
        HttpContextImpl context;
        InputStream rawin;
        OutputStream rawout;
        String protocol;
        ExchangeImpl tx;
        HttpContextImpl ctx;
        boolean rejected = false;

        Exchange (SocketChannel chan, String protocol, HttpConnection conn) throws IOException {
            this.chan = chan;
            this.connection = conn;
            this.protocol = protocol;
        }

        public void run () {
            /* context will be null for new connections */
            context = connection.getHttpContext();
            boolean newconnection;
            SSLEngine engine = null;
            String requestLine = null;
            SSLStreams sslStreams = null;
            try {
                if (context != null ) {
                    this.rawin = connection.getInputStream();
                    this.rawout = connection.getRawOutputStream();
                    newconnection = false;
                } else {
                    /* figure out what kind of connection this is */
                    newconnection = true;
                    if (https) {
                        if (sslContext == null) {
                            logger.warning ("SSL connection received. No https contxt created");
                            throw new HttpError ("No SSL context established");
                        }
                        sslStreams = new SSLStreams (ServerImpl.this, sslContext, chan);
                        rawin = sslStreams.getInputStream();
                        rawout = sslStreams.getOutputStream();
                        engine = sslStreams.getSSLEngine();
                        connection.sslStreams = sslStreams;
                    } else {
                        rawin = new BufferedInputStream(
                            new Request.ReadStream (
                                ServerImpl.this, chan
                        ));
                        rawout = new Request.WriteStream (
                            ServerImpl.this, chan
                        );
                    }
                    connection.raw = rawin;
                    connection.rawout = rawout;
                }
                Request req = new Request (rawin, rawout);
                requestLine = req.requestLine();
                if (requestLine == null) {
                    /* connection closed */
                    closeConnection(connection);
                    return;
                }
                int space = requestLine.indexOf (' ');
                if (space == -1) {
                    reject (Code.HTTP_BAD_REQUEST,
                            requestLine, "Bad request line");
                    return;
                }
                String method = requestLine.substring (0, space);
                int start = space+1;
                space = requestLine.indexOf(' ', start);
                if (space == -1) {
                    reject (Code.HTTP_BAD_REQUEST,
                            requestLine, "Bad request line");
                    return;
                }
                String uriStr = requestLine.substring (start, space);
                URI uri = new URI (uriStr);
                start = space+1;
                String version = requestLine.substring (start);
                Headers headers = req.headers();
                String s = headers.getFirst ("Transfer-encoding");
                long clen = 0L;
                if (s !=null && s.equalsIgnoreCase ("chunked")) {
                    clen = -1L;
                } else {
                    s = headers.getFirst ("Content-Length");
                    if (s != null) {
                        clen = Long.parseLong(s);
                    }
                    if (clen == 0) {
                        requestCompleted (connection);
                    }
                }
                ctx = contexts.findContext (protocol, uri.getPath());
                if (ctx == null) {
                    reject (Code.HTTP_NOT_FOUND,
                            requestLine, "No context found for request");
                    return;
                }
                connection.setContext (ctx);
                if (ctx.getHandler() == null) {
                    reject (Code.HTTP_INTERNAL_ERROR,
                            requestLine, "No handler for context");
                    return;
                }
                tx = new ExchangeImpl (
                    method, uri, req, clen, connection
                );
                String chdr = headers.getFirst("Connection");
                Headers rheaders = tx.getResponseHeaders();

                if (chdr != null && chdr.equalsIgnoreCase ("close")) {
                    tx.close = true;
                }
                if (version.equalsIgnoreCase ("http/1.0")) {
                    tx.http10 = true;
                    if (chdr == null) {
                        tx.close = true;
                        rheaders.set ("Connection", "close");
                    } else if (chdr.equalsIgnoreCase ("keep-alive")) {
                        rheaders.set ("Connection", "keep-alive");
                        int idle=(int)(ServerConfig.getIdleInterval()/1000);
                        int max=ServerConfig.getMaxIdleConnections();
                        String val = "timeout="+idle+", max="+max;
                        rheaders.set ("Keep-Alive", val);
                    }
                }

                if (newconnection) {
                    connection.setParameters (
                        rawin, rawout, chan, engine, sslStreams,
                        sslContext, protocol, ctx, rawin
                    );
                }
                /* check if client sent an Expect 100 Continue.
                 * In that case, need to send an interim response.
                 * In future API may be modified to allow app to
                 * be involved in this process.
                 */
                String exp = headers.getFirst("Expect");
                if (exp != null && exp.equalsIgnoreCase ("100-continue")) {
                    logReply (100, requestLine, null);
                    sendReply (
                        Code.HTTP_CONTINUE, false, null
                    );
                }
                /* uf is the list of filters seen/set by the user.
                 * sf is the list of filters established internally
                 * and which are not visible to the user. uc and sc
                 * are the corresponding Filter.Chains.
                 * They are linked together by a LinkHandler
                 * so that they can both be invoked in one call.
                 */
                List<Filter> sf = ctx.getSystemFilters();
                List<Filter> uf = ctx.getFilters();

                Filter.Chain sc = new Filter.Chain(sf, ctx.getHandler());
                Filter.Chain uc = new Filter.Chain(uf, new LinkHandler (sc));

                /* set up the two stream references */
                tx.getRequestBody();
                tx.getResponseBody();
                if (https) {
                    uc.doFilter (new HttpsExchangeImpl (tx));
                } else {
                    uc.doFilter (new HttpExchangeImpl (tx));
                }

            } catch (IOException e1) {
                logger.log (Level.FINER, "ServerImpl.Exchange (1)", e1);
                closeConnection(connection);
            } catch (NumberFormatException e3) {
                reject (Code.HTTP_BAD_REQUEST,
                        requestLine, "NumberFormatException thrown");
            } catch (URISyntaxException e) {
                reject (Code.HTTP_BAD_REQUEST,
                        requestLine, "URISyntaxException thrown");
            } catch (Exception e4) {
                logger.log (Level.FINER, "ServerImpl.Exchange (2)", e4);
                closeConnection(connection);
            }
        }

        /* used to link to 2 or more Filter.Chains together */

        class LinkHandler implements HttpHandler {
            Filter.Chain nextChain;

            LinkHandler (Filter.Chain nextChain) {
                this.nextChain = nextChain;
            }

            public void handle (HttpExchange exchange) throws IOException {
                nextChain.doFilter (exchange);
            }
        }

        void reject (int code, String requestStr, String message) {
            rejected = true;
            logReply (code, requestStr, message);
            sendReply (
                code, false, "<h1>"+code+Code.msg(code)+""+message
            );
            closeConnection(connection);
        }

        void sendReply (
            int code, boolean closeNow, String text)
        {
            try {
                StringBuilder builder = new StringBuilder (512);
                builder.append ("HTTP/1.1 ")
                    .append (code).append (Code.msg(code)).append ("\r\n");

                if (text != null && text.length() != 0) {
                    builder.append ("Content-Length: ")
                        .append (text.length()).append ("\r\n")
                        .append ("Content-Type: text/html\r\n");
                } else {
                    builder.append ("Content-Length: 0\r\n");
                    text = "";
                }
                if (closeNow) {
                    builder.append ("Connection: close\r\n");
                }
                builder.append ("\r\n").append (text);
                String s = builder.toString();
                byte[] b = s.getBytes("ISO8859_1");
                rawout.write (b);
                rawout.flush();
                if (closeNow) {
                    closeConnection(connection);
                }
            } catch (IOException e) {
                logger.log (Level.FINER, "ServerImpl.sendReply", e);
                closeConnection(connection);
            }
        }

    }

    void logReply (int code, String requestStr, String text) {
        if (!logger.isLoggable(Level.FINE)) {
            return;
        }
        if (text == null) {
            text = "";
        }
        String r;
        if (requestStr.length() > 80) {
           r = requestStr.substring (0, 80) + "<TRUNCATED>";
        } else {
           r = requestStr;
        }
        String message = r + " [" + code + " " +
                    Code.msg(code) + "] ("+text+")";
        logger.fine (message);
    }

    long getTicks() {
        return ticks;
    }

    public long getTime() {
        return time;
    }

    void delay () {
        Thread.yield();
        try {
            Thread.sleep (200);
        } catch (InterruptedException e) {}
    }

    private int exchangeCount = 0;

    synchronized void startExchange () {
        exchangeCount ++;
    }

    synchronized int endExchange () {
        exchangeCount --;
        assert exchangeCount >= 0;
        return exchangeCount;
    }

    HttpServer getWrapper () {
        return wrapper;
    }

    void requestStarted (HttpConnection c) {
        c.creationTime = getTime();
        c.setState (State.REQUEST);
        reqConnections.add (c);
    }

    // called after a request has been completely read
    // by the server. This stops the timer which would
    // close the connection if the request doesn't arrive
    // quickly enough. It then starts the timer
    // that ensures the client reads the response in a timely
    // fashion.

    void requestCompleted (HttpConnection c) {
        assert c.getState() == State.REQUEST;
        reqConnections.remove (c);
        c.rspStartedTime = getTime();
        rspConnections.add (c);
        c.setState (State.RESPONSE);
    }

    // called after response has been sent
    void responseCompleted (HttpConnection c) {
        assert c.getState() == State.RESPONSE;
        rspConnections.remove (c);
        c.setState (State.IDLE);
    }

    /**
     * TimerTask run every CLOCK_TICK ms
     */
    class ServerTimerTask extends TimerTask {
        public void run () {
            LinkedList<HttpConnection> toClose = new LinkedList();
            time = System.currentTimeMillis();
            ticks ++;
            synchronized (idleConnections) {
                for (HttpConnection c : idleConnections) {
                    if (c.time <= time) {
                        toClose.add (c);
                    }
                }
                for (HttpConnection c : toClose) {
                    idleConnections.remove (c);
                    allConnections.remove (c);
                    c.close();
                }
            }
        }
    }

    class ServerTimerTask1 extends TimerTask {

        // runs every TIMER_MILLIS
        public void run () {
            LinkedList<HttpConnection> toClose = new LinkedList();
            time = System.currentTimeMillis();
            synchronized (reqConnections) {
                if (MAX_REQ_TIME != -1) {
                    for (HttpConnection c : reqConnections) {
                        if (c.creationTime + TIMER_MILLIS + MAX_REQ_TIME <= time) {
                            toClose.add (c);
                        }
                    }
                    for (HttpConnection c : toClose) {
                        logger.log (Level.FINE, "closing: no request: " + c);
                        reqConnections.remove (c);
                        allConnections.remove (c);
                        c.close();
                    }
                }
            }
            toClose = new LinkedList<HttpConnection>();
            synchronized (rspConnections) {
                if (MAX_RSP_TIME != -1) {
                    for (HttpConnection c : rspConnections) {
                        if (c.rspStartedTime + TIMER_MILLIS +MAX_RSP_TIME <= time) {
                            toClose.add (c);
                        }
                    }
                    for (HttpConnection c : toClose) {
                        logger.log (Level.FINE, "closing: no response: " + c);
                        rspConnections.remove (c);
                        allConnections.remove (c);
                        c.close();
                    }
                }
            }
        }
    }

    void logStackTrace (String s) {
        logger.finest (s);
        StringBuilder b = new StringBuilder ();
        StackTraceElement[] e = Thread.currentThread().getStackTrace();
        for (int i=0; i<e.length; i++) {
            b.append (e[i].toString()).append("\n");
        }
        logger.finest (b.toString());
    }

    static long getTimeMillis(long secs) {
        if (secs == -1) {
            return -1;
        } else {
            return secs * 1000;
        }
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java ServerImpl.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.