private void resetClientTimer(Socket socket) { if (this.idleClientTimer == null) { if (log.logTrace()) { log.trace("No idle client timeout configured, skipping timer reset"); } return; } if (log.logTrace()) { log.trace("Resetting idle client timer: " + System.identityHashCode(socket)); } // Store this in a local so we don't have to worry about // the value changing underneath us. long timeout = this.idleClientTimeout; // Cancel the existing task for this socket ... TimerTask curTask = (TimerTask) this.socketActivity.get(socket); if (curTask != null) { curTask.cancel(); } // And schedule a new one. TimerTask task = new IdleClientTimerTask(socket); this.socketActivity.put(socket, task); this.idleClientTimer.schedule(task, timeout); }
/** * Converts an exception raised while processing an HTTP request into a suitable HTTP response. * * <p>The response is marshalled and queued for writing on the socket associated with the original * request. * * @param msg The HTTP request being processed when the exception occurred. * @param e The exception that was raised. * @throws IOException if an error occurs marshalling or writing the response. */ protected void handleMessageException(HttpMessageBuffer msg, Exception e) throws IOException { HttpResponse httpRsp; if (e instanceof HttpResponseException) { if (log.logWarn()) { log.warn("HttpResponseException", e); } httpRsp = this.newHttpResponse(msg, (HttpResponseException) e); this.queueWrite(msg.getSocket(), httpRsp.marshal(), true); } else if (e instanceof RemoteSocketClosedException) { if (log.logTrace()) { log.trace("Remote entity closed connection", e); } } else { if (log.logError()) { log.error("Internal Server Error", e); } httpRsp = this.newHttpResponse( msg, new HttpResponseException( HttpConstants.StatusCodes._500_INTERNAL_SERVER_ERROR, "Internal Server Error", e)); this.queueWrite(msg.getSocket(), httpRsp.marshal(), true); } }
/** * Called when a new connection is pending on the underlying {@link ServerSocketChannel}. * * @param key The {@link SelectionKey} for the socket on which a connection is pending. * @throws IOException if an error occurs while accepting the new connection. */ protected void accept(SelectionKey key) throws IOException { // Pull out the socket channel that has a connection pending ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel(); // Accept the connection SocketChannel socketChannel = serverSocketChannel.accept(); Socket socket = socketChannel.socket(); // Check if our AcceptPolicy will allow this new connection if (this.acceptPolicy != null && !this.acceptPolicy.shouldRetain(socketChannel, this.getSocketSelector().keys().size())) { if (log.logTrace()) { log.trace("Closing accepted connection (accept policy enforced)"); } socketChannel.close(); return; } this.registerChannel(socketChannel); // Register the new socket. This will promote it to an SSLSocket // if we're configured for HTTPS. this.registerSocket(socket, this.host, this.port, false); // Add the new SocketChannel to our Selector socketChannel.configureBlocking(false); SelectionKey acceptKey = socketChannel.register(this.getSocketSelector(), SelectionKey.OP_READ); this.resetClientTimer(socketChannel.socket()); }