/** * Expected to be used by the handler once the processor is no longer required. * * @param socket * @param processor * @param isSocketClosing Not used in HTTP * @param addToPoller */ @Override public void release( SocketWrapper<NioChannel> socket, Processor<NioChannel> processor, boolean isSocketClosing, boolean addToPoller) { processor.recycle(isSocketClosing); recycledProcessors.offer(processor); if (addToPoller) { // The only time this method is called with addToPoller == true // is when the socket is in keep-alive so set the appropriate // timeout. socket.setTimeout(getProtocol().getKeepAliveTimeout()); socket.getSocket().getPoller().add(socket.getSocket()); } }
/** * Process pipelined HTTP requests using the specified input and output streams. * * @throws IOException error during an I/O operation */ @Override public SocketState process(SocketWrapper<NioChannel> socket) throws IOException { RequestInfo rp = request.getRequestProcessor(); rp.setStage(org.apache.coyote.Constants.STAGE_PARSE); // Setting up the socket this.socketWrapper = socket; long soTimeout = endpoint.getSoTimeout(); boolean cping = false; // Error flag error = false; while (!error && !endpoint.isPaused()) { // Parsing the request header try { // Get first message of the request int bytesRead = readMessage(requestHeaderMessage, false); if (bytesRead == 0) { break; } // Set back timeout if keep alive timeout is enabled if (keepAliveTimeout > 0) { socket.setTimeout(soTimeout); } // Check message type, process right away and break if // not regular request processing int type = requestHeaderMessage.getByte(); if (type == Constants.JK_AJP13_CPING_REQUEST) { if (endpoint.isPaused()) { recycle(true); break; } cping = true; try { output(pongMessageArray, 0, pongMessageArray.length); } catch (IOException e) { error = true; } recycle(false); continue; } else if (type != Constants.JK_AJP13_FORWARD_REQUEST) { // Unexpected packet type. Unread body packets should have // been swallowed in finish(). if (log.isDebugEnabled()) { log.debug("Unexpected message: " + type); } error = true; recycle(true); break; } request.setStartTime(System.currentTimeMillis()); } catch (IOException e) { error = true; break; } catch (Throwable t) { ExceptionUtils.handleThrowable(t); log.debug(sm.getString("ajpprocessor.header.error"), t); // 400 - Bad Request response.setStatus(400); adapter.log(request, response, 0); error = true; } if (!error) { // Setting up filters, and parse some request headers rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE); try { prepareRequest(); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); log.debug(sm.getString("ajpprocessor.request.prepare"), t); // 400 - Internal Server Error response.setStatus(400); adapter.log(request, response, 0); error = true; } } if (!error && !cping && endpoint.isPaused()) { // 503 - Service unavailable response.setStatus(503); adapter.log(request, response, 0); error = true; } cping = false; // Process the request in the adapter if (!error) { try { rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE); adapter.service(request, response); } catch (InterruptedIOException e) { error = true; } catch (Throwable t) { ExceptionUtils.handleThrowable(t); log.error(sm.getString("ajpprocessor.request.process"), t); // 500 - Internal Server Error response.setStatus(500); adapter.log(request, response, 0); error = true; } } if (isAsync() && !error) { break; } // Finish the response if not done yet if (!finished) { try { finish(); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); error = true; } } // If there was an error, make sure the request is counted as // and error, and update the statistics counter if (error) { response.setStatus(500); } request.updateCounters(); rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE); // Set keep alive timeout if enabled if (keepAliveTimeout > 0) { socket.setTimeout(keepAliveTimeout); } recycle(false); } rp.setStage(org.apache.coyote.Constants.STAGE_ENDED); if (!error && !endpoint.isPaused()) { if (isAsync()) { return SocketState.LONG; } else { return SocketState.OPEN; } } else { return SocketState.CLOSED; } }
/** * Send an action to the connector. * * @param actionCode Type of the action * @param param Action parameter */ @Override public void actionInternal(ActionCode actionCode, Object param) { if (actionCode == ActionCode.REQ_SSL_ATTRIBUTE) { try { if (sslSupport != null) { Object sslO = sslSupport.getCipherSuite(); if (sslO != null) request.setAttribute(SSLSupport.CIPHER_SUITE_KEY, sslO); sslO = sslSupport.getPeerCertificateChain(false); if (sslO != null) request.setAttribute(SSLSupport.CERTIFICATE_KEY, sslO); sslO = sslSupport.getKeySize(); if (sslO != null) request.setAttribute(SSLSupport.KEY_SIZE_KEY, sslO); sslO = sslSupport.getSessionId(); if (sslO != null) request.setAttribute(SSLSupport.SESSION_ID_KEY, sslO); request.setAttribute(SSLSupport.SESSION_MGR, sslSupport); } } catch (Exception e) { log.warn(sm.getString("http11processor.socket.ssl"), e); } } else if (actionCode == ActionCode.REQ_HOST_ADDR_ATTRIBUTE) { if ((remoteAddr == null) && (socket != null)) { InetAddress inetAddr = socket.getSocket().getInetAddress(); if (inetAddr != null) { remoteAddr = inetAddr.getHostAddress(); } } request.remoteAddr().setString(remoteAddr); } else if (actionCode == ActionCode.REQ_LOCAL_NAME_ATTRIBUTE) { if ((localName == null) && (socket != null)) { InetAddress inetAddr = socket.getSocket().getLocalAddress(); if (inetAddr != null) { localName = inetAddr.getHostName(); } } request.localName().setString(localName); } else if (actionCode == ActionCode.REQ_HOST_ATTRIBUTE) { if ((remoteHost == null) && (socket != null)) { InetAddress inetAddr = socket.getSocket().getInetAddress(); if (inetAddr != null) { remoteHost = inetAddr.getHostName(); } if (remoteHost == null) { if (remoteAddr != null) { remoteHost = remoteAddr; } else { // all we can do is punt request.remoteHost().recycle(); } } } request.remoteHost().setString(remoteHost); } else if (actionCode == ActionCode.REQ_LOCAL_ADDR_ATTRIBUTE) { if (localAddr == null) localAddr = socket.getSocket().getLocalAddress().getHostAddress(); request.localAddr().setString(localAddr); } else if (actionCode == ActionCode.REQ_REMOTEPORT_ATTRIBUTE) { if ((remotePort == -1) && (socket != null)) { remotePort = socket.getSocket().getPort(); } request.setRemotePort(remotePort); } else if (actionCode == ActionCode.REQ_LOCALPORT_ATTRIBUTE) { if ((localPort == -1) && (socket != null)) { localPort = socket.getSocket().getLocalPort(); } request.setLocalPort(localPort); } else if (actionCode == ActionCode.REQ_SSL_CERTIFICATE) { if (sslSupport != null) { /* * Consume and buffer the request body, so that it does not * interfere with the client's handshake messages */ InputFilter[] inputFilters = inputBuffer.getFilters(); ((BufferedInputFilter) inputFilters[Constants.BUFFERED_FILTER]).setLimit(maxSavePostSize); inputBuffer.addActiveFilter(inputFilters[Constants.BUFFERED_FILTER]); try { Object sslO = sslSupport.getPeerCertificateChain(true); if (sslO != null) { request.setAttribute(SSLSupport.CERTIFICATE_KEY, sslO); } } catch (Exception e) { log.warn(sm.getString("http11processor.socket.ssl"), e); } } } else if (actionCode == ActionCode.ASYNC_COMPLETE) { if (asyncStateMachine.asyncComplete()) { ((JIoEndpoint) endpoint).processSocketAsync(this.socket, SocketStatus.OPEN); } } else if (actionCode == ActionCode.ASYNC_SETTIMEOUT) { if (param == null) return; long timeout = ((Long) param).longValue(); // if we are not piggy backing on a worker thread, set the timeout socket.setTimeout(timeout); } else if (actionCode == ActionCode.ASYNC_DISPATCH) { if (asyncStateMachine.asyncDispatch()) { ((JIoEndpoint) endpoint).processSocketAsync(this.socket, SocketStatus.OPEN); } } }